1 // Copyright (C) 2012 Vicente J. Botet Escriba
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // 2013/04 Vicente J. Botet Escriba
7 //    Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
8 //    Make use of Boost.Move
9 //    Make use of Boost.Tuple (movable)
10 // 2012/11 Vicente J. Botet Escriba
11 //    Adapt to boost libc++ implementation
12 
13 //===----------------------------------------------------------------------===//
14 //
15 //                     The LLVM Compiler Infrastructure
16 //
17 // This file is dual licensed under the MIT and the University of Illinois Open
18 // Source Licenses. See LICENSE.TXT for details.
19 //
20 // The invoker code is based on the one from libcxx.
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef BOOST_THREAD_DETAIL_INVOKER_HPP
24 #define BOOST_THREAD_DETAIL_INVOKER_HPP
25 
26 #include <boost/config.hpp>
27 
28 #include <boost/utility/result_of.hpp>
29 #include <boost/thread/detail/move.hpp>
30 #include <boost/thread/detail/invoke.hpp>
31 #include <boost/thread/detail/make_tuple_indices.hpp>
32 #include <boost/thread/csbl/tuple.hpp>
33 #include <boost/tuple/tuple.hpp>
34 
35 #include <boost/thread/detail/variadic_header.hpp>
36 
37 namespace boost
38 {
39   namespace detail
40   {
41 
42 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
43 
44     template <class Fp, class ... Args>
45     class invoker
46     {
47       //typedef typename decay<Fp>::type Fpd;
48       //typedef tuple<typename decay<Args>::type...> Argsd;
49 
50       //csbl::tuple<Fpd, Argsd...> f_;
51       csbl::tuple<Fp, Args...> f_;
52 
53     public:
54       BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker)
55       //typedef typename invoke_of<_Fp, _Args...>::type Rp;
56       typedef typename result_of<Fp(Args...)>::type result_type;
57 
58       template <class F, class ... As>
59       BOOST_SYMBOL_VISIBLE
invoker(BOOST_THREAD_FWD_REF (F)f,BOOST_THREAD_FWD_REF (As)...args)60       explicit invoker(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args)
61       : f_(boost::forward<F>(f), boost::forward<As>(args)...)
62       {}
63 
64       BOOST_SYMBOL_VISIBLE
invoker(BOOST_THREAD_RV_REF (invoker)f)65       invoker(BOOST_THREAD_RV_REF(invoker) f) : f_(boost::move(BOOST_THREAD_RV(f).f_))
66       {}
67 
68       BOOST_SYMBOL_VISIBLE
invoker(const invoker & f)69       invoker( const invoker& f) : f_(f.f_)
70       {}
71 
72       BOOST_SYMBOL_VISIBLE
operator =(BOOST_THREAD_RV_REF (invoker)f)73       invoker& operator=(BOOST_THREAD_RV_REF(invoker) f)
74       {
75         f_ = boost::move(BOOST_THREAD_RV(f).f_);
76       }
77 
78       BOOST_SYMBOL_VISIBLE
operator =(BOOST_THREAD_COPY_ASSIGN_REF (invoker)f)79       invoker& operator=( BOOST_THREAD_COPY_ASSIGN_REF(invoker) f)
80       {
81         f_ = f.f_;
82       }
83 
operator ()()84       result_type operator()()
85       {
86         typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index;
87         return execute(Index());
88       }
89     private:
90       template <size_t ...Indices>
91       result_type
execute(tuple_indices<Indices...>)92       execute(tuple_indices<Indices...>)
93       {
94         return invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
95       }
96     };
97 
98     template <class R, class Fp, class ... Args>
99     class invoker_ret
100     {
101       //typedef typename decay<Fp>::type Fpd;
102       //typedef tuple<typename decay<Args>::type...> Argsd;
103 
104       //csbl::tuple<Fpd, Argsd...> f_;
105       csbl::tuple<Fp, Args...> f_;
106 
107     public:
108       BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker_ret)
109       typedef R result_type;
110 
111       template <class F, class ... As>
112       BOOST_SYMBOL_VISIBLE
invoker_ret(BOOST_THREAD_FWD_REF (F)f,BOOST_THREAD_FWD_REF (As)...args)113       explicit invoker_ret(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args)
114       : f_(boost::forward<F>(f), boost::forward<As>(args)...)
115       {}
116 
117       BOOST_SYMBOL_VISIBLE
invoker_ret(BOOST_THREAD_RV_REF (invoker_ret)f)118       invoker_ret(BOOST_THREAD_RV_REF(invoker_ret) f) : f_(boost::move(BOOST_THREAD_RV(f).f_))
119       {}
120 
operator ()()121       result_type operator()()
122       {
123         typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index;
124         return execute(Index());
125       }
126     private:
127       template <size_t ...Indices>
128       result_type
execute(tuple_indices<Indices...>)129       execute(tuple_indices<Indices...>)
130       {
131         return invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
132       }
133     };
134   //BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END
135 #else
136 
137 #if ! defined BOOST_MSVC && defined(BOOST_THREAD_PROVIDES_INVOKE)
138 
139 #define BOOST_THREAD_RV_REF_ARG_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(Arg##n)
140 #define BOOST_THREAD_RV_REF_A_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(A##n)
141 #define BOOST_THREAD_RV_REF_ARG(z, n, unused) , BOOST_THREAD_RV_REF(Arg##n) arg##n
142 #define BOOST_THREAD_FWD_REF_A(z, n, unused)   , BOOST_THREAD_FWD_REF(A##n) arg##n
143 #define BOOST_THREAD_FWD_REF_ARG(z, n, unused) , BOOST_THREAD_FWD_REF(Arg##n) arg##n
144 #define BOOST_THREAD_FWD_PARAM(z, n, unused) , boost::forward<Arg##n>(arg##n)
145 #define BOOST_THREAD_FWD_PARAM_A(z, n, unused) , boost::forward<A##n>(arg##n)
146 #define BOOST_THREAD_DCL(z, n, unused) Arg##n v##n;
147 #define BOOST_THREAD_MOVE_PARAM(z, n, unused) , v##n(boost::move(arg##n))
148 #define BOOST_THREAD_FORWARD_PARAM_A(z, n, unused) , v##n(boost::forward<A##n>(arg##n))
149 #define BOOST_THREAD_MOVE_RHS_PARAM(z, n, unused) , v##n(boost::move(x.v##n))
150 #define BOOST_THREAD_MOVE_DCL(z, n, unused) , boost::move(v##n)
151 #define BOOST_THREAD_MOVE_DCL_T(z, n, unused) BOOST_PP_COMMA_IF(n) boost::move(v##n)
152 #define BOOST_THREAD_ARG_DEF(z, n, unused) , class Arg##n = tuples::null_type
153 
154   template  <class Fp, class Arg = tuples::null_type
155     BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ARG_DEF, ~)
156     >
157     class invoker;
158 
159 #define BOOST_THREAD_ASYNC_FUNCT(z, n, unused) \
160     template <class Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \
161     class invoker<Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \
162     { \
163       Fp fp_; \
164       BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \
165     public: \
166       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \
167       typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \
168       \
169       template <class F BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \
170       BOOST_SYMBOL_VISIBLE \
171       explicit invoker(BOOST_THREAD_FWD_REF(F) f \
172           BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \
173       ) \
174       : fp_(boost::forward<F>(f)) \
175       BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \
176       {} \
177       \
178       BOOST_SYMBOL_VISIBLE \
179       invoker(BOOST_THREAD_RV_REF(invoker) x) \
180       : fp_(boost::move(x.fp_)) \
181       BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \
182       {} \
183       \
184       result_type operator()() { \
185         return invoke(boost::move(fp_) \
186             BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL, ~) \
187         ); \
188       } \
189     }; \
190     \
191     template <class R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \
192     class invoker<R(*)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \
193     { \
194       typedef R(*Fp)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)); \
195       Fp fp_; \
196       BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \
197     public: \
198       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \
199       typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \
200       \
201       template <class R2 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \
202       BOOST_SYMBOL_VISIBLE \
203       explicit invoker(R2(*f)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_A_T, ~))  \
204           BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \
205       ) \
206       : fp_(f) \
207       BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \
208       {} \
209       \
210       BOOST_SYMBOL_VISIBLE \
211       invoker(BOOST_THREAD_RV_REF(invoker) x) \
212       : fp_(x.fp_) \
213       BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \
214       {} \
215       \
216       result_type operator()() { \
217         return fp_( \
218             BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL_T, ~) \
219         ); \
220       } \
221     };
222 
223     BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ASYNC_FUNCT, ~)
224 
225     #undef BOOST_THREAD_RV_REF_ARG_T
226     #undef BOOST_THREAD_RV_REF_ARG
227     #undef BOOST_THREAD_FWD_REF_ARG
228     #undef BOOST_THREAD_FWD_REF_A
229     #undef BOOST_THREAD_FWD_PARAM
230     #undef BOOST_THREAD_FWD_PARAM_A
231     #undef BOOST_THREAD_DCL
232     #undef BOOST_THREAD_MOVE_PARAM
233     #undef BOOST_THREAD_MOVE_RHS_PARAM
234     #undef BOOST_THREAD_MOVE_DCL
235     #undef BOOST_THREAD_ARG_DEF
236     #undef BOOST_THREAD_ASYNC_FUNCT
237 
238 #else
239 
240     template <class Fp,
241     class T0 = tuples::null_type, class T1 = tuples::null_type, class T2 = tuples::null_type,
242     class T3 = tuples::null_type, class T4 = tuples::null_type, class T5 = tuples::null_type,
243     class T6 = tuples::null_type, class T7 = tuples::null_type, class T8 = tuples::null_type
244     , class T9 = tuples::null_type
245     >
246     class invoker;
247 
248     template <class Fp,
249     class T0 , class T1 , class T2 ,
250     class T3 , class T4 , class T5 ,
251     class T6 , class T7 , class T8 >
252     class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8>
253     {
254       Fp fp_;
255       T0 v0_;
256       T1 v1_;
257       T2 v2_;
258       T3 v3_;
259       T4 v4_;
260       T5 v5_;
261       T6 v6_;
262       T7 v7_;
263       T8 v8_;
264       //::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> f_;
265 
266     public:
267       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
268       typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7, T8)>::type result_type;
269 
270       BOOST_SYMBOL_VISIBLE
271       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
272           , BOOST_THREAD_RV_REF(T0) a0
273           , BOOST_THREAD_RV_REF(T1) a1
274           , BOOST_THREAD_RV_REF(T2) a2
275           , BOOST_THREAD_RV_REF(T3) a3
276           , BOOST_THREAD_RV_REF(T4) a4
277           , BOOST_THREAD_RV_REF(T5) a5
278           , BOOST_THREAD_RV_REF(T6) a6
279           , BOOST_THREAD_RV_REF(T7) a7
280           , BOOST_THREAD_RV_REF(T8) a8
281       )
282       : fp_(boost::move(f))
283       , v0_(boost::move(a0))
284       , v1_(boost::move(a1))
285       , v2_(boost::move(a2))
286       , v3_(boost::move(a3))
287       , v4_(boost::move(a4))
288       , v5_(boost::move(a5))
289       , v6_(boost::move(a6))
290       , v7_(boost::move(a7))
291       , v8_(boost::move(a8))
292       {}
293 
294       BOOST_SYMBOL_VISIBLE
295       invoker(BOOST_THREAD_RV_REF(invoker) f)
296       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
297       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
298       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
299       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
300       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
301       , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
302       , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
303       , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
304       , v7_(boost::move(BOOST_THREAD_RV(f).v7_))
305       , v8_(boost::move(BOOST_THREAD_RV(f).v8_))
306       {}
307 
308       result_type operator()()
309       {
310         return invoke(boost::move(fp_)
311             , boost::move(v0_)
312             , boost::move(v1_)
313             , boost::move(v2_)
314             , boost::move(v3_)
315             , boost::move(v4_)
316             , boost::move(v5_)
317             , boost::move(v6_)
318             , boost::move(v7_)
319             , boost::move(v8_)
320         );
321       }
322     };
323     template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7 >
324     class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7>
325     {
326       Fp fp_;
327       T0 v0_;
328       T1 v1_;
329       T2 v2_;
330       T3 v3_;
331       T4 v4_;
332       T5 v5_;
333       T6 v6_;
334       T7 v7_;
335     public:
336       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
337       typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7)>::type result_type;
338 
339       BOOST_SYMBOL_VISIBLE
340       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
341           , BOOST_THREAD_RV_REF(T0) a0
342           , BOOST_THREAD_RV_REF(T1) a1
343           , BOOST_THREAD_RV_REF(T2) a2
344           , BOOST_THREAD_RV_REF(T3) a3
345           , BOOST_THREAD_RV_REF(T4) a4
346           , BOOST_THREAD_RV_REF(T5) a5
347           , BOOST_THREAD_RV_REF(T6) a6
348           , BOOST_THREAD_RV_REF(T7) a7
349       )
350       : fp_(boost::move(f))
351       , v0_(boost::move(a0))
352       , v1_(boost::move(a1))
353       , v2_(boost::move(a2))
354       , v3_(boost::move(a3))
355       , v4_(boost::move(a4))
356       , v5_(boost::move(a5))
357       , v6_(boost::move(a6))
358       , v7_(boost::move(a7))
359       {}
360 
361       BOOST_SYMBOL_VISIBLE
362       invoker(BOOST_THREAD_RV_REF(invoker) f)
363       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
364       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
365       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
366       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
367       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
368       , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
369       , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
370       , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
371       , v7_(boost::move(BOOST_THREAD_RV(f).v7_))
372       {}
373 
374       result_type operator()()
375       {
376         return invoke(boost::move(fp_)
377             , boost::move(v0_)
378             , boost::move(v1_)
379             , boost::move(v2_)
380             , boost::move(v3_)
381             , boost::move(v4_)
382             , boost::move(v5_)
383             , boost::move(v6_)
384             , boost::move(v7_)
385         );
386       }
387     };
388     template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6>
389     class invoker<Fp, T0, T1, T2, T3, T4, T5, T6>
390     {
391       Fp fp_;
392       T0 v0_;
393       T1 v1_;
394       T2 v2_;
395       T3 v3_;
396       T4 v4_;
397       T5 v5_;
398       T6 v6_;
399     public:
400       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
401       typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6)>::type result_type;
402 
403       BOOST_SYMBOL_VISIBLE
404       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
405           , BOOST_THREAD_RV_REF(T0) a0
406           , BOOST_THREAD_RV_REF(T1) a1
407           , BOOST_THREAD_RV_REF(T2) a2
408           , BOOST_THREAD_RV_REF(T3) a3
409           , BOOST_THREAD_RV_REF(T4) a4
410           , BOOST_THREAD_RV_REF(T5) a5
411           , BOOST_THREAD_RV_REF(T6) a6
412       )
413       : fp_(boost::move(f))
414       , v0_(boost::move(a0))
415       , v1_(boost::move(a1))
416       , v2_(boost::move(a2))
417       , v3_(boost::move(a3))
418       , v4_(boost::move(a4))
419       , v5_(boost::move(a5))
420       , v6_(boost::move(a6))
421       {}
422 
423       BOOST_SYMBOL_VISIBLE
424       invoker(BOOST_THREAD_RV_REF(invoker) f)
425       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
426       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
427       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
428       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
429       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
430       , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
431       , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
432       , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
433       {}
434 
435       result_type operator()()
436       {
437         return invoke(boost::move(fp_)
438             , boost::move(v0_)
439             , boost::move(v1_)
440             , boost::move(v2_)
441             , boost::move(v3_)
442             , boost::move(v4_)
443             , boost::move(v5_)
444             , boost::move(v6_)
445         );
446       }
447     };
448     template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5>
449     class invoker<Fp, T0, T1, T2, T3, T4, T5>
450     {
451       Fp fp_;
452       T0 v0_;
453       T1 v1_;
454       T2 v2_;
455       T3 v3_;
456       T4 v4_;
457       T5 v5_;
458     public:
459       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
460       typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5)>::type result_type;
461 
462       BOOST_SYMBOL_VISIBLE
463       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
464           , BOOST_THREAD_RV_REF(T0) a0
465           , BOOST_THREAD_RV_REF(T1) a1
466           , BOOST_THREAD_RV_REF(T2) a2
467           , BOOST_THREAD_RV_REF(T3) a3
468           , BOOST_THREAD_RV_REF(T4) a4
469           , BOOST_THREAD_RV_REF(T5) a5
470       )
471       : fp_(boost::move(f))
472       , v0_(boost::move(a0))
473       , v1_(boost::move(a1))
474       , v2_(boost::move(a2))
475       , v3_(boost::move(a3))
476       , v4_(boost::move(a4))
477       , v5_(boost::move(a5))
478       {}
479 
480       BOOST_SYMBOL_VISIBLE
481       invoker(BOOST_THREAD_RV_REF(invoker) f)
482       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
483       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
484       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
485       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
486       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
487       , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
488       , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
489       {}
490 
491       result_type operator()()
492       {
493         return invoke(boost::move(fp_)
494             , boost::move(v0_)
495             , boost::move(v1_)
496             , boost::move(v2_)
497             , boost::move(v3_)
498             , boost::move(v4_)
499             , boost::move(v5_)
500         );
501       }
502     };
503     template <class Fp, class T0, class T1, class T2, class T3, class T4>
504     class invoker<Fp, T0, T1, T2, T3, T4>
505     {
506       Fp fp_;
507       T0 v0_;
508       T1 v1_;
509       T2 v2_;
510       T3 v3_;
511       T4 v4_;
512     public:
513       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
514       typedef typename result_of<Fp(T0, T1, T2, T3, T4)>::type result_type;
515 
516       BOOST_SYMBOL_VISIBLE
517       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
518           , BOOST_THREAD_RV_REF(T0) a0
519           , BOOST_THREAD_RV_REF(T1) a1
520           , BOOST_THREAD_RV_REF(T2) a2
521           , BOOST_THREAD_RV_REF(T3) a3
522           , BOOST_THREAD_RV_REF(T4) a4
523       )
524       : fp_(boost::move(f))
525       , v0_(boost::move(a0))
526       , v1_(boost::move(a1))
527       , v2_(boost::move(a2))
528       , v3_(boost::move(a3))
529       , v4_(boost::move(a4))
530       {}
531 
532       BOOST_SYMBOL_VISIBLE
533       invoker(BOOST_THREAD_RV_REF(invoker) f)
534       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
535       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
536       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
537       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
538       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
539       , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
540       {}
541 
542       result_type operator()()
543       {
544         return invoke(boost::move(fp_)
545             , boost::move(v0_)
546             , boost::move(v1_)
547             , boost::move(v2_)
548             , boost::move(v3_)
549             , boost::move(v4_)
550         );
551       }
552     };
553     template <class Fp, class T0, class T1, class T2, class T3>
554     class invoker<Fp, T0, T1, T2, T3>
555     {
556       Fp fp_;
557       T0 v0_;
558       T1 v1_;
559       T2 v2_;
560       T3 v3_;
561     public:
562       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
563       typedef typename result_of<Fp(T0, T1, T2, T3)>::type result_type;
564 
565       BOOST_SYMBOL_VISIBLE
566       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
567           , BOOST_THREAD_RV_REF(T0) a0
568           , BOOST_THREAD_RV_REF(T1) a1
569           , BOOST_THREAD_RV_REF(T2) a2
570           , BOOST_THREAD_RV_REF(T3) a3
571       )
572       : fp_(boost::move(f))
573       , v0_(boost::move(a0))
574       , v1_(boost::move(a1))
575       , v2_(boost::move(a2))
576       , v3_(boost::move(a3))
577       {}
578 
579       BOOST_SYMBOL_VISIBLE
580       invoker(BOOST_THREAD_RV_REF(invoker) f)
581       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
582       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
583       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
584       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
585       , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
586       {}
587 
588       result_type operator()()
589       {
590         return invoke(boost::move(fp_)
591             , boost::move(v0_)
592             , boost::move(v1_)
593             , boost::move(v2_)
594             , boost::move(v3_)
595         );
596       }
597     };
598     template <class Fp, class T0, class T1, class T2>
599     class invoker<Fp, T0, T1, T2>
600     {
601       Fp fp_;
602       T0 v0_;
603       T1 v1_;
604       T2 v2_;
605     public:
606       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
607       typedef typename result_of<Fp(T0, T1, T2)>::type result_type;
608 
609       BOOST_SYMBOL_VISIBLE
610       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
611           , BOOST_THREAD_RV_REF(T0) a0
612           , BOOST_THREAD_RV_REF(T1) a1
613           , BOOST_THREAD_RV_REF(T2) a2
614       )
615       : fp_(boost::move(f))
616       , v0_(boost::move(a0))
617       , v1_(boost::move(a1))
618       , v2_(boost::move(a2))
619       {}
620 
621       BOOST_SYMBOL_VISIBLE
622       invoker(BOOST_THREAD_RV_REF(invoker) f)
623       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
624       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
625       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
626       , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
627       {}
628 
629       result_type operator()()
630       {
631         return invoke(boost::move(fp_)
632             , boost::move(v0_)
633             , boost::move(v1_)
634             , boost::move(v2_)
635         );
636       }
637     };
638     template <class Fp, class T0, class T1>
639     class invoker<Fp, T0, T1>
640     {
641       Fp fp_;
642       T0 v0_;
643       T1 v1_;
644     public:
645       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
646       typedef typename result_of<Fp(T0, T1)>::type result_type;
647 
648       BOOST_SYMBOL_VISIBLE
649       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
650           , BOOST_THREAD_RV_REF(T0) a0
651           , BOOST_THREAD_RV_REF(T1) a1
652       )
653       : fp_(boost::move(f))
654       , v0_(boost::move(a0))
655       , v1_(boost::move(a1))
656       {}
657 
658       BOOST_SYMBOL_VISIBLE
659       invoker(BOOST_THREAD_RV_REF(invoker) f)
660       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
661       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
662       , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
663       {}
664 
665       result_type operator()()
666       {
667         return invoke(boost::move(fp_)
668             , boost::move(v0_)
669             , boost::move(v1_)
670         );
671       }
672     };
673     template <class Fp, class T0>
674     class invoker<Fp, T0>
675     {
676       Fp fp_;
677       T0 v0_;
678     public:
679       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
680       typedef typename result_of<Fp(T0)>::type result_type;
681 
682       BOOST_SYMBOL_VISIBLE
683       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
684           , BOOST_THREAD_RV_REF(T0) a0
685       )
686       : fp_(boost::move(f))
687       , v0_(boost::move(a0))
688       {}
689 
690       BOOST_SYMBOL_VISIBLE
691       invoker(BOOST_THREAD_RV_REF(invoker) f)
692       : fp_(boost::move(BOOST_THREAD_RV(f).fp))
693       , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
694       {}
695 
696       result_type operator()()
697       {
698         return invoke(boost::move(fp_)
699             , boost::move(v0_)
700         );
701       }
702     };
703     template <class Fp>
704     class invoker<Fp>
705     {
706       Fp fp_;
707     public:
708       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
709       typedef typename result_of<Fp()>::type result_type;
710       BOOST_SYMBOL_VISIBLE
711       explicit invoker(BOOST_THREAD_FWD_REF(Fp) f)
712       : fp_(boost::move(f))
713       {}
714 
715       BOOST_SYMBOL_VISIBLE
716       invoker(BOOST_THREAD_RV_REF(invoker) f)
717       : fp_(boost::move(f.fp_))
718       {}
719       result_type operator()()
720       {
721         return fp_();
722       }
723     };
724     template <class R>
725     class invoker<R(*)()>
726     {
727       typedef R(*Fp)();
728       Fp fp_;
729     public:
730       BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
731       typedef typename result_of<Fp()>::type result_type;
732       BOOST_SYMBOL_VISIBLE
733       explicit invoker(Fp f)
734       : fp_(f)
735       {}
736 
737       BOOST_SYMBOL_VISIBLE
738       invoker(BOOST_THREAD_RV_REF(invoker) f)
739       : fp_(f.fp_)
740       {}
741       result_type operator()()
742       {
743         return fp_();
744       }
745     };
746 #endif
747 #endif
748 
749   }
750 }
751 
752 #include <boost/thread/detail/variadic_footer.hpp>
753 
754 #endif // header
755