00001 00012 template <typename T> 00013 class Visitor 00014 { 00015 protected: 00016 //Defines the type that is being operated on 00017 typedef T ArgBase; 00018 00023 virtual void do_visit(ArgBase &obj)=0; 00024 00030 virtual void try_visit(ArgBase & obj) 00031 { 00032 do_visit(obj); 00033 } 00034 00035 public: 00040 virtual void visit(ArgBase &obj) 00041 { 00042 do_visit(obj); 00043 } 00044 }; 00045 00049 namespace visitor 00050 { 00059 template <typename S, typename P> 00060 class SV: public P 00061 { 00062 protected: 00064 typedef P Parent; 00065 00067 typedef S ArgSub; 00068 00070 typedef typename Parent::ArgBase ArgBase; 00071 00077 void try_visit(ArgBase &ob) 00078 { 00079 // We dynamically cast pointers because this is probably faster than 00080 // casting references 00081 ArgSub *s=dynamic_cast<ArgSub *>(&ob); 00082 if (s==NULL) Parent::try_visit(ob); 00083 else do_visit(*s); 00084 } 00085 00090 virtual void do_visit(ArgSub &ob)=0; 00091 00092 public: 00097 void visit(ArgBase &ob) 00098 { 00099 try_visit(ob); 00100 } 00101 }; 00102 00109 template <typename Mytype, typename ListRemain> 00110 class TlVisitor_helper 00111 { 00112 public: 00114 typedef SV<Mytype, typename TlVisitor_helper<typename ListRemain::Head, 00115 typename ListRemain::Tail>::Ret> Ret; 00116 }; 00117 00118 00124 template <typename Mytype> 00125 class TlVisitor_helper<Mytype, meta::Nil> 00126 { 00127 public: 00129 typedef Visitor<Mytype> Ret; 00130 }; 00131 00132 00142 template <typename List> 00143 class TlVisitor 00144 { 00145 public: 00150 typedef typename TlVisitor_helper<typename List::Head, typename List::Tail>::Ret Ret; 00151 }; 00152 }