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
41namespace 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
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
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
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
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
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
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
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
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>
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>
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