Lumiera  0.pre.03
»edit your freedom«
visitor.hpp
Go to the documentation of this file.
1 /*
2  VISITOR.hpp - Generic Visitor library implementation
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 ====================================================================
22 This code is heavily inspired by
23  The Loki Library (loki-lib/trunk/include/loki/Visitor.h)
24  Copyright (c) 2001 by Andrei Alexandrescu
25  This Loki code accompanies the book:
26  Alexandrescu, Andrei. "Modern C++ Design: Generic Programming
27  and Design Patterns Applied".
28  Copyright (c) 2001. Addison-Wesley. ISBN 0201704315
29 
30 Credits for many further implementation ideas go to
31  Cooperative Visitor: A Template Technique for Visitor Creation
32  by Anand Shankar Krishnamoorthi (July 2007)
33  http://www.artima.com/cppsource/cooperative_visitor.html
34 
35 */
36 
37 
81 #ifndef LIB_VISITOR_H
82 #define LIB_VISITOR_H
83 
84 #include "lib/visitor-policies.hpp"
86 
87 #include "lib/meta/typelist.hpp"
88 
89 
90 namespace lib {
91 namespace visitor {
92 
93  namespace typelist = lib::meta;
94 
95 
103  template
104  < typename RET = void
105  , template <class> class ERR = UseDefault
106  >
107  class Tool : public ERR<RET>
108  {
109  public:
110  typedef RET ReturnType;
111  typedef Tool ToolBase;
112 
113  virtual ~Tool () { };
114 
117  virtual Tag<ToolBase> getTag() = 0;
118  };
119 
120 
121 
122 
139  template
140  < class TOOLImpl, // concrete tool implementation type
141  class TYPES, // List of applicable Types goes here...
142  class BASE=Tool<> // "visiting tool" base class
143  >
144  class Applicable;
145 
146  template // recursion end: inherit from BASE
147  < class TOOLImpl,
148  class BASE
149  >
150  class Applicable<TOOLImpl, typelist::NullType, BASE>
151  : public BASE
152  { }
153  ;
154 
155  template
156  < class TOOLImpl,
157  class TAR, class TYPES,
158  class BASE
159  >
160  class Applicable<TOOLImpl, typelist::Node<TAR, TYPES>, BASE>
161  : public Applicable<TOOLImpl, TYPES, BASE>
162  {
163 
164  typedef typename BASE::ToolBase ToolBase;
165 
166  protected:
167  virtual ~Applicable () {}
168  Applicable ()
169  {
170  TOOLImpl* typeref = 0;
171  Dispatcher<TAR,ToolBase>::instance().enrol (typeref);
172  }
173 
174  public:
175  virtual Tag<ToolBase>
176  getTag ()
177  {
178  TOOLImpl* typeref = 0;
179  return Tag<ToolBase>::get (typeref);
180  }
181  };
182 
183  using typelist::Types; // convenience for the user of "Applicable"
184 
185 
186 
194  template
195  < class TOOL = Tool<>
196  >
197  class Visitable
198  {
199  public:
200  typedef typename TOOL::ReturnType ReturnType;
201 
204  virtual ReturnType apply (TOOL&) = 0;
205 
206 
207  protected:
208  virtual ~Visitable () { };
209 
211  typedef typename TOOL::ToolBase ToolBase;
212 
218  template <class TAR>
219  static inline ReturnType
220  dispatchOp (TAR& target, TOOL& tool)
221  {
222  return Dispatcher<TAR,ToolBase>::instance().forwardCall (target,tool);
223  }
224  };
225 
226 
231 #define DEFINE_PROCESSABLE_BY(TOOL) \
232  virtual ReturnType apply (TOOL& tool) \
233  { return dispatchOp (*this, tool); }
234 
235 
236 
237 }} // namespace lib::visitor
238 #endif
TOOL::ToolBase ToolBase
Definition: visitor.hpp:208
Marker template to declare that some "visiting tool" wants to treat a set of concrete Visitable class...
Definition: visitor.hpp:144
A template metaprogramming technique for manipulating collections of types.
Marker interface or base class for all "Visitables".
Definition: visitor.hpp:197
virtual Tag< ToolBase > getTag()=0
use RTTI for all visiting tools
Marker interface / base class for all "visiting tools".
Definition: visitor.hpp:107
Implementation namespace for support and library code.
static ReturnType dispatchOp(TAR &target, TOOL &tool)
Definition: visitor.hpp:220
Tool ToolBase
for templating the Tag and Dispatcher
Definition: visitor.hpp:111
RET ReturnType
Tool function invocation return type.
Definition: visitor.hpp:110
Helper for a trampoline table based implementation of the visitor pattern.
Type tag for concrete visiting tool classes.
static Depend< Dispatcher< TAR, TOOL > > instance
storage for the dispatcher table(s)
Policies usable for configuring the lib::visitor::Tool for different kinds of error handling...