1 // Copyright (C) 2012-2013 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 Vicente J. Botet Escriba
11 //    Provide implementation _RET using bind when BOOST_NO_CXX11_HDR_FUNCTIONAL and BOOST_NO_SFINAE_EXPR are not defined
12 // 2012 Vicente J. Botet Escriba
13 //    Adapt to boost libc++ implementation
14 
15 //===----------------------------------------------------------------------===//
16 //
17 //                     The LLVM Compiler Infrastructure
18 //
19 // This file is dual licensed under the MIT and the University of Illinois Open
20 // Source Licenses. See LICENSE.TXT for details.
21 //
22 // The invoke code is based on the one from libcxx.
23 //===----------------------------------------------------------------------===//
24 
25 #ifndef BOOST_THREAD_DETAIL_INVOKE_HPP
26 #define BOOST_THREAD_DETAIL_INVOKE_HPP
27 
28 #include <boost/config.hpp>
29 #include <boost/static_assert.hpp>
30 #include <boost/thread/detail/move.hpp>
31 #include <boost/core/enable_if.hpp>
32 #include <boost/type_traits/is_base_of.hpp>
33 #include <boost/type_traits/is_pointer.hpp>
34 #include <boost/type_traits/is_member_function_pointer.hpp>
35 #include <boost/type_traits/remove_reference.hpp>
36 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
37 #include <functional>
38 #endif
39 
40 namespace boost
41 {
42   namespace detail
43   {
44 
45 
46 #if ! defined(BOOST_NO_SFINAE_EXPR) && \
47     ! defined(BOOST_NO_CXX11_DECLTYPE) && \
48     ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
49     ! defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
50 
51 #define BOOST_THREAD_PROVIDES_INVOKE
52 
53 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
54     // bullets 1 and 2
55 
56     template <class Fp, class A0, class ...Args>
57     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0,BOOST_THREAD_RV_REF (Args)...args)58     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
59         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
60     {
61         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
62     }
63     template <class R, class Fp, class A0, class ...Args>
64     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0,BOOST_THREAD_RV_REF (Args)...args)65     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
66         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
67     {
68         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
69     }
70 
71     template <class Fp, class A0, class ...Args>
72     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0,BOOST_THREAD_RV_REF (Args)...args)73     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
74         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
75     {
76         return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
77     }
78     template <class R, class Fp, class A0, class ...Args>
79     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0,BOOST_THREAD_RV_REF (Args)...args)80     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
81         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
82     {
83         return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
84     }
85 
86     // bullets 3 and 4
87 
88     template <class Fp, class A0>
89     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0)90     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
91         -> decltype(boost::forward<A0>(a0).*f)
92     {
93         return boost::forward<A0>(a0).*f;
94     }
95 
96     template <class Fp, class A0>
97     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0)98     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
99         -> decltype((*boost::forward<A0>(a0)).*f)
100     {
101         return (*boost::forward<A0>(a0)).*f;
102     }
103 
104     template <class R, class Fp, class A0>
105     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0)106     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
107         -> decltype(boost::forward<A0>(a0).*f)
108     {
109         return boost::forward<A0>(a0).*f;
110     }
111 
112     template <class R, class Fp, class A0>
113     inline auto
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (A0)a0)114     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
115         -> decltype((*boost::forward<A0>(a0)).*f)
116     {
117         return (*boost::forward<A0>(a0)).*f;
118     }
119 
120 
121     // bullet 5
122 
123     template <class R, class Fp, class ...Args>
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (Args)...args)124     inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
125     -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
126     {
127       return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
128     }
129     template <class Fp, class ...Args>
invoke(BOOST_THREAD_RV_REF (Fp)f,BOOST_THREAD_RV_REF (Args)...args)130     inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
131     -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
132     {
133       return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
134     }
135 
136 #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
137 
138     // bullets 1 and 2
139 
140     template <class Fp, class A0>
141     inline
142     auto
143     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
144         -> decltype((boost::forward<A0>(a0).*f)())
145     {
146         return (boost::forward<A0>(a0).*f)();
147     }
148     template <class R, class Fp, class A0>
149     inline
150     auto
151     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
152         -> decltype((boost::forward<A0>(a0).*f)())
153     {
154         return (boost::forward<A0>(a0).*f)();
155     }
156     template <class Fp, class A0, class A1>
157     inline
158     auto
159     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
160         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1)))
161     {
162         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
163     }
164     template <class R, class Fp, class A0, class A1>
165     inline
166     auto
167     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
168         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1)))
169     {
170         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
171     }
172     template <class Fp, class A0, class A1, class A2>
173     inline
174     auto
175     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
176         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
177     {
178         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
179     }
180     template <class R, class Fp, class A0, class A1, class A2>
181     inline
182     auto
183     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
184         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
185     {
186         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
187     }
188 
189     template <class Fp, class A0>
190     inline
191     auto
192     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
193         -> decltype(((*boost::forward<A0>(a0)).*f)())
194     {
195         return ((*boost::forward<A0>(a0)).*f)();
196     }
197     template <class R, class Fp, class A0>
198     inline
199     auto
200     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
201         -> decltype(((*boost::forward<A0>(a0)).*f)())
202     {
203         return ((*boost::forward<A0>(a0)).*f)();
204     }
205     template <class Fp, class A0, class A1>
206     inline
207     auto
208     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
209         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1)))
210     {
211         return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
212     }
213     template <class R, class Fp, class A0, class A1>
214     inline
215     auto
216     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
217         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1)))
218     {
219         return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
220     }
221     template <class Fp, class A0, class A1, class A2>
222     inline
223     auto
224     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
225         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
226     {
227         return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
228     }
229     template <class R, class Fp, class A0, class A1, class A2>
230     inline
231     auto
232     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
233         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
234     {
235         return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
236     }
237 
238     // bullets 3 and 4
239 
240     template <class Fp, class A0>
241     inline
242     auto
243     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
244         -> decltype(boost::forward<A0>(a0).*f)
245     {
246         return boost::forward<A0>(a0).*f;
247     }
248     template <class R, class Fp, class A0>
249     inline
250     auto
251     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
252         -> decltype(boost::forward<A0>(a0).*f)
253     {
254         return boost::forward<A0>(a0).*f;
255     }
256 
257     template <class Fp, class A0>
258     inline
259     auto
260     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
261         -> decltype((*boost::forward<A0>(a0)).*f)
262     {
263         return (*boost::forward<A0>(a0)).*f;
264     }
265     template <class R, class Fp, class A0>
266     inline
267     auto
268     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
269         -> decltype((*boost::forward<A0>(a0)).*f)
270     {
271         return (*boost::forward<A0>(a0)).*f;
272     }
273 
274     // bullet 5
275 
276     template <class Fp>
277     inline
278     auto invoke(BOOST_THREAD_RV_REF(Fp) f)
279     -> decltype(boost::forward<Fp>(f)())
280     {
281       return boost::forward<Fp>(f)();
282     }
283     template <class Fp, class A1>
284     inline
285     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
286     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1)))
287     {
288       return boost::forward<Fp>(f)(boost::forward<A1>(a1));
289     }    template <class Fp, class A1, class A2>
290     inline
291     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
292     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
293     {
294       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
295     }
296     template <class Fp, class A1, class A2, class A3>
297     inline
298     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
299     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)))
300     {
301       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
302     }
303 
304 
305     template <class R, class Fp>
306     inline
307     auto invoke(BOOST_THREAD_RV_REF(Fp) f)
308     -> decltype(boost::forward<Fp>(f)())
309     {
310       return boost::forward<Fp>(f)();
311     }
312     template <class R, class Fp, class A1>
313     inline
314     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
315     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1)))
316     {
317       return boost::forward<Fp>(f)(boost::forward<A1>(a1));
318     }
319     template <class R, class Fp, class A1, class A2>
320     inline
321     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
322     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
323     {
324       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
325     }
326     template <class R, class Fp, class A1, class A2, class A3>
327     inline
328     auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
329     -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)))
330     {
331       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
332     }
333 
334 #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
335 
336 #elif ! defined(BOOST_NO_SFINAE_EXPR) && \
337     ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \
338     defined  BOOST_MSVC
339 
340     template <class Ret, class Fp>
341     inline
342     Ret invoke(BOOST_THREAD_RV_REF(Fp) f)
343     {
344       return f();
345     }
346     template <class Ret, class Fp, class A1>
347     inline
348     Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
349     {
350       return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1))();
351     }
352     template <class Ret, class Fp, class A1, class A2>
353     inline
354     Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
355     {
356       return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2))();
357     }
358     template <class Ret, class Fp, class A1, class A2, class A3>
359     inline
360     Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
361     {
362       return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3))();
363     }
364 
365 #define BOOST_THREAD_PROVIDES_INVOKE_RET
366 
367 #elif ! defined  BOOST_MSVC
368 //!!!!!  WARNING !!!!! THIS DOESN'T WORKS YET
369 #define BOOST_THREAD_PROVIDES_INVOKE_RET
370 
371 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
372 
373     // bullet 1
374     // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
375     // type T or a reference to an object of type T or a reference to an object of a type derived from T
376     template <class Ret, class A, class A0, class ...Args>
377     inline
378     typename enable_if_c
379     <
380         is_base_of<A, typename remove_reference<A0>::type>::value,
381         Ret
382     >::type
383     invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
384     {
385         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
386     }
387 
388     template <class Ret, class A, class A0, class ...Args>
389     inline
390     typename enable_if_c
391     <
392         is_base_of<A, typename remove_reference<A0>::type>::value,
393         Ret
394     >::type
395     invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
396     {
397         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
398     }
399 
400     template <class Ret, class A, class A0, class ...Args>
401     inline
402     typename enable_if_c
403     <
404         is_base_of<A, typename remove_reference<A0>::type>::value,
405         Ret
406     >::type
407     invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
408     {
409         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
410     }
411 
412     template <class Ret, class A, class A0, class ...Args>
413     inline
414     typename enable_if_c
415     <
416         is_base_of<A, typename remove_reference<A0>::type>::value,
417         Ret
418     >::type
419     invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
420     {
421         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
422     }
423 
424     // bullet 2
425     // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
426     // the types described in the previous item;
427     template <class Ret, class A, class A0, class ...Args>
428     inline
429     typename enable_if_c
430     <
431         ! is_base_of<A, typename remove_reference<A0>::type>::value,
432         Ret
433     >::type
434     invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
435     {
436       return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
437     }
438 
439     template <class Ret, class A, class A0, class ...Args>
440     inline
441     typename enable_if_c
442     <
443         ! is_base_of<A, typename remove_reference<A0>::type>::value,
444         Ret
445     >::type
446     invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
447     {
448       return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
449     }
450 
451     template <class Ret, class A, class A0, class ...Args>
452     inline
453     typename enable_if_c
454     <
455         ! is_base_of<A, typename remove_reference<A0>::type>::value,
456         Ret
457     >::type
458     invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
459     {
460       return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
461     }
462 
463     template <class Ret, class A, class A0, class ...Args>
464     inline
465     typename enable_if_c
466     <
467         ! is_base_of<A, typename remove_reference<A0>::type>::value,
468         Ret
469     >::type
470     invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
471     {
472       return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
473     }
474 
475     // bullet 3
476     // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
477     // reference to an object of type T or a reference to an object of a type derived from T;
478 //    template <class Ret, class A, class A0>
479 //    inline
480 //    typename enable_if_c
481 //    <
482 //        is_base_of<A, typename remove_reference<A0>::type>::value,
483 //        typename detail::apply_cv<A0, A>::type&
484 //    >::type
485 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
486 //    {
487 //        return boost::forward<A0>(a0).*f;
488 //    }
489 
490     // bullet 4
491     // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
492     //described in the previous item;
493 
494 //    template <class A0, class Ret, bool>
495 //    struct d4th_helper
496 //    {
497 //    };
498 //
499 //    template <class A0, class Ret>
500 //    struct d4th_helper<A0, Ret, true>
501 //    {
502 //        typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
503 //    };
504 //
505 //    template <class Ret, class A, class A0>
506 //    inline
507 //    typename detail::4th_helper<A, Ret,
508 //                          !is_base_of<A,
509 //                                      typename remove_reference<A0>::type
510 //                                     >::value
511 //                         >::type&
512 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
513 //    {
514 //        return (*boost::forward<A0>(a0)).*f;
515 //    }
516 
517 //    template <class Ret, class A, class A0>
518 //    inline
519 //    typename enable_if_c
520 //    <
521 //        !is_base_of<A, typename remove_reference<A0>::type>::value,
522 //        typename detail::ref_return1<Ret A::*, A0>::type
523 //    >::type
524 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
525 //    {
526 //        return (*boost::forward<A0>(a0)).*f;
527 //    }
528 
529     // bullet 5
530     // f(t1, t2, ..., tN) in all other cases.
531 
532     template <class Ret, class Fp, class ...Args>
533     inline Ret do_invoke(boost::false_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
534     {
535       return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
536     }
537 
538     template <class Ret, class Fp, class ...Args>
539     inline Ret do_invoke(boost::true_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
540     {
541       return f(boost::forward<Args>(args)...);
542     }
543 
544     template <class Ret, class Fp, class ...Args>
545     inline
546     typename disable_if_c
547     <
548         is_member_function_pointer<Fp>::value,
549         Ret
550     >::type
551     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
552     {
553       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<Args>(args)...);
554     }
555 #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
556     // bullet 1
557     // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
558     // type T or a reference to an object of type T or a reference to an object of a type derived from T
559 
560     template <class Ret, class A, class A0>
561     inline
562     typename enable_if_c
563     <
564         is_base_of<A, typename remove_reference<A0>::type>::value,
565         Ret
566     >::type
567     invoke(Ret (A::*f)(), A0& a0)
568     {
569         return (a0.*f)();
570     }
571     template <class Ret, class A, class A0>
572     inline
573     typename enable_if_c
574     <
575         is_base_of<A, typename remove_reference<A0>::type>::value,
576         Ret
577     >::type
578     invoke(Ret (A::*f)(), A0* a0)
579     {
580         return ((*a0).*f)();
581     }
582 
583     template <class Ret, class A, class A0, class A1>
584     inline
585     typename enable_if_c
586     <
587         is_base_of<A, typename remove_reference<A0>::type>::value,
588         Ret
589     >::type
590     invoke(Ret (A::*f)(A1),
591         A0& a0, BOOST_THREAD_RV_REF(A1) a1
592         )
593     {
594         return (a0.*f)(boost::forward<A1>(a1));
595     }
596     template <class Ret, class A, class A0, class A1>
597     inline
598     typename enable_if_c
599     <
600         is_base_of<A, typename remove_reference<A0>::type>::value,
601         Ret
602     >::type
603     invoke(Ret (A::*f)(A1), A0& a0, A1 a1)
604     {
605         return (a0.*f)(a1);
606     }
607     template <class Ret, class A, class A0, class A1>
608     inline
609     typename enable_if_c
610     <
611         is_base_of<A, typename remove_reference<A0>::type>::value,
612         Ret
613     >::type
614     invoke(Ret (A::*f)(A1), A0* a0, BOOST_THREAD_RV_REF(A1) a1
615         )
616     {
617         return (*(a0).*f)(boost::forward<A1>(a1));
618     }
619     template <class Ret, class A, class A0, class A1>
620     inline
621     typename enable_if_c
622     <
623         is_base_of<A, typename remove_reference<A0>::type>::value,
624         Ret
625     >::type
626     invoke(Ret (A::*f)(A1), A0* a0, A1 a1)
627     {
628         return (*a0.*f)(a1);
629     }
630     template <class Ret, class A, class A0, class A1, class A2>
631     inline
632     typename enable_if_c
633     <
634         is_base_of<A, typename remove_reference<A0>::type>::value,
635         Ret
636     >::type
637     invoke(Ret (A::*f)(A1, A2),
638         A0& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
639         )
640     {
641         return (a0.*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
642     }
643     template <class Ret, class A, class A0, class A1, class A2>
644     inline
645     typename enable_if_c
646     <
647         is_base_of<A, typename remove_reference<A0>::type>::value,
648         Ret
649     >::type
650     invoke(Ret (A::*f)(A1, A2), A0* a0, A1 a1, A2 a2)
651     {
652         return ((*a0).*f)(a1, a2);
653     }
654     template <class Ret, class A, class A0, class A1, class A2, class A3>
655     inline
656     typename enable_if_c
657     <
658         is_base_of<A, typename remove_reference<A0>::type>::value,
659         Ret
660     >::type
661     invoke(Ret (A::*f)(A1, A2, A3),
662         A0& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
663     {
664         return (a0.*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
665     }
666     template <class Ret, class A, class A0, class A1, class A2, class A3>
667     inline
668     typename enable_if_c
669     <
670         is_base_of<A, typename remove_reference<A0>::type>::value,
671         Ret
672     >::type
673     invoke(Ret (A::*f)(A1, A2, A3), A0* a0, A1 a1, A2 a2, A3 a3)
674     {
675         return ((*a0).*f)(a1, a2, a3);
676     }
677 
678 ///
679     template <class Ret, class A, class A0>
680     inline
681     typename enable_if_c
682     <
683         is_base_of<A, typename remove_reference<A0>::type>::value,
684         Ret
685     >::type
686     invoke(Ret (A::*f)() const, A0 const& a0)
687     {
688         return (a0.*f)();
689     }
690     template <class Ret, class A, class A0>
691     inline
692     typename enable_if_c
693     <
694         is_base_of<A, typename remove_reference<A0>::type>::value,
695         Ret
696     >::type
697     invoke(Ret (A::*f)() const, A0 const* a0)
698     {
699         return ((*a0).*f)();
700     }
701     template <class Ret, class A, class A0, class A1>
702     inline
703     typename enable_if_c
704     <
705         is_base_of<A, typename remove_reference<A0>::type>::value,
706         Ret
707     >::type
708     invoke(Ret (A::*f)(A1) const, A0 const& a0, BOOST_THREAD_RV_REF(A1) a1)
709     {
710         return (a0.*f)(boost::forward<A1>(a1));
711     }
712     template <class Ret, class A, class A0, class A1>
713     inline
714     typename enable_if_c
715     <
716         is_base_of<A, typename remove_reference<A0>::type>::value,
717         Ret
718     >::type
719     invoke(Ret (A::*f)(A1) const, A0 const* a0, BOOST_THREAD_RV_REF(A1) a1)
720     {
721         return ((*a0).*f)(boost::forward<A1>(a1));
722     }
723 
724     template <class Ret, class A, class A0, class A1>
725     inline
726     typename enable_if_c
727     <
728         is_base_of<A, typename remove_reference<A0>::type>::value,
729         Ret
730     >::type
731     invoke(Ret (A::*f)(A1) const, A0 const& a0, A1 a1)
732     {
733         return (a0.*f)(a1);
734     }
735     template <class Ret, class A, class A0, class A1, class A2>
736     inline
737     typename enable_if_c
738     <
739         is_base_of<A, typename remove_reference<A0>::type>::value,
740         Ret
741     >::type
742     invoke(Ret (A::*f)(A1, A2) const,
743         A0 const& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
744         )
745     {
746         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)
747             );
748     }
749     template <class Ret, class A, class A0, class A1, class A2>
750     inline
751     typename enable_if_c
752     <
753         is_base_of<A, typename remove_reference<A0>::type>::value,
754         Ret
755     >::type
756     invoke(Ret (A::*f)(A1, A2) const, A0 const& a0, A1 a1, A2 a2)
757     {
758         return (a0.*f)(a1, a2);
759     }
760     template <class Ret, class A, class A0, class A1, class A2, class A3>
761     inline
762     typename enable_if_c
763     <
764         is_base_of<A, typename remove_reference<A0>::type>::value,
765         Ret
766     >::type
767     invoke(Ret (A::*f)(A1, A2, A3) const,
768         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
769         )
770     {
771         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
772     }
773     template <class Ret, class A, class A0, class A1, class A2, class A3>
774     inline
775     typename enable_if_c
776     <
777         is_base_of<A, typename remove_reference<A0>::type>::value,
778         Ret
779     >::type
780     invoke(Ret (A::*f)(A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3)
781     {
782         return (a0.*f)(a1, a2, a3);
783     }
784     ///
785     template <class Ret, class A, class A0>
786     inline
787     typename enable_if_c
788     <
789         is_base_of<A, typename remove_reference<A0>::type>::value,
790         Ret
791     >::type
792     invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
793     {
794         return (boost::forward<A0>(a0).*f)();
795     }
796     template <class Ret, class A, class A0, class A1>
797     inline
798     typename enable_if_c
799     <
800         is_base_of<A, typename remove_reference<A0>::type>::value,
801         Ret
802     >::type
803     invoke(Ret (A::*f)(A1) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
804     {
805         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
806     }
807     template <class Ret, class A, class A0, class A1>
808     inline
809     typename enable_if_c
810     <
811         is_base_of<A, typename remove_reference<A0>::type>::value,
812         Ret
813     >::type
814     invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
815     {
816         return (a0.*f)(a1);
817     }
818     template <class Ret, class A, class A0, class A1, class A2>
819     inline
820     typename enable_if_c
821     <
822         is_base_of<A, typename remove_reference<A0>::type>::value,
823         Ret
824     >::type
825     invoke(Ret (A::*f)(A1, A2) volatile,
826         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
827     {
828         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
829     }
830     template <class Ret, class A, class A0, class A1, class A2>
831     inline
832     typename enable_if_c
833     <
834         is_base_of<A, typename remove_reference<A0>::type>::value,
835         Ret
836     >::type
837     invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2 )
838     {
839         return (a0.*f)(a1, a2);
840     }
841     template <class Ret, class A, class A0, class A1, class A2, class A3>
842     inline
843     typename enable_if_c
844     <
845         is_base_of<A, typename remove_reference<A0>::type>::value,
846         Ret
847     >::type
848     invoke(Ret (A::*f)(A1, A2, A3) volatile,
849         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
850         )
851     {
852         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
853     }
854     template <class Ret, class A, class A0, class A1, class A2, class A3>
855     inline
856     typename enable_if_c
857     <
858         is_base_of<A, typename remove_reference<A0>::type>::value,
859         Ret
860     >::type
861     invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
862     {
863         return (a0.*f)(a1, a2, a3);
864     }
865     ///
866     template <class Ret, class A, class A0>
867     inline
868     typename enable_if_c
869     <
870         is_base_of<A, typename remove_reference<A0>::type>::value,
871         Ret
872     >::type
873     invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
874     {
875         return (boost::forward<A0>(a0).*f)();
876     }
877     template <class Ret, class A, class A0, class A1>
878     inline
879     typename enable_if_c
880     <
881         is_base_of<A, typename remove_reference<A0>::type>::value,
882         Ret
883     >::type
884     invoke(Ret (A::*f)(A1) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
885     {
886         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
887     }
888     template <class Ret, class A, class A0, class A1>
889     inline
890     typename enable_if_c
891     <
892         is_base_of<A, typename remove_reference<A0>::type>::value,
893         Ret
894     >::type
895     invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
896     {
897         return (a0.*f)(a1);
898     }
899     template <class Ret, class A, class A0, class A1, class A2>
900     inline
901     typename enable_if_c
902     <
903         is_base_of<A, typename remove_reference<A0>::type>::value,
904         Ret
905     >::type
906     invoke(Ret (A::*f)(A1, A2) const volatile,
907         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
908         )
909     {
910         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
911     }
912     template <class Ret, class A, class A0, class A1, class A2>
913     inline
914     typename enable_if_c
915     <
916         is_base_of<A, typename remove_reference<A0>::type>::value,
917         Ret
918     >::type
919     invoke(Ret (A::*f)(A1, A2) const volatile,
920         A0 a0, A1 a1, A2 a2
921         )
922     {
923         return (a0.*f)(a1, a2);
924     }
925     template <class Ret, class A, class A0, class A1, class A2, class A3>
926     inline
927     typename enable_if_c
928     <
929         is_base_of<A, typename remove_reference<A0>::type>::value,
930         Ret
931     >::type
932     invoke(Ret (A::*f)(A1, A2, A3) const volatile,
933         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
934         )
935     {
936         return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
937     }
938     template <class Ret, class A, class A0, class A1, class A2, class A3>
939     inline
940     typename enable_if_c
941     <
942         is_base_of<A, typename remove_reference<A0>::type>::value,
943         Ret
944     >::type
945     invoke(Ret (A::*f)(A1, A2, A3) const volatile,
946         A0 a0, A1 a1, A2 a2, A3 a3
947         )
948     {
949         return (a0.*f)(a1, a2, a3);
950     }
951 
952     // bullet 2
953     // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
954     // the types described in the previous item;
955     template <class Ret, class A, class A0>
956     inline
957     typename enable_if_c
958     <
959         ! is_base_of<A, typename remove_reference<A0>::type>::value,
960         Ret
961     >::type
962     invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0)
963     {
964       return ((*boost::forward<A0>(a0)).*f)();
965     }
966     template <class Ret, class A, class A0, class A1>
967     inline
968     typename enable_if_c
969     <
970         ! is_base_of<A, typename remove_reference<A0>::type>::value,
971         Ret
972     >::type
973     invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
974     {
975       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
976     }
977     template <class Ret, class A, class A0, class A1>
978     inline
979     typename enable_if_c
980     <
981         ! is_base_of<A, typename remove_reference<A0>::type>::value,
982         Ret
983     >::type
984     invoke(Ret (A::*f)(A1), A0 a0, A1 a1)
985     {
986       return ((*a0).*f)(a1);
987     }
988     template <class Ret, class A, class A0, class A1, class A2>
989     inline
990     typename enable_if_c
991     <
992         ! is_base_of<A, typename remove_reference<A0>::type>::value,
993         Ret
994     >::type
995     invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2)),
996         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
997     {
998       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
999     }
1000     template <class Ret, class A, class A0, class A1, class A2>
1001     inline
1002     typename enable_if_c
1003     <
1004         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1005         Ret
1006     >::type
1007     invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2)
1008     {
1009       return ((*a0).*f)(a1, a2);
1010     }
1011     template <class Ret, class A, class A0, class A1, class A2, class A3>
1012     inline
1013     typename enable_if_c
1014     <
1015         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1016         Ret
1017     >::type
1018     invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2), BOOST_THREAD_RV_REF(A3)),
1019         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1020     {
1021       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)
1022           );
1023     }
1024     template <class Ret, class A, class A0, class A1, class A2, class A3>
1025     inline
1026     typename enable_if_c
1027     <
1028         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1029         Ret
1030     >::type
1031     invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3)
1032     {
1033       return ((*a0).*f)(a1, a2, a3);
1034     }
1035 
1036 ///
1037     template <class Ret, class A, class A0>
1038     inline
1039     typename enable_if_c
1040     <
1041         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1042         Ret
1043     >::type
1044     invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0)
1045     {
1046       return ((*boost::forward<A0>(a0)).*f)();
1047     }
1048     template <class Ret, class A, class A0, class A1>
1049     inline
1050     typename enable_if_c
1051     <
1052         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1053         Ret
1054     >::type
1055     invoke(Ret (A::*f)(A1) const,
1056         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
1057     {
1058       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
1059     }
1060     template <class Ret, class A, class A0, class A1>
1061     inline
1062     typename enable_if_c
1063     <
1064         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1065         Ret
1066     >::type
1067     invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, A1 a1)
1068     {
1069       return ((*boost::forward<A0>(a0)).*f)(a1);
1070     }
1071     template <class Ret, class A, class A0, class A1>
1072     inline
1073     typename enable_if_c
1074     <
1075         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1076         Ret
1077     >::type
1078     invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1)
1079     {
1080       return ((*a0).*f)(a1);
1081     }
1082     template <class Ret, class A, class A0, class A1, class A2>
1083     inline
1084     typename enable_if_c
1085     <
1086         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1087         Ret
1088     >::type
1089     invoke(Ret (A::*f)(A1, A2) const,
1090         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1091     {
1092       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
1093     }
1094     template <class Ret, class A, class A0, class A1, class A2>
1095     inline
1096     typename enable_if_c
1097     <
1098         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1099         Ret
1100     >::type
1101     invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2)
1102     {
1103       return ((*a0).*f)(a1, a2);
1104     }
1105     template <class Ret, class A, class A0, class A1, class A2, class A3>
1106     inline
1107     typename enable_if_c
1108     <
1109         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1110         Ret
1111     >::type
1112     invoke(Ret (A::*f)(A1, A2, A3) const,
1113         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1114     {
1115       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1116     }
1117     template <class Ret, class A, class A0, class A1, class A2, class A3>
1118     inline
1119     typename enable_if_c
1120     <
1121         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1122         Ret
1123     >::type
1124     invoke(Ret (A::*f)(A1, A2, A3) const,
1125         A0 a0, A1 a1, A2 a2, A3 a3)
1126     {
1127       return ((*a0).*f)(a1, a2, a3);
1128     }
1129     ///
1130     template <class Ret, class A, class A0>
1131     inline
1132     typename enable_if_c
1133     <
1134         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1135         Ret
1136     >::type
1137     invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
1138     {
1139       return ((*boost::forward<A0>(a0)).*f)();
1140     }
1141     template <class Ret, class A, class A0, class A1>
1142     inline
1143     typename enable_if_c
1144     <
1145         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1146         Ret
1147     >::type
1148     invoke(Ret (A::*f)(A1) volatile,
1149         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
1150     {
1151       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
1152     }
1153     template <class Ret, class A, class A0, class A1>
1154     inline
1155     typename enable_if_c
1156     <
1157         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1158         Ret
1159     >::type
1160     invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
1161     {
1162       return ((*a0).*f)(a1);
1163     }
1164     template <class Ret, class A, class A0, class A1, class A2>
1165     inline
1166     typename enable_if_c
1167     <
1168         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1169         Ret
1170     >::type
1171     invoke(Ret (A::*f)(A1, A2) volatile,
1172         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1173     {
1174       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
1175     }
1176     template <class Ret, class A, class A0, class A1, class A2>
1177     inline
1178     typename enable_if_c
1179     <
1180         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1181         Ret
1182     >::type
1183     invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2)
1184     {
1185       return ((*a0).*f)(a1, a2);
1186     }
1187     template <class Ret, class A, class A0, class A1, class A2, class A3>
1188     inline
1189     typename enable_if_c
1190     <
1191         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1192         Ret
1193     >::type
1194     invoke(Ret (A::*f)(A1, A2, A3) volatile,
1195         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1196     {
1197       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1198     }
1199     template <class Ret, class A, class A0, class A1, class A2, class A3>
1200     inline
1201     typename enable_if_c
1202     <
1203         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1204         Ret
1205     >::type
1206     invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
1207     {
1208       return ((*a0).*f)(a1, a2, a3);
1209     }
1210     ///
1211     template <class Ret, class A, class A0>
1212     inline
1213     typename enable_if_c
1214     <
1215         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1216         Ret
1217     >::type
1218     invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
1219     {
1220       return ((*boost::forward<A0>(a0)).*f)();
1221     }
1222     template <class Ret, class A, class A0>
1223     inline
1224     typename enable_if_c
1225     <
1226         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1227         Ret
1228     >::type
1229     invoke(Ret (A::*f)() const volatile, A0 a0)
1230     {
1231       return ((*a0).*f)();
1232     }
1233     template <class Ret, class A, class A0, class A1>
1234     inline
1235     typename enable_if_c
1236     <
1237         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1238         Ret
1239     >::type
1240     invoke(Ret (A::*f)(A1) const volatile,
1241         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
1242     {
1243       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
1244     }
1245     template <class Ret, class A, class A0, class A1>
1246     inline
1247     typename enable_if_c
1248     <
1249         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1250         Ret
1251     >::type
1252     invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
1253     {
1254       return ((*a0).*f)(a1);
1255     }
1256     template <class Ret, class A, class A0, class A1, class A2>
1257     inline
1258     typename enable_if_c
1259     <
1260         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1261         Ret
1262     >::type
1263     invoke(Ret (A::*f)(A1, A2) const volatile,
1264         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1265     {
1266       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
1267     }
1268     template <class Ret, class A, class A0, class A1, class A2>
1269     inline
1270     typename enable_if_c
1271     <
1272         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1273         Ret
1274     >::type
1275     invoke(Ret (A::*f)(A1, A2) const volatile,
1276         A0 a0, A1 a1, A2 a2)
1277     {
1278       return ((*a0).*f)(a1, a2);
1279     }
1280     template <class Ret, class A, class A0, class A1, class A2, class A3>
1281     inline
1282     typename enable_if_c
1283     <
1284         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1285         Ret
1286     >::type
1287     invoke(Ret (A::*f)(A1, A2, A3) const volatile,
1288         BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1289     {
1290       return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1291     }
1292     template <class Ret, class A, class A0, class A1, class A2, class A3>
1293     inline
1294     typename enable_if_c
1295     <
1296         ! is_base_of<A, typename remove_reference<A0>::type>::value,
1297         Ret
1298     >::type
1299     invoke(Ret (A::*f)(A1, A2, A3) const volatile,
1300         A0 a0, A1 a1, A2 a2, A3 a3)
1301     {
1302       return ((*a0).*f)(a1, a2, a3);
1303     }
1304     // bullet 3
1305     // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
1306     // reference to an object of type T or a reference to an object of a type derived from T;
1307 //    template <class Ret, class A, class A0>
1308 //    inline
1309 //    typename enable_if_c
1310 //    <
1311 //        is_base_of<A, typename remove_reference<A0>::type>::value,
1312 //        typename detail::apply_cv<A0, A>::type&
1313 //    >::type
1314 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
1315 //    {
1316 //        return boost::forward<A0>(a0).*f;
1317 //    }
1318 
1319     // bullet 4
1320     // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
1321     //described in the previous item;
1322 
1323 //    template <class A0, class Ret, bool>
1324 //    struct d4th_helper
1325 //    {
1326 //    };
1327 //
1328 //    template <class A0, class Ret>
1329 //    struct d4th_helper<A0, Ret, true>
1330 //    {
1331 //        typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
1332 //    };
1333 //
1334 //    template <class Ret, class A, class A0>
1335 //    inline
1336 //    typename detail::4th_helper<A, Ret,
1337 //                          !is_base_of<A,
1338 //                                      typename remove_reference<A0>::type
1339 //                                     >::value
1340 //                         >::type&
1341 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
1342 //    {
1343 //        return (*boost::forward<A0>(a0)).*f;
1344 //    }
1345 
1346 //    template <class Ret, class A, class A0>
1347 //    inline
1348 //    typename enable_if_c
1349 //    <
1350 //        !is_base_of<A, typename remove_reference<A0>::type>::value,
1351 //        typename detail::ref_return1<Ret A::*, A0>::type
1352 //    >::type
1353 //    invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
1354 //    {
1355 //        return (*boost::forward<A0>(a0)).*f;
1356 //    }
1357 
1358     // bullet 5
1359     // f(t1, t2, ..., tN) in all other cases.
1360 
1361     template <class Ret, class Fp>
1362     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f)
1363     {
1364       return boost::forward<Fp>(f)();
1365     }
1366     template <class Ret, class Fp>
1367     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f)
1368     {
1369       return f();
1370     }
1371     template <class Ret, class Fp>
1372     inline
1373     typename disable_if_c
1374     <
1375         is_member_function_pointer<Fp>::value,
1376         Ret
1377     >::type
1378     invoke(BOOST_THREAD_FWD_REF(Fp) f)
1379     {
1380       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f));
1381     }
1382 
1383     template <class Ret, class Fp, class A1>
1384     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
1385     {
1386       return boost::forward<Fp>(f)(boost::forward<A1>(a1));
1387     }
1388     template <class Ret, class Fp, class A1>
1389     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
1390     {
1391       return f(boost::forward<A1>(a1));
1392     }
1393     template <class Ret, class Fp, class A1>
1394     inline
1395     typename disable_if_c
1396     <
1397         is_member_function_pointer<Fp>::value,
1398         Ret
1399     >::type
1400     invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
1401     {
1402       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1));
1403     }
1404 
1405     template <class Ret, class Fp, class A1, class A2>
1406     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1407     {
1408       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
1409     }
1410     template <class Ret, class Fp, class A1, class A2>
1411     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1412     {
1413       return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
1414     }
1415     template <class Ret, class Fp, class A1, class A2>
1416     inline
1417     typename disable_if_c
1418     <
1419         is_member_function_pointer<Fp>::value,
1420         Ret
1421     >::type
1422     invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1423     {
1424       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2));
1425     }
1426 
1427     template <class Ret, class Fp, class A1, class A2, class A3>
1428     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1429     {
1430       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1431     }
1432     template <class Ret, class Fp, class A1, class A2, class A3>
1433     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1434     {
1435       return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1436     }
1437     template <class Ret, class Fp, class A1, class A2, class A3>
1438     inline
1439     typename disable_if_c
1440     <
1441         is_member_function_pointer<Fp>::value,
1442         Ret
1443     >::type
1444     invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1445     {
1446       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1447     }
1448 
1449 
1450     template <class Ret, class Fp, class A1>
1451     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
1452     {
1453       return boost::forward<Fp>(f)(a1);
1454     }
1455     template <class Ret, class Fp, class A1>
1456     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
1457     {
1458       return f(a1);
1459     }
1460     template <class Ret, class Fp, class A1>
1461     inline
1462     typename disable_if_c
1463     <
1464         is_member_function_pointer<Fp>::value,
1465         Ret
1466     >::type
1467     invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
1468     {
1469       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1);
1470     }
1471 
1472     template <class Ret, class Fp, class A1, class A2>
1473     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
1474     {
1475       return boost::forward<Fp>(f)(a1, a2);
1476     }
1477     template <class Ret, class Fp, class A1, class A2>
1478     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
1479     {
1480       return f(a1, a2);
1481     }
1482     template <class Ret, class Fp, class A1, class A2>
1483     inline
1484     typename disable_if_c
1485     <
1486         is_member_function_pointer<Fp>::value,
1487         Ret
1488     >::type
1489     invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
1490     {
1491       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1, a2);
1492     }
1493 
1494     template <class Ret, class Fp, class A1, class A2, class A3>
1495     inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
1496     {
1497       return boost::forward<Fp>(f)(a1, a2, a3);
1498     }
1499     template <class Ret, class Fp, class A1, class A2, class A3>
1500     inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
1501     {
1502       return f(a1, a2, a3);
1503     }
1504     template <class Ret, class Fp, class A1, class A2, class A3>
1505     inline
1506     typename disable_if_c
1507     <
1508         is_member_function_pointer<Fp>::value,
1509         Ret
1510     >::type
1511     invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
1512     {
1513       return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1, a2, a3);
1514     }
1515 
1516 
1517     ///
1518     template <class Ret, class Fp>
1519     inline
1520     typename disable_if_c
1521     <
1522         is_member_function_pointer<Fp>::value,
1523         Ret
1524     >::type
1525     invoke(Fp &f)
1526     {
1527       return f();
1528     }
1529     template <class Ret, class Fp, class A1>
1530     inline
1531     typename disable_if_c
1532     <
1533         is_member_function_pointer<Fp>::value,
1534         Ret
1535     >::type
1536     invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1)
1537     {
1538       return f(boost::forward<A1>(a1));
1539     }
1540     template <class Ret, class Fp, class A1>
1541     inline
1542     typename disable_if_c
1543     <
1544         is_member_function_pointer<Fp>::value,
1545         Ret
1546     >::type
1547     invoke(Fp &f, A1 a1)
1548     {
1549       return f(a1);
1550     }
1551     template <class Ret, class Fp, class A1, class A2>
1552     inline
1553     typename disable_if_c
1554     <
1555         is_member_function_pointer<Fp>::value,
1556         Ret
1557     >::type
1558     invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
1559     {
1560       return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
1561     }
1562     template <class Ret, class Fp, class A1, class A2>
1563     inline
1564     typename disable_if_c
1565     <
1566         is_member_function_pointer<Fp>::value,
1567         Ret
1568     >::type
1569     invoke(Fp &f, A1 a1, A2 a2)
1570     {
1571       return f(a1, a2);
1572     }
1573     template <class Ret, class Fp, class A1, class A2, class A3>
1574     inline
1575     typename disable_if_c
1576     <
1577         is_member_function_pointer<Fp>::value,
1578         Ret
1579     >::type
1580     invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
1581     {
1582       return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
1583     }
1584     template <class Ret, class Fp, class A1, class A2, class A3>
1585     inline
1586     typename disable_if_c
1587     <
1588         is_member_function_pointer<Fp>::value,
1589         Ret
1590     >::type
1591     invoke(Fp &f, A1 a1, A2 a2, A3 a3)
1592     {
1593       return f(a1, a2, a3);
1594     }
1595     ///
1596 
1597 #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
1598 
1599 #endif  // all
1600       }
1601     }
1602 
1603 #endif // header
1604