00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #ifndef LOKI_VISITOR_INC_
00016 #define LOKI_VISITOR_INC_
00017
00018
00019
00020
00022
00023 #include "Typelist.h"
00024 #include "HierarchyGenerators.h"
00025
00026 namespace Loki
00027 {
00028
00035
00036 class BaseVisitor
00037 {
00038 public:
00039 virtual ~BaseVisitor() {}
00040 };
00041
00124
00125 template <class T, typename R = void, bool ConstVisit = false>
00126 class Visitor;
00127
00128 template <class T, typename R>
00129 class Visitor<T, R, false>
00130 {
00131 public:
00132 typedef R ReturnType;
00133 typedef T ParamType;
00134 virtual ~Visitor() {}
00135 virtual ReturnType Visit(ParamType&) = 0;
00136 };
00137
00138 template <class T, typename R>
00139 class Visitor<T, R, true>
00140 {
00141 public:
00142 typedef R ReturnType;
00143 typedef const T ParamType;
00144 virtual ~Visitor() {}
00145 virtual ReturnType Visit(ParamType&) = 0;
00146 };
00147
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00162
00163 template <class Head, class Tail, typename R>
00164 class Visitor<Typelist<Head, Tail>, R, false>
00165 : public Visitor<Head, R, false>, public Visitor<Tail, R, false>
00166 {
00167 public:
00168 typedef R ReturnType;
00169
00170
00171 };
00172
00173 template <class Head, typename R>
00174 class Visitor<Typelist<Head, NullType>, R, false> : public Visitor<Head, R, false>
00175 {
00176 public:
00177 typedef R ReturnType;
00178 using Visitor<Head, R, false>::Visit;
00179 };
00180
00181 template <class Head, class Tail, typename R>
00182 class Visitor<Typelist<Head, Tail>, R, true>
00183 : public Visitor<Head, R, true>, public Visitor<Tail, R, true>
00184 {
00185 public:
00186 typedef R ReturnType;
00187
00188
00189 };
00190
00191 template <class Head, typename R>
00192 class Visitor<Typelist<Head, NullType>, R, true> : public Visitor<Head, R, true>
00193 {
00194 public:
00195 typedef R ReturnType;
00196 using Visitor<Head, R, true>::Visit;
00197 };
00198
00199
00201
00202
00203
00205
00206 template <class TList, typename R = void> class BaseVisitorImpl;
00207
00208 template <class Head, class Tail, typename R>
00209 class BaseVisitorImpl<Typelist<Head, Tail>, R>
00210 : public Visitor<Head, R>
00211 , public BaseVisitorImpl<Tail, R>
00212 {
00213 public:
00214
00215
00216 virtual R Visit(Head&)
00217 { return R(); }
00218 };
00219
00220 template <class Head, typename R>
00221 class BaseVisitorImpl<Typelist<Head, NullType>, R>
00222 : public Visitor<Head, R>
00223 {
00224 public:
00225 virtual R Visit(Head&)
00226 { return R(); }
00227 };
00228
00230
00232
00233 template <typename R, typename Visited>
00234 struct DefaultCatchAll
00235 {
00236 static R OnUnknownVisitor(Visited&, BaseVisitor&)
00237 { return R(); }
00238 };
00239
00241
00243
00244 template
00245 <
00246 typename R = void,
00247 template <typename, class> class CatchAll = DefaultCatchAll,
00248 bool ConstVisitable = false
00249 >
00250 class BaseVisitable;
00251
00252 template<typename R,template <typename, class> class CatchAll>
00253 class BaseVisitable<R, CatchAll, false>
00254 {
00255 public:
00256 typedef R ReturnType;
00257 virtual ~BaseVisitable() {}
00258 virtual ReturnType Accept(BaseVisitor&) = 0;
00259
00260 protected:
00261 template <class T>
00262 static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
00263 {
00264
00265 if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(&guest))
00266 {
00267 return p->Visit(visited);
00268 }
00269 return CatchAll<R, T>::OnUnknownVisitor(visited, guest);
00270 }
00271 };
00272
00273 template<typename R,template <typename, class> class CatchAll>
00274 class BaseVisitable<R, CatchAll, true>
00275 {
00276 public:
00277 typedef R ReturnType;
00278 virtual ~BaseVisitable() {}
00279 virtual ReturnType Accept(BaseVisitor&) const = 0;
00280
00281 protected:
00282 template <class T>
00283 static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest)
00284 {
00285
00286 if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(&guest))
00287 {
00288 return p->Visit(visited);
00289 }
00290 return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest);
00291 }
00292 };
00293
00294
00301
00302 #define LOKI_DEFINE_VISITABLE() \
00303 virtual ReturnType Accept(::Loki::BaseVisitor& guest) \
00304 { return AcceptImpl(*this, guest); }
00305
00312
00313 #define LOKI_DEFINE_CONST_VISITABLE() \
00314 virtual ReturnType Accept(::Loki::BaseVisitor& guest) const \
00315 { return AcceptImpl(*this, guest); }
00316
00324
00325 template <typename R, class TList>
00326 class CyclicVisitor : public Visitor<TList, R>
00327 {
00328 public:
00329 typedef R ReturnType;
00330
00331
00332 template <class Visited>
00333 ReturnType GenericVisit(Visited& host)
00334 {
00335 Visitor<Visited, ReturnType>& subObj = *this;
00336 return subObj.Visit(host);
00337 }
00338 };
00339
00345
00346 #define LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) \
00347 virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \
00348 { return guest.GenericVisit(*this); }
00349
00350 }
00351
00352
00353
00354 #endif // end file guardian
00355