|
@@ -0,0 +1,161 @@
|
|
|
+#ifndef QLOW_VISITOR_H
|
|
|
+#define QLOW_VISITOR_H
|
|
|
+
|
|
|
+
|
|
|
+namespace qlow
|
|
|
+{
|
|
|
+ template<typename R, typename... T>
|
|
|
+ class Visitor;
|
|
|
+
|
|
|
+ template<typename R>
|
|
|
+ class Visitor<R>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ using ReturnType = R;
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename R, typename T>
|
|
|
+ class Visitor<R, T> :
|
|
|
+ public Visitor<R>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ using ReturnType = R;
|
|
|
+ virtual R visit(T& arg) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ template<typename R, typename T, typename... V>
|
|
|
+ class Visitor<R, T, V...> :
|
|
|
+ public Visitor<R, V...>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ using Visitor<R, V...>::visit;
|
|
|
+ using ReturnType = R;
|
|
|
+ virtual R visit(T& arg) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ template<typename RT, typename V>
|
|
|
+ class Visitable
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ virtual ~Visitable(void) {}
|
|
|
+ virtual RT accept(V& visitor) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//
|
|
|
+// template<class T>
|
|
|
+// class Visitable
|
|
|
+// {
|
|
|
+// public:
|
|
|
+// template<typename Visitor>
|
|
|
+// void accept(Visitor& v)
|
|
|
+// {
|
|
|
+// v.visit(static_cast<T&>(*this));
|
|
|
+// }
|
|
|
+// };
|
|
|
+//
|
|
|
+
|
|
|
+//
|
|
|
+//// Visitor template declaration
|
|
|
+//template<typename... Types>
|
|
|
+//class Visitor;
|
|
|
+//
|
|
|
+//// specialization for single type
|
|
|
+//template<typename T>
|
|
|
+//class Visitor<T> {
|
|
|
+//public:
|
|
|
+// virtual void visit(T & visitable) = 0;
|
|
|
+//};
|
|
|
+//
|
|
|
+//// specialization for multiple types
|
|
|
+//template<typename T, typename... Types>
|
|
|
+//class Visitor<T, Types...> : public Visitor<Types...> {
|
|
|
+//public:
|
|
|
+// // promote the function(s) from the base class
|
|
|
+// using Visitor<Types...>::visit;
|
|
|
+//
|
|
|
+// virtual void visit(T & visitable) = 0;
|
|
|
+//};
|
|
|
+//
|
|
|
+//template<typename... Types>
|
|
|
+//class Visitable {
|
|
|
+//public:
|
|
|
+// virtual void accept(Visitor<Types...>& visitor) = 0;
|
|
|
+//};
|
|
|
+//
|
|
|
+//template<typename Derived, typename... Types>
|
|
|
+//class VisitableImpl : public virtual Visitable<Types...> {
|
|
|
+//public:
|
|
|
+// virtual void accept(Visitor<Types...>& visitor) {
|
|
|
+// visitor.visit(static_cast<Derived&>(*this));
|
|
|
+// }
|
|
|
+//};
|
|
|
+//
|
|
|
+
|
|
|
+
|
|
|
+#if 0
|
|
|
+ template<typename... T>
|
|
|
+ class Visitor;
|
|
|
+
|
|
|
+ template<>
|
|
|
+ class Visitor<>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename T>
|
|
|
+ class Visitor<T> :
|
|
|
+ public Visitor<>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ virtual void visit(T& arg) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ template<typename T, typename... V>
|
|
|
+ class Visitor<T, V...> :
|
|
|
+ public Visitor<V...>
|
|
|
+ {
|
|
|
+ public:
|
|
|
+ using Visitor<V...>::visit;
|
|
|
+ virtual void visit(T& arg) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+//
|
|
|
+// template<typename VT>
|
|
|
+// class VisitableBase
|
|
|
+// {
|
|
|
+// public:
|
|
|
+// virtual typename VisitorType::ReturnType accept(VisitorType& visitor);
|
|
|
+// };
|
|
|
+//
|
|
|
+
|
|
|
+ template<typename VT>
|
|
|
+ class VisitableBase
|
|
|
+ {
|
|
|
+// public:
|
|
|
+// using VisitorType = VT;
|
|
|
+// typename VisitorType::ReturnType accept(VisitorType& visitor)
|
|
|
+// {
|
|
|
+// return visitor.visit(static_cast<T&>(*this));
|
|
|
+// }
|
|
|
+ public:
|
|
|
+ template <typename T>
|
|
|
+ void accept(T& visitor)
|
|
|
+ {
|
|
|
+ visitor.visit(static_cast<VT&>(*this));
|
|
|
+ }
|
|
|
+ };
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#endif // QLOW_VISITOR_H
|
|
|
+
|