diff options
Diffstat (limited to 'shared/loki/Visitor.h')
-rw-r--r-- | shared/loki/Visitor.h | 355 |
1 files changed, 0 insertions, 355 deletions
diff --git a/shared/loki/Visitor.h b/shared/loki/Visitor.h deleted file mode 100644 index 85b8acd2..00000000 --- a/shared/loki/Visitor.h +++ /dev/null @@ -1,355 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_VISITOR_INC_ -#define LOKI_VISITOR_INC_ - -// $Id: Visitor.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -/// \defgroup VisitorGroup Visitor - -#include "Typelist.h" -#include "HierarchyGenerators.h" - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class BaseVisitor -/// -/// \ingroup VisitorGroup -/// The base class of any Acyclic Visitor -//////////////////////////////////////////////////////////////////////////////// - -class BaseVisitor -{ -public: - virtual ~BaseVisitor() {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class Visitor -/// -/// \ingroup VisitorGroup -/// The building block of Acyclic Visitor -/// -/// \par Usage -/// -/// Defining the visitable class: -/// -/// \code -/// class RasterBitmap : public BaseVisitable<> -/// { -/// public: -/// LOKI_DEFINE_VISITABLE() -/// }; -/// \endcode -/// -/// Way 1 to define a visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<RasterBitmap>, -/// public Visitor<Paragraph> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// Way 2 to define the visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// Way 3 to define the visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<Seq<RasterBitmap, Paragraph>::Type> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// \par Using const visit functions: -/// -/// Defining the visitable class (true for const): -/// -/// \code -/// class RasterBitmap : public BaseVisitable<void, DefaultCatchAll, true> -/// { -/// public: -/// LOKI_DEFINE_CONST_VISITABLE() -/// }; -/// \endcode -/// -/// Defining the visitor which only calls const member functions: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<RasterBitmap, void, true>, -/// { -/// public: -/// void Visit(const RasterBitmap&); // visit a RasterBitmap by a const member function -/// }; -/// \endcode -/// -/// \par Example: -/// -/// test/Visitor/main.cpp -//////////////////////////////////////////////////////////////////////////////// - -template <class T, typename R = void, bool ConstVisit = false> -class Visitor; - -template <class T, typename R> -class Visitor<T, R, false> -{ -public: - typedef R ReturnType; - typedef T ParamType; - virtual ~Visitor() {} - virtual ReturnType Visit(ParamType&) = 0; -}; - -template <class T, typename R> -class Visitor<T, R, true> -{ -public: - typedef R ReturnType; - typedef const T ParamType; - virtual ~Visitor() {} - virtual ReturnType Visit(ParamType&) = 0; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Visitor (specialization) -// This specialization is not present in the book. It makes it easier to define -// Visitors for multiple types in a shot by using a typelist. Example: -// -// class SomeVisitor : -// public BaseVisitor // required -// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> -// { -// public: -// void Visit(RasterBitmap&); // visit a RasterBitmap -// void Visit(Paragraph &); // visit a Paragraph -// }; -//////////////////////////////////////////////////////////////////////////////// - -template <class Head, class Tail, typename R> -class Visitor<Typelist<Head, Tail>, R, false> - : public Visitor<Head, R, false>, public Visitor<Tail, R, false> -{ -public: - typedef R ReturnType; - // using Visitor<Head, R>::Visit; - // using Visitor<Tail, R>::Visit; -}; - -template <class Head, typename R> -class Visitor<Typelist<Head, NullType>, R, false> : public Visitor<Head, R, false> -{ -public: - typedef R ReturnType; - using Visitor<Head, R, false>::Visit; -}; - -template <class Head, class Tail, typename R> -class Visitor<Typelist<Head, Tail>, R, true> - : public Visitor<Head, R, true>, public Visitor<Tail, R, true> -{ -public: - typedef R ReturnType; - // using Visitor<Head, R>::Visit; - // using Visitor<Tail, R>::Visit; -}; - -template <class Head, typename R> -class Visitor<Typelist<Head, NullType>, R, true> : public Visitor<Head, R, true> -{ -public: - typedef R ReturnType; - using Visitor<Head, R, true>::Visit; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// class template BaseVisitorImpl -// Implements non-strict visitation (you can implement only part of the Visit -// functions) -//////////////////////////////////////////////////////////////////////////////// - -template <class TList, typename R = void> class BaseVisitorImpl; - -template <class Head, class Tail, typename R> -class BaseVisitorImpl<Typelist<Head, Tail>, R> - : public Visitor<Head, R> - , public BaseVisitorImpl<Tail, R> -{ -public: - // using BaseVisitorImpl<Tail, R>::Visit; - - virtual R Visit(Head&) - { return R(); } -}; - -template <class Head, typename R> -class BaseVisitorImpl<Typelist<Head, NullType>, R> - : public Visitor<Head, R> -{ -public: - virtual R Visit(Head&) - { return R(); } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template BaseVisitable -//////////////////////////////////////////////////////////////////////////////// - -template <typename R, typename Visited> -struct DefaultCatchAll -{ - static R OnUnknownVisitor(Visited&, BaseVisitor&) - { return R(); } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template BaseVisitable -//////////////////////////////////////////////////////////////////////////////// - -template -< -typename R = void, - template <typename, class> class CatchAll = DefaultCatchAll, - bool ConstVisitable = false - > -class BaseVisitable; - -template<typename R, template <typename, class> class CatchAll> -class BaseVisitable<R, CatchAll, false> -{ -public: - typedef R ReturnType; - virtual ~BaseVisitable() {} - virtual ReturnType Accept(BaseVisitor&) = 0; - -protected: // give access only to the hierarchy - template <class T> - static ReturnType AcceptImpl(T& visited, BaseVisitor& guest) - { - // Apply the Acyclic Visitor - if (Visitor<T, R>* p = dynamic_cast<Visitor<T, R>*>(&guest)) - { - return p->Visit(visited); - } - return CatchAll<R, T>::OnUnknownVisitor(visited, guest); - } -}; - -template<typename R, template <typename, class> class CatchAll> -class BaseVisitable<R, CatchAll, true> -{ -public: - typedef R ReturnType; - virtual ~BaseVisitable() {} - virtual ReturnType Accept(BaseVisitor&) const = 0; - -protected: // give access only to the hierarchy - template <class T> - static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest) - { - // Apply the Acyclic Visitor - if (Visitor<T, R, true>* p = dynamic_cast<Visitor<T, R, true>*>(&guest)) - { - return p->Visit(visited); - } - return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest); - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_VISITABLE() -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable -/// (in addition to deriving it from BaseVisitable<R>) -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_VISITABLE() \ - virtual ReturnType Accept(::Loki::BaseVisitor& guest) \ - { return AcceptImpl(*this, guest); } - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_CONST_VISITABLE() -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable by const member -/// functions (in addition to deriving it from BaseVisitable<R>) -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_CONST_VISITABLE() \ - virtual ReturnType Accept(::Loki::BaseVisitor& guest) const \ - { return AcceptImpl(*this, guest); } - -//////////////////////////////////////////////////////////////////////////////// -/// \class CyclicVisitor -/// -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable (in addition to -/// deriving it from BaseVisitable<R> -//////////////////////////////////////////////////////////////////////////////// - -template <typename R, class TList> -class CyclicVisitor : public Visitor<TList, R> -{ -public: - typedef R ReturnType; - // using Visitor<TList, R>::Visit; - - template <class Visited> - ReturnType GenericVisit(Visited& host) - { - Visitor<Visited, ReturnType>& subObj = *this; - return subObj.Visit(host); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable by a cyclic visitor -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) \ - virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \ - { return guest.GenericVisit(*this); } - -} // namespace Loki - - - -#endif // end file guardian - |