00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef PALUDIS_GUARD_PALUDIS_UTIL_SIMPLE_VISITOR_HH
00021 #define PALUDIS_GUARD_PALUDIS_UTIL_SIMPLE_VISITOR_HH 1
00022
00023 #include <paludis/util/simple_visitor-fwd.hh>
00024 #include <paludis/util/no_type.hh>
00025
00026 namespace paludis
00027 {
00028 template <>
00029 struct DeclareAbstractVisitMethods<TypeListTail>
00030 {
00031 void forward_visit(const NoType<0u> &);
00032 };
00033
00034 template <typename TypeList_>
00035 class DeclareAbstractVisitMethods :
00036 public virtual DeclareAbstractVisitMethods<typename TypeList_::Tail>
00037 {
00038 public:
00039 using DeclareAbstractVisitMethods<typename TypeList_::Tail>::forward_visit;
00040
00041 virtual void forward_visit(typename TypeList_::Item &) = 0;
00042 };
00043
00044 template <typename TypeList_>
00045 class WrappedVisitorBase :
00046 public virtual DeclareAbstractVisitMethods<TypeList_>
00047 {
00048 };
00049
00050 template <typename RealClass_>
00051 class ImplementVisitMethods<RealClass_, TypeListTail>
00052 {
00053 public:
00054 void forward_visit(const NoType<1u> &);
00055 };
00056
00057 template <typename RealClass_, typename TypeList_>
00058 class ImplementVisitMethods :
00059 public virtual DeclareAbstractVisitMethods<TypeList_>,
00060 public ImplementVisitMethods<RealClass_, typename TypeList_::Tail>
00061 {
00062 public:
00063 using ImplementVisitMethods<RealClass_, typename TypeList_::Tail>::forward_visit;
00064
00065 virtual void forward_visit(typename TypeList_::Item & n)
00066 {
00067
00068 if (this)
00069 static_cast<RealClass_ *>(this)->perform_visit(n);
00070 }
00071 };
00072
00073 template <typename TypeList_, typename UnwrappedVisitor_>
00074 class WrappedVoidResultVisitor :
00075 public WrappedVisitorBase<TypeList_>,
00076 public ImplementVisitMethods<WrappedVoidResultVisitor<TypeList_, UnwrappedVisitor_>, TypeList_>
00077 {
00078 private:
00079 UnwrappedVisitor_ & _unwrapped_visitor;
00080
00081 public:
00082 WrappedVoidResultVisitor(UnwrappedVisitor_ & v) :
00083 _unwrapped_visitor(v)
00084 {
00085 }
00086
00087 template <typename C_>
00088 void perform_visit(C_ & t)
00089 {
00090 _unwrapped_visitor.visit(t);
00091 }
00092 };
00093
00094 template <typename TypeList_, typename Result_, typename UnwrappedVisitor_>
00095 class WrappedNonVoidResultVisitor :
00096 public WrappedVisitorBase<TypeList_>,
00097 public ImplementVisitMethods<WrappedNonVoidResultVisitor<TypeList_, Result_, UnwrappedVisitor_>,
00098 TypeList_>
00099 {
00100 private:
00101 UnwrappedVisitor_ & _unwrapped_visitor;
00102
00103 public:
00104 Result_ result;
00105
00106 WrappedNonVoidResultVisitor(UnwrappedVisitor_ & v, const Result_ & r) :
00107 _unwrapped_visitor(v),
00108 result(r)
00109 {
00110 }
00111
00112 template <typename C_>
00113 void perform_visit(C_ & t)
00114 {
00115 result = _unwrapped_visitor.visit(t);
00116 }
00117 };
00118
00119 template <typename BaseClass_, typename VisitableTypeList_>
00120 class DeclareAbstractAcceptMethods
00121 {
00122 private:
00123 virtual void _real_accept(WrappedVisitorBase<VisitableTypeList_> &) = 0;
00124 virtual void _real_accept_const(WrappedVisitorBase<typename MakeTypeListConst<VisitableTypeList_>::Type> &) const = 0;
00125
00126 public:
00127 typedef VisitableTypeList_ VisitableTypeList;
00128
00129 template <typename UnwrappedVisitor_>
00130 void accept(UnwrappedVisitor_ & v)
00131 {
00132 WrappedVoidResultVisitor<VisitableTypeList_, UnwrappedVisitor_> vv(v);
00133 _real_accept(vv);
00134 }
00135
00136 template <typename UnwrappedVisitor_>
00137 void accept(UnwrappedVisitor_ & v) const
00138 {
00139 WrappedVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type, UnwrappedVisitor_> vv(v);
00140 _real_accept_const(vv);
00141 }
00142
00143 template <typename Result_, typename UnwrappedVisitor_>
00144 Result_ accept_returning(UnwrappedVisitor_ & v, const Result_ & r = Result_())
00145 {
00146 WrappedNonVoidResultVisitor<VisitableTypeList_, Result_, UnwrappedVisitor_> vv(v, r);
00147 _real_accept(vv);
00148 return vv.result;
00149 }
00150
00151 template <typename Result_, typename UnwrappedVisitor_>
00152 Result_ accept_returning(UnwrappedVisitor_ & v, const Result_ & r = Result_()) const
00153 {
00154 WrappedNonVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type, Result_, UnwrappedVisitor_> vv(v, r);
00155 _real_accept_const(vv);
00156 return vv.result;
00157 }
00158 };
00159
00160 template <typename BaseClass_, typename RealClass_>
00161 class ImplementAcceptMethods :
00162 public virtual DeclareAbstractAcceptMethods<BaseClass_, typename BaseClass_::VisitableTypeList>
00163 {
00164 private:
00165 void _real_accept(WrappedVisitorBase<typename BaseClass_::VisitableTypeList> & v)
00166 {
00167 v.forward_visit(*static_cast<RealClass_ *>(this));
00168 };
00169
00170 void _real_accept_const(WrappedVisitorBase<typename MakeTypeListConst<typename BaseClass_::VisitableTypeList>::Type> & v) const
00171 {
00172 v.forward_visit(*static_cast<const RealClass_ *>(this));
00173 };
00174 };
00175 }
00176
00177 #endif