compose.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. // Copyright Rene Rivera 2006.
  2. // Copyright Cromwell D. Enage 2017.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/parameter/nested_keyword.hpp>
  7. #include <boost/parameter/name.hpp>
  8. #include <boost/parameter/config.hpp>
  9. namespace param {
  10. BOOST_PARAMETER_NESTED_KEYWORD(tag, a0, a_zero)
  11. BOOST_PARAMETER_NESTED_KEYWORD(tag, a1, a_one)
  12. BOOST_PARAMETER_NAME(a2)
  13. BOOST_PARAMETER_NAME(a3)
  14. BOOST_PARAMETER_NAME(in(lrc))
  15. BOOST_PARAMETER_NAME(out(lr))
  16. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  17. BOOST_PARAMETER_NAME(consume(rr))
  18. #else
  19. BOOST_PARAMETER_NAME(rr)
  20. #endif
  21. }
  22. #include <boost/parameter/is_argument_pack.hpp>
  23. #include <boost/mpl/void.hpp>
  24. #include <boost/mpl/bool.hpp>
  25. #include <boost/mpl/int.hpp>
  26. #include <boost/mpl/if.hpp>
  27. #include <boost/mpl/has_key.hpp>
  28. #include <boost/mpl/key_type.hpp>
  29. #include <boost/mpl/order.hpp>
  30. #include <boost/mpl/count.hpp>
  31. #include <boost/mpl/equal_to.hpp>
  32. #include <boost/mpl/assert.hpp>
  33. #include <boost/type_traits/is_same.hpp>
  34. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  35. #include <boost/mp11/list.hpp>
  36. #include <boost/mp11/map.hpp>
  37. #include <type_traits>
  38. #endif
  39. #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  40. #include <boost/function.hpp>
  41. #else
  42. #include <functional>
  43. #endif
  44. namespace test {
  45. struct A
  46. {
  47. int i;
  48. int j;
  49. template <typename ArgPack>
  50. A(ArgPack const& args) : i(args[param::a0]), j(args[param::a1])
  51. {
  52. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  53. static_assert(
  54. boost::mp11::mp_map_contains<ArgPack,param::tag::a0>::value
  55. , "param::tag::a0 must be in ArgPack"
  56. );
  57. static_assert(
  58. boost::mp11::mp_map_contains<ArgPack,param::tag::a1>::value
  59. , "param::tag::a1 must be in ArgPack"
  60. );
  61. static_assert(
  62. !boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
  63. , "param::tag::lrc must not be in ArgPack"
  64. );
  65. static_assert(
  66. !boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
  67. , "param::tag::lr must not be in ArgPack"
  68. );
  69. static_assert(
  70. !boost::mp11::mp_map_contains<ArgPack,param::tag::rr>::value
  71. , "param::tag::rr must not be in ArgPack"
  72. );
  73. static_assert(
  74. !std::is_same<
  75. ::boost::mp11::mp_map_find<ArgPack,param::tag::a0>
  76. , void
  77. >::value
  78. , "param::tag::a0 must be found in ArgPack"
  79. );
  80. static_assert(
  81. !std::is_same<
  82. ::boost::mp11::mp_map_find<ArgPack,param::tag::a1>
  83. , void
  84. >::value
  85. , "param::tag::a1 must be found in ArgPack"
  86. );
  87. static_assert(
  88. std::is_same<
  89. ::boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
  90. , void
  91. >::value
  92. , "param::tag::lrc must not be found in ArgPack"
  93. );
  94. static_assert(
  95. std::is_same<
  96. ::boost::mp11::mp_map_find<ArgPack,param::tag::lr>
  97. , void
  98. >::value
  99. , "param::tag::lr must not be found in ArgPack"
  100. );
  101. static_assert(
  102. std::is_same<
  103. ::boost::mp11::mp_map_find<ArgPack,param::tag::rr>
  104. , void
  105. >::value
  106. , "param::tag::rr must not be found in ArgPack"
  107. );
  108. #endif // BOOST_PARAMETER_CAN_USE_MP11
  109. BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
  110. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::a0>));
  111. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::a1>));
  112. BOOST_MPL_ASSERT_NOT((
  113. boost::mpl::has_key<ArgPack,param::tag::lrc>
  114. ));
  115. BOOST_MPL_ASSERT_NOT((
  116. boost::mpl::has_key<ArgPack,param::tag::lr>
  117. ));
  118. BOOST_MPL_ASSERT_NOT((
  119. boost::mpl::has_key<ArgPack,param::tag::rr>
  120. ));
  121. BOOST_MPL_ASSERT((
  122. boost::mpl::equal_to<
  123. typename boost::mpl::count<ArgPack,param::tag::a0>::type
  124. , boost::mpl::int_<1>
  125. >
  126. ));
  127. BOOST_MPL_ASSERT((
  128. boost::mpl::equal_to<
  129. typename boost::mpl::count<ArgPack,param::tag::a1>::type
  130. , boost::mpl::int_<1>
  131. >
  132. ));
  133. BOOST_MPL_ASSERT((
  134. typename boost::mpl::if_<
  135. boost::is_same<
  136. typename boost::mpl
  137. ::key_type<ArgPack,param::tag::a0>::type
  138. , param::tag::a0
  139. >
  140. , boost::mpl::true_
  141. , boost::mpl::false_
  142. >::type
  143. ));
  144. BOOST_MPL_ASSERT((
  145. typename boost::mpl::if_<
  146. boost::is_same<
  147. typename boost::mpl
  148. ::key_type<ArgPack,param::tag::a1>::type
  149. , param::tag::a1
  150. >
  151. , boost::mpl::true_
  152. , boost::mpl::false_
  153. >::type
  154. ));
  155. BOOST_MPL_ASSERT((
  156. typename boost::mpl::if_<
  157. boost::is_same<
  158. typename boost::mpl
  159. ::order<ArgPack,param::tag::a0>::type
  160. , boost::mpl::void_
  161. >
  162. , boost::mpl::false_
  163. , boost::mpl::true_
  164. >::type
  165. ));
  166. BOOST_MPL_ASSERT((
  167. typename boost::mpl::if_<
  168. boost::is_same<
  169. typename boost::mpl
  170. ::order<ArgPack,param::tag::a1>::type
  171. , boost::mpl::void_
  172. >
  173. , boost::mpl::false_
  174. , boost::mpl::true_
  175. >::type
  176. ));
  177. }
  178. };
  179. float F()
  180. {
  181. return 4.0f;
  182. }
  183. float E()
  184. {
  185. return 4.625f;
  186. }
  187. double D()
  188. {
  189. return 198.9;
  190. }
  191. struct C
  192. {
  193. struct result_type
  194. {
  195. double operator()() const
  196. {
  197. return 2.5;
  198. }
  199. };
  200. result_type operator()() const
  201. {
  202. return result_type();
  203. }
  204. };
  205. struct B : A
  206. {
  207. #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  208. boost::function<float()> k;
  209. boost::function<double()> l;
  210. #else
  211. std::function<float()> k;
  212. std::function<double()> l;
  213. #endif
  214. template <typename ArgPack>
  215. B(ArgPack const& args)
  216. : A((args, param::tag::a0::a_zero = 1))
  217. , k(args[param::_a2 | E])
  218. , l(args[param::_a3 || C()])
  219. {
  220. }
  221. };
  222. struct G
  223. {
  224. int i;
  225. int& j;
  226. int const& k;
  227. template <typename ArgPack>
  228. G(ArgPack const& args)
  229. : i(args[param::_rr])
  230. , j(args[param::_lr])
  231. , k(args[param::_lrc])
  232. {
  233. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  234. static_assert(
  235. boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
  236. , "param::tag::lrc must be in ArgPack"
  237. );
  238. static_assert(
  239. boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
  240. , "param::tag::lr must be in ArgPack"
  241. );
  242. static_assert(
  243. boost::mp11::mp_map_contains<ArgPack,param::tag::rr>::value
  244. , "param::tag::rr must be in ArgPack"
  245. );
  246. static_assert(
  247. !boost::mp11::mp_map_contains<ArgPack,param::tag::a0>::value
  248. , "param::tag::a0 must not be in ArgPack"
  249. );
  250. static_assert(
  251. !boost::mp11::mp_map_contains<ArgPack,param::tag::a1>::value
  252. , "param::tag::a1 must not be in ArgPack"
  253. );
  254. static_assert(
  255. !boost::mp11::mp_map_contains<ArgPack,param::tag::a2>::value
  256. , "param::tag::a2 must not be in ArgPack"
  257. );
  258. static_assert(
  259. !boost::mp11::mp_map_contains<ArgPack,param::tag::a3>::value
  260. , "param::tag::a3 must not be in ArgPack"
  261. );
  262. static_assert(
  263. !std::is_same<
  264. boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
  265. , void
  266. >::value
  267. , "param::tag::lrc must be found in ArgPack"
  268. );
  269. static_assert(
  270. !std::is_same<
  271. boost::mp11::mp_map_find<ArgPack,param::tag::lr>
  272. , void
  273. >::value
  274. , "param::tag::lr must be found in ArgPack"
  275. );
  276. static_assert(
  277. !std::is_same<
  278. boost::mp11::mp_map_find<ArgPack,param::tag::rr>
  279. , void
  280. >::value
  281. , "param::tag::rr must be found in ArgPack"
  282. );
  283. static_assert(
  284. std::is_same<
  285. boost::mp11::mp_map_find<ArgPack,param::tag::a0>
  286. , void
  287. >::value
  288. , "param::tag::a0 must not be found in ArgPack"
  289. );
  290. static_assert(
  291. std::is_same<
  292. boost::mp11::mp_map_find<ArgPack,param::tag::a1>
  293. , void
  294. >::value
  295. , "param::tag::a1 must not be found in ArgPack"
  296. );
  297. static_assert(
  298. std::is_same<
  299. boost::mp11::mp_map_find<ArgPack,param::tag::a2>
  300. , void
  301. >::value
  302. , "param::tag::a2 must not be found in ArgPack"
  303. );
  304. static_assert(
  305. std::is_same<
  306. boost::mp11::mp_map_find<ArgPack,param::tag::a3>
  307. , void
  308. >::value
  309. , "param::tag::a3 must not be found in ArgPack"
  310. );
  311. #endif // BOOST_PARAMETER_CAN_USE_MP11
  312. BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
  313. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::rr>));
  314. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lr>));
  315. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lrc>));
  316. BOOST_MPL_ASSERT_NOT((
  317. boost::mpl::has_key<ArgPack,param::tag::a0>
  318. ));
  319. BOOST_MPL_ASSERT_NOT((
  320. boost::mpl::has_key<ArgPack,param::tag::a1>
  321. ));
  322. BOOST_MPL_ASSERT_NOT((
  323. boost::mpl::has_key<ArgPack,param::tag::a2>
  324. ));
  325. BOOST_MPL_ASSERT_NOT((
  326. boost::mpl::has_key<ArgPack,param::tag::a3>
  327. ));
  328. BOOST_MPL_ASSERT((
  329. boost::mpl::equal_to<
  330. typename boost::mpl::count<ArgPack,param::tag::rr>::type
  331. , boost::mpl::int_<1>
  332. >
  333. ));
  334. BOOST_MPL_ASSERT((
  335. boost::mpl::equal_to<
  336. typename boost::mpl::count<ArgPack,param::tag::lr>::type
  337. , boost::mpl::int_<1>
  338. >
  339. ));
  340. BOOST_MPL_ASSERT((
  341. boost::mpl::equal_to<
  342. typename boost::mpl::count<ArgPack,param::tag::lrc>::type
  343. , boost::mpl::int_<1>
  344. >
  345. ));
  346. BOOST_MPL_ASSERT((
  347. typename boost::mpl::if_<
  348. boost::is_same<
  349. typename boost::mpl
  350. ::key_type<ArgPack,param::tag::rr>::type
  351. , param::tag::rr
  352. >
  353. , boost::mpl::true_
  354. , boost::mpl::false_
  355. >::type
  356. ));
  357. BOOST_MPL_ASSERT((
  358. typename boost::mpl::if_<
  359. boost::is_same<
  360. typename boost::mpl
  361. ::key_type<ArgPack,param::tag::lr>::type
  362. , param::tag::lr
  363. >
  364. , boost::mpl::true_
  365. , boost::mpl::false_
  366. >::type
  367. ));
  368. BOOST_MPL_ASSERT((
  369. typename boost::mpl::if_<
  370. boost::is_same<
  371. typename boost::mpl
  372. ::key_type<ArgPack,param::tag::lrc>::type
  373. , param::tag::lrc
  374. >
  375. , boost::mpl::true_
  376. , boost::mpl::false_
  377. >::type
  378. ));
  379. BOOST_MPL_ASSERT((
  380. typename boost::mpl::if_<
  381. boost::is_same<
  382. typename boost::mpl
  383. ::order<ArgPack,param::tag::rr>::type
  384. , boost::mpl::void_
  385. >
  386. , boost::mpl::false_
  387. , boost::mpl::true_
  388. >::type
  389. ));
  390. BOOST_MPL_ASSERT((
  391. typename boost::mpl::if_<
  392. boost::is_same<
  393. typename boost::mpl
  394. ::order<ArgPack,param::tag::lr>::type
  395. , boost::mpl::void_
  396. >
  397. , boost::mpl::false_
  398. , boost::mpl::true_
  399. >::type
  400. ));
  401. BOOST_MPL_ASSERT((
  402. typename boost::mpl::if_<
  403. boost::is_same<
  404. typename boost::mpl
  405. ::order<ArgPack,param::tag::lrc>::type
  406. , boost::mpl::void_
  407. >
  408. , boost::mpl::false_
  409. , boost::mpl::true_
  410. >::type
  411. ));
  412. }
  413. };
  414. } // namespace test
  415. #include <utility>
  416. namespace test {
  417. std::pair<int,int> const& lvalue_const_pair()
  418. {
  419. static std::pair<int,int> const clp = std::pair<int,int>(7, 10);
  420. return clp;
  421. }
  422. struct H
  423. {
  424. std::pair<int,int> i;
  425. std::pair<int,int>& j;
  426. std::pair<int,int> const& k;
  427. template <typename ArgPack>
  428. H(ArgPack const& args)
  429. : i(args[param::_rr | test::lvalue_const_pair()])
  430. , j(args[param::_lr])
  431. , k(args[param::_lrc])
  432. {
  433. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  434. static_assert(
  435. boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
  436. , "param::tag::lrc must be in ArgPack"
  437. );
  438. static_assert(
  439. boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
  440. , "param::tag::lr must be in ArgPack"
  441. );
  442. static_assert(
  443. !std::is_same<
  444. boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
  445. , void
  446. >::value
  447. , "param::tag::lrc must be found in ArgPack"
  448. );
  449. static_assert(
  450. !std::is_same<
  451. boost::mp11::mp_map_find<ArgPack,param::tag::lr>
  452. , void
  453. >::value
  454. , "param::tag::lr must be found in ArgPack"
  455. );
  456. #endif // BOOST_PARAMETER_CAN_USE_MP11
  457. BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
  458. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lr>));
  459. BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lrc>));
  460. BOOST_MPL_ASSERT((
  461. boost::mpl::equal_to<
  462. typename boost::mpl::count<ArgPack,param::tag::lr>::type
  463. , boost::mpl::int_<1>
  464. >
  465. ));
  466. BOOST_MPL_ASSERT((
  467. boost::mpl::equal_to<
  468. typename boost::mpl::count<ArgPack,param::tag::lrc>::type
  469. , boost::mpl::int_<1>
  470. >
  471. ));
  472. BOOST_MPL_ASSERT((
  473. typename boost::mpl::if_<
  474. boost::is_same<
  475. typename boost::mpl
  476. ::key_type<ArgPack,param::tag::lr>::type
  477. , param::tag::lr
  478. >
  479. , boost::mpl::true_
  480. , boost::mpl::false_
  481. >::type
  482. ));
  483. BOOST_MPL_ASSERT((
  484. typename boost::mpl::if_<
  485. boost::is_same<
  486. typename boost::mpl
  487. ::key_type<ArgPack,param::tag::lrc>::type
  488. , param::tag::lrc
  489. >
  490. , boost::mpl::true_
  491. , boost::mpl::false_
  492. >::type
  493. ));
  494. BOOST_MPL_ASSERT((
  495. typename boost::mpl::if_<
  496. boost::is_same<
  497. typename boost::mpl
  498. ::order<ArgPack,param::tag::lr>::type
  499. , boost::mpl::void_
  500. >
  501. , boost::mpl::false_
  502. , boost::mpl::true_
  503. >::type
  504. ));
  505. BOOST_MPL_ASSERT((
  506. typename boost::mpl::if_<
  507. boost::is_same<
  508. typename boost::mpl
  509. ::order<ArgPack,param::tag::lrc>::type
  510. , boost::mpl::void_
  511. >
  512. , boost::mpl::false_
  513. , boost::mpl::true_
  514. >::type
  515. ));
  516. }
  517. };
  518. } // namespace test
  519. #include <boost/core/lightweight_test.hpp>
  520. void test_compose0()
  521. {
  522. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  523. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  524. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  525. // MSVC 11.0 on AppVeyor fails without this workaround.
  526. test::A a((
  527. param::a0 = 1
  528. , param::a1 = 13
  529. , param::_a2 = std::function<double()>(test::D)
  530. ));
  531. #else
  532. test::A a((param::a0 = 1, param::a1 = 13, param::_a2 = test::D));
  533. #endif
  534. BOOST_TEST_EQ(1, a.i);
  535. BOOST_TEST_EQ(13, a.j);
  536. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  537. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  538. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  539. // MSVC 11.0 on AppVeyor fails without this workaround.
  540. test::B b0((
  541. param::tag::a1::a_one = 13
  542. , param::_a2 = std::function<float()>(test::F)
  543. ));
  544. #else
  545. test::B b0((param::tag::a1::a_one = 13, param::_a2 = test::F));
  546. #endif
  547. BOOST_TEST_EQ(1, b0.i);
  548. BOOST_TEST_EQ(13, b0.j);
  549. BOOST_TEST_EQ(4.0f, b0.k());
  550. BOOST_TEST_EQ(2.5, b0.l());
  551. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  552. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  553. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  554. // MSVC 11.0 on AppVeyor fails without this workaround.
  555. test::B b1((
  556. param::_a3 = std::function<double()>(test::D)
  557. , param::a1 = 13
  558. ));
  559. #else
  560. test::B b1((param::_a3 = test::D, param::a1 = 13));
  561. #endif
  562. BOOST_TEST_EQ(1, b1.i);
  563. BOOST_TEST_EQ(13, b1.j);
  564. BOOST_TEST_EQ(4.625f, b1.k());
  565. BOOST_TEST_EQ(198.9, b1.l());
  566. int x = 23;
  567. int const y = 42;
  568. #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_0)
  569. test::G g((param::_lr = 15, param::_rr = 16, param::_lrc = y));
  570. #else
  571. test::G g((param::_lr = x, param::_rr = 16, param::_lrc = y));
  572. #endif
  573. BOOST_TEST_EQ(16, g.i);
  574. BOOST_TEST_EQ(23, g.j);
  575. BOOST_TEST_EQ(42, g.k);
  576. x = 1;
  577. BOOST_TEST_EQ(1, g.j);
  578. std::pair<int,int> p1(8, 9);
  579. std::pair<int,int> const p2(11, 12);
  580. test::H h0((param::_lr = p1, param::_lrc = p2));
  581. #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_1)
  582. test::H h1((
  583. param::_lr = p2
  584. , param::_rr = std::make_pair(7, 10)
  585. , param::_lrc = p2
  586. ));
  587. #else
  588. test::H h1((
  589. param::_lr = p1
  590. , param::_rr = std::make_pair(7, 10)
  591. , param::_lrc = p2
  592. ));
  593. #endif
  594. BOOST_TEST_EQ(h0.i.first, h1.i.first);
  595. BOOST_TEST_EQ(h0.i.second, h1.i.second);
  596. BOOST_TEST_EQ(p1.first, h1.j.first);
  597. BOOST_TEST_EQ(p1.second, h1.j.second);
  598. BOOST_TEST_EQ(p2.first, h1.k.first);
  599. BOOST_TEST_EQ(p2.second, h1.k.second);
  600. p1.first = 1;
  601. BOOST_TEST_EQ(p1.first, h1.j.first);
  602. }
  603. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) || \
  604. (2 < BOOST_PARAMETER_COMPOSE_MAX_ARITY)
  605. #include <boost/parameter/compose.hpp>
  606. void test_compose1()
  607. {
  608. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  609. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  610. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  611. // MSVC 11.0 on AppVeyor fails without this workaround.
  612. test::A a(boost::parameter::compose(
  613. param::a0 = 1
  614. , param::a1 = 13
  615. , param::_a2 = std::function<double()>(test::D)
  616. ));
  617. #else
  618. test::A a(boost::parameter::compose(
  619. param::a0 = 1
  620. , param::a1 = 13
  621. , param::_a2 = test::D
  622. ));
  623. #endif
  624. BOOST_TEST_EQ(1, a.i);
  625. BOOST_TEST_EQ(13, a.j);
  626. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  627. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  628. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  629. // MSVC 11.0 on AppVeyor fails without this workaround.
  630. test::B b0(boost::parameter::compose(
  631. param::tag::a1::a_one = 13
  632. , param::_a2 = std::function<float()>(test::F)
  633. ));
  634. #else
  635. test::B b0(boost::parameter::compose(
  636. param::tag::a1::a_one = 13
  637. , param::_a2 = test::F
  638. ));
  639. #endif
  640. BOOST_TEST_EQ(1, b0.i);
  641. BOOST_TEST_EQ(13, b0.j);
  642. BOOST_TEST_EQ(4.0f, b0.k());
  643. BOOST_TEST_EQ(2.5, b0.l());
  644. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  645. BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
  646. BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  647. // MSVC 11.0 on AppVeyor fails without this workaround.
  648. test::B b1(boost::parameter::compose(
  649. param::_a3 = std::function<double()>(test::D)
  650. , param::a1 = 13
  651. ));
  652. #else
  653. test::B b1(boost::parameter::compose(
  654. param::_a3 = test::D
  655. , param::a1 = 13
  656. ));
  657. #endif
  658. BOOST_TEST_EQ(1, b1.i);
  659. BOOST_TEST_EQ(13, b1.j);
  660. BOOST_TEST_EQ(4.625f, b1.k());
  661. BOOST_TEST_EQ(198.9, b1.l());
  662. int x = 23;
  663. int const y = 42;
  664. #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_0)
  665. test::G g(boost::parameter::compose(
  666. param::_lr = 15
  667. , param::_rr = 16
  668. , param::_lrc = y
  669. ));
  670. #else
  671. test::G g(boost::parameter::compose(
  672. param::_lr = x
  673. , param::_rr = 16
  674. , param::_lrc = y
  675. ));
  676. #endif
  677. BOOST_TEST_EQ(16, g.i);
  678. BOOST_TEST_EQ(23, g.j);
  679. BOOST_TEST_EQ(42, g.k);
  680. x = 1;
  681. BOOST_TEST_EQ(1, g.j);
  682. std::pair<int,int> p1(8, 9);
  683. std::pair<int,int> const p2(11, 12);
  684. test::H h0(boost::parameter::compose(param::_lr = p1, param::_lrc = p2));
  685. #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_1)
  686. test::H h1(boost::parameter::compose(
  687. param::_lr = p2
  688. , param::_rr = std::make_pair(7, 10)
  689. , param::_lrc = p2
  690. ));
  691. #else
  692. test::H h1(boost::parameter::compose(
  693. param::_lr = p1
  694. , param::_rr = std::make_pair(7, 10)
  695. , param::_lrc = p2
  696. ));
  697. #endif
  698. BOOST_TEST_EQ(h0.i.first, h1.i.first);
  699. BOOST_TEST_EQ(h0.i.second, h1.i.second);
  700. BOOST_TEST_EQ(p1.first, h1.j.first);
  701. BOOST_TEST_EQ(p1.second, h1.j.second);
  702. BOOST_TEST_EQ(p2.first, h1.k.first);
  703. BOOST_TEST_EQ(p2.second, h1.k.second);
  704. p1.first = 1;
  705. BOOST_TEST_EQ(p1.first, h1.j.first);
  706. }
  707. #endif // can invoke boost::parameter::compose
  708. int main()
  709. {
  710. test_compose0();
  711. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) || \
  712. (2 < BOOST_PARAMETER_COMPOSE_MAX_ARITY)
  713. test_compose1();
  714. #endif
  715. return boost::report_errors();
  716. }