preprocessor_eval_category.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. // Copyright Cromwell D. Enage 2017.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/parameter/config.hpp>
  6. #if (BOOST_PARAMETER_MAX_ARITY < 4)
  7. #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater.
  8. #endif
  9. #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \
  10. (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5)
  11. #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \
  12. as 5 or greater.
  13. #endif
  14. #include <boost/parameter/name.hpp>
  15. namespace test {
  16. BOOST_PARAMETER_NAME((_lrc0, kw) in(lrc0))
  17. BOOST_PARAMETER_NAME((_lr0, kw) in_out(lr0))
  18. BOOST_PARAMETER_NAME((_rrc0, kw) in(rrc0))
  19. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  20. BOOST_PARAMETER_NAME((_rr0, kw) consume(rr0))
  21. #else
  22. BOOST_PARAMETER_NAME((_rr0, kw) rr0)
  23. #endif
  24. } // namespace test
  25. #include <boost/parameter/preprocessor.hpp>
  26. #include <boost/parameter/value_type.hpp>
  27. #include <boost/core/lightweight_test.hpp>
  28. #include <boost/type_traits/is_scalar.hpp>
  29. #include <boost/type_traits/remove_const.hpp>
  30. #include <boost/type_traits/remove_reference.hpp>
  31. #include "evaluate_category.hpp"
  32. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  33. #include <utility>
  34. #endif
  35. namespace test {
  36. BOOST_PARAMETER_FUNCTION((bool), evaluate, kw,
  37. (required
  38. (lrc0, *)
  39. (lr0, *)
  40. (rrc0, *)
  41. (rr0, *)
  42. )
  43. )
  44. {
  45. BOOST_TEST((
  46. test::passed_by_lvalue_reference_to_const == test::A<
  47. typename boost::remove_const<
  48. typename boost::parameter::value_type<
  49. Args
  50. , test::kw::lrc0
  51. >::type
  52. >::type
  53. >::evaluate_category(args[test::_lrc0])
  54. ));
  55. BOOST_TEST_EQ(
  56. test::passed_by_lvalue_reference_to_const
  57. , test::A<
  58. typename boost::remove_const<
  59. typename boost::remove_reference<lrc0_type>::type
  60. >::type
  61. >::evaluate_category(lrc0)
  62. );
  63. BOOST_TEST((
  64. test::passed_by_lvalue_reference == test::A<
  65. typename boost::remove_const<
  66. typename boost::parameter::value_type<
  67. Args
  68. , test::kw::lr0
  69. >::type
  70. >::type
  71. >::evaluate_category(args[test::_lr0])
  72. ));
  73. BOOST_TEST_EQ(
  74. test::passed_by_lvalue_reference
  75. , test::A<
  76. typename boost::remove_const<
  77. typename boost::remove_reference<lr0_type>::type
  78. >::type
  79. >::evaluate_category(lr0)
  80. );
  81. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  82. if (
  83. boost::is_scalar<
  84. typename boost::remove_const<
  85. typename boost::remove_reference<rrc0_type>::type
  86. >::type
  87. >::value
  88. )
  89. {
  90. BOOST_TEST((
  91. test::passed_by_lvalue_reference_to_const == test::A<
  92. typename boost::remove_const<
  93. typename boost::parameter::value_type<
  94. Args
  95. , test::kw::rrc0
  96. >::type
  97. >::type
  98. >::evaluate_category(args[test::_rrc0])
  99. ));
  100. BOOST_TEST_EQ(
  101. test::passed_by_lvalue_reference_to_const
  102. , test::A<
  103. typename boost::remove_const<
  104. typename boost::remove_reference<rrc0_type>::type
  105. >::type
  106. >::evaluate_category(std::forward<rrc0_type>(rrc0))
  107. );
  108. BOOST_TEST((
  109. test::passed_by_lvalue_reference_to_const == test::A<
  110. typename boost::remove_const<
  111. typename boost::parameter::value_type<
  112. Args
  113. , test::kw::rr0
  114. >::type
  115. >::type
  116. >::evaluate_category(args[test::_rr0])
  117. ));
  118. BOOST_TEST_EQ(
  119. test::passed_by_lvalue_reference_to_const
  120. , test::A<
  121. typename boost::remove_const<
  122. typename boost::remove_reference<rr0_type>::type
  123. >::type
  124. >::evaluate_category(std::forward<rr0_type>(rr0))
  125. );
  126. }
  127. else // rrc0's value type isn't scalar
  128. {
  129. BOOST_TEST((
  130. test::passed_by_rvalue_reference_to_const == test::A<
  131. typename boost::remove_const<
  132. typename boost::parameter::value_type<
  133. Args
  134. , test::kw::rrc0
  135. >::type
  136. >::type
  137. >::evaluate_category(args[test::_rrc0])
  138. ));
  139. BOOST_TEST_EQ(
  140. test::passed_by_rvalue_reference_to_const
  141. , test::A<
  142. typename boost::remove_const<
  143. typename boost::remove_reference<rrc0_type>::type
  144. >::type
  145. >::evaluate_category(std::forward<rrc0_type>(rrc0))
  146. );
  147. BOOST_TEST((
  148. test::passed_by_rvalue_reference == test::A<
  149. typename boost::remove_const<
  150. typename boost::parameter::value_type<
  151. Args
  152. , test::kw::rr0
  153. >::type
  154. >::type
  155. >::evaluate_category(args[test::_rr0])
  156. ));
  157. BOOST_TEST_EQ(
  158. test::passed_by_rvalue_reference
  159. , test::A<
  160. typename boost::remove_const<
  161. typename boost::remove_reference<rr0_type>::type
  162. >::type
  163. >::evaluate_category(std::forward<rr0_type>(rr0))
  164. );
  165. }
  166. #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  167. BOOST_TEST((
  168. test::passed_by_lvalue_reference_to_const == test::A<
  169. typename boost::remove_const<
  170. typename boost::parameter::value_type<
  171. Args
  172. , test::kw::rrc0
  173. >::type
  174. >::type
  175. >::evaluate_category(args[test::_rrc0])
  176. ));
  177. BOOST_TEST_EQ(
  178. test::passed_by_lvalue_reference_to_const
  179. , test::A<
  180. typename boost::remove_const<
  181. typename boost::remove_reference<rrc0_type>::type
  182. >::type
  183. >::evaluate_category(rrc0)
  184. );
  185. BOOST_TEST((
  186. test::passed_by_lvalue_reference_to_const == test::A<
  187. typename boost::remove_const<
  188. typename boost::parameter::value_type<
  189. Args
  190. , test::kw::rr0
  191. >::type
  192. >::type
  193. >::evaluate_category(args[test::_rr0])
  194. ));
  195. BOOST_TEST_EQ(
  196. test::passed_by_lvalue_reference_to_const
  197. , test::A<
  198. typename boost::remove_const<
  199. typename boost::remove_reference<rr0_type>::type
  200. >::type
  201. >::evaluate_category(rr0)
  202. );
  203. #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
  204. return true;
  205. }
  206. } // namespace test
  207. #include <boost/mpl/bool.hpp>
  208. #include <boost/mpl/if.hpp>
  209. #if !defined(BOOST_NO_SFINAE)
  210. #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
  211. #include <boost/core/enable_if.hpp>
  212. #include <boost/type_traits/is_base_of.hpp>
  213. #endif
  214. namespace test {
  215. char const* baz = "baz";
  216. struct B
  217. {
  218. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  219. BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
  220. B()
  221. {
  222. }
  223. #endif
  224. template <typename Args>
  225. explicit B(
  226. Args const& args
  227. #if !defined(BOOST_NO_SFINAE)
  228. , typename boost::disable_if<
  229. typename boost::mpl::if_<
  230. boost::is_base_of<B,Args>
  231. , boost::mpl::true_
  232. , boost::mpl::false_
  233. >::type
  234. >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR
  235. #endif // BOOST_NO_SFINAE
  236. )
  237. {
  238. test::evaluate(
  239. args[test::_lrc0]
  240. , args[test::_lr0]
  241. , args[test::_rrc0]
  242. , args[test::_rr0]
  243. );
  244. }
  245. #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
  246. typedef test::string_predicate<test::kw::lr0> rr0_pred;
  247. BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
  248. (required
  249. (lrc0, (char))
  250. )
  251. (deduced
  252. (optional
  253. (rrc0, (float), 0.0f)
  254. (lr0, (char const*), test::baz)
  255. (rr0, *(rr0_pred), std::string(lr0))
  256. )
  257. )
  258. )
  259. #else // !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
  260. BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
  261. (required
  262. (lrc0, (char))
  263. )
  264. (deduced
  265. (optional
  266. (rrc0, (float), 0.0f)
  267. (lr0, (char const*), test::baz)
  268. (rr0
  269. , *(test::string_predicate<test::kw::lr0>)
  270. , std::string(lr0)
  271. )
  272. )
  273. )
  274. )
  275. #endif // SunPro CC workarounds needed.
  276. {
  277. BOOST_TEST((
  278. test::passed_by_lvalue_reference_to_const == test::A<
  279. typename boost::remove_const<
  280. typename boost::parameter::value_type<
  281. Args
  282. , test::kw::lrc0
  283. >::type
  284. >::type
  285. >::evaluate_category(args[test::_lrc0])
  286. ));
  287. BOOST_TEST_EQ(
  288. test::passed_by_lvalue_reference_to_const
  289. , test::A<
  290. typename boost::remove_const<
  291. typename boost::remove_reference<lrc0_type>::type
  292. >::type
  293. >::evaluate_category(lrc0)
  294. );
  295. BOOST_TEST((
  296. test::passed_by_lvalue_reference == test::A<
  297. typename boost::remove_const<
  298. typename boost::parameter::value_type<
  299. Args
  300. , test::kw::lr0
  301. >::type
  302. >::type
  303. >::evaluate_category(args[test::_lr0])
  304. ));
  305. BOOST_TEST_EQ(
  306. test::passed_by_lvalue_reference
  307. , test::A<
  308. typename boost::remove_const<
  309. typename boost::remove_reference<lr0_type>::type
  310. >::type
  311. >::evaluate_category(lr0)
  312. );
  313. BOOST_TEST((
  314. test::passed_by_lvalue_reference_to_const == test::A<
  315. typename boost::remove_const<
  316. typename boost::parameter::value_type<
  317. Args
  318. , test::kw::rrc0
  319. >::type
  320. >::type
  321. >::evaluate_category(args[test::_rrc0])
  322. ));
  323. BOOST_TEST_EQ(
  324. test::passed_by_lvalue_reference_to_const
  325. , test::A<
  326. typename boost::remove_const<
  327. typename boost::remove_reference<rrc0_type>::type
  328. >::type
  329. >::evaluate_category(rrc0)
  330. );
  331. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  332. BOOST_TEST((
  333. test::passed_by_rvalue_reference == test::A<
  334. typename boost::remove_const<
  335. typename boost::parameter::value_type<
  336. Args
  337. , test::kw::rr0
  338. >::type
  339. >::type
  340. >::evaluate_category(args[test::_rr0])
  341. ));
  342. BOOST_TEST_EQ(
  343. test::passed_by_rvalue_reference
  344. , test::A<
  345. typename boost::remove_const<
  346. typename boost::remove_reference<rr0_type>::type
  347. >::type
  348. >::evaluate_category(std::forward<rr0_type>(rr0))
  349. );
  350. #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  351. BOOST_TEST((
  352. test::passed_by_lvalue_reference_to_const == test::A<
  353. typename boost::remove_const<
  354. typename boost::parameter::value_type<
  355. Args
  356. , test::kw::rr0
  357. >::type
  358. >::type
  359. >::evaluate_category(args[test::_rr0])
  360. ));
  361. BOOST_TEST_EQ(
  362. test::passed_by_lvalue_reference_to_const
  363. , test::A<
  364. typename boost::remove_const<
  365. typename boost::remove_reference<rr0_type>::type
  366. >::type
  367. >::evaluate_category(rr0)
  368. );
  369. #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
  370. return true;
  371. }
  372. };
  373. struct C : B
  374. {
  375. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  376. BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
  377. C() : B()
  378. {
  379. }
  380. #endif
  381. BOOST_PARAMETER_CONSTRUCTOR(C, (B), kw,
  382. (required
  383. (lrc0, *)
  384. (lr0, *)
  385. (rrc0, *)
  386. (rr0, *)
  387. )
  388. )
  389. };
  390. } // namespace test
  391. int main()
  392. {
  393. test::evaluate(
  394. test::lvalue_const_float()
  395. , test::lvalue_float()
  396. , test::rvalue_const_float()
  397. , test::rvalue_float()
  398. );
  399. test::evaluate(
  400. test::lvalue_const_char_ptr()
  401. , test::lvalue_char_ptr()
  402. , test::rvalue_const_char_ptr()
  403. , test::rvalue_char_ptr()
  404. );
  405. test::evaluate(
  406. test::lvalue_const_str()
  407. , test::lvalue_str()
  408. , test::rvalue_const_str()
  409. , test::rvalue_str()
  410. );
  411. test::evaluate(
  412. test::_lr0 = test::lvalue_float()
  413. , test::_rrc0 = test::rvalue_const_float()
  414. , test::_rr0 = test::rvalue_float()
  415. , test::_lrc0 = test::lvalue_const_float()
  416. );
  417. test::evaluate(
  418. test::_lr0 = test::lvalue_char_ptr()
  419. , test::_rrc0 = test::rvalue_const_char_ptr()
  420. , test::_rr0 = test::rvalue_char_ptr()
  421. , test::_lrc0 = test::lvalue_const_char_ptr()
  422. );
  423. test::evaluate(
  424. test::_lr0 = test::lvalue_str()
  425. , test::_rrc0 = test::rvalue_const_str()
  426. , test::_rr0 = test::rvalue_str()
  427. , test::_lrc0 = test::lvalue_const_str()
  428. );
  429. test::C cf0(
  430. test::lvalue_const_float()
  431. , test::lvalue_float()
  432. , test::rvalue_const_float()
  433. , test::rvalue_float()
  434. );
  435. test::C cc0(
  436. test::lvalue_const_char_ptr()
  437. , test::lvalue_char_ptr()
  438. , test::rvalue_const_char_ptr()
  439. , test::rvalue_char_ptr()
  440. );
  441. test::C cs0(
  442. test::lvalue_const_str()
  443. , test::lvalue_str()
  444. , test::rvalue_const_str()
  445. , test::rvalue_str()
  446. );
  447. test::C cf1(
  448. test::_lr0 = test::lvalue_float()
  449. , test::_rrc0 = test::rvalue_const_float()
  450. , test::_rr0 = test::rvalue_float()
  451. , test::_lrc0 = test::lvalue_const_float()
  452. );
  453. test::C cc1(
  454. test::_lr0 = test::lvalue_char_ptr()
  455. , test::_rrc0 = test::rvalue_const_char_ptr()
  456. , test::_rr0 = test::rvalue_char_ptr()
  457. , test::_lrc0 = test::lvalue_const_char_ptr()
  458. );
  459. test::C cs1(
  460. test::_lr0 = test::lvalue_str()
  461. , test::_rrc0 = test::rvalue_const_str()
  462. , test::_rr0 = test::rvalue_str()
  463. , test::_lrc0 = test::lvalue_const_str()
  464. );
  465. char baz_arr[4] = "qux";
  466. typedef char char_arr[4];
  467. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  468. BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
  469. // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
  470. #else
  471. test::evaluate(
  472. "q2x"
  473. , baz_arr
  474. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  475. , static_cast<char_arr const&&>("mos")
  476. , static_cast<char_arr&&>(baz_arr)
  477. #else
  478. , "crg"
  479. , "uir"
  480. #endif
  481. );
  482. test::evaluate(
  483. test::_lr0 = baz_arr
  484. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  485. , test::_rrc0 = static_cast<char_arr const&&>("def")
  486. , test::_rr0 = static_cast<char_arr&&>(baz_arr)
  487. #else
  488. , test::_rrc0 = "grl"
  489. , test::_rr0 = "grp"
  490. #endif
  491. , test::_lrc0 = "wld"
  492. );
  493. #endif // MSVC-12+
  494. test::B::evaluate(test::lvalue_const_str()[0]);
  495. test::C::evaluate(
  496. test::lvalue_const_str()[0]
  497. , test::rvalue_const_float()
  498. );
  499. #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
  500. BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
  501. // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
  502. test::C cp0;
  503. test::C cp1;
  504. #else
  505. test::C cp0(
  506. "frd"
  507. , baz_arr
  508. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  509. , static_cast<char_arr const&&>("dfs")
  510. , static_cast<char_arr&&>(baz_arr)
  511. #else
  512. , "plg"
  513. , "thd"
  514. #endif
  515. );
  516. test::C cp1(
  517. test::_lr0 = baz_arr
  518. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  519. , test::_rrc0 = static_cast<char_arr const&&>("dgx")
  520. , test::_rr0 = static_cast<char_arr&&>(baz_arr)
  521. #else
  522. , test::_rrc0 = "hnk"
  523. , test::_rr0 = "xzz"
  524. #endif
  525. , test::_lrc0 = "zts"
  526. );
  527. #endif // MSVC-12+
  528. cp0.evaluate(
  529. test::lvalue_const_str()[0]
  530. , test::lvalue_char_ptr()
  531. , test::rvalue_str()
  532. , test::rvalue_const_float()
  533. );
  534. cp1.evaluate(
  535. test::lvalue_const_str()[0]
  536. , test::rvalue_str()
  537. , test::rvalue_const_float()
  538. , test::lvalue_char_ptr()
  539. );
  540. return boost::report_errors();
  541. }