function_cast.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. // Copyright Daniel Wallin 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. #ifndef BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP
  7. #define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP
  8. #include <boost/parameter/config.hpp>
  9. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  10. namespace boost { namespace parameter { namespace aux {
  11. // Handles possible implicit casts. Used by preprocessor.hpp
  12. // to normalize user input.
  13. //
  14. // cast<void*>::execute() is identity
  15. // cast<void*(X)>::execute() is identity
  16. // cast<void(X)>::execute() casts to X
  17. //
  18. // preprocessor.hpp uses this like this:
  19. //
  20. // #define X(value, predicate)
  21. // cast<void predicate>::execute(value)
  22. //
  23. // X(something, *)
  24. // X(something, *(predicate))
  25. // X(something, (int))
  26. template <typename VoidExpr, typename Args>
  27. struct cast;
  28. }}} // namespace boost::parameter::aux
  29. #include <boost/parameter/aux_/use_default_tag.hpp>
  30. namespace boost { namespace parameter { namespace aux {
  31. template <typename T, typename B>
  32. inline ::boost::parameter::aux::use_default_tag
  33. forward(::boost::parameter::aux::use_default_tag)
  34. {
  35. return ::boost::parameter::aux::use_default_tag();
  36. }
  37. }}} // namespace boost::parameter::aux
  38. #include <boost/mpl/bool.hpp>
  39. #include <boost/mpl/if.hpp>
  40. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  41. #include <boost/mp11/integral.hpp>
  42. #include <boost/mp11/utility.hpp>
  43. #endif
  44. namespace boost { namespace parameter { namespace aux {
  45. template <typename Args>
  46. struct cast<void*,Args>
  47. {
  48. template <typename T, typename B>
  49. struct apply
  50. {
  51. typedef typename ::boost::mpl
  52. ::if_<B,T,::boost::mpl::true_>::type type;
  53. };
  54. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  55. template <typename T, typename B>
  56. using fn = ::boost::mp11::mp_if<B,T,::boost::mp11::mp_true>;
  57. #endif
  58. };
  59. }}} // namespace boost::parameter::aux
  60. #include <boost/parameter/aux_/void.hpp>
  61. namespace boost { namespace parameter { namespace aux {
  62. template <typename Predicate, typename Args>
  63. struct cast<void*(Predicate),Args>
  64. : ::boost::parameter::aux::cast<void*,Args>
  65. {
  66. };
  67. }}} // namespace boost::parameter::aux
  68. #include <boost/mpl/placeholders.hpp>
  69. namespace boost { namespace parameter { namespace aux {
  70. // This is a hack used in cast<> to turn the user supplied type,
  71. // which may or may not be a placeholder expression, into one,
  72. // so that it will be properly evaluated by mpl::apply.
  73. template <typename T, typename Dummy = ::boost::mpl::_1>
  74. struct as_placeholder_expr
  75. {
  76. typedef T type;
  77. };
  78. }}} // namespace boost::parameter::aux
  79. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  80. #include <boost/mp11/list.hpp>
  81. namespace boost { namespace parameter { namespace aux {
  82. template <typename Target, typename Source, typename Args>
  83. struct apply_target_fn
  84. {
  85. using type = ::boost::mp11
  86. ::mp_apply_q<Target,::boost::mp11::mp_list<Source,Args> >;
  87. };
  88. }}} // namespace boost::parameter::aux
  89. #endif
  90. #include <boost/mpl/apply.hpp>
  91. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  92. #include <boost/parameter/aux_/has_nested_template_fn.hpp>
  93. #include <type_traits>
  94. #else
  95. #include <boost/type_traits/is_same.hpp>
  96. #include <boost/type_traits/remove_const.hpp>
  97. #include <boost/type_traits/remove_reference.hpp>
  98. #endif
  99. namespace boost { namespace parameter { namespace aux {
  100. template <typename Target, typename Source, typename Args>
  101. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  102. using is_target_same_as_source = ::std::is_same<
  103. typename ::std::remove_const<
  104. typename ::std::remove_reference<
  105. typename ::boost::mp11::mp_if<
  106. ::boost::parameter::aux::has_nested_template_fn<Target>
  107. , ::boost::parameter::aux
  108. ::apply_target_fn<Target,Source,Args>
  109. , ::boost::mpl::apply2<
  110. ::boost::parameter::aux::as_placeholder_expr<Target>
  111. , Source
  112. , Args
  113. >
  114. >::type
  115. >::type
  116. >::type
  117. , typename ::std::remove_const<Source>::type
  118. >;
  119. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  120. struct is_target_same_as_source
  121. : ::boost::mpl::if_<
  122. ::boost::is_same<
  123. typename ::boost::remove_const<
  124. typename ::boost::remove_reference<
  125. typename ::boost::mpl::apply2<
  126. ::boost::parameter::aux
  127. ::as_placeholder_expr<Target>
  128. , Source
  129. , Args
  130. >::type
  131. >::type
  132. >::type
  133. , typename ::boost::remove_const<Source>::type
  134. >
  135. , ::boost::mpl::true_
  136. , ::boost::mpl::false_
  137. >::type
  138. {
  139. };
  140. #endif // BOOST_PARAMETER_CAN_USE_MP11
  141. }}} // namespace boost::parameter::aux
  142. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  143. #include <boost/type_traits/add_const.hpp>
  144. #include <boost/type_traits/is_const.hpp>
  145. #endif
  146. namespace boost { namespace parameter { namespace aux {
  147. // Covers the case where is_convertible<Source,Target> but not
  148. // is_same<Source,Target>. Use cases are covered
  149. // by test/normalize_argument_types.cpp
  150. template <typename Source, typename Target>
  151. class cast_convert
  152. {
  153. typedef ::boost::parameter::aux::cast_convert<Source,Target> _self;
  154. public:
  155. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  156. using type = typename ::boost::mp11::mp_if<
  157. ::std::is_const<Source>
  158. , ::std::add_const<Target>
  159. , ::std::remove_const<Target>
  160. >::type;
  161. #else
  162. typedef typename boost::mpl::eval_if<
  163. ::boost::is_const<Source>
  164. , ::boost::add_const<Target>
  165. , ::boost::remove_const<Target>
  166. >::type type;
  167. #endif
  168. private:
  169. inline static typename _self::type
  170. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  171. _copy(typename ::std::remove_const<Target>::type value)
  172. #else
  173. _copy(typename ::boost::remove_const<Target>::type value)
  174. #endif
  175. {
  176. return value;
  177. }
  178. public:
  179. inline static typename _self::type evaluate(Source&& source)
  180. {
  181. return _self::_copy(source);
  182. }
  183. };
  184. template <typename Target, typename Source, typename Args>
  185. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  186. using cast_impl = ::std::remove_reference<
  187. typename ::boost::mp11::mp_if<
  188. ::boost::parameter::aux::has_nested_template_fn<Target>
  189. , ::boost::parameter::aux
  190. ::is_target_same_as_source<Target,Source,Args>
  191. , ::boost::mpl::apply2<
  192. ::boost::parameter::aux::as_placeholder_expr<Target>
  193. , Source
  194. , Args
  195. >
  196. >::type
  197. >;
  198. #else
  199. struct cast_impl
  200. : ::boost::remove_reference<
  201. typename ::boost::mpl::apply2<
  202. ::boost::parameter::aux::as_placeholder_expr<Target>
  203. , Source
  204. , Args
  205. >::type
  206. >
  207. {
  208. };
  209. #endif // BOOST_PARAMETER_CAN_USE_MP11
  210. }}} // namespace boost::parameter::aux
  211. #include <boost/mpl/eval_if.hpp>
  212. #include <boost/mpl/identity.hpp>
  213. namespace boost { namespace parameter { namespace aux {
  214. template <typename Target, typename Args>
  215. struct cast<void(Target),Args>
  216. {
  217. template <typename T, typename B>
  218. struct apply
  219. {
  220. typedef typename ::boost::mpl::eval_if<
  221. B
  222. , ::boost::mpl::eval_if<
  223. ::boost::parameter::aux
  224. ::is_target_same_as_source<Target,T,Args>
  225. , ::boost::mpl::identity<T>
  226. , ::boost::parameter::aux::cast_impl<Target,T,Args>
  227. >
  228. , ::boost::parameter::aux
  229. ::is_target_same_as_source<Target,T,Args>
  230. >::type type;
  231. };
  232. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  233. template <typename T, typename B>
  234. using fn = typename ::boost::mp11::mp_if<
  235. B
  236. , ::boost::mp11::mp_if<
  237. ::boost::parameter::aux
  238. ::is_target_same_as_source<Target,T,Args>
  239. , ::boost::mp11::mp_identity<T>
  240. , ::boost::parameter::aux::cast_impl<Target,T,Args>
  241. >
  242. , ::boost::parameter::aux
  243. ::is_target_same_as_source<Target,T,Args>
  244. >::type;
  245. #endif
  246. };
  247. }}} // namespace boost::parameter::aux
  248. #include <boost/parameter/value_type.hpp>
  249. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  250. #include <boost/mpl/apply_wrap.hpp>
  251. #endif
  252. // Expands to the target type of the argument as indicated by the predicate.
  253. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  254. #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
  255. ::boost::mp11::mp_apply_q< \
  256. ::boost::parameter::aux::cast<void predicate, args> \
  257. , ::boost::mp11::mp_list< \
  258. typename ::boost::parameter::value_type< \
  259. args \
  260. , tag \
  261. , ::boost::parameter::aux::use_default_tag \
  262. >::type \
  263. , ::boost::mp11::mp_true \
  264. > \
  265. >
  266. /**/
  267. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  268. #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
  269. typename ::boost::mpl::apply_wrap2< \
  270. ::boost::parameter::aux::cast<void predicate, args> \
  271. , typename ::boost::parameter::value_type< \
  272. args \
  273. , tag \
  274. , ::boost::parameter::aux::use_default_tag \
  275. >::type \
  276. , ::boost::mpl::true_ \
  277. >::type
  278. /**/
  279. #endif // BOOST_PARAMETER_CAN_USE_MP11
  280. // Expands to boost::mpl::true_ if and only if the argument's source and
  281. // target types are the same.
  282. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  283. #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \
  284. ::boost::mp11::mp_apply_q< \
  285. ::boost::parameter::aux::cast<void predicate, args> \
  286. , ::boost::mp11::mp_list< \
  287. typename ::boost::parameter::value_type< \
  288. args \
  289. , tag \
  290. , ::boost::parameter::aux::use_default_tag \
  291. >::type \
  292. , ::boost::mp11::mp_false \
  293. > \
  294. >
  295. /**/
  296. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  297. #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \
  298. typename ::boost::mpl::apply_wrap2< \
  299. ::boost::parameter::aux::cast<void predicate, args> \
  300. , typename ::boost::parameter::value_type< \
  301. args \
  302. , tag \
  303. , ::boost::parameter::aux::use_default_tag \
  304. >::type \
  305. , ::boost::mpl::false_ \
  306. >::type
  307. /**/
  308. #endif // BOOST_PARAMETER_CAN_USE_MP11
  309. #include <boost/core/enable_if.hpp>
  310. #include <utility>
  311. namespace boost { namespace parameter { namespace aux {
  312. // If the source and target types are not the same,
  313. // then perform an implicit conversion.
  314. template <typename Target, typename B, typename Source>
  315. inline typename ::boost::lazy_disable_if<
  316. B
  317. , ::boost::parameter::aux::cast_convert<Source,Target>
  318. >::type
  319. forward(Source&& source)
  320. {
  321. return ::boost::parameter::aux::cast_convert<Source,Target>
  322. ::evaluate(::std::forward<Source>(source));
  323. }
  324. // If the source and target types are the same,
  325. // then simply forward the argument.
  326. // However, treat rvalue references to scalars as const lvalue references.
  327. template <typename T, typename B>
  328. inline typename ::boost::enable_if<B,T const&>::type forward(T const& t)
  329. {
  330. return t;
  331. }
  332. template <typename T, typename B>
  333. inline typename ::boost::enable_if<
  334. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  335. ::boost::mp11::mp_if<
  336. B
  337. , ::boost::mp11::mp_if<
  338. ::std::is_const<T>
  339. , ::boost::mp11::mp_false
  340. , ::boost::mp11::mp_true
  341. >
  342. , ::boost::mp11::mp_false
  343. >
  344. #else
  345. typename ::boost::mpl::eval_if<
  346. B
  347. , ::boost::mpl::if_<
  348. ::boost::is_const<T>
  349. , ::boost::mpl::false_
  350. , ::boost::mpl::true_
  351. >
  352. , ::boost::mpl::false_
  353. >::type
  354. #endif // BOOST_PARAMETER_CAN_USE_MP11
  355. , T&
  356. >::type
  357. forward(T& t)
  358. {
  359. return t;
  360. }
  361. }}} // namespace boost::parameter::aux
  362. #include <boost/type_traits/is_scalar.hpp>
  363. namespace boost { namespace parameter { namespace aux {
  364. template <typename T, typename B>
  365. inline typename ::boost::enable_if<
  366. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  367. ::boost::mp11::mp_if<
  368. B
  369. , ::boost::mp11::mp_if<
  370. ::std::is_scalar<T>
  371. , ::boost::mp11::mp_false
  372. , ::boost::mp11::mp_true
  373. >
  374. , ::boost::mp11::mp_false
  375. >
  376. #else
  377. typename ::boost::mpl::eval_if<
  378. B
  379. , ::boost::mpl::if_<
  380. ::boost::is_scalar<T>
  381. , ::boost::mpl::false_
  382. , ::boost::mpl::true_
  383. >
  384. , ::boost::mpl::false_
  385. >::type
  386. #endif // BOOST_PARAMETER_CAN_USE_MP11
  387. , T const&&
  388. >::type
  389. forward(T const&& t)
  390. {
  391. return static_cast<T const&&>(t);
  392. }
  393. template <typename T, typename B>
  394. inline typename ::boost::enable_if<
  395. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  396. ::boost::mp11::mp_if<
  397. B
  398. , ::boost::mp11::mp_if<
  399. ::std::is_scalar<T>
  400. , ::boost::mp11::mp_false
  401. , ::boost::mp11::mp_true
  402. >
  403. , ::boost::mp11::mp_false
  404. >
  405. #else
  406. typename ::boost::mpl::eval_if<
  407. B
  408. , ::boost::mpl::if_<
  409. ::boost::is_scalar<T>
  410. , ::boost::mpl::false_
  411. , ::boost::mpl::true_
  412. >
  413. , ::boost::mpl::false_
  414. >::type
  415. #endif // BOOST_PARAMETER_CAN_USE_MP11
  416. , T&&
  417. >::type
  418. forward(T&& t)
  419. {
  420. return ::std::forward<T>(t);
  421. }
  422. }}} // namespace boost::parameter::aux
  423. #elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  424. #define BOOST_PARAMETER_FUNCTION_CAST_T(value_t, predicate, args) value_t
  425. #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) value
  426. #else // no perfect forwarding support and no Borland workarounds needed
  427. namespace boost { namespace parameter { namespace aux {
  428. // Handles possible implicit casts. Used by preprocessor.hpp
  429. // to normalize user input.
  430. //
  431. // cast<void*>::execute() is identity
  432. // cast<void*(X)>::execute() is identity
  433. // cast<void(X)>::execute() casts to X
  434. //
  435. // preprocessor.hpp uses this like this:
  436. //
  437. // #define X(value, predicate)
  438. // cast<void predicate>::execute(value)
  439. //
  440. // X(something, *)
  441. // X(something, *(predicate))
  442. // X(something, (int))
  443. template <typename VoidExpr, typename Args>
  444. struct cast;
  445. }}} // namespace boost::parameter::aux
  446. #include <boost/parameter/aux_/use_default_tag.hpp>
  447. #include <boost/mpl/bool.hpp>
  448. #include <boost/mpl/if.hpp>
  449. namespace boost { namespace parameter { namespace aux {
  450. template <typename Args>
  451. struct cast<void*,Args>
  452. {
  453. template <typename T>
  454. struct apply
  455. {
  456. typedef T& type;
  457. };
  458. inline static ::boost::parameter::aux::use_default_tag
  459. execute(::boost::parameter::aux::use_default_tag)
  460. {
  461. return ::boost::parameter::aux::use_default_tag();
  462. }
  463. template <typename U>
  464. inline static U& execute(U& value)
  465. {
  466. return value;
  467. }
  468. };
  469. }}} // namespace boost::parameter::aux
  470. #include <boost/parameter/aux_/void.hpp>
  471. namespace boost { namespace parameter { namespace aux {
  472. template <typename Predicate, typename Args>
  473. #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
  474. struct cast< ::boost::parameter::aux::voidstar(Predicate),Args>
  475. #else
  476. struct cast<void*(Predicate),Args>
  477. #endif
  478. : ::boost::parameter::aux::cast<void*,Args>
  479. {
  480. };
  481. }}} // namespace boost::parameter::aux
  482. #include <boost/mpl/placeholders.hpp>
  483. namespace boost { namespace parameter { namespace aux {
  484. // This is a hack used in cast<> to turn the user supplied type,
  485. // which may or may not be a placeholder expression, into one,
  486. // so that it will be properly evaluated by mpl::apply.
  487. template <typename T, typename Dummy = ::boost::mpl::_1>
  488. struct as_placeholder_expr
  489. {
  490. typedef T type;
  491. };
  492. }}} // namespace boost::parameter::aux
  493. #include <boost/mpl/apply.hpp>
  494. #include <boost/type_traits/is_same.hpp>
  495. #include <boost/type_traits/remove_const.hpp>
  496. #include <boost/type_traits/remove_reference.hpp>
  497. namespace boost { namespace parameter { namespace aux {
  498. template <typename Target, typename Source, typename Args>
  499. struct is_target_same_as_source
  500. : ::boost::mpl::if_<
  501. ::boost::is_same<
  502. typename ::boost::remove_const<
  503. typename ::boost::remove_reference<
  504. typename ::boost::mpl::apply2<
  505. ::boost::parameter::aux
  506. ::as_placeholder_expr<Target>
  507. , Source
  508. , Args
  509. >::type
  510. >::type
  511. >::type
  512. , typename ::boost::remove_const<Source>::type
  513. >
  514. , ::boost::mpl::true_
  515. , ::boost::mpl::false_
  516. >::type
  517. {
  518. };
  519. template <
  520. typename Target
  521. , typename Source
  522. , typename Args
  523. , typename Enable = ::boost::parameter::aux
  524. ::is_target_same_as_source<Target,Source,Args>
  525. >
  526. struct cast_impl
  527. {
  528. typedef Source& type;
  529. inline static Source& evaluate(Source& value)
  530. {
  531. return value;
  532. }
  533. };
  534. }}} // namespace boost::parameter::aux
  535. #include <boost/type_traits/add_const.hpp>
  536. #include <boost/type_traits/add_lvalue_reference.hpp>
  537. namespace boost { namespace parameter { namespace aux {
  538. // Covers the case where is_convertible<Source,Target> but not
  539. // is_same<Source,Target>. Use cases are covered
  540. // by test/normalize_argument_types.cpp
  541. template <typename Source, typename Target>
  542. class cast_convert
  543. {
  544. typedef ::boost::parameter::aux::cast_convert<Source,Target> _self;
  545. public:
  546. typedef typename ::boost::add_lvalue_reference<
  547. typename ::boost::add_const<Target>::type
  548. >::type type;
  549. private:
  550. template <typename U>
  551. inline static typename _self::type _mod_const(U const& u)
  552. {
  553. return u;
  554. }
  555. inline static Target _copy(Target value)
  556. {
  557. return value;
  558. }
  559. public:
  560. inline static typename _self::type evaluate(Source& source)
  561. {
  562. return _self::_mod_const(_self::_copy(source));
  563. }
  564. };
  565. template <typename Target, typename Source, typename Args>
  566. struct cast_impl<Target,Source,Args,::boost::mpl::false_>
  567. : ::boost::parameter::aux::cast_convert<
  568. Source,
  569. typename ::boost::mpl::apply2<
  570. ::boost::parameter::aux::as_placeholder_expr<Target>
  571. , Source
  572. , Args
  573. >::type
  574. >
  575. {
  576. };
  577. }}} // namespace boost::parameter::aux
  578. #include <boost/mpl/eval_if.hpp>
  579. namespace boost { namespace parameter { namespace aux {
  580. template <typename Target, typename Args>
  581. struct cast<void(Target),Args>
  582. {
  583. template <typename T>
  584. struct apply
  585. {
  586. typedef typename ::boost::mpl::eval_if<
  587. ::boost::parameter::aux
  588. ::is_target_same_as_source<Target,T,Args>
  589. , ::boost::add_lvalue_reference<T>
  590. , ::boost::parameter::aux::cast_impl<
  591. Target
  592. , T
  593. , Args
  594. , ::boost::mpl::false_
  595. >
  596. >::type type;
  597. };
  598. inline static ::boost::parameter::aux::use_default_tag
  599. execute(::boost::parameter::aux::use_default_tag)
  600. {
  601. return ::boost::parameter::aux::use_default_tag();
  602. }
  603. template <typename U>
  604. inline static typename ::boost::parameter::aux
  605. ::cast_impl<Target,U const,Args>::type
  606. execute(U const& value)
  607. {
  608. return ::boost::parameter::aux
  609. ::cast_impl<Target,U const,Args>::evaluate(value);
  610. }
  611. template <typename U>
  612. inline static typename ::boost::parameter::aux
  613. ::cast_impl<Target,U,Args>::type
  614. execute(U& value)
  615. {
  616. return ::boost::parameter::aux
  617. ::cast_impl<Target,U,Args>::evaluate(value);
  618. }
  619. };
  620. }}} // namespace boost::parameter::aux
  621. #include <boost/mpl/apply_wrap.hpp>
  622. #include <boost/parameter/value_type.hpp>
  623. // Expands to the reference-qualified target type of the argument
  624. // as indicated by the predicate.
  625. #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
  626. typename ::boost::mpl::apply_wrap1< \
  627. ::boost::parameter::aux::cast<void predicate, args> \
  628. , typename ::boost::parameter::value_type< \
  629. args \
  630. , tag \
  631. , ::boost::parameter::aux::use_default_tag \
  632. >::type \
  633. >::type
  634. /**/
  635. // Expands to the converted or passed-through value
  636. // as indicated by the predicate.
  637. #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) \
  638. ::boost::parameter::aux::cast<void predicate, args>::execute(value)
  639. /**/
  640. #endif // perfect forwarding support, or Borland workarounds needed
  641. #endif // include guard