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