Ticket #2749: Multimethod.4.hpp

File Multimethod.4.hpp, 48.4 KB (added by nowake@…, 14 years ago)

Update MultiMethod to enhance flexibility.

Line 
1#ifndef MultimethodH
2#define MultimethodH
3/*---------------------------------------------------------------------------
4 Multimethod.hpp
5
6 ---------------------------------------------------------------------------
7 Copyright (C) 2009/01 - 2009 Nowake nowake@fircewinds.net
8
9----------------------------------------------------------------------------*/
10
11#include <map>
12#include <boost/type_traits.hpp>
13#include <boost/any.hpp>
14#include <boost/unordered_map.hpp>
15#include <loki/LokiTypeInfo.h>
16
17
18namespace Loki {
19 std::size_t hash_value(const TypeInfo& value) {
20 boost::hash<const std::type_info*> hasher;
21 return hasher(&(value.Get()));
22 }
23}
24
25//////////////////////////////////////////////////////////////////////////////
26// multi method executor
27//////////////////////////////////////////////////////////////////////////////
28struct Multimethod {
29 Multimethod() {};
30public: //////////////////////////////////////////////////////////////////////
31 template<typename holder_t> struct ArgumentTraits;
32 template<typename R>
33 struct ApplyTraits {
34 template<typename A00> R operator()(A00& a00) { return a00(); };
35 template<typename A00, typename A01> R operator()(A00& a00, A01& a01) { return a00(a01); };
36 template<typename A00, typename A01, typename A02> R operator()(A00& a00, A01& a01, A02& a02) { return a00(a01, a02); };
37 template<typename A00, typename A01, typename A02, typename A03> R operator()(A00& a00, A01& a01, A02& a02, A03& a03) { return a00(a01, a02, a03); };
38 };
39 template<>
40 struct ApplyTraits<void> {
41 template<typename A00> void operator()(A00& a00) { a00(); };
42 template<typename A00, typename A01> void operator()(A00& a00, A01& a01) { a00(a01); };
43 template<typename A00, typename A01, typename A02> void operator()(A00& a00, A01& a01, A02& a02) { a00(a01, a02); };
44 template<typename A00, typename A01, typename A02, typename A03> void operator()(A00& a00, A01& a01, A02& a02, A03& a03) { a00(a01, a02, a03); };
45 };
46 ///////////////////////////////////////////////////////////////////////////
47 template<typename R>
48 struct ReturnEmptyValue {
49 template<typename A00> R operator()(A00& a00) { a00(); return R(); };
50 template<typename A00, typename A01> R operator()(A00& a00, A01& a01) { a00(a01); return R(); };
51 template<typename A00, typename A01, typename A02> R operator()(A00& a00, A01& a01, A02& a02) { a00(a01, a02); return R(); };
52 template<typename A00, typename A01, typename A02, typename A03> R operator()(A00& a00, A01& a01, A02& a02, A03& a03) { a00(a01, a02, a03); return R(); };
53 };
54public: //////////////////////////////////////////////////////////////////////
55 class BadMultimethod : public std::bad_cast {
56 public:
57 virtual const char * what() const throw() {
58 return "Bad Multimethod apply: no entried argument set.";
59 };
60 };
61private: /////////////////////////////////////////////////////////////////////
62 template<typename R, typename T, unsigned int N> class map {
63 public:
64 typedef map<R, T, N-1> item_type;
65 typedef std::map<const T, item_type> map_type;
66 //typedef boost::unordered_map<const T, item_type> map_type;
67 item_type& find(const T& t) {
68 std::pair<map_type::iterator, bool> r(d_.insert(make_pair(t, item_type())));
69 return r.first->second;
70 }
71 private:
72 map_type d_;
73 };
74 template<typename R, typename T> struct map<R, T, 0> {
75 public:
76 typedef R item_type;
77 typedef std::map<const T, item_type> map_type;
78 //typedef boost::unordered_map<const T, item_type> map_type;
79 item_type& find(const T& t) {
80 std::pair<map_type::iterator, bool> r(d_.insert(make_pair(t, item_type())));
81 return r.first->second;
82 }
83 private:
84 map_type d_;
85 };
86 template<typename R, typename T>
87 static R& find(const T& t00) {
88 static map<R, T, 0> m;
89 return m.find(t00);
90 };
91 template<typename R, typename T>
92 static R& find(const T& t00, const T& t01) {
93 static map<R, T, 1> m;
94 return m.find(t00).find(t01);
95 };
96 template<typename R, typename T>
97 static R& find(const T& t00, const T& t01, const T& t02) {
98 static map<R, T, 2> m;
99 return m.find(t00).find(t01).find(t02);
100 };
101 template<typename R, typename T>
102 static R& find(const T& t00, const T& t01, const T& t02, const T& t03) {
103 static map<R, T, 3> m;
104 return m.find(t00).find(t01).find(t02).find(t03);
105 };
106private:////////////////////////////////////////////////////////////////////////
107 template<typename R, typename HHH, typename A00, typename A>
108 struct Apply00 {
109 static A& apply() { static A a; return a; };
110 static R trampoline(HHH& a00) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00)); };
111 };
112public:
113 template<typename R, typename HHH, typename A00>
114 static bool entry() { return entry<R, HHH, A00>(ApplyTraits<R>()); };
115 template<typename R, typename HHH, typename A00, typename A>
116 static bool entry(A apply) {
117 typedef R (*T00)(HHH&);
118 find<T00>(ArgumentTraits<HHH>::id<A00>()) = &Apply00<R, HHH, A00, A>::trampoline;
119 Apply00<R, HHH, A00, A>::apply() = apply;
120 return true;
121 };
122 template<typename R, typename HHH>
123 static R apply(HHH& a00) {
124 typedef R (*T)(HHH&);
125 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
126 if (!t) throw BadMultimethod();
127 return t(a00);
128 };
129private:////////////////////////////////////////////////////////////////////////
130 template<typename R, typename HHH, typename A00, typename A01, typename A>
131 struct Apply01 {
132 static A& apply() { static A a; return a; };
133 static R trampoline(HHH& a00, HHH& a01) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01)); };
134 static R trampoline(A00& a00, HHH& a01) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01)); };
135 static R trampoline(HHH& a00, A01& a01) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01); };
136 };
137public:
138 template<typename R, typename HHH, typename A00, typename A01>
139 static bool entry() { return entry<R, HHH, A00, A01>(ApplyTraits<R>()); };
140 template<typename R, typename HHH, typename A00, typename A01, typename A>
141 static bool entry(A apply) {
142 typedef R (*T00)(HHH&, HHH&);
143 find<T00>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>()) = &Apply01<R, HHH, A00, A01, A>::trampoline;
144 typedef R (*T01)(A00&, HHH&);
145 find<T01>(ArgumentTraits<HHH>::id<A01>()) = &Apply01<R, HHH, A00, A01, A>::trampoline;
146 typedef R (*T02)(HHH&, A01&);
147 find<T02>(ArgumentTraits<HHH>::id<A00>()) = &Apply01<R, HHH, A00, A01, A>::trampoline;
148 Apply01<R, HHH, A00, A01, A>::apply() = apply;
149 return true;
150 };
151 template<typename R, typename HHH, typename T00, typename T01>
152 static R apply(T00& a00, T01& a01) {
153 typedef R (*T)(T00&, T01&);
154 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
155 if (!t) throw BadMultimethod();
156 return t(a00, a01);
157 };
158 template<typename R, typename HHH>
159 static R apply(HHH& a00, HHH& a01) {
160 typedef R (*T)(HHH&, HHH&);
161 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
162 if (!t) throw BadMultimethod();
163 return t(a00, a01);
164 };
165 template<typename R, typename HHH, typename T00>
166 static R apply(T00& a00, HHH& a01, typename ArgumentTraits<HHH>::type* = 0) {
167 typedef R (*T)(T00&, HHH&);
168 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
169 if (!t) throw BadMultimethod();
170 return t(a00, a01);
171 };
172 template<typename R, typename HHH, typename T00>
173 static R apply(HHH& a00, T00& a01, typename ArgumentTraits<HHH>::type* = 0) {
174 typedef R (*T)(HHH&, T00&);
175 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
176 if (!t) throw BadMultimethod();
177 return t(a00, a01);
178 };
179 template<typename R, typename HHH, typename T00>
180 static R apply(const T00& a00, HHH& a01, typename ArgumentTraits<HHH>::type* = 0) {
181 typedef R (*T)(const T00&, HHH&);
182 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
183 if (!t) throw BadMultimethod();
184 return t(a00, a01);
185 };
186 template<typename R, typename HHH, typename T00>
187 static R apply(HHH& a00, const T00& a01, typename ArgumentTraits<HHH>::type* = 0) {
188 typedef R (*T)(HHH&, const T00&);
189 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
190 if (!t) throw BadMultimethod();
191 return t(a00, a01);
192 };
193private: ///////////////////////////////////////////////////////////////////////
194 template<typename R, typename HHH, typename A00, typename A01, typename A02, typename A>
195 struct Apply02 {
196 static A& apply() { static A a; return a; };
197 static R trampoline(HHH& a00, HHH& a01, HHH& a02) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02)); };
198 static R trampoline(A00& a00, HHH& a01, HHH& a02) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02)); };
199 static R trampoline(HHH& a00, A01& a01, HHH& a02) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, ArgumentTraits<HHH>::cast<A02&>(a02)); };
200 static R trampoline(HHH& a00, HHH& a01, A02& a02) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), a02); };
201 static R trampoline(HHH& a00, A01& a01, A02& a02) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, a02); };
202 static R trampoline(A00& a00, HHH& a01, A02& a02) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), a02); };
203 static R trampoline(A00& a00, A01& a01, HHH& a02) { return apply()(a00, a01, ArgumentTraits<HHH>::cast<A02&>(a02)); };
204 };
205public:
206 template<typename R, typename HHH, typename A00, typename A01, typename A02>
207 static bool entry() { return entry<R, HHH, A00, A01, A02>(ApplyTraits<R>()); };
208 template<typename R, typename HHH, typename A00, typename A01, typename A02, typename A>
209 static bool entry(A apply) {
210 typedef R (*T00)(HHH&, HHH&, HHH&);
211 find<T00>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A02>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
212 typedef R (*T01)(A00&, HHH&, HHH&);
213 find<T01>(ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A02>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
214 typedef R (*T02)(HHH&, A01&, HHH&);
215 find<T02>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A02>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
216 typedef R (*T03)(HHH&, HHH&, A02&);
217 find<T02>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
218 typedef R (*T04)(HHH&, A01&, A02&);
219 find<T04>(ArgumentTraits<HHH>::id<A00>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
220 typedef R (*T05)(A00&, HHH&, A02&);
221 find<T05>(ArgumentTraits<HHH>::id<A01>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
222 typedef R (*T06)(A00&, A01&, HHH&);
223 find<T06>(ArgumentTraits<HHH>::id<A02>()) = &Apply02<R, HHH, A00, A01, A02, A>::trampoline;
224 Apply02<R, HHH, A00, A01, A02, A>::apply() = apply;
225 return true;
226 };
227 template<typename R, typename HHH>
228 static R apply(HHH& a00, HHH& a01, HHH& a02) {
229 typedef R (*T)(HHH&, HHH&, HHH&);
230 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
231 if (!t) throw BadMultimethod();
232 return t(a00, a01, a02);
233 };
234 template<typename R, typename HHH, typename T00>
235 static R apply(T00& a00, HHH& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
236 typedef R (*T)(T00&, HHH&, HHH&);
237 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
238 if (!t) throw BadMultimethod();
239 return t(a00, a01, a02);
240 };
241 template<typename R, typename HHH, typename T00>
242 static R apply(HHH& a00, T00& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
243 typedef R (*T)(HHH&, T00&, HHH&);
244 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(ma02)));
245 if (!t) throw BadMultimethod();
246 return t(a00, a01, a02);
247 };
248 template<typename R, typename HHH, typename T00>
249 static R apply(HHH& a00, HHH& a01, T00& a02, typename ArgumentTraits<HHH>::type* = 0) {
250 typedef R (*T)(const T00&, HHH&);
251 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
252 if (!t) throw BadMultimethod();
253 return t(a00, a01, a02);
254 };
255 template<typename R, typename HHH, typename T00, typename T01>
256 static R apply(HHH& a00, T00& a01, T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
257 typedef R (*T)(HHH&, T00&, T01&);
258 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
259 if (!t) throw BadMultimethod();
260 return t(a00, a01, a02);
261 };
262 template<typename R, typename HHH, typename T00, typename T01>
263 static R apply(T00& a00, HHH& a01, T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
264 typedef R (*T)(T00&, HHH&, T01&);
265 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
266 if (!t) throw BadMultimethod();
267 return t(a00, a01, a02);
268 };
269 template<typename R, typename HHH, typename T00, typename T01>
270 static R apply(T00& a00, T01& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
271 typedef R (*T)(T00&, T01&, HHH&);
272 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
273 if (!t) throw BadMultimethod();
274 return t(a00, a01, a02);
275 };
276 template<typename R, typename HHH, typename T00>
277 static R apply(const T00& a00, HHH& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
278 typedef R (*T)(const T00&, HHH&, HHH&);
279 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
280 if (!t) throw BadMultimethod();
281 return t(a00, a01, a02);
282 };
283 template<typename R, typename HHH, typename T00>
284 static R apply(HHH& a00, const T00& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
285 typedef R (*T)(HHH&, const T00&, HHH&);
286 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(ma02)));
287 if (!t) throw BadMultimethod();
288 return t(a00, a01, a02);
289 };
290 template<typename R, typename HHH, typename T00>
291 static R apply(HHH& a00, HHH& a01, const T00& a02, typename ArgumentTraits<HHH>::type* = 0) {
292 typedef R (*T)(HHH&, HHH&, const T00);
293 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
294 if (!t) throw BadMultimethod();
295 return t(a00, a01, a02);
296 };
297 template<typename R, typename HHH, typename T00, typename T01>
298 static R apply(HHH& a00, const T00& a01, T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
299 typedef R (*T)(HHH&, const T00&, T01&);
300 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
301 if (!t) throw BadMultimethod();
302 return t(a00, a01, a02);
303 };
304 template<typename R, typename HHH, typename T00, typename T01>
305 static R apply(HHH& a00, T00& a01, const T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
306 typedef R (*T)(HHH&, T00&, const T01&);
307 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
308 if (!t) throw BadMultimethod();
309 return t(a00, a01, a02);
310 };
311 template<typename R, typename HHH, typename T00, typename T01>
312 static R apply(HHH& a00, const T00& a01, const T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
313 typedef R (*T)(HHH&, const T00&, const T01&);
314 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
315 if (!t) throw BadMultimethod();
316 return t(a00, a01, a02);
317 };
318 template<typename R, typename HHH, typename T00, typename T01>
319 static R apply(const T00& a00, HHH& a01, T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
320 typedef R (*T)(const T00&, HHH&, T01&);
321 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
322 if (!t) throw BadMultimethod();
323 return t(a00, a01, a02);
324 };
325 template<typename R, typename HHH, typename T00, typename T01>
326 static R apply(T00& a00, HHH& a01, const T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
327 typedef R (*T)(T00&, HHH&, const T01&);
328 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
329 if (!t) throw BadMultimethod();
330 return t(a00, a01, a02);
331 };
332 template<typename R, typename HHH, typename T00, typename T01>
333 static R apply(const T00& a00, HHH& a01, const T01& a02, typename ArgumentTraits<HHH>::type* = 0) {
334 typedef R (*T)(const T00&, HHH&, const T01&);
335 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
336 if (!t) throw BadMultimethod();
337 return t(a00, a01, a02);
338 };
339 template<typename R, typename HHH, typename T00, typename T01>
340 static R apply(const T00& a00, T01& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
341 typedef R (*T)(const T00&, T01&, HHH&);
342 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
343 if (!t) throw BadMultimethod();
344 return t(a00, a01, a02);
345 };
346 template<typename R, typename HHH, typename T00, typename T01>
347 static R apply(T00& a00, const T01& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
348 typedef R (*T)(T00&, const T01&, HHH&);
349 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
350 if (!t) throw BadMultimethod();
351 return t(a00, a01, a02);
352 };
353 template<typename R, typename HHH, typename T00, typename T01>
354 static R apply(const T00& a00, const T01& a01, HHH& a02, typename ArgumentTraits<HHH>::type* = 0) {
355 typedef R (*T)(const T00&, const T01&, HHH&);
356 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
357 if (!t) throw BadMultimethod();
358 return t(a00, a01, a02);
359 };
360private: //////////////////////////////////////////////////////////////////////
361 template<typename R, typename HHH, typename A00, typename A01, typename A02, typename A03, typename A>
362 struct Apply03 {
363 static A& apply() { static A a; return a; };
364 static R trampoline(HHH& a00, HHH& a01, HHH& a02, HHH& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02), ArgumentTraits<HHH>::cast<A03&>(a03)); };
365 static R trampoline(A00& a00, HHH& a01, HHH& a02, HHH& a03) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02), ArgumentTraits<HHH>::cast<A03&>(a03)); };
366 static R trampoline(HHH& a00, A01& a01, HHH& a02, HHH& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, ArgumentTraits<HHH>::cast<A02&>(a02), ArgumentTraits<HHH>::cast<A03&>(a03)); };
367 static R trampoline(HHH& a00, HHH& a01, A02& a02, HHH& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), a02, ArgumentTraits<HHH>::cast<A03&>(a03)); };
368 static R trampoline(HHH& a00, HHH& a01, HHH& a02, A03& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02), a03); };
369 static R trampoline(A00& a00, A01& a01, HHH& a02, HHH& a03) { return apply()(a00, a01, ArgumentTraits<HHH>::cast<A02&>(a02), ArgumentTraits<HHH>::cast<A03&>(a03)); };
370 static R trampoline(A00& a00, HHH& a01, A02& a02, HHH& a03) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), a02, ArgumentTraits<HHH>::cast<A03&>(a03)); };
371 static R trampoline(A00& a00, HHH& a01, HHH& a02, A03& a03) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), ArgumentTraits<HHH>::cast<A02&>(a02), a03); };
372 static R trampoline(HHH& a00, A01& a01, A02& a02, HHH& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, a02, ArgumentTraits<HHH>::cast<A03&>(a03)); };
373 static R trampoline(HHH& a00, A01& a01, HHH& a02, A03& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, ArgumentTraits<HHH>::cast<A02&>(a02), a03); };
374 static R trampoline(HHH& a00, HHH& a01, A02& a02, A03& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), ArgumentTraits<HHH>::cast<A01&>(a01), a02, a03); };
375 static R trampoline(HHH& a00, A01& a01, A02& a02, A03& a03) { return apply()(ArgumentTraits<HHH>::cast<A00&>(a00), a01, a02, a03); };
376 static R trampoline(A00& a00, HHH& a01, A02& a02, A03& a03) { return apply()(a00, ArgumentTraits<HHH>::cast<A01&>(a01), a02, a03); };
377 static R trampoline(A00& a00, A01& a01, HHH& a02, A03& a03) { return apply()(a00, a01, ArgumentTraits<HHH>::cast<A02&>(a02), a03); };
378 static R trampoline(A00& a00, A01& a01, A02& a02, HHH& a03) { return apply()(a00, a01, a02, ArgumentTraits<HHH>::cast<A03&>(a03)); };
379 };
380public:
381 template<typename R, typename HHH, typename A00, typename A01, typename A02, typename A03>
382 static bool entry() { return entry<R, HHH, A00, A01, A02, A03>(ApplyTraits<R>()); };
383 template<typename R, typename HHH, typename A00, typename A01, typename A02, typename A03, typename A>
384 static bool entry(A apply) {
385 typedef R (*T00)(HHH&, HHH&, HHH&, HHH&);
386 find<T00>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A02>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
387 typedef R (*T01)(A00&, HHH&, HHH&, HHH&);
388 find<T01>(ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A02>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
389 typedef R (*T02)(HHH&, A01&, HHH&, HHH&);
390 find<T02>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A02>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
391 typedef R (*T03)(HHH&, HHH&, A02&, HHH&);
392 find<T03>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
393 typedef R (*T04)(HHH&, HHH&, HHH&, A03&);
394 find<T04>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A01>(), ArgumentTraits<HHH>::id<A02>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
395 typedef R (*T05)(A00&, A01&, HHH&, HHH&);
396 find<T05>(ArgumentTraits<HHH>::id<A02>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
397 typedef R (*T06)(A00&, HHH&, A02&, HHH&);
398 find<T06>(ArgumentTraits<HHH>::id<A00>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
399 typedef R (*T07)(A00&, A01&, HHH&, HHH&);
400 find<T07>(ArgumentTraits<HHH>::id<A02>(), ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
401 typedef R (*T08)(HHH&, A01&, A02&, A03&);
402 find<T08>(ArgumentTraits<HHH>::id<A00>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
403 typedef R (*T09)(A00&, HHH&, A02&, A03&);
404 find<T09>(ArgumentTraits<HHH>::id<A01>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
405 typedef R (*T10)(A00&, A01&, HHH&, A03&);
406 find<T10>(ArgumentTraits<HHH>::id<A02>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
407 typedef R (*T11)(A00&, A01&, A02&, HHH&);
408 find<T11>(ArgumentTraits<HHH>::id<A03>()) = &Apply03<R, HHH, A00, A01, A02, A03, A>::trampoline;
409 Apply03<R, HHH, A00, A01, A02, A03, A>::apply() = apply;
410 return true;
411 };
412 template<typename R, typename HHH>
413 static R apply(HHH& a00, HHH& a01, HHH& a02, HHH& a03) {
414 typedef R (*T)(HHH&, HHH&, HHH&, HHH&);
415 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
416 if (!t) throw BadMultimethod();
417 return t(a00, a01, a02, a03);
418 };
419 template<typename R, typename HHH, typename T00>
420 static R apply(T00& a00, HHH& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
421 typedef R (*T)(T00&, HHH&, HHH&, HHH&);
422 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
423 if (!t) throw BadMultimethod();
424 return t(a00, a01, a02, a03);
425 };
426 template<typename R, typename HHH, typename T00>
427 static R apply(const T00& a00, HHH& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
428 typedef R (*T)(const T00&, HHH&, HHH&, HHH&);
429 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
430 if (!t) throw BadMultimethod();
431 return t(a00, a01, a02, a03);
432 };
433 template<typename R, typename HHH, typename T00>
434 static R apply(HHH& a00, T00& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
435 typedef R (*T)(HHH&, T00&, HHH&, HHH&);
436 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
437 if (!t) throw BadMultimethod();
438 return t(a00, a01, a02, a03);
439 };
440 template<typename R, typename HHH, typename T00>
441 static R apply(HHH& a00, const T00& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
442 typedef R (*T)(HHH&, const T00&, HHH&, HHH&);
443 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
444 if (!t) throw BadMultimethod();
445 return t(a00, a01, a02, a03);
446 };
447 template<typename R, typename HHH, typename T00>
448 static R apply(HHH& a00, HHH& a01, T00& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
449 typedef R (*T)(HHH&, HHH&, T00&, HHH&);
450 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
451 if (!t) throw BadMultimethod();
452 return t(a00, a01, a02, a03);
453 };
454 template<typename R, typename HHH, typename T00>
455 static R apply(HHH& a00, HHH& a01, const T00& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
456 typedef R (*T)(HHH&, HHH&, const T00&, HHH&);
457 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
458 if (!t) throw BadMultimethod();
459 return t(a00, a01, a02, a03);
460 };
461 template<typename R, typename HHH, typename T00>
462 static R apply(HHH& a00, HHH& a01, HHH& a02, T00& a03, typename ArgumentTraits<HHH>::type* = 0) {
463 typedef R (*T)(HHH&, HHH&, HHH&, T00&);
464 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
465 if (!t) throw BadMultimethod();
466 return t(a00, a01, a02, a03);
467 };
468 template<typename R, typename HHH, typename T00>
469 static R apply(HHH& a00, HHH& a01, HHH& a02, const T00& a03, typename ArgumentTraits<HHH>::type* = 0) {
470 typedef R (*T)(HHH&, HHH&, HHH&, const T00&);
471 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
472 if (!t) throw BadMultimethod();
473 return t(a00, a01, a02, a03);
474 };
475 template<typename R, typename HHH, typename T00, typename T01>
476 static R apply(T00& a00, T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
477 typedef R (*T)(T00&, T01&, HHH&, HHH&);
478 T t(find<T>(ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
479 if (!t) throw BadMultimethod();
480 return t(a00, a01, a02, a03);
481 };
482 template<typename R, typename HHH, typename T00, typename T01>
483 static R apply(const T00& a00, T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
484 typedef R (*T)(const T00&, T01&, HHH&, HHH&);
485 T t(find<T>(ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
486 if (!t) throw BadMultimethod();
487 return t(a00, a01, a02, a03);
488 };
489 template<typename R, typename HHH, typename T00, typename T01>
490 static R apply(T00& a00, const T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
491 typedef R (*T)(T00&, const T01&, HHH&, HHH&);
492 T t(find<T>(ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
493 if (!t) throw BadMultimethod();
494 return t(a00, a01, a02, a03);
495 };
496 template<typename R, typename HHH, typename T00, typename T01>
497 static R apply(const T00& a00, const T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
498 typedef R (*T)(const T00&, const T01&, HHH&, HHH&);
499 T t(find<T>(ArgumentTraits<HHH>::id(a02), ArgumentTraits<HHH>::id(a03)));
500 if (!t) throw BadMultimethod();
501 return t(a00, a01, a02, a03);
502 };
503 template<typename R, typename HHH, typename T00, typename T01>
504 static R apply(T00& a00, HHH& a01, T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
505 typedef R (*T)(T00&, HHH&, T01&, HHH&);
506 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
507 if (!t) throw BadMultimethod();
508 return t(a00, a01, a02, a03);
509 };
510 template<typename R, typename HHH, typename T00, typename T01>
511 static R apply(const T00& a00, HHH& a01, T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
512 typedef R (*T)(const T00&, HHH&, T01&, HHH&);
513 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
514 if (!t) throw BadMultimethod();
515 return t(a00, a01, a02, a03);
516 };
517 template<typename R, typename HHH, typename T00, typename T01>
518 static R apply(T00& a00, HHH& a01, const T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
519 typedef R (*T)(T00&, HHH&, const T01&, HHH&);
520 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
521 if (!t) throw BadMultimethod();
522 return t(a00, a01, a02, a03);
523 };
524 template<typename R, typename HHH, typename T00, typename T01>
525 static R apply(const T00& a00, HHH& a01, const T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
526 typedef R (*T)(const T00&, HHH&, const T01&, HHH&);
527 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a03)));
528 if (!t) throw BadMultimethod();
529 return t(a00, a01, a02, a03);
530 };
531 template<typename R, typename HHH, typename T00, typename T01>
532 static R apply(T00& a00, HHH& a01, HHH& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
533 typedef R (*T)(T00&, HHH&, HHH&, T01&);
534 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
535 if (!t) throw BadMultimethod();
536 return t(a00, a01, a02, a03);
537 };
538 template<typename R, typename HHH, typename T00, typename T01>
539 static R apply(const T00& a00, HHH& a01, HHH& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
540 typedef R (*T)(const T00&, HHH&, HHH&, T01&);
541 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
542 if (!t) throw BadMultimethod();
543 return t(a00, a01, a02, a03);
544 };
545 template<typename R, typename HHH, typename T00, typename T01>
546 static R apply(T00& a00, HHH& a01, HHH& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
547 typedef R (*T)(T00&, HHH&, HHH&, const T01&);
548 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
549 if (!t) throw BadMultimethod();
550 return t(a00, a01, a02, a03);
551 };
552 template<typename R, typename HHH, typename T00, typename T01>
553 static R apply(const T00& a00, HHH& a01, HHH& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
554 typedef R (*T)(const T00&, HHH&, HHH&, const T01&);
555 T t(find<T>(ArgumentTraits<HHH>::id(a01), ArgumentTraits<HHH>::id(a02)));
556 if (!t) throw BadMultimethod();
557 return t(a00, a01, a02, a03);
558 };
559 template<typename R, typename HHH, typename T00, typename T01>
560 static R apply(HHH& a00, T00& a01, T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
561 typedef R (*T)(HHH&, T00&, T01&, HHH&);
562 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a03)));
563 if (!t) throw BadMultimethod();
564 return t(a00, a01, a02, a03);
565 };
566 template<typename R, typename HHH, typename T00, typename T01>
567 static R apply(HHH& a00, const T00& a01, T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
568 typedef R (*T)(HHH&, const T00&, T01&, HHH&);
569 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a03)));
570 if (!t) throw BadMultimethod();
571 return t(a00, a01, a02, a03);
572 };
573 template<typename R, typename HHH, typename T00, typename T01>
574 static R apply(HHH& a00, T00& a01, const T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
575 typedef R (*T)(HHH&, T00&, const T01&, HHH&);
576 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a03)));
577 if (!t) throw BadMultimethod();
578 return t(a00, a01, a02, a03);
579 };
580 template<typename R, typename HHH, typename T00, typename T01>
581 static R apply(HHH& a00, const T00& a01, const T01& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
582 typedef R (*T)(HHH&, const T00&, const T01&, HHH&);
583 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a03)));
584 if (!t) throw BadMultimethod();
585 return t(a00, a01, a02, a03);
586 };
587 template<typename R, typename HHH, typename T00, typename T01>
588 static R apply(HHH& a00, T00& a01, HHH& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
589 typedef R (*T)(HHH&, T00&, HHH&, T01&);
590 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02)));
591 if (!t) throw BadMultimethod();
592 return t(a00, a01, a02, a03);
593 };
594 template<typename R, typename HHH, typename T00, typename T01>
595 static R apply(HHH& a00, const T00& a01, HHH& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
596 typedef R (*T)(HHH&, const T00&, HHH&, T01&);
597 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02)));
598 if (!t) throw BadMultimethod();
599 return t(a00, a01, a02, a03);
600 };
601 template<typename R, typename HHH, typename T00, typename T01>
602 static R apply(HHH& a00, T00& a01, HHH& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
603 typedef R (*T)(HHH&, T00&, HHH&, const T01&);
604 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02)));
605 if (!t) throw BadMultimethod();
606 return t(a00, a01, a02, a03);
607 };
608 template<typename R, typename HHH, typename T00, typename T01>
609 static R apply(HHH& a00, const T00& a01, HHH& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
610 typedef R (*T)(HHH&, const T00&, HHH&, const T01&);
611 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a02)));
612 if (!t) throw BadMultimethod();
613 return t(a00, a01, a02, a03);
614 };
615 template<typename R, typename HHH, typename T00, typename T01>
616 static R apply(HHH& a00, HHH& a01, T00& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
617 typedef R (*T)(HHH&, HHH&, T00&, T01&);
618 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
619 if (!t) throw BadMultimethod();
620 return t(a00, a01, a02, a03);
621 };
622 template<typename R, typename HHH, typename T00, typename T01>
623 static R apply(HHH& a00, HHH& a01, const T00& a02, T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
624 typedef R (*T)(HHH&, HHH&, const T00&, T01&);
625 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
626 if (!t) throw BadMultimethod();
627 return t(a00, a01, a02, a03);
628 };
629 template<typename R, typename HHH, typename T00, typename T01>
630 static R apply(HHH& a00, HHH& a01, T00& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
631 typedef R (*T)(HHH&, HHH&, T00&, const T01&);
632 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
633 if (!t) throw BadMultimethod();
634 return t(a00, a01, a02, a03);
635 };
636 template<typename R, typename HHH, typename T00, typename T01>
637 static R apply(HHH& a00, HHH& a01, const T00& a02, const T01& a03, typename ArgumentTraits<HHH>::type* = 0) {
638 typedef R (*T)(HHH&, HHH&, const T00&, const T01&);
639 T t(find<T>(ArgumentTraits<HHH>::id(a00), ArgumentTraits<HHH>::id(a01)));
640 if (!t) throw BadMultimethod();
641 return t(a00, a01, a02, a03);
642 };
643 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
644 static R apply(HHH& a00, T00& a01, T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
645 typedef R (*T)(HHH&, T00&, T01&, T02&);
646 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
647 if (!t) throw BadMultimethod();
648 return t(a00, a01, a02, a03);
649 };
650 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
651 static R apply(HHH& a00, const T00& a01, T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
652 typedef R (*T)(HHH&, const T00&, T01&, T02&);
653 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
654 if (!t) throw BadMultimethod();
655 return t(a00, a01, a02, a03);
656 };
657 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
658 static R apply(HHH& a00, T00& a01, const T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
659 typedef R (*T)(HHH&, T00&, const T01&, T02&);
660 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
661 if (!t) throw BadMultimethod();
662 return t(a00, a01, a02, a03);
663 };
664 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
665 static R apply(HHH& a00, T00& a01, T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
666 typedef R (*T)(HHH&, T00&, T01&, const T02&);
667 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
668 if (!t) throw BadMultimethod();
669 return t(a00, a01, a02, a03);
670 };
671 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
672 static R apply(HHH& a00, const T00& a01, const T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
673 typedef R (*T)(HHH&, const T00&, const T01&, T02&);
674 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
675 if (!t) throw BadMultimethod();
676 return t(a00, a01, a02, a03);
677 };
678 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
679 static R apply(HHH& a00, const T00& a01, T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
680 typedef R (*T)(HHH&, const T00&, T01&, const T02&);
681 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
682 if (!t) throw BadMultimethod();
683 return t(a00, a01, a02, a03);
684 };
685 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
686 static R apply(HHH& a00, T00& a01, const T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
687 typedef R (*T)(HHH&, T00&, const T01&, const T02&);
688 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
689 if (!t) throw BadMultimethod();
690 return t(a00, a01, a02, a03);
691 };
692 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
693 static R apply(HHH& a00, const T00& a01, const T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
694 typedef R (*T)(HHH&, const T00&, const T01&, const T02&);
695 T t(find<T>(ArgumentTraits<HHH>::id(a00)));
696 if (!t) throw BadMultimethod();
697 return t(a00, a01, a02, a03);
698 };
699 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
700 static R apply(T00& a00, HHH& a01, T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
701 typedef R (*T)(T00&, HHH&, T01&, T02&);
702 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
703 if (!t) throw BadMultimethod();
704 return t(a00, a01, a02, a03);
705 };
706 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
707 static R apply(const T00& a00, HHH& a01, T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
708 typedef R (*T)(const T00&, HHH&, T01&, T02&);
709 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
710 if (!t) throw BadMultimethod();
711 return t(a00, a01, a02, a03);
712 };
713 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
714 static R apply(T00& a00, HHH& a01, const T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
715 typedef R (*T)(T00&, HHH&, const T01&, T02&);
716 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
717 if (!t) throw BadMultimethod();
718 return t(a00, a01, a02, a03);
719 };
720 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
721 static R apply(T00& a00, HHH& a01, T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
722 typedef R (*T)(T00&, HHH&, T01&, const T02&);
723 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
724 if (!t) throw BadMultimethod();
725 return t(a00, a01, a02, a03);
726 };
727 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
728 static R apply(const T00& a00, HHH& a01, const T01& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
729 typedef R (*T)(const T00&, HHH&, const T01&, T02&);
730 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
731 if (!t) throw BadMultimethod();
732 return t(a00, a01, a02, a03);
733 };
734 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
735 static R apply(const T00& a00, HHH& a01, T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
736 typedef R (*T)(const T00&, HHH&, T01&, const T02&);
737 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
738 if (!t) throw BadMultimethod();
739 return t(a00, a01, a02, a03);
740 };
741 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
742 static R apply(const T00& a00, HHH& a01, const T01& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
743 typedef R (*T)(const T00&, HHH&, const T01&, const T02&);
744 T t(find<T>(ArgumentTraits<HHH>::id(a01)));
745 if (!t) throw BadMultimethod();
746 return t(a00, a01, a02, a03);
747 };
748 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
749 static R apply(T00& a00, T01& a01, HHH& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
750 typedef R (*T)(T00&, T01&, HHH&, T02&);
751 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
752 if (!t) throw BadMultimethod();
753 return t(a00, a01, a02, a03);
754 };
755 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
756 static R apply(const T00& a00, T01& a01, HHH& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
757 typedef R (*T)(const T00&, T01&, HHH&, T02&);
758 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
759 if (!t) throw BadMultimethod();
760 return t(a00, a01, a02, a03);
761 };
762 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
763 static R apply(T00& a00, const T01& a01, HHH& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
764 typedef R (*T)(T00&, const T01&, HHH&, T02&);
765 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
766 if (!t) throw BadMultimethod();
767 return t(a00, a01, a02, a03);
768 };
769 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
770 static R apply(T00& a00, T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
771 typedef R (*T)(T00&, T01&, HHH&, const T02&);
772 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
773 if (!t) throw BadMultimethod();
774 return t(a00, a01, a02, a03);
775 };
776 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
777 static R apply(const T00& a00, const T01& a01, HHH& a02, T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
778 typedef R (*T)(const T00&, const T01&, HHH&, T02&);
779 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
780 if (!t) throw BadMultimethod();
781 return t(a00, a01, a02, a03);
782 };
783 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
784 static R apply(const T00& a00, T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
785 typedef R (*T)(const T00&, T01&, HHH&, const T02&);
786 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
787 if (!t) throw BadMultimethod();
788 return t(a00, a01, a02, a03);
789 };
790 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
791 static R apply(T00& a00, const T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
792 typedef R (*T)(T00&, const T01&, HHH&, const T02&);
793 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
794 if (!t) throw BadMultimethod();
795 return t(a00, a01, a02, a03);
796 };
797 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
798 static R apply(const T00& a00, const T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits<HHH>::type* = 0) {
799 typedef R (*T)(const T00&, const T01&, HHH&, const T02&);
800 T t(find<T>(ArgumentTraits<HHH>::id(a02)));
801 if (!t) throw BadMultimethod();
802 return t(a00, a01, a02, a03);
803 };
804 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
805 static R apply(T00& a00, T01& a01, T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
806 typedef R (*T)(T00&, T01&, T02&, HHH&);
807 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
808 if (!t) throw BadMultimethod();
809 return t(a00, a01, a02, a03);
810 };
811 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
812 static R apply(const T00& a00, T01& a01, T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
813 typedef R (*T)(const T00&, T01&, T02&, HHH&);
814 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
815 if (!t) throw BadMultimethod();
816 return t(a00, a01, a02, a03);
817 };
818 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
819 static R apply(T00& a00, const T01& a01, T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
820 typedef R (*T)(T00&, const T01&, T02&, HHH&);
821 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
822 if (!t) throw BadMultimethod();
823 return t(a00, a01, a02, a03);
824 };
825 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
826 static R apply(T00& a00, T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
827 typedef R (*T)(T00&, T01&, const T02&, HHH&);
828 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
829 if (!t) throw BadMultimethod();
830 return t(a00, a01, a02, a03);
831 };
832 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
833 static R apply(const T00& a00, const T01& a01, T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
834 typedef R (*T)(const T00&, const T01&, T02&, HHH&);
835 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
836 if (!t) throw BadMultimethod();
837 return t(a00, a01, a02, a03);
838 };
839 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
840 static R apply(const T00& a00, T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
841 typedef R (*T)(const T00&, T01&, const T02&, HHH&);
842 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
843 if (!t) throw BadMultimethod();
844 return t(a00, a01, a02, a03);
845 };
846 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
847 static R apply(T00& a00, const T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
848 typedef R (*T)(T00&, const T01&, const T02&, HHH&);
849 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
850 if (!t) throw BadMultimethod();
851 return t(a00, a01, a02, a03);
852 };
853 template<typename R, typename HHH, typename T00, typename T01, typename T02, typename T03>
854 static R apply(const T00& a00, const T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits<HHH>::type* = 0) {
855 typedef R (*T)(const T00&, const T01&, const T02&, HHH&);
856 T t(find<T>(ArgumentTraits<HHH>::id(a03)));
857 if (!t) throw BadMultimethod();
858 return t(a00, a01, a02, a03);
859 };
860};
861
862
863//////////////////////////////////////////////////////////////////////////////
864template<> struct Multimethod::ArgumentTraits<boost::any> {
865 typedef boost::any type;
866 static Loki::TypeInfo id(type& target) { return Loki::TypeInfo(target.type()); };
867 template<typename target_t>
868 static Loki::TypeInfo id() { static Loki::TypeInfo r(Loki::TypeInfo((type(target_t()).type()))); return r; };
869 template<typename type_t>
870 static type_t cast(type& operand) { return boost::any_cast<remove_reference<type_t>::type&>(operand); };
871};
872
873#endif