20 #ifndef PALUDIS_GUARD_PALUDIS_UTIL_VISITOR_HH
21 #define PALUDIS_GUARD_PALUDIS_UTIL_VISITOR_HH 1
24 #include <paludis/util/visitor-fwd.hh>
36 template <
typename TypeList_>
43 virtual void forward_visit(
typename TypeList_::Item &) = 0;
46 template <
typename TypeList_>
47 class WrappedVisitorBase :
48 public virtual DeclareAbstractVisitMethods<TypeList_>
52 template <
typename RealClass_>
59 template <
typename RealClass_,
typename TypeList_>
67 virtual void forward_visit(
typename TypeList_::Item & n)
71 static_cast<RealClass_ *
>(
this)->perform_visit(n);
75 template <
typename TypeList_,
typename UnwrappedVisitor_>
76 class WrappedVoidResultVisitor :
77 public WrappedVisitorBase<TypeList_>,
78 public ImplementVisitMethods<WrappedVoidResultVisitor<TypeList_, UnwrappedVisitor_>, TypeList_>
81 UnwrappedVisitor_ & _unwrapped_visitor;
84 WrappedVoidResultVisitor(UnwrappedVisitor_ & v) :
89 template <
typename C_>
90 void perform_visit(C_ & t)
92 _unwrapped_visitor.visit(t);
96 template <
typename TypeList_,
typename Result_,
typename UnwrappedVisitor_>
97 class WrappedNonVoidResultVisitor :
98 public WrappedVisitorBase<TypeList_>,
99 public ImplementVisitMethods<WrappedNonVoidResultVisitor<TypeList_, Result_, UnwrappedVisitor_>,
103 UnwrappedVisitor_ & _unwrapped_visitor;
108 WrappedNonVoidResultVisitor(UnwrappedVisitor_ & v,
const Result_ & r) :
109 _unwrapped_visitor(v),
114 template <
typename C_>
115 void perform_visit(C_ & t)
117 result = _unwrapped_visitor.visit(t);
121 template <
typename BaseClass_,
typename VisitableTypeList_>
122 class DeclareAbstractAcceptMethods
125 virtual void _real_accept(WrappedVisitorBase<VisitableTypeList_> &) = 0;
126 virtual void _real_accept_const(WrappedVisitorBase<
typename MakeTypeListConst<VisitableTypeList_>::Type> &)
const = 0;
129 typedef VisitableTypeList_ VisitableTypeList;
130 typedef BaseClass_ VisitableBaseClass;
132 template <
typename UnwrappedVisitor_>
133 void accept(UnwrappedVisitor_ & v)
135 WrappedVoidResultVisitor<VisitableTypeList_, UnwrappedVisitor_> vv(v);
139 template <
typename UnwrappedVisitor_>
140 void accept(UnwrappedVisitor_ & v)
const
142 WrappedVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type, UnwrappedVisitor_> vv(v);
143 _real_accept_const(vv);
146 template <
typename UnwrappedVisitor_>
147 void accept(
const UnwrappedVisitor_ & v)
149 WrappedVoidResultVisitor<VisitableTypeList_, const UnwrappedVisitor_> vv(v);
153 template <
typename UnwrappedVisitor_>
154 void accept(
const UnwrappedVisitor_ & v)
const
156 WrappedVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type,
const UnwrappedVisitor_> vv(v);
157 _real_accept_const(vv);
160 template <
typename Result_,
typename UnwrappedVisitor_>
161 Result_ accept_returning(UnwrappedVisitor_ & v,
const Result_ & r = Result_())
163 WrappedNonVoidResultVisitor<VisitableTypeList_, Result_, UnwrappedVisitor_> vv(v, r);
168 template <
typename Result_,
typename UnwrappedVisitor_>
169 Result_ accept_returning(
const UnwrappedVisitor_ & v,
const Result_ & r = Result_())
171 WrappedNonVoidResultVisitor<VisitableTypeList_, Result_, const UnwrappedVisitor_> vv(v, r);
176 template <
typename Result_,
typename UnwrappedVisitor_>
177 Result_ accept_returning(UnwrappedVisitor_ & v,
const Result_ & r = Result_())
const
179 WrappedNonVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type, Result_, UnwrappedVisitor_> vv(v, r);
180 _real_accept_const(vv);
184 template <
typename Result_,
typename UnwrappedVisitor_>
185 Result_ accept_returning(
const UnwrappedVisitor_ & v,
const Result_ & r = Result_())
const
187 WrappedNonVoidResultVisitor<typename MakeTypeListConst<VisitableTypeList_>::Type, Result_,
const UnwrappedVisitor_> vv(v, r);
188 _real_accept_const(vv);
193 template <
typename BaseClass_,
typename RealClass_>
195 public virtual DeclareAbstractAcceptMethods<BaseClass_, typename BaseClass_::VisitableTypeList>
198 void _real_accept(WrappedVisitorBase<typename BaseClass_::VisitableTypeList> & v)
200 v.forward_visit(*static_cast<RealClass_ *>(
this));
203 void _real_accept_const(WrappedVisitorBase<
typename MakeTypeListConst<typename BaseClass_::VisitableTypeList>::Type> & v)
const
205 v.forward_visit(*static_cast<const RealClass_ *>(
this));