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