1 /*
2  *  Functor.h
3  *  Apto
4  *
5  *  Created by David on 5/12/11.
6  *  Copyright 2011 David Michael Bryson. All rights reserved.
7  *  http://programerror.com/software/apto
8  *
9  *  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
10  *  following conditions are met:
11  *
12  *  1.  Redistributions of source code must retain the above copyright notice, this list of conditions and the
13  *      following disclaimer.
14  *  2.  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
15  *      following disclaimer in the documentation and/or other materials provided with the distribution.
16  *  3.  Neither the name of David Michael Bryson, nor the names of contributors may be used to endorse or promote
17  *      products derived from this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY DAVID MICHAEL BRYSON AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  *  DISCLAIMED. IN NO EVENT SHALL DAVID MICHAEL BRYSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  *  Authors: David M. Bryson <david@programerror.com>
28  *
29  *  Functor based off of ideas presented in Modern C++ Design (2001) by Andrei Alexandrescu
30  */
31 
32 #ifndef AptoCoreFunctor_h
33 #define AptoCoreFunctor_h
34 
35 #include "apto/core/SmartPtr.h"
36 #include "apto/core/TypeList.h"
37 #include "apto/core/TypeTraits.h"
38 
39 #include "apto/platform/Visibility.h"
40 
41 #include <cassert>
42 
43 
44 namespace Apto {
45 
46   // Internal Functor Implemenation
47   // --------------------------------------------------------------------------------------------------------------
48 
49   namespace Internal {
50     template <typename R> class FunctorBase
51     {
52     public:
53       typedef R ReturnType;
54       typedef EmptyType Param1;
55       typedef EmptyType Param2;
56       typedef EmptyType Param3;
57       typedef EmptyType Param4;
58       typedef EmptyType Param5;
59       typedef EmptyType Param6;
60       typedef EmptyType Param7;
61       typedef EmptyType Param8;
62       typedef EmptyType Param9;
63       typedef EmptyType Param10;
64       typedef EmptyType Param11;
65       typedef EmptyType Param12;
66       typedef EmptyType Param13;
67       typedef EmptyType Param14;
68       typedef EmptyType Param15;
69       typedef EmptyType Param16;
70 
71       virtual FunctorBase* DoClone() const = 0;
~FunctorBase()72       virtual ~FunctorBase() { ; }
73 
74       template <class U>
Clone(U * obj)75       static U* Clone(U* obj)
76       {
77         if (!obj) return NULL;
78         U* clone = static_cast<U*>(obj->DoClone());
79         assert(typeid(*clone) == typeid(*obj));
80         return clone;
81       }
82     };
83   };
84 
85 
86   // Functor Container Interface Definitions (supporting up to 16 arguments)
87   // --------------------------------------------------------------------------------------------------------------
88 
89   template <typename ReturnType, class TList> class FunctorContainer;
90 
91   template <
92     typename ReturnType
93   > class FunctorContainer<ReturnType, NullType>
94   : public Internal::FunctorBase<ReturnType>
95   {
96   public:
97     virtual ReturnType operator()() = 0;
98   };
99 
100   template <
101     typename ReturnType,
102     typename P1
103   > class FunctorContainer<ReturnType, TL::Create<P1> >
104   : public Internal::FunctorBase<ReturnType>
105   {
106   public:
107     typedef typename TypeTraits<P1>::ParameterType Param1;
108     virtual ReturnType operator()(Param1) = 0;
109   };
110 
111   template <
112     typename ReturnType,
113     typename P1, typename P2
114   > class FunctorContainer<ReturnType, TL::Create<P1, P2> >
115   : public Internal::FunctorBase<ReturnType>
116   {
117   public:
118     typedef typename TypeTraits<P1>::ParameterType Param1;
119     typedef typename TypeTraits<P2>::ParameterType Param2;
120     virtual ReturnType operator()(Param1, Param2) = 0;
121   };
122 
123   template <
124     typename ReturnType,
125     typename P1, typename P2, typename P3
126   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3> >
127   : public Internal::FunctorBase<ReturnType>
128   {
129   public:
130     typedef typename TypeTraits<P1>::ParameterType Param1;
131     typedef typename TypeTraits<P2>::ParameterType Param2;
132     typedef typename TypeTraits<P3>::ParameterType Param3;
133     virtual ReturnType operator()(Param1, Param2, Param3) = 0;
134   };
135 
136   template <
137     typename ReturnType,
138     typename P1, typename P2, typename P3, typename P4
139   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4> >
140   : public Internal::FunctorBase<ReturnType>
141   {
142   public:
143     typedef typename TypeTraits<P1>::ParameterType Param1;
144     typedef typename TypeTraits<P2>::ParameterType Param2;
145     typedef typename TypeTraits<P3>::ParameterType Param3;
146     typedef typename TypeTraits<P4>::ParameterType Param4;
147     virtual ReturnType operator()(Param1, Param2, Param3, Param4) = 0;
148   };
149 
150   template <
151     typename ReturnType,
152     typename P1, typename P2, typename P3, typename P4, typename P5
153   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5> >
154   : public Internal::FunctorBase<ReturnType>
155   {
156   public:
157     typedef typename TypeTraits<P1>::ParameterType Param1;
158     typedef typename TypeTraits<P2>::ParameterType Param2;
159     typedef typename TypeTraits<P3>::ParameterType Param3;
160     typedef typename TypeTraits<P4>::ParameterType Param4;
161     typedef typename TypeTraits<P5>::ParameterType Param5;
162     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5) = 0;
163   };
164 
165   template <
166     typename ReturnType,
167     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6
168   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6> >
169   : public Internal::FunctorBase<ReturnType>
170   {
171   public:
172     typedef typename TypeTraits<P1>::ParameterType Param1;
173     typedef typename TypeTraits<P2>::ParameterType Param2;
174     typedef typename TypeTraits<P3>::ParameterType Param3;
175     typedef typename TypeTraits<P4>::ParameterType Param4;
176     typedef typename TypeTraits<P5>::ParameterType Param5;
177     typedef typename TypeTraits<P6>::ParameterType Param6;
178     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6) = 0;
179   };
180 
181   template <
182     typename ReturnType,
183     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7
184   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7> > : public Internal::FunctorBase<ReturnType>
185   {
186   public:
187     typedef typename TypeTraits<P1>::ParameterType Param1;
188     typedef typename TypeTraits<P2>::ParameterType Param2;
189     typedef typename TypeTraits<P3>::ParameterType Param3;
190     typedef typename TypeTraits<P4>::ParameterType Param4;
191     typedef typename TypeTraits<P5>::ParameterType Param5;
192     typedef typename TypeTraits<P6>::ParameterType Param6;
193     typedef typename TypeTraits<P7>::ParameterType Param7;
194     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = 0;
195   };
196 
197   template <
198     typename ReturnType,
199     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8
200   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8> >
201   : public Internal::FunctorBase<ReturnType>
202   {
203   public:
204     typedef typename TypeTraits<P1>::ParameterType Param1;
205     typedef typename TypeTraits<P2>::ParameterType Param2;
206     typedef typename TypeTraits<P3>::ParameterType Param3;
207     typedef typename TypeTraits<P4>::ParameterType Param4;
208     typedef typename TypeTraits<P5>::ParameterType Param5;
209     typedef typename TypeTraits<P6>::ParameterType Param6;
210     typedef typename TypeTraits<P7>::ParameterType Param7;
211     typedef typename TypeTraits<P8>::ParameterType Param8;
212     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = 0;
213   };
214 
215   template <
216     typename ReturnType,
217     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
218     typename P9
219   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9> >
220   : public Internal::FunctorBase<ReturnType>
221   {
222   public:
223     typedef typename TypeTraits<P1>::ParameterType Param1;
224     typedef typename TypeTraits<P2>::ParameterType Param2;
225     typedef typename TypeTraits<P3>::ParameterType Param3;
226     typedef typename TypeTraits<P4>::ParameterType Param4;
227     typedef typename TypeTraits<P5>::ParameterType Param5;
228     typedef typename TypeTraits<P6>::ParameterType Param6;
229     typedef typename TypeTraits<P7>::ParameterType Param7;
230     typedef typename TypeTraits<P8>::ParameterType Param8;
231     typedef typename TypeTraits<P9>::ParameterType Param9;
232     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = 0;
233   };
234 
235   template <
236     typename ReturnType,
237     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
238     typename P9, typename P10
239   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >
240   : public Internal::FunctorBase<ReturnType>
241   {
242   public:
243     typedef typename TypeTraits<P1>::ParameterType Param1;
244     typedef typename TypeTraits<P2>::ParameterType Param2;
245     typedef typename TypeTraits<P3>::ParameterType Param3;
246     typedef typename TypeTraits<P4>::ParameterType Param4;
247     typedef typename TypeTraits<P5>::ParameterType Param5;
248     typedef typename TypeTraits<P6>::ParameterType Param6;
249     typedef typename TypeTraits<P7>::ParameterType Param7;
250     typedef typename TypeTraits<P8>::ParameterType Param8;
251     typedef typename TypeTraits<P9>::ParameterType Param9;
252     typedef typename TypeTraits<P10>::ParameterType Param10;
253     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = 0;
254   };
255 
256   template <
257     typename ReturnType,
258     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
259     typename P9, typename P10, typename P11
260   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
261   : public Internal::FunctorBase<ReturnType>
262   {
263   public:
264     typedef typename TypeTraits<P1>::ParameterType Param1;
265     typedef typename TypeTraits<P2>::ParameterType Param2;
266     typedef typename TypeTraits<P3>::ParameterType Param3;
267     typedef typename TypeTraits<P4>::ParameterType Param4;
268     typedef typename TypeTraits<P5>::ParameterType Param5;
269     typedef typename TypeTraits<P6>::ParameterType Param6;
270     typedef typename TypeTraits<P7>::ParameterType Param7;
271     typedef typename TypeTraits<P8>::ParameterType Param8;
272     typedef typename TypeTraits<P9>::ParameterType Param9;
273     typedef typename TypeTraits<P10>::ParameterType Param10;
274     typedef typename TypeTraits<P11>::ParameterType Param11;
275     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
276                                   Param11) = 0;
277   };
278 
279   template <
280     typename ReturnType,
281     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
282     typename P9, typename P10, typename P11, typename P12
283   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >
284   : public Internal::FunctorBase<ReturnType>
285   {
286   public:
287     typedef typename TypeTraits<P1>::ParameterType Param1;
288     typedef typename TypeTraits<P2>::ParameterType Param2;
289     typedef typename TypeTraits<P3>::ParameterType Param3;
290     typedef typename TypeTraits<P4>::ParameterType Param4;
291     typedef typename TypeTraits<P5>::ParameterType Param5;
292     typedef typename TypeTraits<P6>::ParameterType Param6;
293     typedef typename TypeTraits<P7>::ParameterType Param7;
294     typedef typename TypeTraits<P8>::ParameterType Param8;
295     typedef typename TypeTraits<P9>::ParameterType Param9;
296     typedef typename TypeTraits<P10>::ParameterType Param10;
297     typedef typename TypeTraits<P11>::ParameterType Param11;
298     typedef typename TypeTraits<P12>::ParameterType Param12;
299     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
300                                   Param11, Param12) = 0;
301   };
302 
303   template <
304     typename ReturnType,
305     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
306     typename P9, typename P10, typename P11, typename P12, typename P13
307   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> >
308   : public Internal::FunctorBase<ReturnType>
309   {
310   public:
311     typedef typename TypeTraits<P1>::ParameterType Param1;
312     typedef typename TypeTraits<P2>::ParameterType Param2;
313     typedef typename TypeTraits<P3>::ParameterType Param3;
314     typedef typename TypeTraits<P4>::ParameterType Param4;
315     typedef typename TypeTraits<P5>::ParameterType Param5;
316     typedef typename TypeTraits<P6>::ParameterType Param6;
317     typedef typename TypeTraits<P7>::ParameterType Param7;
318     typedef typename TypeTraits<P8>::ParameterType Param8;
319     typedef typename TypeTraits<P9>::ParameterType Param9;
320     typedef typename TypeTraits<P10>::ParameterType Param10;
321     typedef typename TypeTraits<P11>::ParameterType Param11;
322     typedef typename TypeTraits<P12>::ParameterType Param12;
323     typedef typename TypeTraits<P13>::ParameterType Param13;
324     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
325                                   Param11, Param12, Param13) = 0;
326   };
327 
328   template <
329     typename ReturnType,
330     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
331     typename P9, typename P10, typename P11, typename P12, typename P13, typename P14
332   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> >
333   : public Internal::FunctorBase<ReturnType>
334   {
335   public:
336     typedef typename TypeTraits<P1>::ParameterType Param1;
337     typedef typename TypeTraits<P2>::ParameterType Param2;
338     typedef typename TypeTraits<P3>::ParameterType Param3;
339     typedef typename TypeTraits<P4>::ParameterType Param4;
340     typedef typename TypeTraits<P5>::ParameterType Param5;
341     typedef typename TypeTraits<P6>::ParameterType Param6;
342     typedef typename TypeTraits<P7>::ParameterType Param7;
343     typedef typename TypeTraits<P8>::ParameterType Param8;
344     typedef typename TypeTraits<P9>::ParameterType Param9;
345     typedef typename TypeTraits<P10>::ParameterType Param10;
346     typedef typename TypeTraits<P11>::ParameterType Param11;
347     typedef typename TypeTraits<P12>::ParameterType Param12;
348     typedef typename TypeTraits<P13>::ParameterType Param13;
349     typedef typename TypeTraits<P14>::ParameterType Param14;
350     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
351                                   Param11, Param12, Param13, Param14) = 0;
352   };
353 
354   template <
355     typename ReturnType,
356     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
357     typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15
358   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> >
359   : public Internal::FunctorBase<ReturnType>
360   {
361   public:
362     typedef typename TypeTraits<P1>::ParameterType Param1;
363     typedef typename TypeTraits<P2>::ParameterType Param2;
364     typedef typename TypeTraits<P3>::ParameterType Param3;
365     typedef typename TypeTraits<P4>::ParameterType Param4;
366     typedef typename TypeTraits<P5>::ParameterType Param5;
367     typedef typename TypeTraits<P6>::ParameterType Param6;
368     typedef typename TypeTraits<P7>::ParameterType Param7;
369     typedef typename TypeTraits<P8>::ParameterType Param8;
370     typedef typename TypeTraits<P9>::ParameterType Param9;
371     typedef typename TypeTraits<P10>::ParameterType Param10;
372     typedef typename TypeTraits<P11>::ParameterType Param11;
373     typedef typename TypeTraits<P12>::ParameterType Param12;
374     typedef typename TypeTraits<P13>::ParameterType Param13;
375     typedef typename TypeTraits<P14>::ParameterType Param14;
376     typedef typename TypeTraits<P15>::ParameterType Param15;
377     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
378                                   Param11, Param12, Param13, Param14, Param15) = 0;
379   };
380 
381   template <
382     typename ReturnType,
383     typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
384     typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15, typename P16
385   > class FunctorContainer<ReturnType, TL::Create<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16> >
386   : public Internal::FunctorBase<ReturnType>
387   {
388   public:
389     typedef typename TypeTraits<P1>::ParameterType Param1;
390     typedef typename TypeTraits<P2>::ParameterType Param2;
391     typedef typename TypeTraits<P3>::ParameterType Param3;
392     typedef typename TypeTraits<P4>::ParameterType Param4;
393     typedef typename TypeTraits<P5>::ParameterType Param5;
394     typedef typename TypeTraits<P6>::ParameterType Param6;
395     typedef typename TypeTraits<P7>::ParameterType Param7;
396     typedef typename TypeTraits<P8>::ParameterType Param8;
397     typedef typename TypeTraits<P9>::ParameterType Param9;
398     typedef typename TypeTraits<P10>::ParameterType Param10;
399     typedef typename TypeTraits<P11>::ParameterType Param11;
400     typedef typename TypeTraits<P12>::ParameterType Param12;
401     typedef typename TypeTraits<P13>::ParameterType Param13;
402     typedef typename TypeTraits<P14>::ParameterType Param14;
403     typedef typename TypeTraits<P15>::ParameterType Param15;
404     typedef typename TypeTraits<P16>::ParameterType Param16;
405     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
406                                   Param11, Param12, Param13, Param14, Param15, Param16) = 0;
407   };
408 
409 
410   template <
411   typename ReturnType,
412   typename P1
413   > class FunctorContainer<ReturnType, TypeList<P1, NullType> >
414   : public Internal::FunctorBase<ReturnType>
415   {
416   public:
417     typedef typename TypeTraits<P1>::ParameterType Param1;
418     virtual ReturnType operator()(Param1) = 0;
419   };
420 
421   template <
422   typename ReturnType,
423   typename P1, typename P2
424   > class FunctorContainer<ReturnType, TypeList<P2, TypeList<P1, NullType> > >
425   : public Internal::FunctorBase<ReturnType>
426   {
427   public:
428     typedef typename TypeTraits<P1>::ParameterType Param1;
429     typedef typename TypeTraits<P2>::ParameterType Param2;
430     virtual ReturnType operator()(Param1, Param2) = 0;
431   };
432 
433   template <
434   typename ReturnType,
435   typename P1, typename P2, typename P3
436   > class FunctorContainer<ReturnType, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > >
437   : public Internal::FunctorBase<ReturnType>
438   {
439   public:
440     typedef typename TypeTraits<P1>::ParameterType Param1;
441     typedef typename TypeTraits<P2>::ParameterType Param2;
442     typedef typename TypeTraits<P3>::ParameterType Param3;
443     virtual ReturnType operator()(Param1, Param2, Param3) = 0;
444   };
445 
446   template <
447   typename ReturnType,
448   typename P1, typename P2, typename P3, typename P4
449   > class FunctorContainer<ReturnType, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > >
450   : public Internal::FunctorBase<ReturnType>
451   {
452   public:
453     typedef typename TypeTraits<P1>::ParameterType Param1;
454     typedef typename TypeTraits<P2>::ParameterType Param2;
455     typedef typename TypeTraits<P3>::ParameterType Param3;
456     typedef typename TypeTraits<P4>::ParameterType Param4;
457     virtual ReturnType operator()(Param1, Param2, Param3, Param4) = 0;
458   };
459 
460   template <
461   typename ReturnType,
462   typename P1, typename P2, typename P3, typename P4, typename P5
463   > class FunctorContainer<ReturnType, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > >
464   : public Internal::FunctorBase<ReturnType>
465   {
466   public:
467     typedef typename TypeTraits<P1>::ParameterType Param1;
468     typedef typename TypeTraits<P2>::ParameterType Param2;
469     typedef typename TypeTraits<P3>::ParameterType Param3;
470     typedef typename TypeTraits<P4>::ParameterType Param4;
471     typedef typename TypeTraits<P5>::ParameterType Param5;
472     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5) = 0;
473   };
474 
475   template <
476   typename ReturnType,
477   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6
478   > class FunctorContainer<
479     ReturnType,
480     TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > >
481   >
482   : public Internal::FunctorBase<ReturnType>
483   {
484   public:
485     typedef typename TypeTraits<P1>::ParameterType Param1;
486     typedef typename TypeTraits<P2>::ParameterType Param2;
487     typedef typename TypeTraits<P3>::ParameterType Param3;
488     typedef typename TypeTraits<P4>::ParameterType Param4;
489     typedef typename TypeTraits<P5>::ParameterType Param5;
490     typedef typename TypeTraits<P6>::ParameterType Param6;
491     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6) = 0;
492   };
493 
494   template <
495   typename ReturnType,
496   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7
497   > class FunctorContainer<
498     ReturnType,
499     TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > > >
500   >
501   {
502   public:
503     typedef typename TypeTraits<P1>::ParameterType Param1;
504     typedef typename TypeTraits<P2>::ParameterType Param2;
505     typedef typename TypeTraits<P3>::ParameterType Param3;
506     typedef typename TypeTraits<P4>::ParameterType Param4;
507     typedef typename TypeTraits<P5>::ParameterType Param5;
508     typedef typename TypeTraits<P6>::ParameterType Param6;
509     typedef typename TypeTraits<P7>::ParameterType Param7;
510     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = 0;
511   };
512 
513   template <
514   typename ReturnType,
515   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8
516   > class FunctorContainer<
517     ReturnType,
518     TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2,
519       TypeList<P1, NullType> > > > > > > >
520   >
521   : public Internal::FunctorBase<ReturnType>
522   {
523   public:
524     typedef typename TypeTraits<P1>::ParameterType Param1;
525     typedef typename TypeTraits<P2>::ParameterType Param2;
526     typedef typename TypeTraits<P3>::ParameterType Param3;
527     typedef typename TypeTraits<P4>::ParameterType Param4;
528     typedef typename TypeTraits<P5>::ParameterType Param5;
529     typedef typename TypeTraits<P6>::ParameterType Param6;
530     typedef typename TypeTraits<P7>::ParameterType Param7;
531     typedef typename TypeTraits<P8>::ParameterType Param8;
532     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = 0;
533   };
534 
535   template <
536   typename ReturnType,
537   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
538   typename P9
539   > class FunctorContainer<
540     ReturnType,
541     TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2,
542       TypeList<P1, NullType> > > > > > > > >
543   >
544   : public Internal::FunctorBase<ReturnType>
545   {
546   public:
547     typedef typename TypeTraits<P1>::ParameterType Param1;
548     typedef typename TypeTraits<P2>::ParameterType Param2;
549     typedef typename TypeTraits<P3>::ParameterType Param3;
550     typedef typename TypeTraits<P4>::ParameterType Param4;
551     typedef typename TypeTraits<P5>::ParameterType Param5;
552     typedef typename TypeTraits<P6>::ParameterType Param6;
553     typedef typename TypeTraits<P7>::ParameterType Param7;
554     typedef typename TypeTraits<P8>::ParameterType Param8;
555     typedef typename TypeTraits<P9>::ParameterType Param9;
556     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = 0;
557   };
558 
559   template <
560   typename ReturnType,
561   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
562   typename P9, typename P10
563   > class FunctorContainer<
564     ReturnType,
565     TypeList<P10, TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2,
566       TypeList<P1, NullType> > > > > > > > > >
567   >
568   : public Internal::FunctorBase<ReturnType>
569   {
570   public:
571     typedef typename TypeTraits<P1>::ParameterType Param1;
572     typedef typename TypeTraits<P2>::ParameterType Param2;
573     typedef typename TypeTraits<P3>::ParameterType Param3;
574     typedef typename TypeTraits<P4>::ParameterType Param4;
575     typedef typename TypeTraits<P5>::ParameterType Param5;
576     typedef typename TypeTraits<P6>::ParameterType Param6;
577     typedef typename TypeTraits<P7>::ParameterType Param7;
578     typedef typename TypeTraits<P8>::ParameterType Param8;
579     typedef typename TypeTraits<P9>::ParameterType Param9;
580     typedef typename TypeTraits<P10>::ParameterType Param10;
581     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = 0;
582   };
583 
584   template <
585   typename ReturnType,
586   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
587   typename P9, typename P10, typename P11
588   > class FunctorContainer<
589     ReturnType,
590     TypeList<P11, TypeList<P10, TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3,
591       TypeList<P2, TypeList<P1, NullType> > > > > > > > > > >
592   >
593   : public Internal::FunctorBase<ReturnType>
594   {
595   public:
596     typedef typename TypeTraits<P1>::ParameterType Param1;
597     typedef typename TypeTraits<P2>::ParameterType Param2;
598     typedef typename TypeTraits<P3>::ParameterType Param3;
599     typedef typename TypeTraits<P4>::ParameterType Param4;
600     typedef typename TypeTraits<P5>::ParameterType Param5;
601     typedef typename TypeTraits<P6>::ParameterType Param6;
602     typedef typename TypeTraits<P7>::ParameterType Param7;
603     typedef typename TypeTraits<P8>::ParameterType Param8;
604     typedef typename TypeTraits<P9>::ParameterType Param9;
605     typedef typename TypeTraits<P10>::ParameterType Param10;
606     typedef typename TypeTraits<P11>::ParameterType Param11;
607     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
608                                   Param11) = 0;
609   };
610 
611   template <
612   typename ReturnType,
613   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
614   typename P9, typename P10, typename P11, typename P12
615   > class FunctorContainer<
616     ReturnType,
617     TypeList<P12, TypeList<P11, TypeList<P10, TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4,
618       TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > > > > > > > >
619   >
620   : public Internal::FunctorBase<ReturnType>
621   {
622   public:
623     typedef typename TypeTraits<P1>::ParameterType Param1;
624     typedef typename TypeTraits<P2>::ParameterType Param2;
625     typedef typename TypeTraits<P3>::ParameterType Param3;
626     typedef typename TypeTraits<P4>::ParameterType Param4;
627     typedef typename TypeTraits<P5>::ParameterType Param5;
628     typedef typename TypeTraits<P6>::ParameterType Param6;
629     typedef typename TypeTraits<P7>::ParameterType Param7;
630     typedef typename TypeTraits<P8>::ParameterType Param8;
631     typedef typename TypeTraits<P9>::ParameterType Param9;
632     typedef typename TypeTraits<P10>::ParameterType Param10;
633     typedef typename TypeTraits<P11>::ParameterType Param11;
634     typedef typename TypeTraits<P12>::ParameterType Param12;
635     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
636                                   Param11, Param12) = 0;
637   };
638 
639   template <
640   typename ReturnType,
641   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
642   typename P9, typename P10, typename P11, typename P12, typename P13
643   > class FunctorContainer<
644     ReturnType,
645     TypeList<P13, TypeList<P12, TypeList<P11, TypeList<P10, TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5,
646       TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > > > > > > > > >
647   >
648   : public Internal::FunctorBase<ReturnType>
649   {
650   public:
651     typedef typename TypeTraits<P1>::ParameterType Param1;
652     typedef typename TypeTraits<P2>::ParameterType Param2;
653     typedef typename TypeTraits<P3>::ParameterType Param3;
654     typedef typename TypeTraits<P4>::ParameterType Param4;
655     typedef typename TypeTraits<P5>::ParameterType Param5;
656     typedef typename TypeTraits<P6>::ParameterType Param6;
657     typedef typename TypeTraits<P7>::ParameterType Param7;
658     typedef typename TypeTraits<P8>::ParameterType Param8;
659     typedef typename TypeTraits<P9>::ParameterType Param9;
660     typedef typename TypeTraits<P10>::ParameterType Param10;
661     typedef typename TypeTraits<P11>::ParameterType Param11;
662     typedef typename TypeTraits<P12>::ParameterType Param12;
663     typedef typename TypeTraits<P13>::ParameterType Param13;
664     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
665                                   Param11, Param12, Param13) = 0;
666   };
667 
668   template <
669   typename ReturnType,
670   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
671   typename P9, typename P10, typename P11, typename P12, typename P13, typename P14
672   > class FunctorContainer<
673     ReturnType,
674     TypeList<P14, TypeList<P13, TypeList<P12, TypeList<P11, TypeList<P10, TypeList<P9, TypeList<P8, TypeList<P7, TypeList<P6,
675       TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType> > > > > > > > > > > > > >
676   >
677   : public Internal::FunctorBase<ReturnType>
678   {
679   public:
680     typedef typename TypeTraits<P1>::ParameterType Param1;
681     typedef typename TypeTraits<P2>::ParameterType Param2;
682     typedef typename TypeTraits<P3>::ParameterType Param3;
683     typedef typename TypeTraits<P4>::ParameterType Param4;
684     typedef typename TypeTraits<P5>::ParameterType Param5;
685     typedef typename TypeTraits<P6>::ParameterType Param6;
686     typedef typename TypeTraits<P7>::ParameterType Param7;
687     typedef typename TypeTraits<P8>::ParameterType Param8;
688     typedef typename TypeTraits<P9>::ParameterType Param9;
689     typedef typename TypeTraits<P10>::ParameterType Param10;
690     typedef typename TypeTraits<P11>::ParameterType Param11;
691     typedef typename TypeTraits<P12>::ParameterType Param12;
692     typedef typename TypeTraits<P13>::ParameterType Param13;
693     typedef typename TypeTraits<P14>::ParameterType Param14;
694     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
695                                   Param11, Param12, Param13, Param14) = 0;
696   };
697 
698   template <
699   typename ReturnType,
700   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
701   typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15
702   > class FunctorContainer<
703     ReturnType,
704     TypeList<P15, TypeList<P14, TypeList<P13, TypeList<P12, TypeList<P11, TypeList<P10, TypeList<P9, TypeList<P8,
705       TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType>
706     > > > > > > > > > > > > > >
707   >
708   : public Internal::FunctorBase<ReturnType>
709   {
710   public:
711     typedef typename TypeTraits<P1>::ParameterType Param1;
712     typedef typename TypeTraits<P2>::ParameterType Param2;
713     typedef typename TypeTraits<P3>::ParameterType Param3;
714     typedef typename TypeTraits<P4>::ParameterType Param4;
715     typedef typename TypeTraits<P5>::ParameterType Param5;
716     typedef typename TypeTraits<P6>::ParameterType Param6;
717     typedef typename TypeTraits<P7>::ParameterType Param7;
718     typedef typename TypeTraits<P8>::ParameterType Param8;
719     typedef typename TypeTraits<P9>::ParameterType Param9;
720     typedef typename TypeTraits<P10>::ParameterType Param10;
721     typedef typename TypeTraits<P11>::ParameterType Param11;
722     typedef typename TypeTraits<P12>::ParameterType Param12;
723     typedef typename TypeTraits<P13>::ParameterType Param13;
724     typedef typename TypeTraits<P14>::ParameterType Param14;
725     typedef typename TypeTraits<P15>::ParameterType Param15;
726     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
727                                   Param11, Param12, Param13, Param14, Param15) = 0;
728   };
729 
730   template <
731   typename ReturnType,
732   typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
733   typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15, typename P16
734   > class FunctorContainer<
735     ReturnType,
736     TypeList<P16, TypeList<P15, TypeList<P14, TypeList<P13, TypeList<P12, TypeList<P11, TypeList<P10, TypeList<P9,
737       TypeList<P8, TypeList<P7, TypeList<P6, TypeList<P5, TypeList<P4, TypeList<P3, TypeList<P2, TypeList<P1, NullType>
738     > > > > > > > > > > > > > > >
739   >
740   : public Internal::FunctorBase<ReturnType>
741   {
742   public:
743     typedef typename TypeTraits<P1>::ParameterType Param1;
744     typedef typename TypeTraits<P2>::ParameterType Param2;
745     typedef typename TypeTraits<P3>::ParameterType Param3;
746     typedef typename TypeTraits<P4>::ParameterType Param4;
747     typedef typename TypeTraits<P5>::ParameterType Param5;
748     typedef typename TypeTraits<P6>::ParameterType Param6;
749     typedef typename TypeTraits<P7>::ParameterType Param7;
750     typedef typename TypeTraits<P8>::ParameterType Param8;
751     typedef typename TypeTraits<P9>::ParameterType Param9;
752     typedef typename TypeTraits<P10>::ParameterType Param10;
753     typedef typename TypeTraits<P11>::ParameterType Param11;
754     typedef typename TypeTraits<P12>::ParameterType Param12;
755     typedef typename TypeTraits<P13>::ParameterType Param13;
756     typedef typename TypeTraits<P14>::ParameterType Param14;
757     typedef typename TypeTraits<P15>::ParameterType Param15;
758     typedef typename TypeTraits<P16>::ParameterType Param16;
759     virtual ReturnType operator()(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10,
760                                   Param11, Param12, Param13, Param14, Param15, Param16) = 0;
761   };
762 
763 
764   // BasicFunctorHandler - handle raw function pointers and other functor objects
765   // --------------------------------------------------------------------------------------------------------------
766 
767   template <class ParentFunctor, typename ActionType> class BasicFunctorHandler : public ParentFunctor::ContainerType
768   {
769     typedef typename ParentFunctor::ContainerType Base;
770 
771   public:
772     typedef typename Base::ReturnType ReturnType;
773     typedef typename Base::Param1 Param1;
774     typedef typename Base::Param2 Param2;
775     typedef typename Base::Param3 Param3;
776     typedef typename Base::Param4 Param4;
777     typedef typename Base::Param5 Param5;
778     typedef typename Base::Param6 Param6;
779     typedef typename Base::Param7 Param7;
780     typedef typename Base::Param8 Param8;
781     typedef typename Base::Param9 Param9;
782     typedef typename Base::Param10 Param10;
783     typedef typename Base::Param11 Param11;
784     typedef typename Base::Param12 Param12;
785     typedef typename Base::Param13 Param13;
786     typedef typename Base::Param14 Param14;
787     typedef typename Base::Param15 Param15;
788     typedef typename Base::Param16 Param16;
789 
790   private:
791     ActionType m_action;
792 
793   public:
BasicFunctorHandler(const ActionType & action)794     BasicFunctorHandler(const ActionType& action) : m_action(action) { ; }
DoClone()795     BasicFunctorHandler* DoClone() const { return new BasicFunctorHandler(*this); }
796 
operator()797     ReturnType operator()()
798     {
799       return m_action();
800     }
801 
operator()802     ReturnType operator()(Param1 p1)
803     {
804       return m_action(p1);
805     }
806 
operator()807     ReturnType operator()(Param1 p1, Param2 p2)
808     {
809       return m_action(p1, p2);
810     }
811 
operator()812     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3)
813     {
814       return m_action(p1, p2, p3);
815     }
816 
operator()817     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4)
818     {
819       return m_action(p1, p2, p3, p4);
820     }
821 
operator()822     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)
823     {
824       return m_action(p1, p2, p3, p4, p5);
825     }
826 
operator()827     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)
828     {
829       return m_action(p1, p2, p3, p4, p5, p6);
830     }
831 
operator()832     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)
833     {
834       return m_action(p1, p2, p3, p4, p5, p6, p7);
835     }
836 
operator()837     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8)
838     {
839       return m_action(p1, p2, p3, p4, p5, p6, p7, p8);
840     }
841 
operator()842     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9)
843     {
844       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9);
845     }
846 
operator()847     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
848                           Param10 p10)
849     {
850       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
851     }
852 
operator()853     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
854                           Param10 p10, Param11 p11)
855     {
856       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
857     }
858 
operator()859     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
860                           Param10 p10, Param11 p11, Param12 p12)
861     {
862       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
863     }
864 
operator()865     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
866                           Param10 p10, Param11 p11, Param12 p12, Param13 p13)
867     {
868       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
869     }
870 
operator()871     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
872                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)
873     {
874       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
875     }
876 
operator()877     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
878                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)
879     {
880       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
881     }
882 
operator()883     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
884                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)
885     {
886       return m_action(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
887     }
888   };
889 
890 
891   // Member Function Handler
892   // --------------------------------------------------------------------------------------------------------------
893 
894   template <class ParentFunctor, typename ObjectPointer, typename MemberFunction>
895   class MemberFunctionHandler : public ParentFunctor::ContainerType
896   {
897     typedef typename ParentFunctor::ContainerType Base;
898 
899   public:
900     typedef typename Base::ReturnType ReturnType;
901     typedef typename Base::Param1 Param1;
902     typedef typename Base::Param2 Param2;
903     typedef typename Base::Param3 Param3;
904     typedef typename Base::Param4 Param4;
905     typedef typename Base::Param5 Param5;
906     typedef typename Base::Param6 Param6;
907     typedef typename Base::Param7 Param7;
908     typedef typename Base::Param8 Param8;
909     typedef typename Base::Param9 Param9;
910     typedef typename Base::Param10 Param10;
911     typedef typename Base::Param11 Param11;
912     typedef typename Base::Param12 Param12;
913     typedef typename Base::Param13 Param13;
914     typedef typename Base::Param14 Param14;
915     typedef typename Base::Param15 Param15;
916     typedef typename Base::Param16 Param16;
917 
918   private:
919     ObjectPointer m_obj;
920     MemberFunction m_action;
921 
922   public:
MemberFunctionHandler(const ObjectPointer & obj,MemberFunction action)923     MemberFunctionHandler(const ObjectPointer& obj, MemberFunction action) : m_obj(obj), m_action(action) { ; }
DoClone()924     MemberFunctionHandler* DoClone() const { return new MemberFunctionHandler(*this); }
925 
operator()926     ReturnType operator()()
927     {
928       return ((*m_obj).*m_action)();
929     }
930 
operator()931     ReturnType operator()(Param1 p1)
932     {
933       return ((*m_obj).*m_action)(p1);
934     }
935 
operator()936     ReturnType operator()(Param1 p1, Param2 p2)
937     {
938       return ((*m_obj).*m_action)(p1, p2);
939     }
940 
operator()941     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3)
942     {
943       return ((*m_obj).*m_action)(p1, p2, p3);
944     }
945 
operator()946     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4)
947     {
948       return ((*m_obj).*m_action)(p1, p2, p3, p4);
949     }
950 
operator()951     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)
952     {
953       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5);
954     }
955 
operator()956     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)
957     {
958       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6);
959     }
960 
operator()961     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)
962     {
963       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7);
964     }
965 
operator()966     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8)
967     {
968       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8);
969     }
970 
operator()971     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9)
972     {
973       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
974     }
975 
operator()976     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
977                           Param10 p10)
978     {
979       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
980     }
981 
operator()982     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
983                           Param10 p10, Param11 p11)
984     {
985       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
986     }
987 
operator()988     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
989                           Param10 p10, Param11 p11, Param12 p12)
990     {
991       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
992     }
993 
operator()994     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
995                           Param10 p10, Param11 p11, Param12 p12, Param13 p13)
996     {
997       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
998     }
999 
operator()1000     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1001                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)
1002     {
1003       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
1004     }
1005 
operator()1006     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1007                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)
1008     {
1009       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
1010     }
1011 
operator()1012     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1013                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)
1014     {
1015       return ((*m_obj).*m_action)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
1016     }
1017   };
1018 
1019 
1020   // Functor
1021   // --------------------------------------------------------------------------------------------------------------
1022 
1023   template <typename R = void, class TList = NullType> class Functor
1024   {
1025   public:
1026     typedef FunctorContainer<R, TList> ContainerType;
1027     typedef R ReturnType;
1028     typedef TList ParameterList;
1029     typedef typename ContainerType::Param1 Param1;
1030     typedef typename ContainerType::Param2 Param2;
1031     typedef typename ContainerType::Param3 Param3;
1032     typedef typename ContainerType::Param4 Param4;
1033     typedef typename ContainerType::Param5 Param5;
1034     typedef typename ContainerType::Param6 Param6;
1035     typedef typename ContainerType::Param7 Param7;
1036     typedef typename ContainerType::Param8 Param8;
1037     typedef typename ContainerType::Param9 Param9;
1038     typedef typename ContainerType::Param10 Param10;
1039     typedef typename ContainerType::Param11 Param11;
1040     typedef typename ContainerType::Param12 Param12;
1041     typedef typename ContainerType::Param13 Param13;
1042     typedef typename ContainerType::Param14 Param14;
1043     typedef typename ContainerType::Param15 Param15;
1044     typedef typename ContainerType::Param16 Param16;
1045 
1046   private:
1047     SmartPtr<ContainerType, DestructiveCopy> m_container;
1048 
1049   public:
Functor()1050     Functor() : m_container(NULL) { ; }
Functor(const Functor & rhs)1051     Functor(const Functor& rhs)
1052       : m_container(ContainerType::Clone(SmartPtr<ContainerType, DestructiveCopy>::GetPointer(rhs.m_container))) { ; }
Functor(SmartPtr<ContainerType,DestructiveCopy> container)1053     Functor(SmartPtr<ContainerType, DestructiveCopy> container) : m_container(container) { ; }
1054 
1055     template <typename ActionType>
Functor(ActionType action)1056     Functor(ActionType action) : m_container(new BasicFunctorHandler<Functor, ActionType>(action)) { ; }
1057 
1058     template <typename ObjectPointer, typename MemberFunction>
Functor(const ObjectPointer & obj,MemberFunction action)1059     Functor(const ObjectPointer& obj, MemberFunction action)
1060       : m_container(new MemberFunctionHandler<Functor, ObjectPointer, MemberFunction>(obj, action)) { ; }
1061 
1062     Functor& operator=(const Functor& rhs)
1063     {
1064       Functor temp(rhs);
1065       m_container = temp.m_container;
1066       return *this;
1067     }
1068 
1069 
operator()1070     ReturnType operator()() const
1071     {
1072       return (*m_container)();
1073     }
1074 
operator()1075     ReturnType operator()(Param1 p1) const
1076     {
1077       return (*m_container)(p1);
1078     }
1079 
operator()1080     ReturnType operator()(Param1 p1, Param2 p2) const
1081     {
1082       return (*m_container)(p1, p2);
1083     }
1084 
operator()1085     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3) const
1086     {
1087       return (*m_container)(p1, p2, p3);
1088     }
1089 
operator()1090     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const
1091     {
1092       return (*m_container)(p1, p2, p3, p4);
1093     }
1094 
operator()1095     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const
1096     {
1097       return (*m_container)(p1, p2, p3, p4, p5);
1098     }
1099 
operator()1100     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const
1101     {
1102       return (*m_container)(p1, p2, p3, p4, p5, p6);
1103     }
1104 
operator()1105     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const
1106     {
1107       return (*m_container)(p1, p2, p3, p4, p5, p6, p7);
1108     }
1109 
operator()1110     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8) const
1111     {
1112       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8);
1113     }
1114 
operator()1115     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1116                           Param9 p9) const
1117     {
1118       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
1119     }
1120 
operator()1121     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1122                           Param10 p10) const
1123     {
1124       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
1125     }
1126 
operator()1127     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1128                           Param10 p10, Param11 p11) const
1129     {
1130       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
1131     }
1132 
operator()1133     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1134                           Param10 p10, Param11 p11, Param12 p12) const
1135     {
1136       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
1137     }
1138 
operator()1139     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1140                           Param10 p10, Param11 p11, Param12 p12, Param13 p13) const
1141     {
1142       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
1143     }
1144 
operator()1145     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1146                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const
1147     {
1148       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
1149     }
1150 
operator()1151     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1152                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const
1153     {
1154       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
1155     }
1156 
operator()1157     ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8, Param9 p9,
1158                           Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const
1159     {
1160       return (*m_container)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
1161     }
1162 
1163 
1164   private:
1165     struct Tester
1166     {
PlaceholderTester1167       LIB_EXPORT void Placeholder() { ; }
1168     };
1169 
1170     typedef void (Tester::*PlaceholderBooleanType)();
1171 
1172   public:
PlaceholderBooleanType()1173     inline operator PlaceholderBooleanType() const { return (m_container ? &Tester::Placeholder : NULL); }
1174   };
1175 
1176 
1177   // Parameter Binding Internal Support
1178   // --------------------------------------------------------------------------------------------------------------
1179 
1180   namespace Internal {
1181 
1182     template <class Fctor> struct BindFirstTraits;
1183     template <typename R, class TList> struct BindFirstTraits<Functor<R, TList> >
1184     {
1185       typedef Functor<R, TList> OriginalFunctor;
1186       typedef typename TL::Remove<TList, typename TL::TypeAt<TList, 0>::Result>::Result ParameterList;
1187       typedef typename TL::TypeAt<TList, 0>::Result OriginalParam1;
1188       typedef Functor<R, ParameterList> BoundFunctorType;
1189       typedef typename BoundFunctorType::ContainerType ContainerType;
1190     };
1191 
1192 
1193     template <class T> struct BindTypeStorage;
1194     template <class T> struct BindTypeStorage
1195     {
1196       typedef typename TypeTraits<T>::ParameterType RefOrValue;
1197     };
1198     template <typename R, class TList> struct BindTypeStorage<Functor<R, TList> >
1199     {
1200       typedef Functor<R, TList> OriginalFunctor;
1201       typedef const typename TypeTraits<OriginalFunctor>::ReferredType RefOrValue;
1202     };
1203 
1204 
1205     template <class OriginalFunctor> class BindFirst : public BindFirstTraits<OriginalFunctor>::ContainerType
1206     {
1207     public:
1208       typedef typename BindFirstTraits<OriginalFunctor>::ContainerType Base;
1209       typedef typename OriginalFunctor::ReturnType ReturnType;
1210       typedef typename OriginalFunctor::Param1 BoundType;
1211       typedef typename BindTypeStorage<typename BindFirstTraits<OriginalFunctor>::OriginalParam1>::RefOrValue
1212         BoundTypeStorage;
1213 
1214       typedef typename OriginalFunctor::Param2 Param1;
1215       typedef typename OriginalFunctor::Param3 Param2;
1216       typedef typename OriginalFunctor::Param4 Param3;
1217       typedef typename OriginalFunctor::Param5 Param4;
1218       typedef typename OriginalFunctor::Param6 Param5;
1219       typedef typename OriginalFunctor::Param7 Param6;
1220       typedef typename OriginalFunctor::Param8 Param7;
1221       typedef typename OriginalFunctor::Param9 Param8;
1222       typedef typename OriginalFunctor::Param10 Param9;
1223       typedef typename OriginalFunctor::Param11 Param10;
1224       typedef typename OriginalFunctor::Param12 Param11;
1225       typedef typename OriginalFunctor::Param13 Param12;
1226       typedef typename OriginalFunctor::Param14 Param13;
1227       typedef typename OriginalFunctor::Param15 Param14;
1228       typedef typename OriginalFunctor::Param16 Param15;
1229       typedef EmptyType Param16;
1230 
1231     private:
1232       OriginalFunctor m_functor;
1233       BoundTypeStorage m_param;
1234 
1235     public:
1236       BindFirst(const OriginalFunctor& functor, BoundType param) : m_functor(functor), m_param(param) { ; }
1237       BindFirst* DoClone() const { return new BindFirst(*this); }
1238 
1239       ReturnType operator()()
1240       {
1241         return m_functor(m_param);
1242       }
1243 
1244       ReturnType operator()(Param1 p1)
1245       {
1246         return m_functor(m_param, p1);
1247       }
1248 
1249       ReturnType operator()(Param1 p1, Param2 p2)
1250       {
1251         return m_functor(m_param, p1, p2);
1252       }
1253 
1254       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3)
1255       {
1256         return m_functor(m_param, p1, p2, p3);
1257       }
1258 
1259       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4)
1260       {
1261         return m_functor(m_param, p1, p2, p3, p4);
1262       }
1263 
1264       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)
1265       {
1266         return m_functor(m_param, p1, p2, p3, p4, p5);
1267       }
1268 
1269       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)
1270       {
1271         return m_functor(m_param, p1, p2, p3, p4, p5, p6);
1272       }
1273 
1274       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)
1275       {
1276         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7);
1277       }
1278 
1279       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8)
1280       {
1281         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8);
1282       }
1283 
1284       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1285                             Param9 p9)
1286       {
1287         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9);
1288       }
1289 
1290       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1291                             Param9 p9, Param10 p10)
1292       {
1293         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
1294       }
1295 
1296       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1297                             Param9 p9, Param10 p10, Param11 p11)
1298       {
1299         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
1300       }
1301 
1302       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1303                             Param9 p9, Param10 p10, Param11 p11, Param12 p12)
1304       {
1305         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
1306       }
1307 
1308       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1309                             Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)
1310       {
1311         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
1312       }
1313 
1314       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1315                             Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)
1316       {
1317         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
1318       }
1319 
1320       ReturnType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param2 p8,
1321                             Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)
1322       {
1323         return m_functor(m_param, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
1324       }
1325     };
1326   };
1327 
1328   template <class Fctor>
1329   typename Internal::BindFirstTraits<Fctor>::BoundFunctorType BindFirst(const Fctor& f, typename Fctor::Param1 p)
1330   {
1331     typedef typename Internal::BindFirstTraits<Fctor>::BoundFunctorType Outgoing;
1332     return Outgoing(SmartPtr<typename Outgoing::ContainerType, DestructiveCopy>(new Internal::BindFirst<Fctor>(f, p)));
1333   }
1334 
1335 
1336 };
1337 
1338 #endif
1339