1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2001 by Andrei Alexandrescu
4 // This code accompanies the book:
5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
6 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
7 // Permission to use, copy, modify, distribute and sell this software for any
8 // purpose is hereby granted without fee, provided that the above copyright
9 // notice appear in all copies and that both that copyright notice and this
10 // permission notice appear in supporting documentation.
11 // The author or Addison-Welsey Longman make no representations about the
12 // suitability of this software for any purpose. It is provided "as is"
13 // without express or implied warranty.
14 ////////////////////////////////////////////////////////////////////////////////
15
16 // Last update: June 20, 2001
17
18 #ifndef FUNCTOR_INC_
19 #define FUNCTOR_INC_
20
21 #include "Typelist.h"
22 #include "EmptyType.h"
23 #include "SmallObj.h"
24 #include "TypeTraits.h"
25 #include <typeinfo>
26 #include <memory>
27
28 namespace Loki
29 {
30 ////////////////////////////////////////////////////////////////////////////////
31 // class template FunctorImpl (internal)
32 ////////////////////////////////////////////////////////////////////////////////
33
34 namespace Private
35 {
36 template <typename R, template <class> class ThreadingModel>
37 struct FunctorImplBase : public SmallObject<ThreadingModel>
38 {
39 typedef R ResultType;
40
41 typedef EmptyType Parm1;
42 typedef EmptyType Parm2;
43 typedef EmptyType Parm3;
44 typedef EmptyType Parm4;
45 typedef EmptyType Parm5;
46 typedef EmptyType Parm6;
47 typedef EmptyType Parm7;
48 typedef EmptyType Parm8;
49 typedef EmptyType Parm9;
50 typedef EmptyType Parm10;
51 typedef EmptyType Parm11;
52 typedef EmptyType Parm12;
53 typedef EmptyType Parm13;
54 typedef EmptyType Parm14;
55 typedef EmptyType Parm15;
56
57 virtual FunctorImplBase* DoClone() const = 0;
58 template <class U>
59 static U* Clone(U* pObj)
60 {
61 if (!pObj) return 0;
62 U* pClone = static_cast<U*>(pObj->DoClone());
63 assert(typeid(*pClone) == typeid(*pObj));
64 return pClone;
65 }
66 };
67 }
68
69 ////////////////////////////////////////////////////////////////////////////////
70 // macro DEFINE_CLONE_FUNCTORIMPL
71 // Implements the DoClone function for a functor implementation
72 ////////////////////////////////////////////////////////////////////////////////
73
74 #define DEFINE_CLONE_FUNCTORIMPL(Cls) \
75 virtual Cls* DoClone() const { return new Cls(*this); }
76
77 ////////////////////////////////////////////////////////////////////////////////
78 // class template FunctorImpl
79 // The base class for a hierarchy of functors. The FunctorImpl class is not used
80 // directly; rather, the Functor class manages and forwards to a pointer to
81 // FunctorImpl
82 // You may want to derive your own functors from FunctorImpl.
83 // Specializations of FunctorImpl for up to 15 parameters follow
84 ////////////////////////////////////////////////////////////////////////////////
85
86 template <typename R, class TList,
87 template <class> class ThreadingModel = DEFAULT_THREADING>
88 class FunctorImpl;
89
90 ////////////////////////////////////////////////////////////////////////////////
91 // class template FunctorImpl
92 // Specialization for 0 (zero) parameters
93 ////////////////////////////////////////////////////////////////////////////////
94
95 template <typename R, template <class> class ThreadingModel>
96 class FunctorImpl<R, NullType, ThreadingModel>
97 : public Private::FunctorImplBase<R, ThreadingModel>
98 {
99 public:
100 typedef R ResultType;
101 virtual R operator()() = 0;
102 };
103
104 ////////////////////////////////////////////////////////////////////////////////
105 // class template FunctorImpl
106 // Specialization for 1 parameter
107 ////////////////////////////////////////////////////////////////////////////////
108
109 template <typename R, typename P1, template <class> class ThreadingModel>
110 class FunctorImpl<R, TYPELIST_1(P1), ThreadingModel>
111 : public Private::FunctorImplBase<R, ThreadingModel>
112 {
113 public:
114 typedef R ResultType;
115 typedef typename TypeTraits<P1>::ParameterType Parm1;
116 virtual R operator()(Parm1) = 0;
117 };
118
119 ////////////////////////////////////////////////////////////////////////////////
120 // class template FunctorImpl
121 // Specialization for 2 parameters
122 ////////////////////////////////////////////////////////////////////////////////
123
124 template <typename R, typename P1, typename P2,
125 template <class> class ThreadingModel>
126 class FunctorImpl<R, TYPELIST_2(P1, P2), ThreadingModel>
127 : public Private::FunctorImplBase<R, ThreadingModel>
128 {
129 public:
130 typedef R ResultType;
131 typedef typename TypeTraits<P1>::ParameterType Parm1;
132 typedef typename TypeTraits<P2>::ParameterType Parm2;
133 virtual R operator()(Parm1, Parm2) = 0;
134 };
135
136 ////////////////////////////////////////////////////////////////////////////////
137 // class template FunctorImpl
138 // Specialization for 3 parameters
139 ////////////////////////////////////////////////////////////////////////////////
140
141 template <typename R, typename P1, typename P2, typename P3,
142 template <class> class ThreadingModel>
143 class FunctorImpl<R, TYPELIST_3(P1, P2, P3), ThreadingModel>
144 : public Private::FunctorImplBase<R, ThreadingModel>
145 {
146 public:
147 typedef R ResultType;
148 typedef typename TypeTraits<P1>::ParameterType Parm1;
149 typedef typename TypeTraits<P2>::ParameterType Parm2;
150 typedef typename TypeTraits<P3>::ParameterType Parm3;
151 virtual R operator()(Parm1, Parm2, Parm3) = 0;
152 };
153
154 ////////////////////////////////////////////////////////////////////////////////
155 // class template FunctorImpl
156 // Specialization for 4 parameters
157 ////////////////////////////////////////////////////////////////////////////////
158
159 template <typename R, typename P1, typename P2, typename P3, typename P4,
160 template <class> class ThreadingModel>
161 class FunctorImpl<R, TYPELIST_4(P1, P2, P3, P4), ThreadingModel>
162 : public Private::FunctorImplBase<R, ThreadingModel>
163 {
164 public:
165 typedef R ResultType;
166 typedef typename TypeTraits<P1>::ParameterType Parm1;
167 typedef typename TypeTraits<P2>::ParameterType Parm2;
168 typedef typename TypeTraits<P3>::ParameterType Parm3;
169 typedef typename TypeTraits<P4>::ParameterType Parm4;
170 virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
171 };
172
173 ////////////////////////////////////////////////////////////////////////////////
174 // class template FunctorImpl
175 // Specialization for 5 parameters
176 ////////////////////////////////////////////////////////////////////////////////
177
178 template <typename R, typename P1, typename P2, typename P3, typename P4,
179 typename P5,
180 template <class> class ThreadingModel>
181 class FunctorImpl<R, TYPELIST_5(P1, P2, P3, P4, P5), ThreadingModel>
182 : public Private::FunctorImplBase<R, ThreadingModel>
183 {
184 public:
185 typedef R ResultType;
186 typedef typename TypeTraits<P1>::ParameterType Parm1;
187 typedef typename TypeTraits<P2>::ParameterType Parm2;
188 typedef typename TypeTraits<P3>::ParameterType Parm3;
189 typedef typename TypeTraits<P4>::ParameterType Parm4;
190 typedef typename TypeTraits<P5>::ParameterType Parm5;
191 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
192 };
193
194 ////////////////////////////////////////////////////////////////////////////////
195 // class template FunctorImpl
196 // Specialization for 6 parameters
197 ////////////////////////////////////////////////////////////////////////////////
198
199 template <typename R, typename P1, typename P2, typename P3, typename P4,
200 typename P5, typename P6,
201 template <class> class ThreadingModel>
202 class FunctorImpl<R, TYPELIST_6(P1, P2, P3, P4, P5, P6), ThreadingModel>
203 : public Private::FunctorImplBase<R, ThreadingModel>
204 {
205 public:
206 typedef R ResultType;
207 typedef typename TypeTraits<P1>::ParameterType Parm1;
208 typedef typename TypeTraits<P2>::ParameterType Parm2;
209 typedef typename TypeTraits<P3>::ParameterType Parm3;
210 typedef typename TypeTraits<P4>::ParameterType Parm4;
211 typedef typename TypeTraits<P5>::ParameterType Parm5;
212 typedef typename TypeTraits<P6>::ParameterType Parm6;
213 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
214 };
215
216 ////////////////////////////////////////////////////////////////////////////////
217 // class template FunctorImpl
218 // Specialization for 7 parameters
219 ////////////////////////////////////////////////////////////////////////////////
220
221 template <typename R, typename P1, typename P2, typename P3, typename P4,
222 typename P5, typename P6, typename P7,
223 template <class> class ThreadingModel>
224 class FunctorImpl<R, TYPELIST_7(P1, P2, P3, P4, P5, P6, P7), ThreadingModel>
225 : public Private::FunctorImplBase<R, ThreadingModel>
226 {
227 public:
228 typedef R ResultType;
229 typedef typename TypeTraits<P1>::ParameterType Parm1;
230 typedef typename TypeTraits<P2>::ParameterType Parm2;
231 typedef typename TypeTraits<P3>::ParameterType Parm3;
232 typedef typename TypeTraits<P4>::ParameterType Parm4;
233 typedef typename TypeTraits<P5>::ParameterType Parm5;
234 typedef typename TypeTraits<P6>::ParameterType Parm6;
235 typedef typename TypeTraits<P7>::ParameterType Parm7;
236 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
237 Parm7) = 0;
238 };
239
240 ////////////////////////////////////////////////////////////////////////////////
241 // class template FunctorImpl
242 // Specialization for 8 parameters
243 ////////////////////////////////////////////////////////////////////////////////
244
245 template <typename R, typename P1, typename P2, typename P3, typename P4,
246 typename P5, typename P6, typename P7, typename P8,
247 template <class> class ThreadingModel>
248 class FunctorImpl<R, TYPELIST_8(P1, P2, P3, P4, P5, P6, P7, P8),
249 ThreadingModel>
250 : public Private::FunctorImplBase<R, ThreadingModel>
251 {
252 public:
253 typedef R ResultType;
254 typedef typename TypeTraits<P1>::ParameterType Parm1;
255 typedef typename TypeTraits<P2>::ParameterType Parm2;
256 typedef typename TypeTraits<P3>::ParameterType Parm3;
257 typedef typename TypeTraits<P4>::ParameterType Parm4;
258 typedef typename TypeTraits<P5>::ParameterType Parm5;
259 typedef typename TypeTraits<P6>::ParameterType Parm6;
260 typedef typename TypeTraits<P7>::ParameterType Parm7;
261 typedef typename TypeTraits<P8>::ParameterType Parm8;
262 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
263 Parm7, Parm8) = 0;
264 };
265
266 ////////////////////////////////////////////////////////////////////////////////
267 // class template FunctorImpl
268 // Specialization for 9 parameters
269 ////////////////////////////////////////////////////////////////////////////////
270
271 template <typename R, typename P1, typename P2, typename P3, typename P4,
272 typename P5, typename P6, typename P7, typename P8, typename P9,
273 template <class> class ThreadingModel>
274 class FunctorImpl<R, TYPELIST_9(P1, P2, P3, P4, P5, P6, P7, P8, P9),
275 ThreadingModel>
276 : public Private::FunctorImplBase<R, ThreadingModel>
277 {
278 public:
279 typedef R ResultType;
280 typedef typename TypeTraits<P1>::ParameterType Parm1;
281 typedef typename TypeTraits<P2>::ParameterType Parm2;
282 typedef typename TypeTraits<P3>::ParameterType Parm3;
283 typedef typename TypeTraits<P4>::ParameterType Parm4;
284 typedef typename TypeTraits<P5>::ParameterType Parm5;
285 typedef typename TypeTraits<P6>::ParameterType Parm6;
286 typedef typename TypeTraits<P7>::ParameterType Parm7;
287 typedef typename TypeTraits<P8>::ParameterType Parm8;
288 typedef typename TypeTraits<P9>::ParameterType Parm9;
289 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
290 Parm7, Parm8, Parm9) = 0;
291 };
292
293 ////////////////////////////////////////////////////////////////////////////////
294 // class template FunctorImpl
295 // Specialization for 10 parameters
296 ////////////////////////////////////////////////////////////////////////////////
297
298 template <typename R, typename P1, typename P2, typename P3, typename P4,
299 typename P5, typename P6, typename P7, typename P8, typename P9,
300 typename P10,
301 template <class> class ThreadingModel>
302 class FunctorImpl<R, TYPELIST_10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10),
303 ThreadingModel>
304 : public Private::FunctorImplBase<R, ThreadingModel>
305 {
306 public:
307 typedef R ResultType;
308 typedef typename TypeTraits<P1>::ParameterType Parm1;
309 typedef typename TypeTraits<P2>::ParameterType Parm2;
310 typedef typename TypeTraits<P3>::ParameterType Parm3;
311 typedef typename TypeTraits<P4>::ParameterType Parm4;
312 typedef typename TypeTraits<P5>::ParameterType Parm5;
313 typedef typename TypeTraits<P6>::ParameterType Parm6;
314 typedef typename TypeTraits<P7>::ParameterType Parm7;
315 typedef typename TypeTraits<P8>::ParameterType Parm8;
316 typedef typename TypeTraits<P9>::ParameterType Parm9;
317 typedef typename TypeTraits<P10>::ParameterType Parm10;
318 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
319 Parm7, Parm8, Parm9, Parm10) = 0;
320 };
321
322 ////////////////////////////////////////////////////////////////////////////////
323 // class template FunctorImpl
324 // Specialization for 11 parameters
325 ////////////////////////////////////////////////////////////////////////////////
326
327 template <typename R, typename P1, typename P2, typename P3, typename P4,
328 typename P5, typename P6, typename P7, typename P8, typename P9,
329 typename P10, typename P11,
330 template <class> class ThreadingModel>
331 class FunctorImpl<R,
332 TYPELIST_11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11),
333 ThreadingModel>
334 : public Private::FunctorImplBase<R, ThreadingModel>
335 {
336 public:
337 typedef R ResultType;
338 typedef typename TypeTraits<P1>::ParameterType Parm1;
339 typedef typename TypeTraits<P2>::ParameterType Parm2;
340 typedef typename TypeTraits<P3>::ParameterType Parm3;
341 typedef typename TypeTraits<P4>::ParameterType Parm4;
342 typedef typename TypeTraits<P5>::ParameterType Parm5;
343 typedef typename TypeTraits<P6>::ParameterType Parm6;
344 typedef typename TypeTraits<P7>::ParameterType Parm7;
345 typedef typename TypeTraits<P8>::ParameterType Parm8;
346 typedef typename TypeTraits<P9>::ParameterType Parm9;
347 typedef typename TypeTraits<P10>::ParameterType Parm10;
348 typedef typename TypeTraits<P11>::ParameterType Parm11;
349 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
350 Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
351 };
352
353 ////////////////////////////////////////////////////////////////////////////////
354 // class template FunctorImpl
355 // Specialization for 12 parameters
356 ////////////////////////////////////////////////////////////////////////////////
357
358 template <typename R, typename P1, typename P2, typename P3, typename P4,
359 typename P5, typename P6, typename P7, typename P8, typename P9,
360 typename P10, typename P11, typename P12,
361 template <class> class ThreadingModel>
362 class FunctorImpl<R,
363 TYPELIST_12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12),
364 ThreadingModel>
365 : public Private::FunctorImplBase<R, ThreadingModel>
366 {
367 public:
368 typedef R ResultType;
369 typedef typename TypeTraits<P1>::ParameterType Parm1;
370 typedef typename TypeTraits<P2>::ParameterType Parm2;
371 typedef typename TypeTraits<P3>::ParameterType Parm3;
372 typedef typename TypeTraits<P4>::ParameterType Parm4;
373 typedef typename TypeTraits<P5>::ParameterType Parm5;
374 typedef typename TypeTraits<P6>::ParameterType Parm6;
375 typedef typename TypeTraits<P7>::ParameterType Parm7;
376 typedef typename TypeTraits<P8>::ParameterType Parm8;
377 typedef typename TypeTraits<P9>::ParameterType Parm9;
378 typedef typename TypeTraits<P10>::ParameterType Parm10;
379 typedef typename TypeTraits<P11>::ParameterType Parm11;
380 typedef typename TypeTraits<P12>::ParameterType Parm12;
381 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
382 Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
383 };
384
385 ////////////////////////////////////////////////////////////////////////////////
386 // class template FunctorImpl
387 // Specialization for 13 parameters
388 ////////////////////////////////////////////////////////////////////////////////
389
390 template <typename R, typename P1, typename P2, typename P3, typename P4,
391 typename P5, typename P6, typename P7, typename P8, typename P9,
392 typename P10, typename P11, typename P12, typename P13,
393 template <class> class ThreadingModel>
394 class FunctorImpl<R,
395 TYPELIST_13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13),
396 ThreadingModel>
397 : public Private::FunctorImplBase<R, ThreadingModel>
398 {
399 public:
400 typedef R ResultType;
401 typedef typename TypeTraits<P1>::ParameterType Parm1;
402 typedef typename TypeTraits<P2>::ParameterType Parm2;
403 typedef typename TypeTraits<P3>::ParameterType Parm3;
404 typedef typename TypeTraits<P4>::ParameterType Parm4;
405 typedef typename TypeTraits<P5>::ParameterType Parm5;
406 typedef typename TypeTraits<P6>::ParameterType Parm6;
407 typedef typename TypeTraits<P7>::ParameterType Parm7;
408 typedef typename TypeTraits<P8>::ParameterType Parm8;
409 typedef typename TypeTraits<P9>::ParameterType Parm9;
410 typedef typename TypeTraits<P10>::ParameterType Parm10;
411 typedef typename TypeTraits<P11>::ParameterType Parm11;
412 typedef typename TypeTraits<P12>::ParameterType Parm12;
413 typedef typename TypeTraits<P13>::ParameterType Parm13;
414 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
415 Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
416 };
417
418 ////////////////////////////////////////////////////////////////////////////////
419 // class template FunctorImpl
420 // Specialization for 14 parameters
421 ////////////////////////////////////////////////////////////////////////////////
422
423 template <typename R, typename P1, typename P2, typename P3, typename P4,
424 typename P5, typename P6, typename P7, typename P8, typename P9,
425 typename P10, typename P11, typename P12, typename P13, typename P14,
426 template <class> class ThreadingModel>
427 class FunctorImpl<R,
428 TYPELIST_14(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
429 P14),
430 ThreadingModel>
431 : public Private::FunctorImplBase<R, ThreadingModel>
432 {
433 public:
434 typedef R ResultType;
435 typedef typename TypeTraits<P1>::ParameterType Parm1;
436 typedef typename TypeTraits<P2>::ParameterType Parm2;
437 typedef typename TypeTraits<P3>::ParameterType Parm3;
438 typedef typename TypeTraits<P4>::ParameterType Parm4;
439 typedef typename TypeTraits<P5>::ParameterType Parm5;
440 typedef typename TypeTraits<P6>::ParameterType Parm6;
441 typedef typename TypeTraits<P7>::ParameterType Parm7;
442 typedef typename TypeTraits<P8>::ParameterType Parm8;
443 typedef typename TypeTraits<P9>::ParameterType Parm9;
444 typedef typename TypeTraits<P10>::ParameterType Parm10;
445 typedef typename TypeTraits<P11>::ParameterType Parm11;
446 typedef typename TypeTraits<P12>::ParameterType Parm12;
447 typedef typename TypeTraits<P13>::ParameterType Parm13;
448 typedef typename TypeTraits<P14>::ParameterType Parm14;
449 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
450 Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
451 };
452
453 ////////////////////////////////////////////////////////////////////////////////
454 // class template FunctorImpl
455 // Specialization for 15 parameters
456 ////////////////////////////////////////////////////////////////////////////////
457
458 template <typename R, typename P1, typename P2, typename P3, typename P4,
459 typename P5, typename P6, typename P7, typename P8, typename P9,
460 typename P10, typename P11, typename P12, typename P13, typename P14,
461 typename P15, template <class> class ThreadingModel>
462 class FunctorImpl<R,
463 TYPELIST_15(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
464 P14, P15),
465 ThreadingModel>
466 : public Private::FunctorImplBase<R, ThreadingModel>
467 {
468 public:
469 typedef R ResultType;
470 typedef typename TypeTraits<P1>::ParameterType Parm1;
471 typedef typename TypeTraits<P2>::ParameterType Parm2;
472 typedef typename TypeTraits<P3>::ParameterType Parm3;
473 typedef typename TypeTraits<P4>::ParameterType Parm4;
474 typedef typename TypeTraits<P5>::ParameterType Parm5;
475 typedef typename TypeTraits<P6>::ParameterType Parm6;
476 typedef typename TypeTraits<P7>::ParameterType Parm7;
477 typedef typename TypeTraits<P8>::ParameterType Parm8;
478 typedef typename TypeTraits<P9>::ParameterType Parm9;
479 typedef typename TypeTraits<P10>::ParameterType Parm10;
480 typedef typename TypeTraits<P11>::ParameterType Parm11;
481 typedef typename TypeTraits<P12>::ParameterType Parm12;
482 typedef typename TypeTraits<P13>::ParameterType Parm13;
483 typedef typename TypeTraits<P14>::ParameterType Parm14;
484 typedef typename TypeTraits<P15>::ParameterType Parm15;
485 virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
486 Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
487 Parm15) = 0;
488 };
489
490 ////////////////////////////////////////////////////////////////////////////////
491 // class template FunctorHandler
492 // Wraps functors and pointers to functions
493 ////////////////////////////////////////////////////////////////////////////////
494
495 template <class ParentFunctor, typename Fun>
496 class FunctorHandler
497 : public ParentFunctor::Impl
498 {
499 typedef typename ParentFunctor::Impl Base;
500
501 public:
502 typedef typename Base::ResultType ResultType;
503 typedef typename Base::Parm1 Parm1;
504 typedef typename Base::Parm2 Parm2;
505 typedef typename Base::Parm3 Parm3;
506 typedef typename Base::Parm4 Parm4;
507 typedef typename Base::Parm5 Parm5;
508 typedef typename Base::Parm6 Parm6;
509 typedef typename Base::Parm7 Parm7;
510 typedef typename Base::Parm8 Parm8;
511 typedef typename Base::Parm9 Parm9;
512 typedef typename Base::Parm10 Parm10;
513 typedef typename Base::Parm11 Parm11;
514 typedef typename Base::Parm12 Parm12;
515 typedef typename Base::Parm13 Parm13;
516 typedef typename Base::Parm14 Parm14;
517 typedef typename Base::Parm15 Parm15;
518
519 FunctorHandler(const Fun& fun) : f_(fun) {}
520
521 DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
522
523 // operator() implementations for up to 15 arguments
524
525 ResultType operator()()
526 { return f_(); }
527
528 ResultType operator()(Parm1 p1)
529 { return f_(p1); }
530
531 ResultType operator()(Parm1 p1, Parm2 p2)
532 { return f_(p1, p2); }
533
534 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
535 { return f_(p1, p2, p3); }
536
537 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
538 { return f_(p1, p2, p3, p4); }
539
540 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
541 { return f_(p1, p2, p3, p4, p5); }
542
543 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
544 Parm6 p6)
545 { return f_(p1, p2, p3, p4, p5, p6); }
546
547 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
548 Parm6 p6, Parm7 p7)
549 { return f_(p1, p2, p3, p4, p5, p6, p7); }
550
551 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
552 Parm6 p6, Parm7 p7, Parm8 p8)
553 { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
554
555 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
556 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
557 { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
558
559 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
560 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
561 { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
562
563 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
564 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
565 { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
566
567 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
568 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
569 Parm12 p12)
570 { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
571
572 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
573 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
574 Parm12 p12, Parm13 p13)
575 { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
576
577 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
578 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
579 Parm12 p12, Parm13 p13, Parm14 p14)
580 {
581 return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
582 p14);
583 }
584
585 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
586 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
587 Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
588 {
589 return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
590 p14, p15);
591 }
592
593 private:
594 Fun f_;
595 };
596
597 ////////////////////////////////////////////////////////////////////////////////
598 // class template FunctorHandler
599 // Wraps pointers to member functions
600 ////////////////////////////////////////////////////////////////////////////////
601
602 template <class ParentFunctor, typename PointerToObj,
603 typename PointerToMemFn>
604 class MemFunHandler : public ParentFunctor::Impl
605 {
606 typedef typename ParentFunctor::Impl Base;
607
608 public:
609 typedef typename Base::ResultType ResultType;
610 typedef typename Base::Parm1 Parm1;
611 typedef typename Base::Parm2 Parm2;
612 typedef typename Base::Parm3 Parm3;
613 typedef typename Base::Parm4 Parm4;
614 typedef typename Base::Parm5 Parm5;
615 typedef typename Base::Parm6 Parm6;
616 typedef typename Base::Parm7 Parm7;
617 typedef typename Base::Parm8 Parm8;
618 typedef typename Base::Parm9 Parm9;
619 typedef typename Base::Parm10 Parm10;
620 typedef typename Base::Parm11 Parm11;
621 typedef typename Base::Parm12 Parm12;
622 typedef typename Base::Parm13 Parm13;
623 typedef typename Base::Parm14 Parm14;
624 typedef typename Base::Parm15 Parm15;
625
626 MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
627 : pObj_(pObj), pMemFn_(pMemFn)
628 {}
629
630 DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
631
632 ResultType operator()()
633 { return ((*pObj_).*pMemFn_)(); }
634
635 ResultType operator()(Parm1 p1)
636 { return ((*pObj_).*pMemFn_)(p1); }
637
638 ResultType operator()(Parm1 p1, Parm2 p2)
639 { return ((*pObj_).*pMemFn_)(p1, p2); }
640
641 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
642 { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
643
644 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
645 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
646
647 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
648 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
649
650 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
651 Parm6 p6)
652 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
653
654 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
655 Parm6 p6, Parm7 p7)
656 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
657
658 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
659 Parm6 p6, Parm7 p7, Parm8 p8)
660 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
661
662 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
663 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
664 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
665
666 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
667 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
668 { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
669
670 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
671 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
672 {
673 return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
674 p11);
675 }
676
677 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
678 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
679 Parm12 p12)
680 {
681 return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
682 p11, p12);
683 }
684
685 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
686 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
687 Parm12 p12, Parm13 p13)
688 {
689 return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
690 p11, p12, p13);
691 }
692
693 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
694 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
695 Parm12 p12, Parm13 p13, Parm14 p14)
696 {
697 return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
698 p11, p12, p13, p14);
699 }
700
701 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
702 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
703 Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
704 {
705 return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
706 p11, p12, p13, p14, p15);
707 }
708
709 private:
710 PointerToObj pObj_;
711 PointerToMemFn pMemFn_;
712 };
713
714 ////////////////////////////////////////////////////////////////////////////////
715 // class template Functor
716 // A generalized functor implementation with value semantics
717 ////////////////////////////////////////////////////////////////////////////////
718
719 template <typename R, class TList = NullType,
720 template<class> class ThreadingModel = DEFAULT_THREADING>
721 class Functor
722 {
723 public:
724 // Handy type definitions for the body type
725 typedef FunctorImpl<R, TList, ThreadingModel> Impl;
726 typedef R ResultType;
727 typedef TList ParmList;
728 typedef typename Impl::Parm1 Parm1;
729 typedef typename Impl::Parm2 Parm2;
730 typedef typename Impl::Parm3 Parm3;
731 typedef typename Impl::Parm4 Parm4;
732 typedef typename Impl::Parm5 Parm5;
733 typedef typename Impl::Parm6 Parm6;
734 typedef typename Impl::Parm7 Parm7;
735 typedef typename Impl::Parm8 Parm8;
736 typedef typename Impl::Parm9 Parm9;
737 typedef typename Impl::Parm10 Parm10;
738 typedef typename Impl::Parm11 Parm11;
739 typedef typename Impl::Parm12 Parm12;
740 typedef typename Impl::Parm13 Parm13;
741 typedef typename Impl::Parm14 Parm14;
742 typedef typename Impl::Parm15 Parm15;
743
744 // Member functions
745
746 Functor() : spImpl_(0)
747 {}
748
749 Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
750 {}
751
752 Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
753 {}
754
755 template <typename Fun>
756 Functor(Fun fun)
757 : spImpl_(new FunctorHandler<Functor, Fun>(fun))
758 {}
759
760 template <class PtrObj, typename MemFn>
761 Functor(const PtrObj& p, MemFn memFn)
762 : spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
763 {}
764
765 Functor& operator=(const Functor& rhs)
766 {
767 Functor copy(rhs);
768 // swap auto_ptrs by hand
769 Impl* p = spImpl_.release();
770 spImpl_.reset(copy.spImpl_.release());
771 copy.spImpl_.reset(p);
772 return *this;
773 }
774
775 ResultType operator()()
776 { return (*spImpl_)(); }
777
778 ResultType operator()(Parm1 p1)
779 { return (*spImpl_)(p1); }
780
781 ResultType operator()(Parm1 p1, Parm2 p2)
782 { return (*spImpl_)(p1, p2); }
783
784 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
785 { return (*spImpl_)(p1, p2, p3); }
786
787 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
788 { return (*spImpl_)(p1, p2, p3, p4); }
789
790 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
791 { return (*spImpl_)(p1, p2, p3, p4, p5); }
792
793 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
794 Parm6 p6)
795 { return (*spImpl_)(p1, p2, p3, p4, p5, p6); }
796
797 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
798 Parm6 p6, Parm7 p7)
799 { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); }
800
801 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
802 Parm6 p6, Parm7 p7, Parm8 p8)
803 { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); }
804
805 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
806 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
807 { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
808
809 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
810 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
811 { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
812
813 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
814 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
815 { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
816
817 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
818 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
819 Parm12 p12)
820 {
821 return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
822 p12);
823 }
824
825 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
826 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
827 Parm12 p12, Parm13 p13)
828 {
829 return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
830 p12, p13);
831 }
832
833 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
834 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
835 Parm12 p12, Parm13 p13, Parm14 p14)
836 {
837 return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
838 p12, p13, p14);
839 }
840
841 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
842 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
843 Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
844 {
845 return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
846 p12, p13, p14, p15);
847 }
848
849 private:
850 std::auto_ptr<Impl> spImpl_;
851 };
852
853 namespace Private
854 {
855 template <class Fctor> struct BinderFirstTraits;
856
857 template <typename R, class TList, template <class> class ThreadingModel>
858 struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
859 {
860 typedef typename TL::Erase<TList,
861 typename TL::TypeAt<TList, 0>::Result>::Result
862 ParmList;
863 typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
864 typedef typename BoundFunctorType::Impl Impl;
865 };
866 }
867
868 ////////////////////////////////////////////////////////////////////////////////
869 // class template BinderFirst
870 // Binds the first parameter of a Functor object to a specific value
871 ////////////////////////////////////////////////////////////////////////////////
872
873 template <class OriginalFunctor>
874 class BinderFirst
875 : public Private::BinderFirstTraits<OriginalFunctor>::Impl
876 {
877 typedef typename Private::BinderFirstTraits<OriginalFunctor>::Impl Base;
878 typedef typename OriginalFunctor::ResultType ResultType;
879
880 typedef typename OriginalFunctor::Parm1 BoundType;
881
882 typedef typename OriginalFunctor::Parm2 Parm1;
883 typedef typename OriginalFunctor::Parm3 Parm2;
884 typedef typename OriginalFunctor::Parm4 Parm3;
885 typedef typename OriginalFunctor::Parm5 Parm4;
886 typedef typename OriginalFunctor::Parm6 Parm5;
887 typedef typename OriginalFunctor::Parm7 Parm6;
888 typedef typename OriginalFunctor::Parm8 Parm7;
889 typedef typename OriginalFunctor::Parm9 Parm8;
890 typedef typename OriginalFunctor::Parm10 Parm9;
891 typedef typename OriginalFunctor::Parm11 Parm10;
892 typedef typename OriginalFunctor::Parm12 Parm11;
893 typedef typename OriginalFunctor::Parm13 Parm12;
894 typedef typename OriginalFunctor::Parm14 Parm13;
895 typedef typename OriginalFunctor::Parm15 Parm14;
896 typedef EmptyType Parm15;
897
898 public:
899 BinderFirst(const OriginalFunctor& fun, BoundType bound)
900 : f_(fun), b_(bound)
901 {}
902
903 DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
904
905 // operator() implementations for up to 15 arguments
906
907 ResultType operator()()
908 { return f_(b_); }
909
910 ResultType operator()(Parm1 p1)
911 { return f_(b_, p1); }
912
913 ResultType operator()(Parm1 p1, Parm2 p2)
914 { return f_(b_, p1, p2); }
915
916 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
917 { return f_(b_, p1, p2, p3); }
918
919 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
920 { return f_(b_, p1, p2, p3, p4); }
921
922 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
923 { return f_(b_, p1, p2, p3, p4, p5); }
924
925 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
926 Parm6 p6)
927 { return f_(b_, p1, p2, p3, p4, p5, p6); }
928
929 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
930 Parm6 p6, Parm7 p7)
931 { return f_(b_, p1, p2, p3, p4, p5, p6, p7); }
932
933 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
934 Parm6 p6, Parm7 p7, Parm8 p8)
935 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); }
936
937 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
938 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
939 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
940
941 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
942 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
943 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
944
945 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
946 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
947 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
948
949 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
950 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
951 Parm12 p12)
952 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
953
954 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
955 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
956 Parm12 p12, Parm13 p13)
957 { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
958
959 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
960 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
961 Parm12 p12, Parm13 p13, Parm14 p14)
962 {
963 return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
964 p14);
965 }
966
967 private:
968 OriginalFunctor f_;
969 BoundType b_;
970 };
971
972 ////////////////////////////////////////////////////////////////////////////////
973 // function template BindFirst
974 // Binds the first parameter of a Functor object to a specific value
975 ////////////////////////////////////////////////////////////////////////////////
976
977 template <class Fctor>
978 typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
979 BindFirst(
980 const Fctor& fun,
981 typename Fctor::Parm1 bound)
982 {
983 typedef typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
984 Outgoing;
985
986 return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
987 new BinderFirst<Fctor>(fun, bound)));
988 }
989
990 ////////////////////////////////////////////////////////////////////////////////
991 // class template Chainer
992 // Chains two functor calls one after another
993 ////////////////////////////////////////////////////////////////////////////////
994
995 template <typename Fun1, typename Fun2>
996 class Chainer : public Fun2::Impl
997 {
998 typedef Fun2 Base;
999
1000 public:
1001 typedef typename Base::ResultType ResultType;
1002 typedef typename Base::Parm1 Parm1;
1003 typedef typename Base::Parm2 Parm2;
1004 typedef typename Base::Parm3 Parm3;
1005 typedef typename Base::Parm4 Parm4;
1006 typedef typename Base::Parm5 Parm5;
1007 typedef typename Base::Parm6 Parm6;
1008 typedef typename Base::Parm7 Parm7;
1009 typedef typename Base::Parm8 Parm8;
1010 typedef typename Base::Parm9 Parm9;
1011 typedef typename Base::Parm10 Parm10;
1012 typedef typename Base::Parm11 Parm11;
1013 typedef typename Base::Parm12 Parm12;
1014 typedef typename Base::Parm13 Parm13;
1015 typedef typename Base::Parm14 Parm14;
1016 typedef typename Base::Parm15 Parm15;
1017
1018 Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
1019
1020 DEFINE_CLONE_FUNCTORIMPL(Chainer)
1021
1022 // operator() implementations for up to 15 arguments
1023
1024 ResultType operator()()
1025 { return f1_(), f2_(); }
1026
1027 ResultType operator()(Parm1 p1)
1028 { return f1_(p1), f2_(p1); }
1029
1030 ResultType operator()(Parm1 p1, Parm2 p2)
1031 { return f1_(p1, p2), f2_(p1, p2); }
1032
1033 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
1034 { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
1035
1036 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
1037 { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
1038
1039 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
1040 { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
1041
1042 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1043 Parm6 p6)
1044 { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); }
1045
1046 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1047 Parm6 p6, Parm7 p7)
1048 {
1049 return f1_(p1, p2, p3, p4, p5, p6, p7),
1050 f2_(p1, p2, p3, p4, p5, p6, p7);
1051 }
1052
1053 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1054 Parm6 p6, Parm7 p7, Parm8 p8)
1055 {
1056 return f1_(p1, p2, p3, p4, p5, p6, p7, p8),
1057 f2_(p1, p2, p3, p4, p5, p6, p7, p8);
1058 }
1059
1060 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1061 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
1062 {
1063 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9),
1064 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9);
1065 }
1066
1067 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1068 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
1069 {
1070 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10),
1071 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
1072 }
1073
1074 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1075 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
1076 {
1077 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11),
1078 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
1079 }
1080
1081 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1082 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1083 Parm12 p12)
1084 {
1085 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12),
1086 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
1087 }
1088
1089 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1090 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1091 Parm12 p12, Parm13 p13)
1092 {
1093 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13),
1094 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
1095 }
1096
1097 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1098 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1099 Parm12 p12, Parm13 p13, Parm14 p14)
1100 {
1101 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
1102 p14),
1103 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
1104 p14);
1105 }
1106
1107 ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1108 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1109 Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
1110 {
1111 return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
1112 p14, p15),
1113 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
1114 p14, p15);
1115 }
1116
1117 private:
1118 Fun1 f1_;
1119 Fun2 f2_;
1120 };
1121
1122 ////////////////////////////////////////////////////////////////////////////////
1123 // function template Chain
1124 // Chains two functor calls one after another
1125 ////////////////////////////////////////////////////////////////////////////////
1126
1127
1128 template <class Fun1, class Fun2>
1129 Fun2 Chain(
1130 const Fun1& fun1,
1131 const Fun2& fun2)
1132 {
1133 return Fun2(std::auto_ptr<typename Fun2::Impl>(
1134 new Chainer<Fun1, Fun2>(fun1, fun2)));
1135 }
1136
1137 } // namespace Loki
1138
1139 ////////////////////////////////////////////////////////////////////////////////
1140 // Change log:
1141 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
1142 ////////////////////////////////////////////////////////////////////////////////
1143
1144 #endif // FUNCTOR_INC_