Visitor.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #ifndef QLOW_VISITOR_H
  2. #define QLOW_VISITOR_H
  3. namespace qlow
  4. {
  5. template<typename R, typename... T>
  6. class Visitor;
  7. template<typename R>
  8. class Visitor<R>
  9. {
  10. public:
  11. using ReturnType = R;
  12. };
  13. template<typename R, typename T>
  14. class Visitor<R, T> :
  15. public Visitor<R>
  16. {
  17. public:
  18. using ReturnType = R;
  19. virtual R visit(T& arg) = 0;
  20. };
  21. template<typename R, typename T, typename... V>
  22. class Visitor<R, T, V...> :
  23. public Visitor<R, V...>
  24. {
  25. public:
  26. using Visitor<R, V...>::visit;
  27. using ReturnType = R;
  28. virtual R visit(T& arg) = 0;
  29. };
  30. template<typename RT, typename V>
  31. class Visitable
  32. {
  33. public:
  34. virtual ~Visitable(void) {}
  35. virtual RT accept(V& visitor) = 0;
  36. };
  37. //
  38. // template<class T>
  39. // class Visitable
  40. // {
  41. // public:
  42. // template<typename Visitor>
  43. // void accept(Visitor& v)
  44. // {
  45. // v.visit(static_cast<T&>(*this));
  46. // }
  47. // };
  48. //
  49. //
  50. //// Visitor template declaration
  51. //template<typename... Types>
  52. //class Visitor;
  53. //
  54. //// specialization for single type
  55. //template<typename T>
  56. //class Visitor<T> {
  57. //public:
  58. // virtual void visit(T & visitable) = 0;
  59. //};
  60. //
  61. //// specialization for multiple types
  62. //template<typename T, typename... Types>
  63. //class Visitor<T, Types...> : public Visitor<Types...> {
  64. //public:
  65. // // promote the function(s) from the base class
  66. // using Visitor<Types...>::visit;
  67. //
  68. // virtual void visit(T & visitable) = 0;
  69. //};
  70. //
  71. //template<typename... Types>
  72. //class Visitable {
  73. //public:
  74. // virtual void accept(Visitor<Types...>& visitor) = 0;
  75. //};
  76. //
  77. //template<typename Derived, typename... Types>
  78. //class VisitableImpl : public virtual Visitable<Types...> {
  79. //public:
  80. // virtual void accept(Visitor<Types...>& visitor) {
  81. // visitor.visit(static_cast<Derived&>(*this));
  82. // }
  83. //};
  84. //
  85. #if 0
  86. template<typename... T>
  87. class Visitor;
  88. template<>
  89. class Visitor<>
  90. {
  91. public:
  92. };
  93. template<typename T>
  94. class Visitor<T> :
  95. public Visitor<>
  96. {
  97. public:
  98. virtual void visit(T& arg) = 0;
  99. };
  100. template<typename T, typename... V>
  101. class Visitor<T, V...> :
  102. public Visitor<V...>
  103. {
  104. public:
  105. using Visitor<V...>::visit;
  106. virtual void visit(T& arg) = 0;
  107. };
  108. //
  109. // template<typename VT>
  110. // class VisitableBase
  111. // {
  112. // public:
  113. // virtual typename VisitorType::ReturnType accept(VisitorType& visitor);
  114. // };
  115. //
  116. template<typename VT>
  117. class VisitableBase
  118. {
  119. // public:
  120. // using VisitorType = VT;
  121. // typename VisitorType::ReturnType accept(VisitorType& visitor)
  122. // {
  123. // return visitor.visit(static_cast<T&>(*this));
  124. // }
  125. public:
  126. template <typename T>
  127. void accept(T& visitor)
  128. {
  129. visitor.visit(static_cast<VT&>(*this));
  130. }
  131. };
  132. #endif
  133. }
  134. #endif // QLOW_VISITOR_H