tagged_argument.hpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. // Copyright Daniel Wallin, David Abrahams 2005.
  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. #ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
  7. #define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
  8. namespace boost { namespace parameter { namespace aux {
  9. struct error_const_lvalue_bound_to_out_parameter;
  10. struct error_lvalue_bound_to_consume_parameter;
  11. struct error_rvalue_bound_to_out_parameter;
  12. }}} // namespace boost::parameter::aux
  13. #include <boost/parameter/keyword_fwd.hpp>
  14. #include <boost/parameter/config.hpp>
  15. #include <boost/mpl/eval_if.hpp>
  16. #include <boost/type_traits/is_same.hpp>
  17. #include <boost/type_traits/remove_const.hpp>
  18. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  19. #include <boost/mp11/integral.hpp>
  20. #include <boost/mp11/utility.hpp>
  21. #include <type_traits>
  22. #endif
  23. namespace boost { namespace parameter { namespace aux {
  24. template <typename Keyword, typename Arg>
  25. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  26. using tagged_argument_type = ::boost::mp11::mp_if<
  27. ::boost::mp11::mp_if<
  28. ::std::is_scalar<Arg>
  29. , ::boost::mp11::mp_false
  30. , ::std::is_same<
  31. typename Keyword::qualifier
  32. , ::boost::parameter::consume_reference
  33. >
  34. >
  35. , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter
  36. , ::boost::mp11::mp_if<
  37. ::std::is_const<Arg>
  38. , ::boost::mp11::mp_if<
  39. ::std::is_same<
  40. typename Keyword::qualifier
  41. , ::boost::parameter::out_reference
  42. >
  43. , ::boost::parameter::aux
  44. ::error_const_lvalue_bound_to_out_parameter
  45. , ::std::remove_const<Arg>
  46. >
  47. , ::boost::mp11::mp_identity<Arg>
  48. >
  49. >;
  50. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  51. struct tagged_argument_type
  52. : ::boost::mpl::eval_if<
  53. ::boost::is_same<
  54. typename Keyword::qualifier
  55. , ::boost::parameter::out_reference
  56. >
  57. , ::boost::parameter::aux::error_const_lvalue_bound_to_out_parameter
  58. , ::boost::remove_const<Arg>
  59. >
  60. {
  61. };
  62. #endif // BOOST_PARAMETER_CAN_USE_MP11
  63. }}} // namespace boost::parameter::aux
  64. #include <boost/parameter/aux_/tagged_argument_fwd.hpp>
  65. #include <boost/parameter/aux_/is_tagged_argument.hpp>
  66. #include <boost/parameter/aux_/default.hpp>
  67. #include <boost/parameter/aux_/void.hpp>
  68. #include <boost/parameter/aux_/arg_list.hpp>
  69. #include <boost/parameter/aux_/result_of0.hpp>
  70. #include <boost/mpl/bool.hpp>
  71. #include <boost/mpl/if.hpp>
  72. #include <boost/mpl/identity.hpp>
  73. #include <boost/mpl/apply_wrap.hpp>
  74. #include <boost/type_traits/is_const.hpp>
  75. #include <boost/type_traits/is_function.hpp>
  76. #include <boost/type_traits/is_scalar.hpp>
  77. #include <boost/type_traits/remove_reference.hpp>
  78. #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  79. #include <boost/function.hpp>
  80. #else
  81. #include <functional>
  82. #endif
  83. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  84. #include <boost/core/enable_if.hpp>
  85. #include <utility>
  86. namespace boost { namespace parameter { namespace aux {
  87. // Holds an lvalue reference to an argument of type Arg associated with
  88. // keyword Keyword
  89. template <typename Keyword, typename Arg>
  90. class tagged_argument
  91. : public ::boost::parameter::aux::tagged_argument_base
  92. {
  93. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  94. using arg_type = typename ::boost::parameter::aux
  95. ::tagged_argument_type<Keyword,Arg>::type;
  96. #else
  97. typedef typename ::boost::mpl::eval_if<
  98. typename ::boost::mpl::eval_if<
  99. ::boost::is_scalar<Arg>
  100. , ::boost::mpl::false_
  101. , ::boost::is_same<
  102. typename Keyword::qualifier
  103. , ::boost::parameter::consume_reference
  104. >
  105. >::type
  106. , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter
  107. , ::boost::mpl::eval_if<
  108. ::boost::is_const<Arg>
  109. , ::boost::parameter::aux::tagged_argument_type<Keyword,Arg>
  110. , ::boost::mpl::identity<Arg>
  111. >
  112. >::type arg_type;
  113. #endif // BOOST_PARAMETER_CAN_USE_MP11
  114. public:
  115. typedef Keyword key_type;
  116. // Wrap plain (non-UDT) function objects in either
  117. // a boost::function or a std::function. -- Cromwell D. Enage
  118. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  119. using value_type = ::boost::mp11::mp_if<
  120. ::std::is_function<arg_type>
  121. , ::std::function<arg_type>
  122. , Arg
  123. >;
  124. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  125. typedef typename ::boost::mpl::if_<
  126. ::boost::is_function<arg_type>
  127. #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  128. , ::boost::function<arg_type>
  129. #else
  130. , ::std::function<arg_type>
  131. #endif
  132. , Arg
  133. >::type value_type;
  134. #endif // BOOST_PARAMETER_CAN_USE_MP11
  135. // If Arg is void_, then this type will evaluate to void_&. If the
  136. // supplied argument is a plain function, then this type will evaluate
  137. // to a reference-to-const function wrapper type. If the supplied
  138. // argument is an lvalue, then Arg will be deduced to the lvalue
  139. // reference. -- Cromwell D. Enage
  140. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  141. using reference = ::boost::mp11::mp_if<
  142. ::std::is_function<arg_type>
  143. , value_type const&
  144. , Arg&
  145. >;
  146. #else
  147. typedef typename ::boost::mpl::if_<
  148. ::boost::is_function<arg_type>
  149. , value_type const&
  150. , Arg&
  151. >::type reference;
  152. #endif
  153. private:
  154. // Store plain functions by value, everything else by reference.
  155. // -- Cromwell D. Enage
  156. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  157. ::boost::mp11::mp_if<
  158. ::std::is_function<arg_type>
  159. , value_type
  160. , reference
  161. > value;
  162. #else
  163. typename ::boost::mpl::if_<
  164. ::boost::is_function<arg_type>
  165. , value_type
  166. , reference
  167. >::type value;
  168. #endif
  169. public:
  170. inline explicit BOOST_CONSTEXPR tagged_argument(reference x)
  171. : value(x)
  172. {
  173. }
  174. inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy)
  175. : value(copy.value)
  176. {
  177. }
  178. // A metafunction class that, given a keyword and a default type,
  179. // returns the appropriate result type for a keyword lookup given
  180. // that default.
  181. struct binding
  182. {
  183. template <typename KW, typename Default, typename Reference>
  184. struct apply
  185. : ::boost::mpl::eval_if<
  186. ::boost::is_same<KW,key_type>
  187. , ::boost::mpl::if_<Reference,reference,value_type>
  188. , ::boost::mpl::identity<Default>
  189. >
  190. {
  191. };
  192. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  193. template <typename KW, typename Default, typename Reference>
  194. using fn = ::boost::mp11::mp_if<
  195. ::std::is_same<KW,key_type>
  196. , ::boost::mp11::mp_if<Reference,reference,value_type>
  197. , Default
  198. >;
  199. #endif
  200. };
  201. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  202. // Comma operator to compose argument list without using parameters<>.
  203. // Useful for argument lists with undetermined length.
  204. template <typename Keyword2, typename Arg2>
  205. inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
  206. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  207. , ::boost::parameter::aux::arg_list<
  208. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  209. >
  210. >
  211. operator,(
  212. ::boost::parameter::aux
  213. ::tagged_argument<Keyword2,Arg2> const& x
  214. ) const
  215. {
  216. return ::boost::parameter::aux::arg_list<
  217. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  218. , ::boost::parameter::aux::arg_list<
  219. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  220. >
  221. >(
  222. *this
  223. , ::boost::parameter::aux::arg_list<
  224. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  225. >(x, ::boost::parameter::aux::empty_arg_list())
  226. );
  227. }
  228. template <typename Keyword2, typename Arg2>
  229. inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
  230. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  231. , ::boost::parameter::aux::arg_list<
  232. ::boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2>
  233. >
  234. >
  235. operator,(
  236. ::boost::parameter::aux
  237. ::tagged_argument_rref<Keyword2,Arg2> const& x
  238. ) const
  239. {
  240. return ::boost::parameter::aux::arg_list<
  241. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  242. , boost::parameter::aux::arg_list<
  243. boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2>
  244. >
  245. >(
  246. *this
  247. , ::boost::parameter::aux::arg_list<
  248. ::boost::parameter::aux
  249. ::tagged_argument_rref<Keyword2,Arg2>
  250. >(x, ::boost::parameter::aux::empty_arg_list())
  251. );
  252. }
  253. #endif // BOOST_PARAMETER_CAN_USE_MP11
  254. // Accessor interface.
  255. inline BOOST_CONSTEXPR reference get_value() const
  256. {
  257. return this->value;
  258. }
  259. inline BOOST_CONSTEXPR reference
  260. operator[](::boost::parameter::keyword<Keyword> const&) const
  261. {
  262. return this->get_value();
  263. }
  264. template <typename Default>
  265. inline BOOST_CONSTEXPR reference
  266. operator[](
  267. ::boost::parameter::aux::default_<key_type,Default> const&
  268. ) const
  269. {
  270. return this->get_value();
  271. }
  272. template <typename F>
  273. inline BOOST_CONSTEXPR reference
  274. operator[](
  275. ::boost::parameter::aux::lazy_default<key_type,F> const&
  276. ) const
  277. {
  278. return this->get_value();
  279. }
  280. template <typename KW, typename Default>
  281. inline BOOST_CONSTEXPR Default&
  282. operator[](
  283. ::boost::parameter::aux::default_<KW,Default> const& x
  284. ) const
  285. {
  286. return x.value;
  287. }
  288. template <typename KW, typename Default>
  289. inline BOOST_CONSTEXPR Default&&
  290. operator[](
  291. ::boost::parameter::aux::default_r_<KW,Default> const& x
  292. ) const
  293. {
  294. return ::std::forward<Default>(x.value);
  295. }
  296. template <typename KW, typename F>
  297. inline BOOST_CONSTEXPR
  298. typename ::boost::parameter::aux::result_of0<F>::type
  299. operator[](
  300. ::boost::parameter::aux::lazy_default<KW,F> const& x
  301. ) const
  302. {
  303. return x.compute_default();
  304. }
  305. template <typename ParameterRequirements>
  306. static BOOST_CONSTEXPR typename ParameterRequirements::has_default
  307. satisfies(ParameterRequirements*);
  308. template <typename HasDefault, typename Predicate>
  309. static BOOST_CONSTEXPR
  310. typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type
  311. satisfies(
  312. ::boost::parameter::aux::parameter_requirements<
  313. key_type
  314. , Predicate
  315. , HasDefault
  316. >*
  317. );
  318. // MPL sequence support
  319. // Convenience for users
  320. typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type;
  321. // For the benefit of iterators
  322. typedef ::boost::parameter::aux::empty_arg_list tail_type;
  323. // For dispatching to sequence intrinsics
  324. typedef ::boost::parameter::aux::arg_list_tag tag;
  325. };
  326. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  327. template <typename Keyword>
  328. using tagged_argument_rref_key = ::boost::mp11::mp_if<
  329. ::std::is_same<
  330. typename Keyword::qualifier
  331. , ::boost::parameter::out_reference
  332. >
  333. , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter
  334. , ::boost::mp11::mp_identity<Keyword>
  335. >;
  336. #endif
  337. // Holds an rvalue reference to an argument of type Arg associated with
  338. // keyword Keyword
  339. template <typename Keyword, typename Arg>
  340. struct tagged_argument_rref
  341. : ::boost::parameter::aux::tagged_argument_base
  342. {
  343. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  344. using key_type = typename ::boost::parameter::aux
  345. ::tagged_argument_rref_key<Keyword>::type;
  346. #else
  347. typedef typename ::boost::mpl::eval_if<
  348. ::boost::is_same<
  349. typename Keyword::qualifier
  350. , ::boost::parameter::out_reference
  351. >
  352. , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter
  353. , ::boost::mpl::identity<Keyword>
  354. >::type key_type;
  355. #endif
  356. typedef Arg value_type;
  357. typedef Arg&& reference;
  358. private:
  359. reference value;
  360. public:
  361. inline explicit BOOST_CONSTEXPR tagged_argument_rref(reference x)
  362. : value(::std::forward<Arg>(x))
  363. {
  364. }
  365. inline BOOST_CONSTEXPR tagged_argument_rref(
  366. tagged_argument_rref const& copy
  367. ) : value(::std::forward<Arg>(copy.value))
  368. {
  369. }
  370. // A metafunction class that, given a keyword and a default type,
  371. // returns the appropriate result type for a keyword lookup given
  372. // that default.
  373. struct binding
  374. {
  375. template <typename KW, typename Default, typename Reference>
  376. struct apply
  377. {
  378. typedef typename ::boost::mpl::eval_if<
  379. ::boost::is_same<KW,key_type>
  380. , ::boost::mpl::if_<Reference,reference,value_type>
  381. , ::boost::mpl::identity<Default>
  382. >::type type;
  383. };
  384. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  385. template <typename KW, typename Default, typename Reference>
  386. using fn = ::boost::mp11::mp_if<
  387. ::std::is_same<KW,key_type>
  388. , ::boost::mp11::mp_if<Reference,reference,value_type>
  389. , Default
  390. >;
  391. #endif
  392. };
  393. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  394. // Comma operator to compose argument list without using parameters<>.
  395. // Useful for argument lists with undetermined length.
  396. template <typename Keyword2, typename Arg2>
  397. inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
  398. ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
  399. , ::boost::parameter::aux::arg_list<
  400. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  401. >
  402. >
  403. operator,(
  404. ::boost::parameter::aux
  405. ::tagged_argument<Keyword2,Arg2> const& x
  406. ) const
  407. {
  408. return boost::parameter::aux::arg_list<
  409. ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
  410. , ::boost::parameter::aux::arg_list<
  411. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  412. >
  413. >(
  414. *this
  415. , ::boost::parameter::aux::arg_list<
  416. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  417. >(x, ::boost::parameter::aux::empty_arg_list())
  418. );
  419. }
  420. template <typename Keyword2, typename Arg2>
  421. inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
  422. ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
  423. , ::boost::parameter::aux::arg_list<
  424. ::boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2>
  425. >
  426. >
  427. operator,(
  428. ::boost::parameter::aux
  429. ::tagged_argument_rref<Keyword2,Arg2> const& x
  430. ) const
  431. {
  432. return ::boost::parameter::aux::arg_list<
  433. ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
  434. , ::boost::parameter::aux::arg_list<
  435. ::boost::parameter::aux
  436. ::tagged_argument_rref<Keyword2,Arg2>
  437. >
  438. >(
  439. *this
  440. , ::boost::parameter::aux::arg_list<
  441. ::boost::parameter::aux::tagged_argument_rref<
  442. Keyword2
  443. , Arg2
  444. >
  445. >(x, ::boost::parameter::aux::empty_arg_list())
  446. );
  447. }
  448. #endif // BOOST_PARAMETER_CAN_USE_MP11
  449. // Accessor interface.
  450. inline BOOST_CONSTEXPR reference get_value() const
  451. {
  452. return ::std::forward<Arg>(this->value);
  453. }
  454. inline BOOST_CONSTEXPR reference
  455. operator[](::boost::parameter::keyword<Keyword> const&) const
  456. {
  457. return this->get_value();
  458. }
  459. template <typename Default>
  460. inline BOOST_CONSTEXPR reference
  461. operator[](
  462. ::boost::parameter::aux::default_<key_type,Default> const&
  463. ) const
  464. {
  465. return this->get_value();
  466. }
  467. template <typename Default>
  468. inline BOOST_CONSTEXPR reference
  469. operator[](
  470. ::boost::parameter::aux::default_r_<key_type,Default> const&
  471. ) const
  472. {
  473. return this->get_value();
  474. }
  475. template <typename F>
  476. inline BOOST_CONSTEXPR reference
  477. operator[](
  478. ::boost::parameter::aux::lazy_default<key_type,F> const&
  479. ) const
  480. {
  481. return this->get_value();
  482. }
  483. template <typename KW, typename Default>
  484. inline BOOST_CONSTEXPR Default&
  485. operator[](
  486. ::boost::parameter::aux::default_<KW,Default> const& x
  487. ) const
  488. {
  489. return x.value;
  490. }
  491. template <typename KW, typename Default>
  492. inline BOOST_CONSTEXPR Default&&
  493. operator[](
  494. ::boost::parameter::aux::default_r_<KW,Default> const& x
  495. ) const
  496. {
  497. return ::std::forward<Default>(x.value);
  498. }
  499. template <typename KW, typename F>
  500. inline BOOST_CONSTEXPR
  501. typename ::boost::parameter::aux::result_of0<F>::type
  502. operator[](
  503. ::boost::parameter::aux::lazy_default<KW,F> const& x
  504. ) const
  505. {
  506. return x.compute_default();
  507. }
  508. template <typename ParameterRequirements>
  509. static BOOST_CONSTEXPR typename ParameterRequirements::has_default
  510. satisfies(ParameterRequirements*);
  511. template <typename HasDefault, typename Predicate>
  512. static BOOST_CONSTEXPR
  513. typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type
  514. satisfies(
  515. ::boost::parameter::aux::parameter_requirements<
  516. key_type
  517. , Predicate
  518. , HasDefault
  519. >*
  520. );
  521. // MPL sequence support
  522. // Convenience for users
  523. typedef ::boost::parameter::aux
  524. ::tagged_argument_rref<Keyword,Arg> type;
  525. // For the benefit of iterators
  526. typedef ::boost::parameter::aux::empty_arg_list tail_type;
  527. // For dispatching to sequence intrinsics
  528. typedef ::boost::parameter::aux::arg_list_tag tag;
  529. };
  530. }}} // namespace boost::parameter::aux
  531. #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  532. namespace boost { namespace parameter { namespace aux {
  533. // Holds an lvalue reference to an argument of type Arg associated with
  534. // keyword Keyword
  535. template <typename Keyword, typename Arg>
  536. class tagged_argument
  537. : public ::boost::parameter::aux::tagged_argument_base
  538. {
  539. typedef typename ::boost::remove_const<Arg>::type arg_type;
  540. public:
  541. typedef Keyword key_type;
  542. // Wrap plain (non-UDT) function objects in either
  543. // a boost::function or a std::function. -- Cromwell D. Enage
  544. typedef typename ::boost::mpl::if_<
  545. ::boost::is_function<arg_type>
  546. #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  547. , ::boost::function<arg_type>
  548. #else
  549. , ::std::function<arg_type>
  550. #endif
  551. , Arg
  552. >::type value_type;
  553. // If Arg is void_, then this type will evaluate to void_&. If the
  554. // supplied argument is a plain function, then this type will evaluate
  555. // to a reference-to-const function wrapper type. If the supplied
  556. // argument is an lvalue, then Arg will be deduced to the lvalue
  557. // reference. -- Cromwell D. Enage
  558. typedef typename ::boost::mpl::if_<
  559. ::boost::is_function<arg_type>
  560. , value_type const&
  561. , Arg&
  562. >::type reference;
  563. private:
  564. // Store plain functions by value, everything else by reference.
  565. // -- Cromwell D. Enage
  566. typename ::boost::mpl::if_<
  567. ::boost::is_function<arg_type>
  568. , value_type
  569. , reference
  570. >::type value;
  571. public:
  572. inline explicit BOOST_CONSTEXPR tagged_argument(reference x)
  573. : value(x)
  574. {
  575. }
  576. inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy)
  577. : value(copy.value)
  578. {
  579. }
  580. // A metafunction class that, given a keyword and a default type,
  581. // returns the appropriate result type for a keyword lookup given
  582. // that default.
  583. struct binding
  584. {
  585. template <typename KW, typename Default, typename Reference>
  586. struct apply
  587. {
  588. typedef typename ::boost::mpl::eval_if<
  589. ::boost::is_same<KW,key_type>
  590. , ::boost::mpl::if_<Reference,reference,value_type>
  591. , ::boost::mpl::identity<Default>
  592. >::type type;
  593. };
  594. };
  595. // Comma operator to compose argument list without using parameters<>.
  596. // Useful for argument lists with undetermined length.
  597. template <typename Keyword2, typename Arg2>
  598. inline ::boost::parameter::aux::arg_list<
  599. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  600. , ::boost::parameter::aux::arg_list<
  601. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  602. >
  603. >
  604. operator,(
  605. ::boost::parameter::aux
  606. ::tagged_argument<Keyword2,Arg2> const& x
  607. ) const
  608. {
  609. return ::boost::parameter::aux::arg_list<
  610. ::boost::parameter::aux::tagged_argument<Keyword,Arg>
  611. , ::boost::parameter::aux::arg_list<
  612. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  613. >
  614. >(
  615. *this
  616. , ::boost::parameter::aux::arg_list<
  617. ::boost::parameter::aux::tagged_argument<Keyword2,Arg2>
  618. >(x, ::boost::parameter::aux::empty_arg_list())
  619. );
  620. }
  621. // Accessor interface.
  622. inline BOOST_CONSTEXPR reference get_value() const
  623. {
  624. return this->value;
  625. }
  626. inline BOOST_CONSTEXPR reference
  627. operator[](::boost::parameter::keyword<Keyword> const&) const
  628. {
  629. return this->get_value();
  630. }
  631. #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || \
  632. BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  633. template <typename KW, typename Default>
  634. inline BOOST_CONSTEXPR Default&
  635. get_with_default(
  636. ::boost::parameter::aux::default_<KW,Default> const& x
  637. , int
  638. ) const
  639. {
  640. return x.value;
  641. }
  642. template <typename Default>
  643. inline BOOST_CONSTEXPR reference
  644. get_with_default(
  645. ::boost::parameter::aux::default_<key_type,Default> const&
  646. , long
  647. ) const
  648. {
  649. return this->get_value();
  650. }
  651. template <typename KW, typename Default>
  652. inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
  653. binding
  654. , KW
  655. , Default&
  656. , ::boost::mpl::true_
  657. >::type
  658. operator[](
  659. ::boost::parameter::aux::default_<KW,Default> const& x
  660. ) const
  661. {
  662. return this->get_with_default(x, 0L);
  663. }
  664. template <typename KW, typename F>
  665. inline BOOST_CONSTEXPR
  666. typename ::boost::parameter::aux::result_of0<F>::type
  667. get_with_lazy_default(
  668. ::boost::parameter::aux::lazy_default<KW,F> const& x
  669. , int
  670. ) const
  671. {
  672. return x.compute_default();
  673. }
  674. template <typename F>
  675. inline BOOST_CONSTEXPR reference
  676. get_with_lazy_default(
  677. ::boost::parameter::aux::lazy_default<key_type,F> const&
  678. , long
  679. ) const
  680. {
  681. return this->get_value();
  682. }
  683. template <typename KW, typename F>
  684. inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
  685. binding
  686. , KW
  687. , typename ::boost::parameter::aux::result_of0<F>::type
  688. , ::boost::mpl::true_
  689. >::type
  690. operator[](
  691. ::boost::parameter::aux::lazy_default<KW,F> const& x
  692. ) const
  693. {
  694. return this->get_with_lazy_default(x, 0L);
  695. }
  696. #else // No function template ordering or Borland workarounds needed.
  697. template <typename Default>
  698. inline BOOST_CONSTEXPR reference
  699. operator[](
  700. ::boost::parameter::aux::default_<key_type,Default> const&
  701. ) const
  702. {
  703. return this->get_value();
  704. }
  705. template <typename F>
  706. inline BOOST_CONSTEXPR reference
  707. operator[](
  708. ::boost::parameter::aux::lazy_default<key_type,F> const&
  709. ) const
  710. {
  711. return this->get_value();
  712. }
  713. template <typename KW, typename Default>
  714. inline BOOST_CONSTEXPR Default&
  715. operator[](
  716. ::boost::parameter::aux::default_<KW,Default> const& x
  717. ) const
  718. {
  719. return x.value;
  720. }
  721. template <typename KW, typename F>
  722. inline BOOST_CONSTEXPR
  723. typename ::boost::parameter::aux::result_of0<F>::type
  724. operator[](
  725. ::boost::parameter::aux::lazy_default<KW,F> const& x
  726. ) const
  727. {
  728. return x.compute_default();
  729. }
  730. template <typename ParameterRequirements>
  731. static BOOST_CONSTEXPR typename ParameterRequirements::has_default
  732. satisfies(ParameterRequirements*);
  733. template <typename HasDefault, typename Predicate>
  734. static BOOST_CONSTEXPR
  735. typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type
  736. satisfies(
  737. ::boost::parameter::aux::parameter_requirements<
  738. key_type
  739. , Predicate
  740. , HasDefault
  741. >*
  742. );
  743. #endif // Function template ordering, Borland workarounds needed.
  744. // MPL sequence support
  745. // Convenience for users
  746. typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type;
  747. // For the benefit of iterators
  748. typedef ::boost::parameter::aux::empty_arg_list tail_type;
  749. // For dispatching to sequence intrinsics
  750. typedef ::boost::parameter::aux::arg_list_tag tag;
  751. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
  752. // warning suppression
  753. private:
  754. void operator=(type const&);
  755. #endif
  756. };
  757. }}} // namespace boost::parameter::aux
  758. #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
  759. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  760. namespace boost { namespace parameter { namespace aux {
  761. template <typename TaggedArg>
  762. struct tagged_argument_list_of_1 : public TaggedArg
  763. {
  764. using base_type = TaggedArg;
  765. inline explicit BOOST_CONSTEXPR tagged_argument_list_of_1(
  766. typename base_type::reference x
  767. ) : base_type(static_cast<typename base_type::reference>(x))
  768. {
  769. }
  770. inline BOOST_CONSTEXPR tagged_argument_list_of_1(
  771. tagged_argument_list_of_1 const& copy
  772. ) : base_type(static_cast<base_type const&>(copy))
  773. {
  774. }
  775. using base_type::operator[];
  776. using base_type::satisfies;
  777. template <typename TA2>
  778. inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list<
  779. ::boost::parameter::aux
  780. ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg>
  781. , ::boost::parameter::aux::flat_like_arg_tuple<
  782. typename TA2::base_type::key_type
  783. , typename TA2::base_type
  784. >
  785. >
  786. operator,(TA2 const& x) const
  787. {
  788. return boost::parameter::aux::flat_like_arg_list<
  789. ::boost::parameter::aux
  790. ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg>
  791. , ::boost::parameter::aux::flat_like_arg_tuple<
  792. typename TA2::base_type::key_type
  793. , typename TA2::base_type
  794. >
  795. >(
  796. static_cast<base_type const&>(*this)
  797. , ::boost::parameter::aux::arg_list<typename TA2::base_type>(
  798. static_cast<typename TA2::base_type const&>(x)
  799. , ::boost::parameter::aux::empty_arg_list()
  800. )
  801. );
  802. }
  803. };
  804. }}} // namespace boost::parameter::aux
  805. #endif // BOOST_PARAMETER_CAN_USE_MP11
  806. #endif // include guard