Line data Source code
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
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 357 : 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 357 : 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
|