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)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 ====================================================================
13 This code is heavily inspired by
14  The Loki Library (loki-lib/trunk/include/loki/Visitor.h)
15  Copyright (c) 2001 by Andrei Alexandrescu
16  This Loki code accompanies the book:
17  Alexandrescu, Andrei. "Modern C++ Design: Generic Programming
18  and Design Patterns Applied".
19  Copyright (c) 2001. Addison-Wesley. ISBN 0201704315
20 
21 Credits for many further implementation ideas go to
22  Cooperative Visitor: A Template Technique for Visitor Creation
23  by Anand Shankar Krishnamoorthi (July 2007)
24  http://www.artima.com/cppsource/cooperative_visitor.html
25 
26 */
27 
28 
72 #ifndef LIB_VISITOR_H
73 #define LIB_VISITOR_H
74 
75 #include "lib/visitor-policies.hpp"
77 
78 #include "lib/meta/typelist.hpp"
79 
80 
81 namespace lib {
82 namespace visitor {
83 
84  namespace typelist = lib::meta;
85 
86 
94  template
95  < typename RET = void
96  , template <class> class ERR = UseDefault
97  >
98  class Tool : public ERR<RET>
99  {
100  public:
101  typedef RET ReturnType;
102  typedef Tool ToolBase;
103 
104  virtual ~Tool () { };
105 
108  virtual Tag<ToolBase> getTag() = 0;
109  };
110 
111 
112 
113 
130  template
131  < class TOOLImpl, // concrete tool implementation type
132  class TYPES, // List of applicable Types goes here...
133  class BASE=Tool<> // "visiting tool" base class
134  >
135  class Applicable;
136 
137  template // recursion end: inherit from BASE
138  < class TOOLImpl,
139  class BASE
140  >
141  class Applicable<TOOLImpl, typelist::NullType, BASE>
142  : public BASE
143  { }
144  ;
145 
146  template
147  < class TOOLImpl,
148  class TAR, class TYPES,
149  class BASE
150  >
151  class Applicable<TOOLImpl, typelist::Node<TAR, TYPES>, BASE>
152  : public Applicable<TOOLImpl, TYPES, BASE>
153  {
154 
155  typedef typename BASE::ToolBase ToolBase;
156 
157  protected:
158  virtual ~Applicable () {}
159  Applicable ()
160  {
161  TOOLImpl* typeref = 0;
162  Dispatcher<TAR,ToolBase>::instance().enrol (typeref);
163  }
164 
165  public:
166  virtual Tag<ToolBase>
167  getTag ()
168  {
169  TOOLImpl* typeref = 0;
170  return Tag<ToolBase>::get (typeref);
171  }
172  };
173 
174  using typelist::Types; // convenience for the user of "Applicable"
175 
176 
177 
185  template
186  < class TOOL = Tool<>
187  >
188  class Visitable
189  {
190  public:
191  typedef typename TOOL::ReturnType ReturnType;
192 
195  virtual ReturnType apply (TOOL&) = 0;
196 
197 
198  protected:
199  virtual ~Visitable () { };
200 
202  typedef typename TOOL::ToolBase ToolBase;
203 
209  template <class TAR>
210  static inline ReturnType
211  dispatchOp (TAR& target, TOOL& tool)
212  {
213  return Dispatcher<TAR,ToolBase>::instance().forwardCall (target,tool);
214  }
215  };
216 
217 
222 #define DEFINE_PROCESSABLE_BY(TOOL) \
223  virtual ReturnType apply (TOOL& tool) \
224  { return dispatchOp (*this, tool); }
225 
226 
227 
228 }} // namespace lib::visitor
229 #endif
TOOL::ToolBase ToolBase
Definition: visitor.hpp:199
Marker template to declare that some "visiting tool" wants to treat a set of concrete Visitable class...
Definition: visitor.hpp:135
A template metaprogramming technique for manipulating collections of types.
Marker interface or base class for all "Visitables".
Definition: visitor.hpp:188
virtual Tag< ToolBase > getTag()=0
use RTTI for all visiting tools
Marker interface / base class for all "visiting tools".
Definition: visitor.hpp:98
Implementation namespace for support and library code.
static ReturnType dispatchOp(TAR &target, TOOL &tool)
Definition: visitor.hpp:211
Tool ToolBase
for templating the Tag and Dispatcher
Definition: visitor.hpp:102
RET ReturnType
Tool function invocation return type.
Definition: visitor.hpp:101
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...