async_func.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  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. // 2013/04 Vicente J. Botet Escriba
  6. // Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
  7. // Make use of Boost.Move
  8. // Make use of Boost.Tuple (movable)
  9. // 2012/11 Vicente J. Botet Escriba
  10. // Adapt to boost libc++ implementation
  11. //===----------------------------------------------------------------------===//
  12. //
  13. // The LLVM Compiler Infrastructure
  14. //
  15. // This file is dual licensed under the MIT and the University of Illinois Open
  16. // Source Licenses. See LICENSE.TXT for details.
  17. //
  18. // The async_func code is based on the one from libcxx.
  19. //===----------------------------------------------------------------------===//
  20. #ifndef BOOST_THREAD_DETAIL_ASYNC_FUNCT_HPP
  21. #define BOOST_THREAD_DETAIL_ASYNC_FUNCT_HPP
  22. #include <boost/config.hpp>
  23. #include <boost/utility/result_of.hpp>
  24. #include <boost/thread/detail/move.hpp>
  25. #include <boost/thread/detail/invoke.hpp>
  26. #include <boost/thread/detail/make_tuple_indices.hpp>
  27. #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
  28. ! defined(BOOST_NO_CXX11_HDR_TUPLE)
  29. #include <tuple>
  30. #else
  31. #include <boost/tuple/tuple.hpp>
  32. #endif
  33. namespace boost
  34. {
  35. namespace detail
  36. {
  37. #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
  38. ! defined(BOOST_NO_CXX11_HDR_TUPLE)
  39. template <class Fp, class ... Args>
  40. class async_func
  41. {
  42. std::tuple<Fp, Args...> f_;
  43. public:
  44. BOOST_THREAD_MOVABLE_ONLY( async_func)
  45. //typedef typename invoke_of<_Fp, _Args...>::type Rp;
  46. typedef typename result_of<Fp(Args...)>::type result_type;
  47. BOOST_SYMBOL_VISIBLE
  48. explicit async_func(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args)... args)
  49. : f_(boost::move(f), boost::move(args)...)
  50. {}
  51. BOOST_SYMBOL_VISIBLE
  52. async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_))
  53. {}
  54. result_type operator()()
  55. {
  56. typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index;
  57. return execute(Index());
  58. }
  59. private:
  60. template <size_t ...Indices>
  61. result_type
  62. execute(tuple_indices<Indices...>)
  63. {
  64. return invoke(boost::move(std::get<0>(f_)), boost::move(std::get<Indices>(f_))...);
  65. }
  66. };
  67. //BOOST_THREAD_DCL_MOVABLE_BEG(X) async_func<Fp> BOOST_THREAD_DCL_MOVABLE_END
  68. #else
  69. template <class Fp,
  70. class T0 = tuples::null_type, class T1 = tuples::null_type, class T2 = tuples::null_type,
  71. class T3 = tuples::null_type, class T4 = tuples::null_type, class T5 = tuples::null_type,
  72. class T6 = tuples::null_type, class T7 = tuples::null_type, class T8 = tuples::null_type
  73. , class T9 = tuples::null_type
  74. >
  75. class async_func;
  76. template <class Fp,
  77. class T0 , class T1 , class T2 ,
  78. class T3 , class T4 , class T5 ,
  79. class T6 , class T7 , class T8 >
  80. class async_func<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8>
  81. {
  82. Fp fp_;
  83. T0 v0_;
  84. T1 v1_;
  85. T2 v2_;
  86. T3 v3_;
  87. T4 v4_;
  88. T5 v5_;
  89. T6 v6_;
  90. T7 v7_;
  91. T8 v8_;
  92. //::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> f_;
  93. public:
  94. BOOST_THREAD_MOVABLE_ONLY(async_func)
  95. typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7, T8)>::type result_type;
  96. BOOST_SYMBOL_VISIBLE
  97. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  98. , BOOST_THREAD_RV_REF(T0) a0
  99. , BOOST_THREAD_RV_REF(T1) a1
  100. , BOOST_THREAD_RV_REF(T2) a2
  101. , BOOST_THREAD_RV_REF(T3) a3
  102. , BOOST_THREAD_RV_REF(T4) a4
  103. , BOOST_THREAD_RV_REF(T5) a5
  104. , BOOST_THREAD_RV_REF(T6) a6
  105. , BOOST_THREAD_RV_REF(T7) a7
  106. , BOOST_THREAD_RV_REF(T8) a8
  107. )
  108. : fp_(boost::move(f))
  109. , v0_(boost::move(a0))
  110. , v1_(boost::move(a1))
  111. , v2_(boost::move(a2))
  112. , v3_(boost::move(a3))
  113. , v4_(boost::move(a4))
  114. , v5_(boost::move(a5))
  115. , v6_(boost::move(a6))
  116. , v7_(boost::move(a7))
  117. , v8_(boost::move(a8))
  118. {}
  119. BOOST_SYMBOL_VISIBLE
  120. async_func(BOOST_THREAD_RV_REF(async_func) f)
  121. : fp_(boost::move(f.fp))
  122. , v0_(boost::move(f.a0))
  123. , v1_(boost::move(f.a1))
  124. , v2_(boost::move(f.a2))
  125. , v3_(boost::move(f.a3))
  126. , v4_(boost::move(f.a4))
  127. , v5_(boost::move(f.a5))
  128. , v6_(boost::move(f.a6))
  129. , v7_(boost::move(f.a7))
  130. , v8_(boost::move(f.a8))
  131. {}
  132. result_type operator()()
  133. {
  134. return invoke(boost::move(fp_)
  135. , boost::move(v0_)
  136. , boost::move(v1_)
  137. , boost::move(v2_)
  138. , boost::move(v3_)
  139. , boost::move(v4_)
  140. , boost::move(v5_)
  141. , boost::move(v6_)
  142. , boost::move(v7_)
  143. , boost::move(v8_)
  144. );
  145. }
  146. };
  147. template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7 >
  148. class async_func<Fp, T0, T1, T2, T3, T4, T5, T6, T7>
  149. {
  150. Fp fp_;
  151. T0 v0_;
  152. T1 v1_;
  153. T2 v2_;
  154. T3 v3_;
  155. T4 v4_;
  156. T5 v5_;
  157. T6 v6_;
  158. T7 v7_;
  159. public:
  160. BOOST_THREAD_MOVABLE_ONLY(async_func)
  161. typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7)>::type result_type;
  162. BOOST_SYMBOL_VISIBLE
  163. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  164. , BOOST_THREAD_RV_REF(T0) a0
  165. , BOOST_THREAD_RV_REF(T1) a1
  166. , BOOST_THREAD_RV_REF(T2) a2
  167. , BOOST_THREAD_RV_REF(T3) a3
  168. , BOOST_THREAD_RV_REF(T4) a4
  169. , BOOST_THREAD_RV_REF(T5) a5
  170. , BOOST_THREAD_RV_REF(T6) a6
  171. , BOOST_THREAD_RV_REF(T7) a7
  172. )
  173. : fp_(boost::move(f))
  174. , v0_(boost::move(a0))
  175. , v1_(boost::move(a1))
  176. , v2_(boost::move(a2))
  177. , v3_(boost::move(a3))
  178. , v4_(boost::move(a4))
  179. , v5_(boost::move(a5))
  180. , v6_(boost::move(a6))
  181. , v7_(boost::move(a7))
  182. {}
  183. BOOST_SYMBOL_VISIBLE
  184. async_func(BOOST_THREAD_RV_REF(async_func) f)
  185. : fp_(boost::move(f.fp))
  186. , v0_(boost::move(f.a0))
  187. , v1_(boost::move(f.a1))
  188. , v2_(boost::move(f.a2))
  189. , v3_(boost::move(f.a3))
  190. , v4_(boost::move(f.a4))
  191. , v5_(boost::move(f.a5))
  192. , v6_(boost::move(f.a6))
  193. , v7_(boost::move(f.a7))
  194. {}
  195. result_type operator()()
  196. {
  197. return invoke(boost::move(fp_)
  198. , boost::move(v0_)
  199. , boost::move(v1_)
  200. , boost::move(v2_)
  201. , boost::move(v3_)
  202. , boost::move(v4_)
  203. , boost::move(v5_)
  204. , boost::move(v6_)
  205. , boost::move(v7_)
  206. );
  207. }
  208. };
  209. template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6>
  210. class async_func<Fp, T0, T1, T2, T3, T4, T5, T6>
  211. {
  212. Fp fp_;
  213. T0 v0_;
  214. T1 v1_;
  215. T2 v2_;
  216. T3 v3_;
  217. T4 v4_;
  218. T5 v5_;
  219. T6 v6_;
  220. public:
  221. BOOST_THREAD_MOVABLE_ONLY(async_func)
  222. typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6)>::type result_type;
  223. BOOST_SYMBOL_VISIBLE
  224. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  225. , BOOST_THREAD_RV_REF(T0) a0
  226. , BOOST_THREAD_RV_REF(T1) a1
  227. , BOOST_THREAD_RV_REF(T2) a2
  228. , BOOST_THREAD_RV_REF(T3) a3
  229. , BOOST_THREAD_RV_REF(T4) a4
  230. , BOOST_THREAD_RV_REF(T5) a5
  231. , BOOST_THREAD_RV_REF(T6) a6
  232. )
  233. : fp_(boost::move(f))
  234. , v0_(boost::move(a0))
  235. , v1_(boost::move(a1))
  236. , v2_(boost::move(a2))
  237. , v3_(boost::move(a3))
  238. , v4_(boost::move(a4))
  239. , v5_(boost::move(a5))
  240. , v6_(boost::move(a6))
  241. {}
  242. BOOST_SYMBOL_VISIBLE
  243. async_func(BOOST_THREAD_RV_REF(async_func) f)
  244. : fp_(boost::move(f.fp))
  245. , v0_(boost::move(f.a0))
  246. , v1_(boost::move(f.a1))
  247. , v2_(boost::move(f.a2))
  248. , v3_(boost::move(f.a3))
  249. , v4_(boost::move(f.a4))
  250. , v5_(boost::move(f.a5))
  251. , v6_(boost::move(f.a6))
  252. {}
  253. result_type operator()()
  254. {
  255. return invoke(boost::move(fp_)
  256. , boost::move(v0_)
  257. , boost::move(v1_)
  258. , boost::move(v2_)
  259. , boost::move(v3_)
  260. , boost::move(v4_)
  261. , boost::move(v5_)
  262. , boost::move(v6_)
  263. );
  264. }
  265. };
  266. template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5>
  267. class async_func<Fp, T0, T1, T2, T3, T4, T5>
  268. {
  269. Fp fp_;
  270. T0 v0_;
  271. T1 v1_;
  272. T2 v2_;
  273. T3 v3_;
  274. T4 v4_;
  275. T5 v5_;
  276. public:
  277. BOOST_THREAD_MOVABLE_ONLY(async_func)
  278. typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5)>::type result_type;
  279. BOOST_SYMBOL_VISIBLE
  280. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  281. , BOOST_THREAD_RV_REF(T0) a0
  282. , BOOST_THREAD_RV_REF(T1) a1
  283. , BOOST_THREAD_RV_REF(T2) a2
  284. , BOOST_THREAD_RV_REF(T3) a3
  285. , BOOST_THREAD_RV_REF(T4) a4
  286. , BOOST_THREAD_RV_REF(T5) a5
  287. )
  288. : fp_(boost::move(f))
  289. , v0_(boost::move(a0))
  290. , v1_(boost::move(a1))
  291. , v2_(boost::move(a2))
  292. , v3_(boost::move(a3))
  293. , v4_(boost::move(a4))
  294. , v5_(boost::move(a5))
  295. {}
  296. BOOST_SYMBOL_VISIBLE
  297. async_func(BOOST_THREAD_RV_REF(async_func) f)
  298. : fp_(boost::move(f.fp))
  299. , v0_(boost::move(f.a0))
  300. , v1_(boost::move(f.a1))
  301. , v2_(boost::move(f.a2))
  302. , v3_(boost::move(f.a3))
  303. , v4_(boost::move(f.a4))
  304. , v5_(boost::move(f.a5))
  305. {}
  306. result_type operator()()
  307. {
  308. return invoke(boost::move(fp_)
  309. , boost::move(v0_)
  310. , boost::move(v1_)
  311. , boost::move(v2_)
  312. , boost::move(v3_)
  313. , boost::move(v4_)
  314. , boost::move(v5_)
  315. );
  316. }
  317. };
  318. template <class Fp, class T0, class T1, class T2, class T3, class T4>
  319. class async_func<Fp, T0, T1, T2, T3, T4>
  320. {
  321. Fp fp_;
  322. T0 v0_;
  323. T1 v1_;
  324. T2 v2_;
  325. T3 v3_;
  326. T4 v4_;
  327. public:
  328. BOOST_THREAD_MOVABLE_ONLY(async_func)
  329. typedef typename result_of<Fp(T0, T1, T2, T3, T4)>::type result_type;
  330. BOOST_SYMBOL_VISIBLE
  331. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  332. , BOOST_THREAD_RV_REF(T0) a0
  333. , BOOST_THREAD_RV_REF(T1) a1
  334. , BOOST_THREAD_RV_REF(T2) a2
  335. , BOOST_THREAD_RV_REF(T3) a3
  336. , BOOST_THREAD_RV_REF(T4) a4
  337. )
  338. : fp_(boost::move(f))
  339. , v0_(boost::move(a0))
  340. , v1_(boost::move(a1))
  341. , v2_(boost::move(a2))
  342. , v3_(boost::move(a3))
  343. , v4_(boost::move(a4))
  344. {}
  345. BOOST_SYMBOL_VISIBLE
  346. async_func(BOOST_THREAD_RV_REF(async_func) f)
  347. : fp_(boost::move(f.fp))
  348. , v0_(boost::move(f.a0))
  349. , v1_(boost::move(f.a1))
  350. , v2_(boost::move(f.a2))
  351. , v3_(boost::move(f.a3))
  352. , v4_(boost::move(f.a4))
  353. {}
  354. result_type operator()()
  355. {
  356. return invoke(boost::move(fp_)
  357. , boost::move(v0_)
  358. , boost::move(v1_)
  359. , boost::move(v2_)
  360. , boost::move(v3_)
  361. , boost::move(v4_)
  362. );
  363. }
  364. };
  365. template <class Fp, class T0, class T1, class T2, class T3>
  366. class async_func<Fp, T0, T1, T2, T3>
  367. {
  368. Fp fp_;
  369. T0 v0_;
  370. T1 v1_;
  371. T2 v2_;
  372. T3 v3_;
  373. public:
  374. BOOST_THREAD_MOVABLE_ONLY(async_func)
  375. typedef typename result_of<Fp(T0, T1, T2, T3)>::type result_type;
  376. BOOST_SYMBOL_VISIBLE
  377. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  378. , BOOST_THREAD_RV_REF(T0) a0
  379. , BOOST_THREAD_RV_REF(T1) a1
  380. , BOOST_THREAD_RV_REF(T2) a2
  381. , BOOST_THREAD_RV_REF(T3) a3
  382. )
  383. : fp_(boost::move(f))
  384. , v0_(boost::move(a0))
  385. , v1_(boost::move(a1))
  386. , v2_(boost::move(a2))
  387. , v3_(boost::move(a3))
  388. {}
  389. BOOST_SYMBOL_VISIBLE
  390. async_func(BOOST_THREAD_RV_REF(async_func) f)
  391. : fp_(boost::move(f.fp))
  392. , v0_(boost::move(f.a0))
  393. , v1_(boost::move(f.a1))
  394. , v2_(boost::move(f.a2))
  395. , v3_(boost::move(f.a3))
  396. {}
  397. result_type operator()()
  398. {
  399. return invoke(boost::move(fp_)
  400. , boost::move(v0_)
  401. , boost::move(v1_)
  402. , boost::move(v2_)
  403. , boost::move(v3_)
  404. );
  405. }
  406. };
  407. template <class Fp, class T0, class T1, class T2>
  408. class async_func<Fp, T0, T1, T2>
  409. {
  410. Fp fp_;
  411. T0 v0_;
  412. T1 v1_;
  413. T2 v2_;
  414. public:
  415. BOOST_THREAD_MOVABLE_ONLY(async_func)
  416. typedef typename result_of<Fp(T0, T1, T2)>::type result_type;
  417. BOOST_SYMBOL_VISIBLE
  418. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  419. , BOOST_THREAD_RV_REF(T0) a0
  420. , BOOST_THREAD_RV_REF(T1) a1
  421. , BOOST_THREAD_RV_REF(T2) a2
  422. )
  423. : fp_(boost::move(f))
  424. , v0_(boost::move(a0))
  425. , v1_(boost::move(a1))
  426. , v2_(boost::move(a2))
  427. {}
  428. BOOST_SYMBOL_VISIBLE
  429. async_func(BOOST_THREAD_RV_REF(async_func) f)
  430. : fp_(boost::move(f.fp))
  431. , v0_(boost::move(f.a0))
  432. , v1_(boost::move(f.a1))
  433. , v2_(boost::move(f.a2))
  434. {}
  435. result_type operator()()
  436. {
  437. return invoke(boost::move(fp_)
  438. , boost::move(v0_)
  439. , boost::move(v1_)
  440. , boost::move(v2_)
  441. );
  442. }
  443. };
  444. template <class Fp, class T0, class T1>
  445. class async_func<Fp, T0, T1>
  446. {
  447. Fp fp_;
  448. T0 v0_;
  449. T1 v1_;
  450. public:
  451. BOOST_THREAD_MOVABLE_ONLY(async_func)
  452. typedef typename result_of<Fp(T0, T1)>::type result_type;
  453. BOOST_SYMBOL_VISIBLE
  454. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  455. , BOOST_THREAD_RV_REF(T0) a0
  456. , BOOST_THREAD_RV_REF(T1) a1
  457. )
  458. : fp_(boost::move(f))
  459. , v0_(boost::move(a0))
  460. , v1_(boost::move(a1))
  461. {}
  462. BOOST_SYMBOL_VISIBLE
  463. async_func(BOOST_THREAD_RV_REF(async_func) f)
  464. : fp_(boost::move(f.fp))
  465. , v0_(boost::move(f.a0))
  466. , v1_(boost::move(f.a1))
  467. {}
  468. result_type operator()()
  469. {
  470. return invoke(boost::move(fp_)
  471. , boost::move(v0_)
  472. , boost::move(v1_)
  473. );
  474. }
  475. };
  476. template <class Fp, class T0>
  477. class async_func<Fp, T0>
  478. {
  479. Fp fp_;
  480. T0 v0_;
  481. public:
  482. BOOST_THREAD_MOVABLE_ONLY(async_func)
  483. typedef typename result_of<Fp(T0)>::type result_type;
  484. BOOST_SYMBOL_VISIBLE
  485. explicit async_func(BOOST_THREAD_RV_REF(Fp) f
  486. , BOOST_THREAD_RV_REF(T0) a0
  487. )
  488. : fp_(boost::move(f))
  489. , v0_(boost::move(a0))
  490. {}
  491. BOOST_SYMBOL_VISIBLE
  492. async_func(BOOST_THREAD_RV_REF(async_func) f)
  493. : fp_(boost::move(f.fp))
  494. , v0_(boost::move(f.a0))
  495. {}
  496. result_type operator()()
  497. {
  498. return invoke(boost::move(fp_)
  499. , boost::move(v0_)
  500. );
  501. }
  502. };
  503. template <class Fp>
  504. class async_func<Fp>
  505. {
  506. Fp fp_;
  507. public:
  508. BOOST_THREAD_COPYABLE_AND_MOVABLE(async_func)
  509. typedef typename result_of<Fp()>::type result_type;
  510. BOOST_SYMBOL_VISIBLE
  511. explicit async_func(BOOST_THREAD_FWD_REF(Fp) f)
  512. : fp_(boost::move(f))
  513. {}
  514. BOOST_SYMBOL_VISIBLE
  515. async_func(BOOST_THREAD_FWD_REF(async_func) f)
  516. : fp_(boost::move(f.fp_))
  517. {}
  518. result_type operator()()
  519. {
  520. return fp_();
  521. }
  522. };
  523. #endif
  524. }
  525. }
  526. #endif // header