1 // Copyright (C) 2012 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/11 Vicente J. Botet Escriba 11 // Adapt to boost libc++ implementation 12 13 //===----------------------------------------------------------------------===// 14 // 15 // The LLVM Compiler Infrastructure 16 // 17 // This file is dual licensed under the MIT and the University of Illinois Open 18 // Source Licenses. See LICENSE.TXT for details. 19 // 20 // The invoker code is based on the one from libcxx. 21 //===----------------------------------------------------------------------===// 22 23 #ifndef BOOST_THREAD_DETAIL_INVOKER_HPP 24 #define BOOST_THREAD_DETAIL_INVOKER_HPP 25 26 #include <boost/config.hpp> 27 28 #include <boost/utility/result_of.hpp> 29 #include <boost/thread/detail/move.hpp> 30 #include <boost/thread/detail/invoke.hpp> 31 #include <boost/thread/detail/make_tuple_indices.hpp> 32 #include <boost/thread/csbl/tuple.hpp> 33 #include <boost/tuple/tuple.hpp> 34 35 #include <boost/thread/detail/variadic_header.hpp> 36 37 namespace boost 38 { 39 namespace detail 40 { 41 42 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE) 43 44 template <class Fp, class ... Args> 45 class invoker 46 { 47 //typedef typename decay<Fp>::type Fpd; 48 //typedef tuple<typename decay<Args>::type...> Argsd; 49 50 //csbl::tuple<Fpd, Argsd...> f_; 51 csbl::tuple<Fp, Args...> f_; 52 53 public: 54 BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker) 55 //typedef typename invoke_of<_Fp, _Args...>::type Rp; 56 typedef typename result_of<Fp(Args...)>::type result_type; 57 58 template <class F, class ... As> 59 BOOST_SYMBOL_VISIBLE invoker(BOOST_THREAD_FWD_REF (F)f,BOOST_THREAD_FWD_REF (As)...args)60 explicit invoker(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args) 61 : f_(boost::forward<F>(f), boost::forward<As>(args)...) 62 {} 63 64 BOOST_SYMBOL_VISIBLE invoker(BOOST_THREAD_RV_REF (invoker)f)65 invoker(BOOST_THREAD_RV_REF(invoker) f) : f_(boost::move(BOOST_THREAD_RV(f).f_)) 66 {} 67 68 BOOST_SYMBOL_VISIBLE invoker(const invoker & f)69 invoker( const invoker& f) : f_(f.f_) 70 {} 71 72 BOOST_SYMBOL_VISIBLE operator =(BOOST_THREAD_RV_REF (invoker)f)73 invoker& operator=(BOOST_THREAD_RV_REF(invoker) f) 74 { 75 if (this != &f) 76 { 77 f_ = boost::move(BOOST_THREAD_RV(f).f_); 78 } 79 return *this; 80 } 81 82 BOOST_SYMBOL_VISIBLE operator =(BOOST_THREAD_COPY_ASSIGN_REF (invoker)f)83 invoker& operator=( BOOST_THREAD_COPY_ASSIGN_REF(invoker) f) 84 { 85 if (this != &f) 86 { 87 f_ = f.f_; 88 } 89 return *this; 90 } 91 operator ()()92 result_type operator()() 93 { 94 typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index; 95 return execute(Index()); 96 } 97 private: 98 template <size_t ...Indices> 99 result_type execute(tuple_indices<Indices...>)100 execute(tuple_indices<Indices...>) 101 { 102 return detail::invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...); 103 } 104 }; 105 106 template <class R, class Fp, class ... Args> 107 class invoker_ret 108 { 109 //typedef typename decay<Fp>::type Fpd; 110 //typedef tuple<typename decay<Args>::type...> Argsd; 111 112 //csbl::tuple<Fpd, Argsd...> f_; 113 csbl::tuple<Fp, Args...> f_; 114 115 public: 116 BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker_ret) 117 typedef R result_type; 118 119 template <class F, class ... As> 120 BOOST_SYMBOL_VISIBLE invoker_ret(BOOST_THREAD_FWD_REF (F)f,BOOST_THREAD_FWD_REF (As)...args)121 explicit invoker_ret(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args) 122 : f_(boost::forward<F>(f), boost::forward<As>(args)...) 123 {} 124 125 BOOST_SYMBOL_VISIBLE invoker_ret(BOOST_THREAD_RV_REF (invoker_ret)f)126 invoker_ret(BOOST_THREAD_RV_REF(invoker_ret) f) : f_(boost::move(BOOST_THREAD_RV(f).f_)) 127 {} 128 operator ()()129 result_type operator()() 130 { 131 typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index; 132 return execute(Index()); 133 } 134 private: 135 template <size_t ...Indices> 136 result_type execute(tuple_indices<Indices...>)137 execute(tuple_indices<Indices...>) 138 { 139 return detail::invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...); 140 } 141 }; 142 //BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END 143 #else 144 145 #if ! defined BOOST_MSVC && defined(BOOST_THREAD_PROVIDES_INVOKE) 146 147 #define BOOST_THREAD_RV_REF_ARG_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(Arg##n) 148 #define BOOST_THREAD_RV_REF_A_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(A##n) 149 #define BOOST_THREAD_RV_REF_ARG(z, n, unused) , BOOST_THREAD_RV_REF(Arg##n) arg##n 150 #define BOOST_THREAD_FWD_REF_A(z, n, unused) , BOOST_THREAD_FWD_REF(A##n) arg##n 151 #define BOOST_THREAD_FWD_REF_ARG(z, n, unused) , BOOST_THREAD_FWD_REF(Arg##n) arg##n 152 #define BOOST_THREAD_FWD_PARAM(z, n, unused) , boost::forward<Arg##n>(arg##n) 153 #define BOOST_THREAD_FWD_PARAM_A(z, n, unused) , boost::forward<A##n>(arg##n) 154 #define BOOST_THREAD_DCL(z, n, unused) Arg##n v##n; 155 #define BOOST_THREAD_MOVE_PARAM(z, n, unused) , v##n(boost::move(arg##n)) 156 #define BOOST_THREAD_FORWARD_PARAM_A(z, n, unused) , v##n(boost::forward<A##n>(arg##n)) 157 #define BOOST_THREAD_MOVE_RHS_PARAM(z, n, unused) , v##n(boost::move(x.v##n)) 158 #define BOOST_THREAD_MOVE_DCL(z, n, unused) , boost::move(v##n) 159 #define BOOST_THREAD_MOVE_DCL_T(z, n, unused) BOOST_PP_COMMA_IF(n) boost::move(v##n) 160 #define BOOST_THREAD_ARG_DEF(z, n, unused) , class Arg##n = tuples::null_type 161 162 template <class Fp, class Arg = tuples::null_type 163 BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ARG_DEF, ~) 164 > 165 class invoker; 166 167 #define BOOST_THREAD_ASYNC_FUNCT(z, n, unused) \ 168 template <class Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \ 169 class invoker<Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \ 170 { \ 171 Fp fp_; \ 172 BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \ 173 public: \ 174 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \ 175 typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \ 176 \ 177 template <class F BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \ 178 BOOST_SYMBOL_VISIBLE \ 179 explicit invoker(BOOST_THREAD_FWD_REF(F) f \ 180 BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \ 181 ) \ 182 : fp_(boost::forward<F>(f)) \ 183 BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \ 184 {} \ 185 \ 186 BOOST_SYMBOL_VISIBLE \ 187 invoker(BOOST_THREAD_RV_REF(invoker) x) \ 188 : fp_(boost::move(x.fp_)) \ 189 BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \ 190 {} \ 191 \ 192 result_type operator()() { \ 193 return detail::invoke(boost::move(fp_) \ 194 BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL, ~) \ 195 ); \ 196 } \ 197 }; \ 198 \ 199 template <class R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \ 200 class invoker<R(*)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \ 201 { \ 202 typedef R(*Fp)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)); \ 203 Fp fp_; \ 204 BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \ 205 public: \ 206 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \ 207 typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \ 208 \ 209 template <class R2 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \ 210 BOOST_SYMBOL_VISIBLE \ 211 explicit invoker(R2(*f)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_A_T, ~)) \ 212 BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \ 213 ) \ 214 : fp_(f) \ 215 BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \ 216 {} \ 217 \ 218 BOOST_SYMBOL_VISIBLE \ 219 invoker(BOOST_THREAD_RV_REF(invoker) x) \ 220 : fp_(x.fp_) \ 221 BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \ 222 {} \ 223 \ 224 result_type operator()() { \ 225 return fp_( \ 226 BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL_T, ~) \ 227 ); \ 228 } \ 229 }; 230 231 BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ASYNC_FUNCT, ~) 232 233 #undef BOOST_THREAD_RV_REF_ARG_T 234 #undef BOOST_THREAD_RV_REF_ARG 235 #undef BOOST_THREAD_FWD_REF_ARG 236 #undef BOOST_THREAD_FWD_REF_A 237 #undef BOOST_THREAD_FWD_PARAM 238 #undef BOOST_THREAD_FWD_PARAM_A 239 #undef BOOST_THREAD_DCL 240 #undef BOOST_THREAD_MOVE_PARAM 241 #undef BOOST_THREAD_MOVE_RHS_PARAM 242 #undef BOOST_THREAD_MOVE_DCL 243 #undef BOOST_THREAD_ARG_DEF 244 #undef BOOST_THREAD_ASYNC_FUNCT 245 246 #else 247 248 template <class Fp, 249 class T0 = tuples::null_type, class T1 = tuples::null_type, class T2 = tuples::null_type, 250 class T3 = tuples::null_type, class T4 = tuples::null_type, class T5 = tuples::null_type, 251 class T6 = tuples::null_type, class T7 = tuples::null_type, class T8 = tuples::null_type 252 , class T9 = tuples::null_type 253 > 254 class invoker; 255 256 template <class Fp, 257 class T0 , class T1 , class T2 , 258 class T3 , class T4 , class T5 , 259 class T6 , class T7 , class T8 > 260 class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> 261 { 262 Fp fp_; 263 T0 v0_; 264 T1 v1_; 265 T2 v2_; 266 T3 v3_; 267 T4 v4_; 268 T5 v5_; 269 T6 v6_; 270 T7 v7_; 271 T8 v8_; 272 //::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> f_; 273 274 public: 275 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 276 typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7, T8)>::type result_type; 277 278 BOOST_SYMBOL_VISIBLE 279 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 280 , BOOST_THREAD_RV_REF(T0) a0 281 , BOOST_THREAD_RV_REF(T1) a1 282 , BOOST_THREAD_RV_REF(T2) a2 283 , BOOST_THREAD_RV_REF(T3) a3 284 , BOOST_THREAD_RV_REF(T4) a4 285 , BOOST_THREAD_RV_REF(T5) a5 286 , BOOST_THREAD_RV_REF(T6) a6 287 , BOOST_THREAD_RV_REF(T7) a7 288 , BOOST_THREAD_RV_REF(T8) a8 289 ) 290 : fp_(boost::move(f)) 291 , v0_(boost::move(a0)) 292 , v1_(boost::move(a1)) 293 , v2_(boost::move(a2)) 294 , v3_(boost::move(a3)) 295 , v4_(boost::move(a4)) 296 , v5_(boost::move(a5)) 297 , v6_(boost::move(a6)) 298 , v7_(boost::move(a7)) 299 , v8_(boost::move(a8)) 300 {} 301 302 BOOST_SYMBOL_VISIBLE 303 invoker(BOOST_THREAD_RV_REF(invoker) f) 304 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 305 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 306 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 307 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 308 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 309 , v4_(boost::move(BOOST_THREAD_RV(f).v4_)) 310 , v5_(boost::move(BOOST_THREAD_RV(f).v5_)) 311 , v6_(boost::move(BOOST_THREAD_RV(f).v6_)) 312 , v7_(boost::move(BOOST_THREAD_RV(f).v7_)) 313 , v8_(boost::move(BOOST_THREAD_RV(f).v8_)) 314 {} 315 316 result_type operator()() 317 { 318 return detail::invoke(boost::move(fp_) 319 , boost::move(v0_) 320 , boost::move(v1_) 321 , boost::move(v2_) 322 , boost::move(v3_) 323 , boost::move(v4_) 324 , boost::move(v5_) 325 , boost::move(v6_) 326 , boost::move(v7_) 327 , boost::move(v8_) 328 ); 329 } 330 }; 331 template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7 > 332 class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7> 333 { 334 Fp fp_; 335 T0 v0_; 336 T1 v1_; 337 T2 v2_; 338 T3 v3_; 339 T4 v4_; 340 T5 v5_; 341 T6 v6_; 342 T7 v7_; 343 public: 344 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 345 typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7)>::type result_type; 346 347 BOOST_SYMBOL_VISIBLE 348 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 349 , BOOST_THREAD_RV_REF(T0) a0 350 , BOOST_THREAD_RV_REF(T1) a1 351 , BOOST_THREAD_RV_REF(T2) a2 352 , BOOST_THREAD_RV_REF(T3) a3 353 , BOOST_THREAD_RV_REF(T4) a4 354 , BOOST_THREAD_RV_REF(T5) a5 355 , BOOST_THREAD_RV_REF(T6) a6 356 , BOOST_THREAD_RV_REF(T7) a7 357 ) 358 : fp_(boost::move(f)) 359 , v0_(boost::move(a0)) 360 , v1_(boost::move(a1)) 361 , v2_(boost::move(a2)) 362 , v3_(boost::move(a3)) 363 , v4_(boost::move(a4)) 364 , v5_(boost::move(a5)) 365 , v6_(boost::move(a6)) 366 , v7_(boost::move(a7)) 367 {} 368 369 BOOST_SYMBOL_VISIBLE 370 invoker(BOOST_THREAD_RV_REF(invoker) f) 371 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 372 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 373 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 374 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 375 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 376 , v4_(boost::move(BOOST_THREAD_RV(f).v4_)) 377 , v5_(boost::move(BOOST_THREAD_RV(f).v5_)) 378 , v6_(boost::move(BOOST_THREAD_RV(f).v6_)) 379 , v7_(boost::move(BOOST_THREAD_RV(f).v7_)) 380 {} 381 382 result_type operator()() 383 { 384 return detail::invoke(boost::move(fp_) 385 , boost::move(v0_) 386 , boost::move(v1_) 387 , boost::move(v2_) 388 , boost::move(v3_) 389 , boost::move(v4_) 390 , boost::move(v5_) 391 , boost::move(v6_) 392 , boost::move(v7_) 393 ); 394 } 395 }; 396 template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6> 397 class invoker<Fp, T0, T1, T2, T3, T4, T5, T6> 398 { 399 Fp fp_; 400 T0 v0_; 401 T1 v1_; 402 T2 v2_; 403 T3 v3_; 404 T4 v4_; 405 T5 v5_; 406 T6 v6_; 407 public: 408 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 409 typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6)>::type result_type; 410 411 BOOST_SYMBOL_VISIBLE 412 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 413 , BOOST_THREAD_RV_REF(T0) a0 414 , BOOST_THREAD_RV_REF(T1) a1 415 , BOOST_THREAD_RV_REF(T2) a2 416 , BOOST_THREAD_RV_REF(T3) a3 417 , BOOST_THREAD_RV_REF(T4) a4 418 , BOOST_THREAD_RV_REF(T5) a5 419 , BOOST_THREAD_RV_REF(T6) a6 420 ) 421 : fp_(boost::move(f)) 422 , v0_(boost::move(a0)) 423 , v1_(boost::move(a1)) 424 , v2_(boost::move(a2)) 425 , v3_(boost::move(a3)) 426 , v4_(boost::move(a4)) 427 , v5_(boost::move(a5)) 428 , v6_(boost::move(a6)) 429 {} 430 431 BOOST_SYMBOL_VISIBLE 432 invoker(BOOST_THREAD_RV_REF(invoker) f) 433 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 434 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 435 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 436 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 437 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 438 , v4_(boost::move(BOOST_THREAD_RV(f).v4_)) 439 , v5_(boost::move(BOOST_THREAD_RV(f).v5_)) 440 , v6_(boost::move(BOOST_THREAD_RV(f).v6_)) 441 {} 442 443 result_type operator()() 444 { 445 return detail::invoke(boost::move(fp_) 446 , boost::move(v0_) 447 , boost::move(v1_) 448 , boost::move(v2_) 449 , boost::move(v3_) 450 , boost::move(v4_) 451 , boost::move(v5_) 452 , boost::move(v6_) 453 ); 454 } 455 }; 456 template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5> 457 class invoker<Fp, T0, T1, T2, T3, T4, T5> 458 { 459 Fp fp_; 460 T0 v0_; 461 T1 v1_; 462 T2 v2_; 463 T3 v3_; 464 T4 v4_; 465 T5 v5_; 466 public: 467 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 468 typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5)>::type result_type; 469 470 BOOST_SYMBOL_VISIBLE 471 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 472 , BOOST_THREAD_RV_REF(T0) a0 473 , BOOST_THREAD_RV_REF(T1) a1 474 , BOOST_THREAD_RV_REF(T2) a2 475 , BOOST_THREAD_RV_REF(T3) a3 476 , BOOST_THREAD_RV_REF(T4) a4 477 , BOOST_THREAD_RV_REF(T5) a5 478 ) 479 : fp_(boost::move(f)) 480 , v0_(boost::move(a0)) 481 , v1_(boost::move(a1)) 482 , v2_(boost::move(a2)) 483 , v3_(boost::move(a3)) 484 , v4_(boost::move(a4)) 485 , v5_(boost::move(a5)) 486 {} 487 488 BOOST_SYMBOL_VISIBLE 489 invoker(BOOST_THREAD_RV_REF(invoker) f) 490 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 491 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 492 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 493 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 494 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 495 , v4_(boost::move(BOOST_THREAD_RV(f).v4_)) 496 , v5_(boost::move(BOOST_THREAD_RV(f).v5_)) 497 {} 498 499 result_type operator()() 500 { 501 return detail::invoke(boost::move(fp_) 502 , boost::move(v0_) 503 , boost::move(v1_) 504 , boost::move(v2_) 505 , boost::move(v3_) 506 , boost::move(v4_) 507 , boost::move(v5_) 508 ); 509 } 510 }; 511 template <class Fp, class T0, class T1, class T2, class T3, class T4> 512 class invoker<Fp, T0, T1, T2, T3, T4> 513 { 514 Fp fp_; 515 T0 v0_; 516 T1 v1_; 517 T2 v2_; 518 T3 v3_; 519 T4 v4_; 520 public: 521 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 522 typedef typename result_of<Fp(T0, T1, T2, T3, T4)>::type result_type; 523 524 BOOST_SYMBOL_VISIBLE 525 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 526 , BOOST_THREAD_RV_REF(T0) a0 527 , BOOST_THREAD_RV_REF(T1) a1 528 , BOOST_THREAD_RV_REF(T2) a2 529 , BOOST_THREAD_RV_REF(T3) a3 530 , BOOST_THREAD_RV_REF(T4) a4 531 ) 532 : fp_(boost::move(f)) 533 , v0_(boost::move(a0)) 534 , v1_(boost::move(a1)) 535 , v2_(boost::move(a2)) 536 , v3_(boost::move(a3)) 537 , v4_(boost::move(a4)) 538 {} 539 540 BOOST_SYMBOL_VISIBLE 541 invoker(BOOST_THREAD_RV_REF(invoker) f) 542 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 543 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 544 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 545 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 546 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 547 , v4_(boost::move(BOOST_THREAD_RV(f).v4_)) 548 {} 549 550 result_type operator()() 551 { 552 return detail::invoke(boost::move(fp_) 553 , boost::move(v0_) 554 , boost::move(v1_) 555 , boost::move(v2_) 556 , boost::move(v3_) 557 , boost::move(v4_) 558 ); 559 } 560 }; 561 template <class Fp, class T0, class T1, class T2, class T3> 562 class invoker<Fp, T0, T1, T2, T3> 563 { 564 Fp fp_; 565 T0 v0_; 566 T1 v1_; 567 T2 v2_; 568 T3 v3_; 569 public: 570 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 571 typedef typename result_of<Fp(T0, T1, T2, T3)>::type result_type; 572 573 BOOST_SYMBOL_VISIBLE 574 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 575 , BOOST_THREAD_RV_REF(T0) a0 576 , BOOST_THREAD_RV_REF(T1) a1 577 , BOOST_THREAD_RV_REF(T2) a2 578 , BOOST_THREAD_RV_REF(T3) a3 579 ) 580 : fp_(boost::move(f)) 581 , v0_(boost::move(a0)) 582 , v1_(boost::move(a1)) 583 , v2_(boost::move(a2)) 584 , v3_(boost::move(a3)) 585 {} 586 587 BOOST_SYMBOL_VISIBLE 588 invoker(BOOST_THREAD_RV_REF(invoker) f) 589 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 590 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 591 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 592 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 593 , v3_(boost::move(BOOST_THREAD_RV(f).v3_)) 594 {} 595 596 result_type operator()() 597 { 598 return detail::invoke(boost::move(fp_) 599 , boost::move(v0_) 600 , boost::move(v1_) 601 , boost::move(v2_) 602 , boost::move(v3_) 603 ); 604 } 605 }; 606 template <class Fp, class T0, class T1, class T2> 607 class invoker<Fp, T0, T1, T2> 608 { 609 Fp fp_; 610 T0 v0_; 611 T1 v1_; 612 T2 v2_; 613 public: 614 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 615 typedef typename result_of<Fp(T0, T1, T2)>::type result_type; 616 617 BOOST_SYMBOL_VISIBLE 618 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 619 , BOOST_THREAD_RV_REF(T0) a0 620 , BOOST_THREAD_RV_REF(T1) a1 621 , BOOST_THREAD_RV_REF(T2) a2 622 ) 623 : fp_(boost::move(f)) 624 , v0_(boost::move(a0)) 625 , v1_(boost::move(a1)) 626 , v2_(boost::move(a2)) 627 {} 628 629 BOOST_SYMBOL_VISIBLE 630 invoker(BOOST_THREAD_RV_REF(invoker) f) 631 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 632 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 633 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 634 , v2_(boost::move(BOOST_THREAD_RV(f).v2_)) 635 {} 636 637 result_type operator()() 638 { 639 return detail::invoke(boost::move(fp_) 640 , boost::move(v0_) 641 , boost::move(v1_) 642 , boost::move(v2_) 643 ); 644 } 645 }; 646 template <class Fp, class T0, class T1> 647 class invoker<Fp, T0, T1> 648 { 649 Fp fp_; 650 T0 v0_; 651 T1 v1_; 652 public: 653 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 654 typedef typename result_of<Fp(T0, T1)>::type result_type; 655 656 BOOST_SYMBOL_VISIBLE 657 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 658 , BOOST_THREAD_RV_REF(T0) a0 659 , BOOST_THREAD_RV_REF(T1) a1 660 ) 661 : fp_(boost::move(f)) 662 , v0_(boost::move(a0)) 663 , v1_(boost::move(a1)) 664 {} 665 666 BOOST_SYMBOL_VISIBLE 667 invoker(BOOST_THREAD_RV_REF(invoker) f) 668 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 669 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 670 , v1_(boost::move(BOOST_THREAD_RV(f).v1_)) 671 {} 672 673 result_type operator()() 674 { 675 return detail::invoke(boost::move(fp_) 676 , boost::move(v0_) 677 , boost::move(v1_) 678 ); 679 } 680 }; 681 template <class Fp, class T0> 682 class invoker<Fp, T0> 683 { 684 Fp fp_; 685 T0 v0_; 686 public: 687 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 688 typedef typename result_of<Fp(T0)>::type result_type; 689 690 BOOST_SYMBOL_VISIBLE 691 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f 692 , BOOST_THREAD_RV_REF(T0) a0 693 ) 694 : fp_(boost::move(f)) 695 , v0_(boost::move(a0)) 696 {} 697 698 BOOST_SYMBOL_VISIBLE 699 invoker(BOOST_THREAD_RV_REF(invoker) f) 700 : fp_(boost::move(BOOST_THREAD_RV(f).fp)) 701 , v0_(boost::move(BOOST_THREAD_RV(f).v0_)) 702 {} 703 704 result_type operator()() 705 { 706 return detail::invoke(boost::move(fp_) 707 , boost::move(v0_) 708 ); 709 } 710 }; 711 template <class Fp> 712 class invoker<Fp> 713 { 714 Fp fp_; 715 public: 716 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 717 typedef typename result_of<Fp()>::type result_type; 718 BOOST_SYMBOL_VISIBLE 719 explicit invoker(BOOST_THREAD_FWD_REF(Fp) f) 720 : fp_(boost::move(f)) 721 {} 722 723 BOOST_SYMBOL_VISIBLE 724 invoker(BOOST_THREAD_RV_REF(invoker) f) 725 : fp_(boost::move(f.fp_)) 726 {} 727 result_type operator()() 728 { 729 return fp_(); 730 } 731 }; 732 template <class R> 733 class invoker<R(*)()> 734 { 735 typedef R(*Fp)(); 736 Fp fp_; 737 public: 738 BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) 739 typedef typename result_of<Fp()>::type result_type; 740 BOOST_SYMBOL_VISIBLE 741 explicit invoker(Fp f) 742 : fp_(f) 743 {} 744 745 BOOST_SYMBOL_VISIBLE 746 invoker(BOOST_THREAD_RV_REF(invoker) f) 747 : fp_(f.fp_) 748 {} 749 result_type operator()() 750 { 751 return fp_(); 752 } 753 }; 754 #endif 755 #endif 756 757 } 758 } 759 760 #include <boost/thread/detail/variadic_footer.hpp> 761 762 #endif // header 763