Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
visitor-dispatcher.hpp
Go to the documentation of this file.
1/*
2 VISITOR-DISPATCHER.hpp - visitor implementation details
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
14
22#ifndef LUMIERA_VISITOR_DISPATCHER_H
23#define LUMIERA_VISITOR_DISPATCHER_H
24
25#include "lib/error.hpp"
26#include "lib/util.hpp"
28#include "lib/depend.hpp"
29#include "lib/util.hpp"
30
31#include <vector>
32
33
34namespace lib {
35namespace visitor {
36
37 using lib::ClassLock;
38 using lib::Depend;
39
40
41 template<class TOOL> class Tag;
42
43
44 template<class TOOL, class TOOLImpl>
46 {
47 static Tag<TOOL> tag;
48 };
49
55 template<class TOOL>
56 class Tag
57 {
58 size_t tagID;
59 static size_t lastRegisteredID;
60
61 static void
62 generateID (size_t& id)
63 {
64 ClassLock<Tag> guard;
65 if (!id)
66 id = ++lastRegisteredID;
67 }
68
69 public:
70 Tag() : tagID(0) { }
71 operator size_t() const { return tagID; }
72
73
74 template<class TOOLImpl>
75 static Tag&
76 get (TOOLImpl* const =0)
77 {
79 if (!t) generateID (t.tagID);
80 return t;
81 }
82
83 };
84
85
86
88 template<class TOOL, class TOOLImpl>
90
91 template<class TOOL>
93
94
95
96
97
98
99
100
108 template<class TAR, class TOOL>
110 {
111 using ReturnType = TOOL::ReturnType;
112
118 template<class TOOLImpl>
119 static ReturnType
120 callTrampoline (TAR& obj, TOOL& tool)
121 {
122 // cast down to real implementation type
123 REQUIRE (INSTANCEOF (TOOLImpl, &tool));
124 TOOLImpl& toolObj = static_cast<TOOLImpl&> (tool);
125
126 // trigger (compile time) overload resolution
127 // based on concrete type, then dispatch the call.
128 // Note this may cause obj to be upcasted.
129 return toolObj.treat (obj);
130 }
131
132 typedef ReturnType (*Trampoline) (TAR&, TOOL& );
133
134
136 std::vector<Trampoline> table_;
137
138
139 void
140 accomodate (size_t index)
141 {
142 ClassLock<Dispatcher> guard; // note: this lock is also used for the singleton!
143 if (index > table_.size())
144 table_.resize (index); // performance bottleneck?? TODO: measure the real impact!
145 }
146
147 inline bool
148 is_known (size_t id)
149 {
150 return id<=table_.size() and table_[id-1];
151 }
152
153 inline void
154 storePtr (size_t id, Trampoline func)
155 {
156 REQUIRE (func);
157 REQUIRE (0 < id);
158 if (id>table_.size())
159 accomodate (id);
160 table_[id-1] = func;
161 }
162
163 inline Trampoline
165 {
166 if (id<=table_.size() and table_[id-1])
167 return table_[id-1];
168 else
169 return &errorHandler;
170 }
171
172 static ReturnType
173 errorHandler (TAR& target, TOOL& tool)
174 {
175 return tool.onUnknown (target);
176 }
177
178
179 public:
181
182 inline ReturnType
183 forwardCall (TAR& target, TOOL& tool)
184 {
185 // get concrete type via tool's VTable
186 Tag<TOOL> index = tool.getTag();
187 return (*storedTrampoline(index)) (target, tool);
188 }
189
190 template<class TOOLImpl>
191 inline void
192 enrol(TOOLImpl* typeref)
193 {
194 Tag<TOOL>& index = Tag<TOOL>::get (typeref);
195 if (is_known (index))
196 return;
197 else
198 {
199 Trampoline func = &callTrampoline<TOOLImpl>;
200 storePtr (index, func);
201 }
202 }
203 };
204
206 template<class TAR, class TOOL>
208
209
210
211
212}} // namespace lib::visitor
213#endif
A synchronisation protection guard employing a lock scoped to the parameter type as a whole,...
Access point to singletons and other kinds of dependencies designated by type.
Definition depend.hpp:281
For each possible call entry point via some subclass of the visitable hierarchy, we maintain a dispat...
ReturnType forwardCall(TAR &target, TOOL &tool)
std::vector< Trampoline > table_
VTable for storing the Trampoline pointers.
void enrol(TOOLImpl *typeref)
static Depend< Dispatcher< TAR, TOOL > > instance
storage for the dispatcher table(s)
void storePtr(size_t id, Trampoline func)
static ReturnType errorHandler(TAR &target, TOOL &tool)
ReturnType(* Trampoline)(TAR &, TOOL &)
static ReturnType callTrampoline(TAR &obj, TOOL &tool)
generator for Trampoline functions, used to dispatch calls down to the right "treat"-Function on the ...
Trampoline storedTrampoline(size_t id)
Type tag for concrete visiting tool classes.
static void generateID(size_t &id)
static Tag & get(TOOLImpl *const =0)
static size_t lastRegisteredID
Singleton services and Dependency Injection.
Lumiera error handling (C++ interface).
Implementation namespace for support and library code.
static Tag< TOOL > tag
storage for the Tag registry for each concrete tool
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition util.hpp:514