functiondb.h
1 template <class F, template<class> class P>
2 struct AllArgs<F,P,0>
3 {
4  static const bool value=true ;
5 };
6 
7 
8 template <class R>
9 struct Arity<R (*)()>
10 {
11  static const int V=0;
12  static const int value=0;
13 };
14 
15 template <class R>
16 struct Return<R (*)()>
17 {
18  typedef R T;
19  typedef R type;
20 };
21 
22 template <class C, class R>
23 struct Arity<R (C::*)()>
24 {
25  static const int V=0;
26  static const int value=0;
27 };
28 
29 template <class C, class R>
30 struct Return<R (C::*)()>
31 {
32  typedef R T;
33  typedef R type;
34 };
35 
36 template <class C, class R>
37 struct Arity<R (C::*)() const>
38 {
39  static const int V=0;
40  static const int value=0;
41 };
42 
43 template <class C, class R>
44 struct Return<R (C::*)() const>
45 {
46  typedef R T;
47  typedef R type;
48 };
49 
50 template <class C, class R>
51 struct is_member_function_ptr<R (C::*)()>
52 {
53  static const bool value=true;
54 };
55 
56 template <class C, class R>
57 struct is_member_function_ptr<R (C::*)() const>
58 {
59  static const bool value=true;
60 };
61 
62 template <class C, class R>
63 struct is_const_method<R (C::*)() const>
64 {
65  static const bool value=true;
66 };
67 
68 template <class R>
69 struct is_nonmember_function_ptr<R (*)()>
70 {
71  static const bool value=true;
72 };
73 
74 template <class C, class D, class R>
75 class bound_method<C, R (D::*)()>
76 {
77  typedef R (D::*M)();
78  C* obj;
79  M method;
80  public:
81  static const int arity=0;
82  typedef R Ret;
83  template <int i> struct Arg: public functional::Arg<M,i> {};
84  bound_method(C& obj, M method): obj(&obj), method(method) {}
85  R operator()() const {return (obj->*method)();}
86  void rebind(C& newObj) {obj=&newObj;}
87 };
88 
89 template <class C, class D>
90 class bound_method<C, void (D::*)()>
91 {
92  typedef void (D::*M)();
93  C* obj;
94  M method;
95  public:
96  static const int arity=0;
97  typedef void Ret;
98  template <int i> struct Arg: public functional::Arg<M,i> {};
99  bound_method(C& obj, M method): obj(&obj), method(method) {}
100  void operator()() const {(obj->*method)();}
101  void rebind(C& newObj) {obj=&newObj;}
102 };
103 
104 template <class C, class D, class R>
105 class bound_method<C, R (D::*)() const>
106 {
107  typedef R (D::*M)() const;
108  C& obj;
109  M method;
110  public:
111  static const int arity=0;
112  typedef R Ret;
113  template <int i> struct Arg: public functional::Arg<M,i> {};
114  bound_method(C& obj, M method): obj(obj), method(method) {}
115  R operator()() const {return (obj.*method)();}
116 };
117 
118 template <class C, class D>
119 class bound_method<C, void (D::*)() const>
120 {
121  typedef void (D::*M)() const;
122  C& obj;
123  M method;
124  public:
125  static const int arity=0;
126  typedef void Ret;
127  template <int i> struct Arg: public functional::Arg<M,i> {};
128  bound_method(C& obj, M method): obj(obj), method(method) {}
129  void operator()() const {(obj.*method)();}
130 };
131 
132 template <class F, class Args>
133 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 0> >,
134  typename Return<F>::T>::T
135 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
136 {
137  return f();
138 }
139 
140 /*
141  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
142  which require C++-11 ability to test for the existence of a copy constructor.
143  If the return type is not copy constructable, the user must arrange for the return value to be discarded
144 */
145 
146 template <class F, class Args>
147 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 0> >,
148  void>::T
149 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
150 {
151  f();
152 }
153 
154 template <class R, class A1>
155 struct Arg<R (*)(A1), 1>
156 {typedef A1 T;};
157 
158 template <class C, class R, class A1>
159 struct Arg<R (C::*)(A1), 1>
160 {typedef A1 T;};
161 
162 template <class C, class R, class A1>
163 struct Arg<R (C::*)(A1) const, 1>
164 {typedef A1 T;};
165 template <class F, template<class> class P>
166 struct AllArgs<F,P,1>
167 {
168  static const bool value=true && P<typename Arg<F,1>::T>::value;
169 };
170 
171 
172 template <class R, class A1>
173 struct Arity<R (*)(A1)>
174 {
175  static const int V=1;
176  static const int value=1;
177 };
178 
179 template <class R, class A1>
180 struct Return<R (*)(A1)>
181 {
182  typedef R T;
183  typedef R type;
184 };
185 
186 template <class C, class R, class A1>
187 struct Arity<R (C::*)(A1)>
188 {
189  static const int V=1;
190  static const int value=1;
191 };
192 
193 template <class C, class R, class A1>
194 struct Return<R (C::*)(A1)>
195 {
196  typedef R T;
197  typedef R type;
198 };
199 
200 template <class C, class R, class A1>
201 struct Arity<R (C::*)(A1) const>
202 {
203  static const int V=1;
204  static const int value=1;
205 };
206 
207 template <class C, class R, class A1>
208 struct Return<R (C::*)(A1) const>
209 {
210  typedef R T;
211  typedef R type;
212 };
213 
214 template <class C, class R, class A1>
215 struct is_member_function_ptr<R (C::*)(A1)>
216 {
217  static const bool value=true;
218 };
219 
220 template <class C, class R, class A1>
221 struct is_member_function_ptr<R (C::*)(A1) const>
222 {
223  static const bool value=true;
224 };
225 
226 template <class C, class R, class A1>
227 struct is_const_method<R (C::*)(A1) const>
228 {
229  static const bool value=true;
230 };
231 
232 template <class R, class A1>
233 struct is_nonmember_function_ptr<R (*)(A1)>
234 {
235  static const bool value=true;
236 };
237 
238 template <class C, class D, class R, class A1>
239 class bound_method<C, R (D::*)(A1)>
240 {
241  typedef R (D::*M)(A1);
242  C* obj;
243  M method;
244  public:
245  static const int arity=1;
246  typedef R Ret;
247  template <int i> struct Arg: public functional::Arg<M,i> {};
248  bound_method(C& obj, M method): obj(&obj), method(method) {}
249  R operator()(A1 a1) const {return (obj->*method)(a1);}
250  void rebind(C& newObj) {obj=&newObj;}
251 };
252 
253 template <class C, class D, class A1>
254 class bound_method<C, void (D::*)(A1)>
255 {
256  typedef void (D::*M)(A1);
257  C* obj;
258  M method;
259  public:
260  static const int arity=1;
261  typedef void Ret;
262  template <int i> struct Arg: public functional::Arg<M,i> {};
263  bound_method(C& obj, M method): obj(&obj), method(method) {}
264  void operator()(A1 a1) const {(obj->*method)(a1);}
265  void rebind(C& newObj) {obj=&newObj;}
266 };
267 
268 template <class C, class D, class R, class A1>
269 class bound_method<C, R (D::*)(A1) const>
270 {
271  typedef R (D::*M)(A1) const;
272  C& obj;
273  M method;
274  public:
275  static const int arity=1;
276  typedef R Ret;
277  template <int i> struct Arg: public functional::Arg<M,i> {};
278  bound_method(C& obj, M method): obj(obj), method(method) {}
279  R operator()(A1 a1) const {return (obj.*method)(a1);}
280 };
281 
282 template <class C, class D, class A1>
283 class bound_method<C, void (D::*)(A1) const>
284 {
285  typedef void (D::*M)(A1) const;
286  C& obj;
287  M method;
288  public:
289  static const int arity=1;
290  typedef void Ret;
291  template <int i> struct Arg: public functional::Arg<M,i> {};
292  bound_method(C& obj, M method): obj(obj), method(method) {}
293  void operator()(A1 a1) const {(obj.*method)(a1);}
294 };
295 
296 template <class F, class Args>
297 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 1> >,
298  typename Return<F>::T>::T
299 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
300 {
301  return f(a[0]);
302 }
303 
304 /*
305  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
306  which require C++-11 ability to test for the existence of a copy constructor.
307  If the return type is not copy constructable, the user must arrange for the return value to be discarded
308 */
309 
310 template <class F, class Args>
311 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 1> >,
312  void>::T
313 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
314 {
315  f(a[0]);
316 }
317 
318 template <class R, class A1, class A2>
319 struct Arg<R (*)(A1,A2), 1>
320 {typedef A1 T;};
321 
322 template <class C, class R, class A1, class A2>
323 struct Arg<R (C::*)(A1,A2), 1>
324 {typedef A1 T;};
325 
326 template <class C, class R, class A1, class A2>
327 struct Arg<R (C::*)(A1,A2) const, 1>
328 {typedef A1 T;};
329 template <class R, class A1, class A2>
330 struct Arg<R (*)(A1,A2), 2>
331 {typedef A2 T;};
332 
333 template <class C, class R, class A1, class A2>
334 struct Arg<R (C::*)(A1,A2), 2>
335 {typedef A2 T;};
336 
337 template <class C, class R, class A1, class A2>
338 struct Arg<R (C::*)(A1,A2) const, 2>
339 {typedef A2 T;};
340 template <class F, template<class> class P>
341 struct AllArgs<F,P,2>
342 {
343  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value;
344 };
345 
346 
347 template <class R, class A1, class A2>
348 struct Arity<R (*)(A1,A2)>
349 {
350  static const int V=2;
351  static const int value=2;
352 };
353 
354 template <class R, class A1, class A2>
355 struct Return<R (*)(A1,A2)>
356 {
357  typedef R T;
358  typedef R type;
359 };
360 
361 template <class C, class R, class A1, class A2>
362 struct Arity<R (C::*)(A1,A2)>
363 {
364  static const int V=2;
365  static const int value=2;
366 };
367 
368 template <class C, class R, class A1, class A2>
369 struct Return<R (C::*)(A1,A2)>
370 {
371  typedef R T;
372  typedef R type;
373 };
374 
375 template <class C, class R, class A1, class A2>
376 struct Arity<R (C::*)(A1,A2) const>
377 {
378  static const int V=2;
379  static const int value=2;
380 };
381 
382 template <class C, class R, class A1, class A2>
383 struct Return<R (C::*)(A1,A2) const>
384 {
385  typedef R T;
386  typedef R type;
387 };
388 
389 template <class C, class R, class A1, class A2>
390 struct is_member_function_ptr<R (C::*)(A1,A2)>
391 {
392  static const bool value=true;
393 };
394 
395 template <class C, class R, class A1, class A2>
396 struct is_member_function_ptr<R (C::*)(A1,A2) const>
397 {
398  static const bool value=true;
399 };
400 
401 template <class C, class R, class A1, class A2>
402 struct is_const_method<R (C::*)(A1,A2) const>
403 {
404  static const bool value=true;
405 };
406 
407 template <class R, class A1, class A2>
408 struct is_nonmember_function_ptr<R (*)(A1,A2)>
409 {
410  static const bool value=true;
411 };
412 
413 template <class C, class D, class R, class A1, class A2>
414 class bound_method<C, R (D::*)(A1,A2)>
415 {
416  typedef R (D::*M)(A1,A2);
417  C* obj;
418  M method;
419  public:
420  static const int arity=2;
421  typedef R Ret;
422  template <int i> struct Arg: public functional::Arg<M,i> {};
423  bound_method(C& obj, M method): obj(&obj), method(method) {}
424  R operator()(A1 a1,A2 a2) const {return (obj->*method)(a1,a2);}
425  void rebind(C& newObj) {obj=&newObj;}
426 };
427 
428 template <class C, class D, class A1, class A2>
429 class bound_method<C, void (D::*)(A1,A2)>
430 {
431  typedef void (D::*M)(A1,A2);
432  C* obj;
433  M method;
434  public:
435  static const int arity=2;
436  typedef void Ret;
437  template <int i> struct Arg: public functional::Arg<M,i> {};
438  bound_method(C& obj, M method): obj(&obj), method(method) {}
439  void operator()(A1 a1,A2 a2) const {(obj->*method)(a1,a2);}
440  void rebind(C& newObj) {obj=&newObj;}
441 };
442 
443 template <class C, class D, class R, class A1, class A2>
444 class bound_method<C, R (D::*)(A1,A2) const>
445 {
446  typedef R (D::*M)(A1,A2) const;
447  C& obj;
448  M method;
449  public:
450  static const int arity=2;
451  typedef R Ret;
452  template <int i> struct Arg: public functional::Arg<M,i> {};
453  bound_method(C& obj, M method): obj(obj), method(method) {}
454  R operator()(A1 a1,A2 a2) const {return (obj.*method)(a1,a2);}
455 };
456 
457 template <class C, class D, class A1, class A2>
458 class bound_method<C, void (D::*)(A1,A2) const>
459 {
460  typedef void (D::*M)(A1,A2) const;
461  C& obj;
462  M method;
463  public:
464  static const int arity=2;
465  typedef void Ret;
466  template <int i> struct Arg: public functional::Arg<M,i> {};
467  bound_method(C& obj, M method): obj(obj), method(method) {}
468  void operator()(A1 a1,A2 a2) const {(obj.*method)(a1,a2);}
469 };
470 
471 template <class F, class Args>
472 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 2> >,
473  typename Return<F>::T>::T
474 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
475 {
476  return f(a[0],a[1]);
477 }
478 
479 /*
480  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
481  which require C++-11 ability to test for the existence of a copy constructor.
482  If the return type is not copy constructable, the user must arrange for the return value to be discarded
483 */
484 
485 template <class F, class Args>
486 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 2> >,
487  void>::T
488 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
489 {
490  f(a[0],a[1]);
491 }
492 
493 template <class R, class A1, class A2, class A3>
494 struct Arg<R (*)(A1,A2,A3), 1>
495 {typedef A1 T;};
496 
497 template <class C, class R, class A1, class A2, class A3>
498 struct Arg<R (C::*)(A1,A2,A3), 1>
499 {typedef A1 T;};
500 
501 template <class C, class R, class A1, class A2, class A3>
502 struct Arg<R (C::*)(A1,A2,A3) const, 1>
503 {typedef A1 T;};
504 template <class R, class A1, class A2, class A3>
505 struct Arg<R (*)(A1,A2,A3), 2>
506 {typedef A2 T;};
507 
508 template <class C, class R, class A1, class A2, class A3>
509 struct Arg<R (C::*)(A1,A2,A3), 2>
510 {typedef A2 T;};
511 
512 template <class C, class R, class A1, class A2, class A3>
513 struct Arg<R (C::*)(A1,A2,A3) const, 2>
514 {typedef A2 T;};
515 template <class R, class A1, class A2, class A3>
516 struct Arg<R (*)(A1,A2,A3), 3>
517 {typedef A3 T;};
518 
519 template <class C, class R, class A1, class A2, class A3>
520 struct Arg<R (C::*)(A1,A2,A3), 3>
521 {typedef A3 T;};
522 
523 template <class C, class R, class A1, class A2, class A3>
524 struct Arg<R (C::*)(A1,A2,A3) const, 3>
525 {typedef A3 T;};
526 template <class F, template<class> class P>
527 struct AllArgs<F,P,3>
528 {
529  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value;
530 };
531 
532 
533 template <class R, class A1, class A2, class A3>
534 struct Arity<R (*)(A1,A2,A3)>
535 {
536  static const int V=3;
537  static const int value=3;
538 };
539 
540 template <class R, class A1, class A2, class A3>
541 struct Return<R (*)(A1,A2,A3)>
542 {
543  typedef R T;
544  typedef R type;
545 };
546 
547 template <class C, class R, class A1, class A2, class A3>
548 struct Arity<R (C::*)(A1,A2,A3)>
549 {
550  static const int V=3;
551  static const int value=3;
552 };
553 
554 template <class C, class R, class A1, class A2, class A3>
555 struct Return<R (C::*)(A1,A2,A3)>
556 {
557  typedef R T;
558  typedef R type;
559 };
560 
561 template <class C, class R, class A1, class A2, class A3>
562 struct Arity<R (C::*)(A1,A2,A3) const>
563 {
564  static const int V=3;
565  static const int value=3;
566 };
567 
568 template <class C, class R, class A1, class A2, class A3>
569 struct Return<R (C::*)(A1,A2,A3) const>
570 {
571  typedef R T;
572  typedef R type;
573 };
574 
575 template <class C, class R, class A1, class A2, class A3>
576 struct is_member_function_ptr<R (C::*)(A1,A2,A3)>
577 {
578  static const bool value=true;
579 };
580 
581 template <class C, class R, class A1, class A2, class A3>
582 struct is_member_function_ptr<R (C::*)(A1,A2,A3) const>
583 {
584  static const bool value=true;
585 };
586 
587 template <class C, class R, class A1, class A2, class A3>
588 struct is_const_method<R (C::*)(A1,A2,A3) const>
589 {
590  static const bool value=true;
591 };
592 
593 template <class R, class A1, class A2, class A3>
594 struct is_nonmember_function_ptr<R (*)(A1,A2,A3)>
595 {
596  static const bool value=true;
597 };
598 
599 template <class C, class D, class R, class A1, class A2, class A3>
600 class bound_method<C, R (D::*)(A1,A2,A3)>
601 {
602  typedef R (D::*M)(A1,A2,A3);
603  C* obj;
604  M method;
605  public:
606  static const int arity=3;
607  typedef R Ret;
608  template <int i> struct Arg: public functional::Arg<M,i> {};
609  bound_method(C& obj, M method): obj(&obj), method(method) {}
610  R operator()(A1 a1,A2 a2,A3 a3) const {return (obj->*method)(a1,a2,a3);}
611  void rebind(C& newObj) {obj=&newObj;}
612 };
613 
614 template <class C, class D, class A1, class A2, class A3>
615 class bound_method<C, void (D::*)(A1,A2,A3)>
616 {
617  typedef void (D::*M)(A1,A2,A3);
618  C* obj;
619  M method;
620  public:
621  static const int arity=3;
622  typedef void Ret;
623  template <int i> struct Arg: public functional::Arg<M,i> {};
624  bound_method(C& obj, M method): obj(&obj), method(method) {}
625  void operator()(A1 a1,A2 a2,A3 a3) const {(obj->*method)(a1,a2,a3);}
626  void rebind(C& newObj) {obj=&newObj;}
627 };
628 
629 template <class C, class D, class R, class A1, class A2, class A3>
630 class bound_method<C, R (D::*)(A1,A2,A3) const>
631 {
632  typedef R (D::*M)(A1,A2,A3) const;
633  C& obj;
634  M method;
635  public:
636  static const int arity=3;
637  typedef R Ret;
638  template <int i> struct Arg: public functional::Arg<M,i> {};
639  bound_method(C& obj, M method): obj(obj), method(method) {}
640  R operator()(A1 a1,A2 a2,A3 a3) const {return (obj.*method)(a1,a2,a3);}
641 };
642 
643 template <class C, class D, class A1, class A2, class A3>
644 class bound_method<C, void (D::*)(A1,A2,A3) const>
645 {
646  typedef void (D::*M)(A1,A2,A3) const;
647  C& obj;
648  M method;
649  public:
650  static const int arity=3;
651  typedef void Ret;
652  template <int i> struct Arg: public functional::Arg<M,i> {};
653  bound_method(C& obj, M method): obj(obj), method(method) {}
654  void operator()(A1 a1,A2 a2,A3 a3) const {(obj.*method)(a1,a2,a3);}
655 };
656 
657 template <class F, class Args>
658 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 3> >,
659  typename Return<F>::T>::T
660 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
661 {
662  return f(a[0],a[1],a[2]);
663 }
664 
665 /*
666  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
667  which require C++-11 ability to test for the existence of a copy constructor.
668  If the return type is not copy constructable, the user must arrange for the return value to be discarded
669 */
670 
671 template <class F, class Args>
672 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 3> >,
673  void>::T
674 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
675 {
676  f(a[0],a[1],a[2]);
677 }
678 
679 template <class R, class A1, class A2, class A3, class A4>
680 struct Arg<R (*)(A1,A2,A3,A4), 1>
681 {typedef A1 T;};
682 
683 template <class C, class R, class A1, class A2, class A3, class A4>
684 struct Arg<R (C::*)(A1,A2,A3,A4), 1>
685 {typedef A1 T;};
686 
687 template <class C, class R, class A1, class A2, class A3, class A4>
688 struct Arg<R (C::*)(A1,A2,A3,A4) const, 1>
689 {typedef A1 T;};
690 template <class R, class A1, class A2, class A3, class A4>
691 struct Arg<R (*)(A1,A2,A3,A4), 2>
692 {typedef A2 T;};
693 
694 template <class C, class R, class A1, class A2, class A3, class A4>
695 struct Arg<R (C::*)(A1,A2,A3,A4), 2>
696 {typedef A2 T;};
697 
698 template <class C, class R, class A1, class A2, class A3, class A4>
699 struct Arg<R (C::*)(A1,A2,A3,A4) const, 2>
700 {typedef A2 T;};
701 template <class R, class A1, class A2, class A3, class A4>
702 struct Arg<R (*)(A1,A2,A3,A4), 3>
703 {typedef A3 T;};
704 
705 template <class C, class R, class A1, class A2, class A3, class A4>
706 struct Arg<R (C::*)(A1,A2,A3,A4), 3>
707 {typedef A3 T;};
708 
709 template <class C, class R, class A1, class A2, class A3, class A4>
710 struct Arg<R (C::*)(A1,A2,A3,A4) const, 3>
711 {typedef A3 T;};
712 template <class R, class A1, class A2, class A3, class A4>
713 struct Arg<R (*)(A1,A2,A3,A4), 4>
714 {typedef A4 T;};
715 
716 template <class C, class R, class A1, class A2, class A3, class A4>
717 struct Arg<R (C::*)(A1,A2,A3,A4), 4>
718 {typedef A4 T;};
719 
720 template <class C, class R, class A1, class A2, class A3, class A4>
721 struct Arg<R (C::*)(A1,A2,A3,A4) const, 4>
722 {typedef A4 T;};
723 template <class F, template<class> class P>
724 struct AllArgs<F,P,4>
725 {
726  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value;
727 };
728 
729 
730 template <class R, class A1, class A2, class A3, class A4>
731 struct Arity<R (*)(A1,A2,A3,A4)>
732 {
733  static const int V=4;
734  static const int value=4;
735 };
736 
737 template <class R, class A1, class A2, class A3, class A4>
738 struct Return<R (*)(A1,A2,A3,A4)>
739 {
740  typedef R T;
741  typedef R type;
742 };
743 
744 template <class C, class R, class A1, class A2, class A3, class A4>
745 struct Arity<R (C::*)(A1,A2,A3,A4)>
746 {
747  static const int V=4;
748  static const int value=4;
749 };
750 
751 template <class C, class R, class A1, class A2, class A3, class A4>
752 struct Return<R (C::*)(A1,A2,A3,A4)>
753 {
754  typedef R T;
755  typedef R type;
756 };
757 
758 template <class C, class R, class A1, class A2, class A3, class A4>
759 struct Arity<R (C::*)(A1,A2,A3,A4) const>
760 {
761  static const int V=4;
762  static const int value=4;
763 };
764 
765 template <class C, class R, class A1, class A2, class A3, class A4>
766 struct Return<R (C::*)(A1,A2,A3,A4) const>
767 {
768  typedef R T;
769  typedef R type;
770 };
771 
772 template <class C, class R, class A1, class A2, class A3, class A4>
773 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4)>
774 {
775  static const bool value=true;
776 };
777 
778 template <class C, class R, class A1, class A2, class A3, class A4>
779 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4) const>
780 {
781  static const bool value=true;
782 };
783 
784 template <class C, class R, class A1, class A2, class A3, class A4>
785 struct is_const_method<R (C::*)(A1,A2,A3,A4) const>
786 {
787  static const bool value=true;
788 };
789 
790 template <class R, class A1, class A2, class A3, class A4>
791 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4)>
792 {
793  static const bool value=true;
794 };
795 
796 template <class C, class D, class R, class A1, class A2, class A3, class A4>
797 class bound_method<C, R (D::*)(A1,A2,A3,A4)>
798 {
799  typedef R (D::*M)(A1,A2,A3,A4);
800  C* obj;
801  M method;
802  public:
803  static const int arity=4;
804  typedef R Ret;
805  template <int i> struct Arg: public functional::Arg<M,i> {};
806  bound_method(C& obj, M method): obj(&obj), method(method) {}
807  R operator()(A1 a1,A2 a2,A3 a3,A4 a4) const {return (obj->*method)(a1,a2,a3,a4);}
808  void rebind(C& newObj) {obj=&newObj;}
809 };
810 
811 template <class C, class D, class A1, class A2, class A3, class A4>
812 class bound_method<C, void (D::*)(A1,A2,A3,A4)>
813 {
814  typedef void (D::*M)(A1,A2,A3,A4);
815  C* obj;
816  M method;
817  public:
818  static const int arity=4;
819  typedef void Ret;
820  template <int i> struct Arg: public functional::Arg<M,i> {};
821  bound_method(C& obj, M method): obj(&obj), method(method) {}
822  void operator()(A1 a1,A2 a2,A3 a3,A4 a4) const {(obj->*method)(a1,a2,a3,a4);}
823  void rebind(C& newObj) {obj=&newObj;}
824 };
825 
826 template <class C, class D, class R, class A1, class A2, class A3, class A4>
827 class bound_method<C, R (D::*)(A1,A2,A3,A4) const>
828 {
829  typedef R (D::*M)(A1,A2,A3,A4) const;
830  C& obj;
831  M method;
832  public:
833  static const int arity=4;
834  typedef R Ret;
835  template <int i> struct Arg: public functional::Arg<M,i> {};
836  bound_method(C& obj, M method): obj(obj), method(method) {}
837  R operator()(A1 a1,A2 a2,A3 a3,A4 a4) const {return (obj.*method)(a1,a2,a3,a4);}
838 };
839 
840 template <class C, class D, class A1, class A2, class A3, class A4>
841 class bound_method<C, void (D::*)(A1,A2,A3,A4) const>
842 {
843  typedef void (D::*M)(A1,A2,A3,A4) const;
844  C& obj;
845  M method;
846  public:
847  static const int arity=4;
848  typedef void Ret;
849  template <int i> struct Arg: public functional::Arg<M,i> {};
850  bound_method(C& obj, M method): obj(obj), method(method) {}
851  void operator()(A1 a1,A2 a2,A3 a3,A4 a4) const {(obj.*method)(a1,a2,a3,a4);}
852 };
853 
854 template <class F, class Args>
855 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 4> >,
856  typename Return<F>::T>::T
857 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
858 {
859  return f(a[0],a[1],a[2],a[3]);
860 }
861 
862 /*
863  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
864  which require C++-11 ability to test for the existence of a copy constructor.
865  If the return type is not copy constructable, the user must arrange for the return value to be discarded
866 */
867 
868 template <class F, class Args>
869 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 4> >,
870  void>::T
871 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
872 {
873  f(a[0],a[1],a[2],a[3]);
874 }
875 
876 template <class R, class A1, class A2, class A3, class A4, class A5>
877 struct Arg<R (*)(A1,A2,A3,A4,A5), 1>
878 {typedef A1 T;};
879 
880 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
881 struct Arg<R (C::*)(A1,A2,A3,A4,A5), 1>
882 {typedef A1 T;};
883 
884 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
885 struct Arg<R (C::*)(A1,A2,A3,A4,A5) const, 1>
886 {typedef A1 T;};
887 template <class R, class A1, class A2, class A3, class A4, class A5>
888 struct Arg<R (*)(A1,A2,A3,A4,A5), 2>
889 {typedef A2 T;};
890 
891 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
892 struct Arg<R (C::*)(A1,A2,A3,A4,A5), 2>
893 {typedef A2 T;};
894 
895 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
896 struct Arg<R (C::*)(A1,A2,A3,A4,A5) const, 2>
897 {typedef A2 T;};
898 template <class R, class A1, class A2, class A3, class A4, class A5>
899 struct Arg<R (*)(A1,A2,A3,A4,A5), 3>
900 {typedef A3 T;};
901 
902 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
903 struct Arg<R (C::*)(A1,A2,A3,A4,A5), 3>
904 {typedef A3 T;};
905 
906 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
907 struct Arg<R (C::*)(A1,A2,A3,A4,A5) const, 3>
908 {typedef A3 T;};
909 template <class R, class A1, class A2, class A3, class A4, class A5>
910 struct Arg<R (*)(A1,A2,A3,A4,A5), 4>
911 {typedef A4 T;};
912 
913 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
914 struct Arg<R (C::*)(A1,A2,A3,A4,A5), 4>
915 {typedef A4 T;};
916 
917 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
918 struct Arg<R (C::*)(A1,A2,A3,A4,A5) const, 4>
919 {typedef A4 T;};
920 template <class R, class A1, class A2, class A3, class A4, class A5>
921 struct Arg<R (*)(A1,A2,A3,A4,A5), 5>
922 {typedef A5 T;};
923 
924 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
925 struct Arg<R (C::*)(A1,A2,A3,A4,A5), 5>
926 {typedef A5 T;};
927 
928 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
929 struct Arg<R (C::*)(A1,A2,A3,A4,A5) const, 5>
930 {typedef A5 T;};
931 template <class F, template<class> class P>
932 struct AllArgs<F,P,5>
933 {
934  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value;
935 };
936 
937 
938 template <class R, class A1, class A2, class A3, class A4, class A5>
939 struct Arity<R (*)(A1,A2,A3,A4,A5)>
940 {
941  static const int V=5;
942  static const int value=5;
943 };
944 
945 template <class R, class A1, class A2, class A3, class A4, class A5>
946 struct Return<R (*)(A1,A2,A3,A4,A5)>
947 {
948  typedef R T;
949  typedef R type;
950 };
951 
952 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
953 struct Arity<R (C::*)(A1,A2,A3,A4,A5)>
954 {
955  static const int V=5;
956  static const int value=5;
957 };
958 
959 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
960 struct Return<R (C::*)(A1,A2,A3,A4,A5)>
961 {
962  typedef R T;
963  typedef R type;
964 };
965 
966 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
967 struct Arity<R (C::*)(A1,A2,A3,A4,A5) const>
968 {
969  static const int V=5;
970  static const int value=5;
971 };
972 
973 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
974 struct Return<R (C::*)(A1,A2,A3,A4,A5) const>
975 {
976  typedef R T;
977  typedef R type;
978 };
979 
980 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
981 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5)>
982 {
983  static const bool value=true;
984 };
985 
986 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
987 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5) const>
988 {
989  static const bool value=true;
990 };
991 
992 template <class C, class R, class A1, class A2, class A3, class A4, class A5>
993 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5) const>
994 {
995  static const bool value=true;
996 };
997 
998 template <class R, class A1, class A2, class A3, class A4, class A5>
999 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5)>
1000 {
1001  static const bool value=true;
1002 };
1003 
1004 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5>
1005 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5)>
1006 {
1007  typedef R (D::*M)(A1,A2,A3,A4,A5);
1008  C* obj;
1009  M method;
1010  public:
1011  static const int arity=5;
1012  typedef R Ret;
1013  template <int i> struct Arg: public functional::Arg<M,i> {};
1014  bound_method(C& obj, M method): obj(&obj), method(method) {}
1015  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) const {return (obj->*method)(a1,a2,a3,a4,a5);}
1016  void rebind(C& newObj) {obj=&newObj;}
1017 };
1018 
1019 template <class C, class D, class A1, class A2, class A3, class A4, class A5>
1020 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5)>
1021 {
1022  typedef void (D::*M)(A1,A2,A3,A4,A5);
1023  C* obj;
1024  M method;
1025  public:
1026  static const int arity=5;
1027  typedef void Ret;
1028  template <int i> struct Arg: public functional::Arg<M,i> {};
1029  bound_method(C& obj, M method): obj(&obj), method(method) {}
1030  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) const {(obj->*method)(a1,a2,a3,a4,a5);}
1031  void rebind(C& newObj) {obj=&newObj;}
1032 };
1033 
1034 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5>
1035 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5) const>
1036 {
1037  typedef R (D::*M)(A1,A2,A3,A4,A5) const;
1038  C& obj;
1039  M method;
1040  public:
1041  static const int arity=5;
1042  typedef R Ret;
1043  template <int i> struct Arg: public functional::Arg<M,i> {};
1044  bound_method(C& obj, M method): obj(obj), method(method) {}
1045  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) const {return (obj.*method)(a1,a2,a3,a4,a5);}
1046 };
1047 
1048 template <class C, class D, class A1, class A2, class A3, class A4, class A5>
1049 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5) const>
1050 {
1051  typedef void (D::*M)(A1,A2,A3,A4,A5) const;
1052  C& obj;
1053  M method;
1054  public:
1055  static const int arity=5;
1056  typedef void Ret;
1057  template <int i> struct Arg: public functional::Arg<M,i> {};
1058  bound_method(C& obj, M method): obj(obj), method(method) {}
1059  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) const {(obj.*method)(a1,a2,a3,a4,a5);}
1060 };
1061 
1062 template <class F, class Args>
1063 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 5> >,
1064  typename Return<F>::T>::T
1065 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
1066 {
1067  return f(a[0],a[1],a[2],a[3],a[4]);
1068 }
1069 
1070 /*
1071  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
1072  which require C++-11 ability to test for the existence of a copy constructor.
1073  If the return type is not copy constructable, the user must arrange for the return value to be discarded
1074 */
1075 
1076 template <class F, class Args>
1077 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 5> >,
1078  void>::T
1079 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
1080 {
1081  f(a[0],a[1],a[2],a[3],a[4]);
1082 }
1083 
1084 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1085 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 1>
1086 {typedef A1 T;};
1087 
1088 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1089 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 1>
1090 {typedef A1 T;};
1091 
1092 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1093 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 1>
1094 {typedef A1 T;};
1095 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1096 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 2>
1097 {typedef A2 T;};
1098 
1099 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1100 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 2>
1101 {typedef A2 T;};
1102 
1103 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1104 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 2>
1105 {typedef A2 T;};
1106 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1107 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 3>
1108 {typedef A3 T;};
1109 
1110 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1111 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 3>
1112 {typedef A3 T;};
1113 
1114 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1115 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 3>
1116 {typedef A3 T;};
1117 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1118 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 4>
1119 {typedef A4 T;};
1120 
1121 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1122 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 4>
1123 {typedef A4 T;};
1124 
1125 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1126 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 4>
1127 {typedef A4 T;};
1128 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1129 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 5>
1130 {typedef A5 T;};
1131 
1132 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1133 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 5>
1134 {typedef A5 T;};
1135 
1136 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1137 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 5>
1138 {typedef A5 T;};
1139 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1140 struct Arg<R (*)(A1,A2,A3,A4,A5,A6), 6>
1141 {typedef A6 T;};
1142 
1143 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1144 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6), 6>
1145 {typedef A6 T;};
1146 
1147 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1148 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6) const, 6>
1149 {typedef A6 T;};
1150 template <class F, template<class> class P>
1151 struct AllArgs<F,P,6>
1152 {
1153  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value && P<typename Arg<F,6>::T>::value;
1154 };
1155 
1156 
1157 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1158 struct Arity<R (*)(A1,A2,A3,A4,A5,A6)>
1159 {
1160  static const int V=6;
1161  static const int value=6;
1162 };
1163 
1164 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1165 struct Return<R (*)(A1,A2,A3,A4,A5,A6)>
1166 {
1167  typedef R T;
1168  typedef R type;
1169 };
1170 
1171 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1172 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6)>
1173 {
1174  static const int V=6;
1175  static const int value=6;
1176 };
1177 
1178 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1179 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6)>
1180 {
1181  typedef R T;
1182  typedef R type;
1183 };
1184 
1185 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1186 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6) const>
1187 {
1188  static const int V=6;
1189  static const int value=6;
1190 };
1191 
1192 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1193 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6) const>
1194 {
1195  typedef R T;
1196  typedef R type;
1197 };
1198 
1199 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1200 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6)>
1201 {
1202  static const bool value=true;
1203 };
1204 
1205 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1206 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6) const>
1207 {
1208  static const bool value=true;
1209 };
1210 
1211 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1212 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5,A6) const>
1213 {
1214  static const bool value=true;
1215 };
1216 
1217 template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
1218 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5,A6)>
1219 {
1220  static const bool value=true;
1221 };
1222 
1223 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1224 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6)>
1225 {
1226  typedef R (D::*M)(A1,A2,A3,A4,A5,A6);
1227  C* obj;
1228  M method;
1229  public:
1230  static const int arity=6;
1231  typedef R Ret;
1232  template <int i> struct Arg: public functional::Arg<M,i> {};
1233  bound_method(C& obj, M method): obj(&obj), method(method) {}
1234  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) const {return (obj->*method)(a1,a2,a3,a4,a5,a6);}
1235  void rebind(C& newObj) {obj=&newObj;}
1236 };
1237 
1238 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6>
1239 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6)>
1240 {
1241  typedef void (D::*M)(A1,A2,A3,A4,A5,A6);
1242  C* obj;
1243  M method;
1244  public:
1245  static const int arity=6;
1246  typedef void Ret;
1247  template <int i> struct Arg: public functional::Arg<M,i> {};
1248  bound_method(C& obj, M method): obj(&obj), method(method) {}
1249  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) const {(obj->*method)(a1,a2,a3,a4,a5,a6);}
1250  void rebind(C& newObj) {obj=&newObj;}
1251 };
1252 
1253 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6>
1254 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6) const>
1255 {
1256  typedef R (D::*M)(A1,A2,A3,A4,A5,A6) const;
1257  C& obj;
1258  M method;
1259  public:
1260  static const int arity=6;
1261  typedef R Ret;
1262  template <int i> struct Arg: public functional::Arg<M,i> {};
1263  bound_method(C& obj, M method): obj(obj), method(method) {}
1264  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) const {return (obj.*method)(a1,a2,a3,a4,a5,a6);}
1265 };
1266 
1267 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6>
1268 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6) const>
1269 {
1270  typedef void (D::*M)(A1,A2,A3,A4,A5,A6) const;
1271  C& obj;
1272  M method;
1273  public:
1274  static const int arity=6;
1275  typedef void Ret;
1276  template <int i> struct Arg: public functional::Arg<M,i> {};
1277  bound_method(C& obj, M method): obj(obj), method(method) {}
1278  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) const {(obj.*method)(a1,a2,a3,a4,a5,a6);}
1279 };
1280 
1281 template <class F, class Args>
1282 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 6> >,
1283  typename Return<F>::T>::T
1284 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
1285 {
1286  return f(a[0],a[1],a[2],a[3],a[4],a[5]);
1287 }
1288 
1289 /*
1290  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
1291  which require C++-11 ability to test for the existence of a copy constructor.
1292  If the return type is not copy constructable, the user must arrange for the return value to be discarded
1293 */
1294 
1295 template <class F, class Args>
1296 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 6> >,
1297  void>::T
1298 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
1299 {
1300  f(a[0],a[1],a[2],a[3],a[4],a[5]);
1301 }
1302 
1303 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1304 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 1>
1305 {typedef A1 T;};
1306 
1307 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1308 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 1>
1309 {typedef A1 T;};
1310 
1311 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1312 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 1>
1313 {typedef A1 T;};
1314 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1315 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 2>
1316 {typedef A2 T;};
1317 
1318 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1319 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 2>
1320 {typedef A2 T;};
1321 
1322 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1323 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 2>
1324 {typedef A2 T;};
1325 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1326 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 3>
1327 {typedef A3 T;};
1328 
1329 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1330 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 3>
1331 {typedef A3 T;};
1332 
1333 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1334 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 3>
1335 {typedef A3 T;};
1336 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1337 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 4>
1338 {typedef A4 T;};
1339 
1340 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1341 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 4>
1342 {typedef A4 T;};
1343 
1344 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1345 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 4>
1346 {typedef A4 T;};
1347 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1348 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 5>
1349 {typedef A5 T;};
1350 
1351 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1352 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 5>
1353 {typedef A5 T;};
1354 
1355 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1356 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 5>
1357 {typedef A5 T;};
1358 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1359 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 6>
1360 {typedef A6 T;};
1361 
1362 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1363 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 6>
1364 {typedef A6 T;};
1365 
1366 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1367 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 6>
1368 {typedef A6 T;};
1369 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1370 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7), 7>
1371 {typedef A7 T;};
1372 
1373 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1374 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7), 7>
1375 {typedef A7 T;};
1376 
1377 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1378 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const, 7>
1379 {typedef A7 T;};
1380 template <class F, template<class> class P>
1381 struct AllArgs<F,P,7>
1382 {
1383  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value && P<typename Arg<F,6>::T>::value && P<typename Arg<F,7>::T>::value;
1384 };
1385 
1386 
1387 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1388 struct Arity<R (*)(A1,A2,A3,A4,A5,A6,A7)>
1389 {
1390  static const int V=7;
1391  static const int value=7;
1392 };
1393 
1394 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1395 struct Return<R (*)(A1,A2,A3,A4,A5,A6,A7)>
1396 {
1397  typedef R T;
1398  typedef R type;
1399 };
1400 
1401 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1402 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7)>
1403 {
1404  static const int V=7;
1405  static const int value=7;
1406 };
1407 
1408 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1409 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7)>
1410 {
1411  typedef R T;
1412  typedef R type;
1413 };
1414 
1415 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1416 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const>
1417 {
1418  static const int V=7;
1419  static const int value=7;
1420 };
1421 
1422 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1423 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const>
1424 {
1425  typedef R T;
1426  typedef R type;
1427 };
1428 
1429 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1430 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7)>
1431 {
1432  static const bool value=true;
1433 };
1434 
1435 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1436 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const>
1437 {
1438  static const bool value=true;
1439 };
1440 
1441 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1442 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5,A6,A7) const>
1443 {
1444  static const bool value=true;
1445 };
1446 
1447 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1448 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5,A6,A7)>
1449 {
1450  static const bool value=true;
1451 };
1452 
1453 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1454 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7)>
1455 {
1456  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7);
1457  C* obj;
1458  M method;
1459  public:
1460  static const int arity=7;
1461  typedef R Ret;
1462  template <int i> struct Arg: public functional::Arg<M,i> {};
1463  bound_method(C& obj, M method): obj(&obj), method(method) {}
1464  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) const {return (obj->*method)(a1,a2,a3,a4,a5,a6,a7);}
1465  void rebind(C& newObj) {obj=&newObj;}
1466 };
1467 
1468 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1469 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7)>
1470 {
1471  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7);
1472  C* obj;
1473  M method;
1474  public:
1475  static const int arity=7;
1476  typedef void Ret;
1477  template <int i> struct Arg: public functional::Arg<M,i> {};
1478  bound_method(C& obj, M method): obj(&obj), method(method) {}
1479  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) const {(obj->*method)(a1,a2,a3,a4,a5,a6,a7);}
1480  void rebind(C& newObj) {obj=&newObj;}
1481 };
1482 
1483 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1484 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7) const>
1485 {
1486  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7) const;
1487  C& obj;
1488  M method;
1489  public:
1490  static const int arity=7;
1491  typedef R Ret;
1492  template <int i> struct Arg: public functional::Arg<M,i> {};
1493  bound_method(C& obj, M method): obj(obj), method(method) {}
1494  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) const {return (obj.*method)(a1,a2,a3,a4,a5,a6,a7);}
1495 };
1496 
1497 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1498 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7) const>
1499 {
1500  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7) const;
1501  C& obj;
1502  M method;
1503  public:
1504  static const int arity=7;
1505  typedef void Ret;
1506  template <int i> struct Arg: public functional::Arg<M,i> {};
1507  bound_method(C& obj, M method): obj(obj), method(method) {}
1508  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) const {(obj.*method)(a1,a2,a3,a4,a5,a6,a7);}
1509 };
1510 
1511 template <class F, class Args>
1512 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 7> >,
1513  typename Return<F>::T>::T
1514 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
1515 {
1516  return f(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
1517 }
1518 
1519 /*
1520  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
1521  which require C++-11 ability to test for the existence of a copy constructor.
1522  If the return type is not copy constructable, the user must arrange for the return value to be discarded
1523 */
1524 
1525 template <class F, class Args>
1526 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 7> >,
1527  void>::T
1528 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
1529 {
1530  f(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
1531 }
1532 
1533 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1534 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 1>
1535 {typedef A1 T;};
1536 
1537 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1538 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 1>
1539 {typedef A1 T;};
1540 
1541 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1542 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 1>
1543 {typedef A1 T;};
1544 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1545 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 2>
1546 {typedef A2 T;};
1547 
1548 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1549 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 2>
1550 {typedef A2 T;};
1551 
1552 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1553 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 2>
1554 {typedef A2 T;};
1555 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1556 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 3>
1557 {typedef A3 T;};
1558 
1559 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1560 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 3>
1561 {typedef A3 T;};
1562 
1563 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1564 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 3>
1565 {typedef A3 T;};
1566 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1567 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 4>
1568 {typedef A4 T;};
1569 
1570 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1571 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 4>
1572 {typedef A4 T;};
1573 
1574 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1575 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 4>
1576 {typedef A4 T;};
1577 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1578 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 5>
1579 {typedef A5 T;};
1580 
1581 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1582 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 5>
1583 {typedef A5 T;};
1584 
1585 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1586 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 5>
1587 {typedef A5 T;};
1588 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1589 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 6>
1590 {typedef A6 T;};
1591 
1592 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1593 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 6>
1594 {typedef A6 T;};
1595 
1596 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1597 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 6>
1598 {typedef A6 T;};
1599 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1600 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 7>
1601 {typedef A7 T;};
1602 
1603 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1604 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 7>
1605 {typedef A7 T;};
1606 
1607 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1608 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 7>
1609 {typedef A7 T;};
1610 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1611 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8), 8>
1612 {typedef A8 T;};
1613 
1614 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1615 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8), 8>
1616 {typedef A8 T;};
1617 
1618 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1619 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const, 8>
1620 {typedef A8 T;};
1621 template <class F, template<class> class P>
1622 struct AllArgs<F,P,8>
1623 {
1624  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value && P<typename Arg<F,6>::T>::value && P<typename Arg<F,7>::T>::value && P<typename Arg<F,8>::T>::value;
1625 };
1626 
1627 
1628 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1629 struct Arity<R (*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1630 {
1631  static const int V=8;
1632  static const int value=8;
1633 };
1634 
1635 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1636 struct Return<R (*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1637 {
1638  typedef R T;
1639  typedef R type;
1640 };
1641 
1642 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1643 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1644 {
1645  static const int V=8;
1646  static const int value=8;
1647 };
1648 
1649 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1650 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1651 {
1652  typedef R T;
1653  typedef R type;
1654 };
1655 
1656 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1657 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1658 {
1659  static const int V=8;
1660  static const int value=8;
1661 };
1662 
1663 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1664 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1665 {
1666  typedef R T;
1667  typedef R type;
1668 };
1669 
1670 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1671 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1672 {
1673  static const bool value=true;
1674 };
1675 
1676 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1677 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1678 {
1679  static const bool value=true;
1680 };
1681 
1682 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1683 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1684 {
1685  static const bool value=true;
1686 };
1687 
1688 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1689 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1690 {
1691  static const bool value=true;
1692 };
1693 
1694 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1695 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1696 {
1697  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8);
1698  C* obj;
1699  M method;
1700  public:
1701  static const int arity=8;
1702  typedef R Ret;
1703  template <int i> struct Arg: public functional::Arg<M,i> {};
1704  bound_method(C& obj, M method): obj(&obj), method(method) {}
1705  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) const {return (obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8);}
1706  void rebind(C& newObj) {obj=&newObj;}
1707 };
1708 
1709 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1710 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8)>
1711 {
1712  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8);
1713  C* obj;
1714  M method;
1715  public:
1716  static const int arity=8;
1717  typedef void Ret;
1718  template <int i> struct Arg: public functional::Arg<M,i> {};
1719  bound_method(C& obj, M method): obj(&obj), method(method) {}
1720  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) const {(obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8);}
1721  void rebind(C& newObj) {obj=&newObj;}
1722 };
1723 
1724 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1725 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1726 {
1727  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8) const;
1728  C& obj;
1729  M method;
1730  public:
1731  static const int arity=8;
1732  typedef R Ret;
1733  template <int i> struct Arg: public functional::Arg<M,i> {};
1734  bound_method(C& obj, M method): obj(obj), method(method) {}
1735  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) const {return (obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8);}
1736 };
1737 
1738 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1739 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8) const>
1740 {
1741  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8) const;
1742  C& obj;
1743  M method;
1744  public:
1745  static const int arity=8;
1746  typedef void Ret;
1747  template <int i> struct Arg: public functional::Arg<M,i> {};
1748  bound_method(C& obj, M method): obj(obj), method(method) {}
1749  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) const {(obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8);}
1750 };
1751 
1752 template <class F, class Args>
1753 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 8> >,
1754  typename Return<F>::T>::T
1755 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
1756 {
1757  return f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
1758 }
1759 
1760 /*
1761  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
1762  which require C++-11 ability to test for the existence of a copy constructor.
1763  If the return type is not copy constructable, the user must arrange for the return value to be discarded
1764 */
1765 
1766 template <class F, class Args>
1767 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 8> >,
1768  void>::T
1769 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
1770 {
1771  f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
1772 }
1773 
1774 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1775 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 1>
1776 {typedef A1 T;};
1777 
1778 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1779 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 1>
1780 {typedef A1 T;};
1781 
1782 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1783 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 1>
1784 {typedef A1 T;};
1785 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1786 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 2>
1787 {typedef A2 T;};
1788 
1789 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1790 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 2>
1791 {typedef A2 T;};
1792 
1793 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1794 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 2>
1795 {typedef A2 T;};
1796 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1797 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 3>
1798 {typedef A3 T;};
1799 
1800 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1801 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 3>
1802 {typedef A3 T;};
1803 
1804 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1805 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 3>
1806 {typedef A3 T;};
1807 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1808 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 4>
1809 {typedef A4 T;};
1810 
1811 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1812 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 4>
1813 {typedef A4 T;};
1814 
1815 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1816 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 4>
1817 {typedef A4 T;};
1818 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1819 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 5>
1820 {typedef A5 T;};
1821 
1822 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1823 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 5>
1824 {typedef A5 T;};
1825 
1826 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1827 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 5>
1828 {typedef A5 T;};
1829 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1830 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 6>
1831 {typedef A6 T;};
1832 
1833 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1834 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 6>
1835 {typedef A6 T;};
1836 
1837 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1838 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 6>
1839 {typedef A6 T;};
1840 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1841 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 7>
1842 {typedef A7 T;};
1843 
1844 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1845 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 7>
1846 {typedef A7 T;};
1847 
1848 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1849 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 7>
1850 {typedef A7 T;};
1851 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1852 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 8>
1853 {typedef A8 T;};
1854 
1855 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1856 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 8>
1857 {typedef A8 T;};
1858 
1859 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1860 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 8>
1861 {typedef A8 T;};
1862 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1863 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 9>
1864 {typedef A9 T;};
1865 
1866 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1867 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9), 9>
1868 {typedef A9 T;};
1869 
1870 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1871 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const, 9>
1872 {typedef A9 T;};
1873 template <class F, template<class> class P>
1874 struct AllArgs<F,P,9>
1875 {
1876  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value && P<typename Arg<F,6>::T>::value && P<typename Arg<F,7>::T>::value && P<typename Arg<F,8>::T>::value && P<typename Arg<F,9>::T>::value;
1877 };
1878 
1879 
1880 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1881 struct Arity<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1882 {
1883  static const int V=9;
1884  static const int value=9;
1885 };
1886 
1887 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1888 struct Return<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1889 {
1890  typedef R T;
1891  typedef R type;
1892 };
1893 
1894 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1895 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1896 {
1897  static const int V=9;
1898  static const int value=9;
1899 };
1900 
1901 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1902 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1903 {
1904  typedef R T;
1905  typedef R type;
1906 };
1907 
1908 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1909 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1910 {
1911  static const int V=9;
1912  static const int value=9;
1913 };
1914 
1915 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1916 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1917 {
1918  typedef R T;
1919  typedef R type;
1920 };
1921 
1922 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1923 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1924 {
1925  static const bool value=true;
1926 };
1927 
1928 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1929 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1930 {
1931  static const bool value=true;
1932 };
1933 
1934 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1935 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1936 {
1937  static const bool value=true;
1938 };
1939 
1940 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1941 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1942 {
1943  static const bool value=true;
1944 };
1945 
1946 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1947 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1948 {
1949  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9);
1950  C* obj;
1951  M method;
1952  public:
1953  static const int arity=9;
1954  typedef R Ret;
1955  template <int i> struct Arg: public functional::Arg<M,i> {};
1956  bound_method(C& obj, M method): obj(&obj), method(method) {}
1957  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) const {return (obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9);}
1958  void rebind(C& newObj) {obj=&newObj;}
1959 };
1960 
1961 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1962 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)>
1963 {
1964  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9);
1965  C* obj;
1966  M method;
1967  public:
1968  static const int arity=9;
1969  typedef void Ret;
1970  template <int i> struct Arg: public functional::Arg<M,i> {};
1971  bound_method(C& obj, M method): obj(&obj), method(method) {}
1972  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) const {(obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9);}
1973  void rebind(C& newObj) {obj=&newObj;}
1974 };
1975 
1976 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1977 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1978 {
1979  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const;
1980  C& obj;
1981  M method;
1982  public:
1983  static const int arity=9;
1984  typedef R Ret;
1985  template <int i> struct Arg: public functional::Arg<M,i> {};
1986  bound_method(C& obj, M method): obj(obj), method(method) {}
1987  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) const {return (obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9);}
1988 };
1989 
1990 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1991 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const>
1992 {
1993  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const;
1994  C& obj;
1995  M method;
1996  public:
1997  static const int arity=9;
1998  typedef void Ret;
1999  template <int i> struct Arg: public functional::Arg<M,i> {};
2000  bound_method(C& obj, M method): obj(obj), method(method) {}
2001  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) const {(obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9);}
2002 };
2003 
2004 template <class F, class Args>
2005 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 9> >,
2006  typename Return<F>::T>::T
2007 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
2008 {
2009  return f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
2010 }
2011 
2012 /*
2013  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
2014  which require C++-11 ability to test for the existence of a copy constructor.
2015  If the return type is not copy constructable, the user must arrange for the return value to be discarded
2016 */
2017 
2018 template <class F, class Args>
2019 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 9> >,
2020  void>::T
2021 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
2022 {
2023  f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
2024 }
2025 
2026 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2027 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 1>
2028 {typedef A1 T;};
2029 
2030 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2031 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 1>
2032 {typedef A1 T;};
2033 
2034 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2035 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 1>
2036 {typedef A1 T;};
2037 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2038 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 2>
2039 {typedef A2 T;};
2040 
2041 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2042 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 2>
2043 {typedef A2 T;};
2044 
2045 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2046 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 2>
2047 {typedef A2 T;};
2048 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2049 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 3>
2050 {typedef A3 T;};
2051 
2052 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2053 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 3>
2054 {typedef A3 T;};
2055 
2056 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2057 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 3>
2058 {typedef A3 T;};
2059 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2060 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 4>
2061 {typedef A4 T;};
2062 
2063 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2064 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 4>
2065 {typedef A4 T;};
2066 
2067 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2068 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 4>
2069 {typedef A4 T;};
2070 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2071 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 5>
2072 {typedef A5 T;};
2073 
2074 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2075 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 5>
2076 {typedef A5 T;};
2077 
2078 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2079 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 5>
2080 {typedef A5 T;};
2081 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2082 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 6>
2083 {typedef A6 T;};
2084 
2085 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2086 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 6>
2087 {typedef A6 T;};
2088 
2089 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2090 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 6>
2091 {typedef A6 T;};
2092 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2093 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 7>
2094 {typedef A7 T;};
2095 
2096 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2097 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 7>
2098 {typedef A7 T;};
2099 
2100 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2101 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 7>
2102 {typedef A7 T;};
2103 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2104 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 8>
2105 {typedef A8 T;};
2106 
2107 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2108 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 8>
2109 {typedef A8 T;};
2110 
2111 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2112 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 8>
2113 {typedef A8 T;};
2114 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2115 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 9>
2116 {typedef A9 T;};
2117 
2118 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2119 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 9>
2120 {typedef A9 T;};
2121 
2122 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2123 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 9>
2124 {typedef A9 T;};
2125 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2126 struct Arg<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 10>
2127 {typedef A10 T;};
2128 
2129 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2130 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10), 10>
2131 {typedef A10 T;};
2132 
2133 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2134 struct Arg<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const, 10>
2135 {typedef A10 T;};
2136 template <class F, template<class> class P>
2137 struct AllArgs<F,P,10>
2138 {
2139  static const bool value=true && P<typename Arg<F,1>::T>::value && P<typename Arg<F,2>::T>::value && P<typename Arg<F,3>::T>::value && P<typename Arg<F,4>::T>::value && P<typename Arg<F,5>::T>::value && P<typename Arg<F,6>::T>::value && P<typename Arg<F,7>::T>::value && P<typename Arg<F,8>::T>::value && P<typename Arg<F,9>::T>::value && P<typename Arg<F,10>::T>::value;
2140 };
2141 
2142 
2143 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2144 struct Arity<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2145 {
2146  static const int V=10;
2147  static const int value=10;
2148 };
2149 
2150 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2151 struct Return<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2152 {
2153  typedef R T;
2154  typedef R type;
2155 };
2156 
2157 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2158 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2159 {
2160  static const int V=10;
2161  static const int value=10;
2162 };
2163 
2164 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2165 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2166 {
2167  typedef R T;
2168  typedef R type;
2169 };
2170 
2171 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2172 struct Arity<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2173 {
2174  static const int V=10;
2175  static const int value=10;
2176 };
2177 
2178 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2179 struct Return<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2180 {
2181  typedef R T;
2182  typedef R type;
2183 };
2184 
2185 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2186 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2187 {
2188  static const bool value=true;
2189 };
2190 
2191 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2192 struct is_member_function_ptr<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2193 {
2194  static const bool value=true;
2195 };
2196 
2197 template <class C, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2198 struct is_const_method<R (C::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2199 {
2200  static const bool value=true;
2201 };
2202 
2203 template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2204 struct is_nonmember_function_ptr<R (*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2205 {
2206  static const bool value=true;
2207 };
2208 
2209 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2210 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2211 {
2212  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10);
2213  C* obj;
2214  M method;
2215  public:
2216  static const int arity=10;
2217  typedef R Ret;
2218  template <int i> struct Arg: public functional::Arg<M,i> {};
2219  bound_method(C& obj, M method): obj(&obj), method(method) {}
2220  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) const {return (obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);}
2221  void rebind(C& newObj) {obj=&newObj;}
2222 };
2223 
2224 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2225 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
2226 {
2227  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10);
2228  C* obj;
2229  M method;
2230  public:
2231  static const int arity=10;
2232  typedef void Ret;
2233  template <int i> struct Arg: public functional::Arg<M,i> {};
2234  bound_method(C& obj, M method): obj(&obj), method(method) {}
2235  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) const {(obj->*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);}
2236  void rebind(C& newObj) {obj=&newObj;}
2237 };
2238 
2239 template <class C, class D, class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2240 class bound_method<C, R (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2241 {
2242  typedef R (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const;
2243  C& obj;
2244  M method;
2245  public:
2246  static const int arity=10;
2247  typedef R Ret;
2248  template <int i> struct Arg: public functional::Arg<M,i> {};
2249  bound_method(C& obj, M method): obj(obj), method(method) {}
2250  R operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) const {return (obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);}
2251 };
2252 
2253 template <class C, class D, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
2254 class bound_method<C, void (D::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const>
2255 {
2256  typedef void (D::*M)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const;
2257  C& obj;
2258  M method;
2259  public:
2260  static const int arity=10;
2261  typedef void Ret;
2262  template <int i> struct Arg: public functional::Arg<M,i> {};
2263  bound_method(C& obj, M method): obj(obj), method(method) {}
2264  void operator()(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) const {(obj.*method)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);}
2265 };
2266 
2267 template <class F, class Args>
2268 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 10> >,
2269  typename Return<F>::T>::T
2270 apply_nonvoid_fn(F f, Args& a, Fdummy<F> dum=0)
2271 {
2272  return f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
2273 }
2274 
2275 /*
2276  TODO: if any of the arguments to f are lvalues, we need to construct temporaries,
2277  which require C++-11 ability to test for the existence of a copy constructor.
2278  If the return type is not copy constructable, the user must arrange for the return value to be discarded
2279 */
2280 
2281 template <class F, class Args>
2282 typename enable_if<And<AllArgs<F, is_rvalue>, Eq<Arity<F>::value, 10> >,
2283  void>::T
2284 apply_void_fn(F f, Args& a, Fdummy<F> dum=0)
2285 {
2286  f(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
2287 }
2288