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