00001 #ifndef QPID_FRAMING_VISITOR_H
00002 #define QPID_FRAMING_VISITOR_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <boost/mpl/vector.hpp>
00025 #include <boost/type_traits/remove_reference.hpp>
00026 #include <boost/preprocessor/seq/for_each.hpp>
00027
00028 namespace qpid {
00029 namespace framing {
00030
00038 template <class T, class R=void> struct Visit {
00039 typedef R ReturnType;
00040 typedef T VisitType;
00041
00042 virtual ~Visit() {}
00043 virtual R visit(T&) = 0;
00044 };
00045
00046
00047 #define QPID_VISITOR_DECL(_1,_2,T) class T;
00048
00049 #define QPID_VISITOR_BASE(_1,_2,T) , public ::qpid::framing::Visit<T>
00050
00061 #define QPID_VISITOR(visitor,types) \
00062 BOOST_PP_SEQ_FOR_EACH(QPID_VISITOR_DECL, _, types) \
00063 class visitor : public ::qpid::framing::Visit<BOOST_PP_SEQ_HEAD(types)> \
00064 BOOST_PP_SEQ_FOR_EACH(QPID_VISITOR_BASE, _, BOOST_PP_SEQ_TAIL(types)) \
00065 {}
00066
00070 template <class V, class R=void>
00071 struct VisitableRoot {
00072 typedef V VisitorType;
00073 typedef R ReturnType;
00074 virtual ~VisitableRoot() {}
00075 virtual R accept(V& v) = 0;
00076 };
00077
00083 template <class T, class Base>
00084 struct Visitable : public Base {
00085 void accept(typename Base::VisitorType& v) {
00086 static_cast<Visit<T>& >(v).visit(static_cast<T&>(*this));
00087 }
00088 };
00089
00090 }}
00091
00092 #endif