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