diff options
Diffstat (limited to 'shared/loki/Visitor.h')
-rw-r--r-- | shared/loki/Visitor.h | 314 |
1 files changed, 157 insertions, 157 deletions
diff --git a/shared/loki/Visitor.h b/shared/loki/Visitor.h index 4425a9fa..f6b0ad81 100644 --- a/shared/loki/Visitor.h +++ b/shared/loki/Visitor.h @@ -2,14 +2,14 @@ // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// 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 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" +// 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_ @@ -28,17 +28,17 @@ namespace Loki //////////////////////////////////////////////////////////////////////////////// /// \class BaseVisitor -/// +/// /// \ingroup VisitorGroup /// The base class of any Acyclic Visitor //////////////////////////////////////////////////////////////////////////////// - class BaseVisitor - { - public: - virtual ~BaseVisitor() {} - }; - +class BaseVisitor +{ +public: + virtual ~BaseVisitor() {} +}; + //////////////////////////////////////////////////////////////////////////////// /// \class Visitor /// @@ -48,7 +48,7 @@ namespace Loki /// \par Usage /// /// Defining the visitable class: -/// +/// /// \code /// class RasterBitmap : public BaseVisitable<> /// { @@ -59,7 +59,7 @@ namespace Loki /// /// Way 1 to define a visitor: /// \code -/// class SomeVisitor : +/// class SomeVisitor : /// public BaseVisitor // required /// public Visitor<RasterBitmap>, /// public Visitor<Paragraph> @@ -72,7 +72,7 @@ namespace Loki /// /// Way 2 to define the visitor: /// \code -/// class SomeVisitor : +/// class SomeVisitor : /// public BaseVisitor // required /// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> /// { @@ -84,7 +84,7 @@ namespace Loki /// /// Way 3 to define the visitor: /// \code -/// class SomeVisitor : +/// class SomeVisitor : /// public BaseVisitor // required /// public Visitor<Seq<RasterBitmap, Paragraph>::Type> /// { @@ -97,7 +97,7 @@ namespace Loki /// \par Using const visit functions: /// /// Defining the visitable class (true for const): -/// +/// /// \code /// class RasterBitmap : public BaseVisitable<void, DefaultCatchAll, true> /// { @@ -108,7 +108,7 @@ namespace Loki /// /// Defining the visitor which only calls const member functions: /// \code -/// class SomeVisitor : +/// class SomeVisitor : /// public BaseVisitor // required /// public Visitor<RasterBitmap, void, true>, /// { @@ -119,38 +119,38 @@ namespace Loki /// /// \par Example: /// -/// test/Visitor/main.cpp +/// test/Visitor/main.cpp //////////////////////////////////////////////////////////////////////////////// - template <class T, typename R = void, bool ConstVisit = false> - class Visitor; +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; - }; +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 : +// class SomeVisitor : // public BaseVisitor // required // public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> // { @@ -160,41 +160,41 @@ namespace Loki // }; //////////////////////////////////////////////////////////////////////////////// - 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; - }; +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; +}; //////////////////////////////////////////////////////////////////////////////// @@ -203,29 +203,29 @@ namespace Loki // functions) //////////////////////////////////////////////////////////////////////////////// - template <class TList, typename R = void> class BaseVisitorImpl; +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(); } +}; - 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 //////////////////////////////////////////////////////////////////////////////// @@ -241,61 +241,61 @@ struct DefaultCatchAll // class template BaseVisitable //////////////////////////////////////////////////////////////////////////////// - template - < - typename R = void, - template <typename, class> class CatchAll = DefaultCatchAll, - bool ConstVisitable = false - > - class 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> +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) { - 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)) { - // 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); + return p->Visit(visited); } - }; + return CatchAll<R, T>::OnUnknownVisitor(visited, guest); + } +}; - template<typename R,template <typename, class> class CatchAll> - class BaseVisitable<R, CatchAll, true> +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) { - 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)) { - // 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); + 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 +/// Put it in every class that you want to make visitable /// (in addition to deriving it from BaseVisitable<R>) //////////////////////////////////////////////////////////////////////////////// @@ -306,7 +306,7 @@ struct DefaultCatchAll //////////////////////////////////////////////////////////////////////////////// /// \def LOKI_DEFINE_CONST_VISITABLE() /// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable by const member +/// Put it in every class that you want to make visitable by const member /// functions (in addition to deriving it from BaseVisitable<R>) //////////////////////////////////////////////////////////////////////////////// @@ -318,25 +318,25 @@ struct DefaultCatchAll /// \class CyclicVisitor /// /// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable (in addition to +/// 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> +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) { - 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); - } - }; - + Visitor<Visited, ReturnType>& subObj = *this; + return subObj.Visit(host); + } +}; + //////////////////////////////////////////////////////////////////////////////// /// \def LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) /// \ingroup VisitorGroup |