From d25cf6682763c73bcd7dd4517e4aaec2fcd117be Mon Sep 17 00:00:00 2001 From: syntheticpp Date: Mon, 2 Jan 2006 10:36:45 +0000 Subject: [PATCH] add support for visiting constant member functions git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@391 7ec92016-0320-0410-acc4-a06ded1c099a --- include/loki/Visitor.h | 91 +++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/include/loki/Visitor.h b/include/loki/Visitor.h index 07d0915..a795028 100644 --- a/include/loki/Visitor.h +++ b/include/loki/Visitor.h @@ -13,7 +13,7 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: June 20, 2001 +// $Header: #ifndef LOKI_VISITOR_INC_ #define LOKI_VISITOR_INC_ @@ -40,14 +40,27 @@ namespace Loki // The building block of Acyclic Visitor //////////////////////////////////////////////////////////////////////////////// - template - class Visitor + template + class Visitor; + + template + class Visitor { public: typedef R ReturnType; - virtual ReturnType Visit(T&) = 0; + typedef T ParamType; + virtual ReturnType Visit(ParamType&) = 0; }; - + + template + class Visitor + { + public: + typedef R ReturnType; + typedef const T ParamType; + virtual ReturnType Visit(ParamType&) = 0; + }; + //////////////////////////////////////////////////////////////////////////////// // class template Visitor (specialization) // This specialization is not present in the book. It makes it easier to define @@ -55,8 +68,7 @@ namespace Loki // // class SomeVisitor : // public BaseVisitor // required -// public Visitor, -// public Visitor +// public Visitor // { // public: // void Visit(RasterBitmap&); // visit a RasterBitmap @@ -65,8 +77,8 @@ namespace Loki //////////////////////////////////////////////////////////////////////////////// template - class Visitor, R> - : public Visitor, public Visitor + class Visitor, R, false> + : public Visitor, public Visitor { public: typedef R ReturnType; @@ -75,13 +87,32 @@ namespace Loki }; template - class Visitor, R> : public Visitor + class Visitor, R, false> : public Visitor { public: typedef R ReturnType; - using Visitor::Visit; + using Visitor::Visit; }; + template + class Visitor, R, true> + : public Visitor, public Visitor + { + public: + typedef R ReturnType; + // using Visitor::Visit; + // using Visitor::Visit; + }; + + template + class Visitor, R, true> : public Visitor + { + public: + typedef R ReturnType; + using Visitor::Visit; + }; + + //////////////////////////////////////////////////////////////////////////////// // class template BaseVisitorImpl // Implements non-strict visitation (you can implement only part of the Visit @@ -129,9 +160,13 @@ struct DefaultCatchAll template < typename R = void, - template class CatchAll = DefaultCatchAll + template class CatchAll = DefaultCatchAll, + bool ConstVisitable = false > - class BaseVisitable + class BaseVisitable; + + template class CatchAll> + class BaseVisitable { public: typedef R ReturnType; @@ -151,6 +186,27 @@ struct DefaultCatchAll } }; + template class CatchAll> + class BaseVisitable + { + public: + typedef R ReturnType; + virtual ~BaseVisitable() {} + virtual ReturnType Accept(BaseVisitor&) const = 0; + + protected: // give access only to the hierarchy + template + static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest) + { + // Apply the Acyclic Visitor + if (Visitor* p = dynamic_cast*>(&guest)) + { + return p->Visit(visited); + } + return CatchAll::OnUnknownVisitor(const_cast(visited), guest); + } + }; + //////////////////////////////////////////////////////////////////////////////// // macro DEFINE_VISITABLE // Put it in every class that you want to make visitable (in addition to @@ -161,6 +217,10 @@ struct DefaultCatchAll virtual ReturnType Accept(::Loki::BaseVisitor& guest) \ { return AcceptImpl(*this, guest); } +#define LOKI_DEFINE_CONST_VISITABLE() \ + virtual ReturnType Accept(::Loki::BaseVisitor& guest) const \ + { return AcceptImpl(*this, guest); } + //////////////////////////////////////////////////////////////////////////////// // class template CyclicVisitor // Put it in every class that you want to make visitable (in addition to @@ -195,9 +255,10 @@ struct DefaultCatchAll //////////////////////////////////////////////////////////////////////////////// // Change log: -// March 20: add default argument DefaultCatchAll to BaseVisitable -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! +// March 20, ????: add default argument DefaultCatchAll to BaseVisitable +// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! // September 28, 2004: replaced Loki:: with ::Loki:: in DEFINE_VISITABLE +// January 2, 2006: add support for visiting constant member functions, Peter Kümmel //////////////////////////////////////////////////////////////////////////////// #endif // VISITOR_INC_