traits.hpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file traits.hpp
  3. /// Contains definitions for child\<\>, child_c\<\>, left\<\>,
  4. /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(),
  5. /// value(), left() and right().
  6. //
  7. // Copyright 2008 Eric Niebler. Distributed under the Boost
  8. // Software License, Version 1.0. (See accompanying file
  9. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
  11. #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
  12. #include <boost/config.hpp>
  13. #include <boost/detail/workaround.hpp>
  14. #include <boost/preprocessor/iteration/iterate.hpp>
  15. #include <boost/preprocessor/repetition/enum.hpp>
  16. #include <boost/preprocessor/repetition/enum_params.hpp>
  17. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  18. #include <boost/preprocessor/repetition/repeat.hpp>
  19. #include <boost/preprocessor/repetition/repeat_from_to.hpp>
  20. #include <boost/preprocessor/facilities/intercept.hpp>
  21. #include <boost/preprocessor/arithmetic/sub.hpp>
  22. #include <boost/static_assert.hpp>
  23. #include <boost/mpl/bool.hpp>
  24. #include <boost/proto/detail/template_arity.hpp>
  25. #include <boost/type_traits/is_pod.hpp>
  26. #include <boost/type_traits/is_same.hpp>
  27. #include <boost/type_traits/add_const.hpp>
  28. #include <boost/proto/proto_fwd.hpp>
  29. #include <boost/proto/args.hpp>
  30. #include <boost/proto/domain.hpp>
  31. #include <boost/proto/transform/pass_through.hpp>
  32. #if defined(_MSC_VER)
  33. # pragma warning(push)
  34. # if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
  35. # pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
  36. # endif
  37. # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
  38. #endif
  39. namespace boost { namespace proto
  40. {
  41. namespace detail
  42. {
  43. template<typename T, typename Void = void>
  44. struct if_vararg
  45. {};
  46. template<typename T>
  47. struct if_vararg<T, typename T::proto_is_vararg_>
  48. : T
  49. {};
  50. template<typename T, typename Void = void>
  51. struct is_callable2_
  52. : mpl::false_
  53. {};
  54. template<typename T>
  55. struct is_callable2_<T, typename T::proto_is_callable_>
  56. : mpl::true_
  57. {};
  58. template<typename T BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = boost::proto::detail::template_arity<T>::value)>
  59. struct is_callable_
  60. : is_callable2_<T>
  61. {};
  62. }
  63. /// \brief Boolean metafunction which detects whether a type is
  64. /// a callable function object type or not.
  65. ///
  66. /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
  67. /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
  68. /// callable transform or an object transform. (The former are evaluated
  69. /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
  70. /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is
  71. /// a callable transform; otherwise, it is an object transform.
  72. ///
  73. /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt>
  74. /// is computed as follows:
  75. ///
  76. /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
  77. /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt>
  78. /// is <tt>is_same\<YN, proto::callable\>::value</tt>.
  79. /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
  80. /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is
  81. /// the case for any type that derives from \c proto::callable.)
  82. /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false.
  83. template<typename T>
  84. struct is_callable
  85. : proto::detail::is_callable_<T>
  86. {};
  87. /// INTERNAL ONLY
  88. ///
  89. template<>
  90. struct is_callable<proto::_>
  91. : mpl::true_
  92. {};
  93. /// INTERNAL ONLY
  94. ///
  95. template<>
  96. struct is_callable<proto::callable>
  97. : mpl::false_
  98. {};
  99. /// INTERNAL ONLY
  100. ///
  101. template<typename PrimitiveTransform, typename X>
  102. struct is_callable<proto::transform<PrimitiveTransform, X> >
  103. : mpl::false_
  104. {};
  105. #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0)
  106. // work around GCC bug
  107. template<typename Tag, typename Args, long N>
  108. struct is_callable<proto::expr<Tag, Args, N> >
  109. : mpl::false_
  110. {};
  111. // work around GCC bug
  112. template<typename Tag, typename Args, long N>
  113. struct is_callable<proto::basic_expr<Tag, Args, N> >
  114. : mpl::false_
  115. {};
  116. #endif
  117. namespace detail
  118. {
  119. template<typename T, typename Void /*= void*/>
  120. struct is_transform_
  121. : mpl::false_
  122. {};
  123. template<typename T>
  124. struct is_transform_<T, typename T::proto_is_transform_>
  125. : mpl::true_
  126. {};
  127. }
  128. /// \brief Boolean metafunction which detects whether a type is
  129. /// a PrimitiveTransform type or not.
  130. ///
  131. /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform
  132. /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>,
  133. /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data
  134. /// parameters (as needed).
  135. ///
  136. /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt>
  137. /// is computed as follows:
  138. ///
  139. /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef
  140. /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is
  141. /// the case for any type that derives from an instantiation of \c proto::transform.)
  142. /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false.
  143. template<typename T>
  144. struct is_transform
  145. : proto::detail::is_transform_<T>
  146. {};
  147. namespace detail
  148. {
  149. template<typename T, typename Void /*= void*/>
  150. struct is_aggregate_
  151. : is_pod<T>
  152. {};
  153. template<typename Tag, typename Args, long N>
  154. struct is_aggregate_<proto::expr<Tag, Args, N>, void>
  155. : mpl::true_
  156. {};
  157. template<typename Tag, typename Args, long N>
  158. struct is_aggregate_<proto::basic_expr<Tag, Args, N>, void>
  159. : mpl::true_
  160. {};
  161. template<typename T>
  162. struct is_aggregate_<T, typename T::proto_is_aggregate_>
  163. : mpl::true_
  164. {};
  165. }
  166. /// \brief A Boolean metafunction that indicates whether a type requires
  167. /// aggregate initialization.
  168. ///
  169. /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
  170. /// to determine how to construct an object of some type \c T, given some
  171. /// initialization arguments <tt>a0,a1,...aN</tt>.
  172. /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of
  173. /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
  174. /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
  175. template<typename T>
  176. struct is_aggregate
  177. : proto::detail::is_aggregate_<T>
  178. {};
  179. /// \brief A Boolean metafunction that indicates whether a given
  180. /// type \c T is a Proto expression type.
  181. ///
  182. /// If \c T has a nested type \c proto_is_expr_ that is a typedef
  183. /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
  184. /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
  185. /// from <tt>proto::extends\<\></tt> or that uses the
  186. /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
  187. /// <tt>is_expr\<T\>::value</tt> is \c false.
  188. template<typename T, typename Void /* = void*/>
  189. struct is_expr
  190. : mpl::false_
  191. {};
  192. /// \brief A Boolean metafunction that indicates whether a given
  193. /// type \c T is a Proto expression type.
  194. ///
  195. /// If \c T has a nested type \c proto_is_expr_ that is a typedef
  196. /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
  197. /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
  198. /// from <tt>proto::extends\<\></tt> or that uses the
  199. /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
  200. /// <tt>is_expr\<T\>::value</tt> is \c false.
  201. template<typename T>
  202. struct is_expr<T, typename T::proto_is_expr_>
  203. : mpl::true_
  204. {};
  205. template<typename T>
  206. struct is_expr<T &, void>
  207. : is_expr<T>
  208. {};
  209. /// \brief A metafunction that returns the tag type of a
  210. /// Proto expression.
  211. template<typename Expr>
  212. struct tag_of
  213. {
  214. typedef typename Expr::proto_tag type;
  215. };
  216. template<typename Expr>
  217. struct tag_of<Expr &>
  218. {
  219. typedef typename Expr::proto_tag type;
  220. };
  221. /// \brief A metafunction that returns the arity of a
  222. /// Proto expression.
  223. template<typename Expr>
  224. struct arity_of
  225. : Expr::proto_arity
  226. {};
  227. template<typename Expr>
  228. struct arity_of<Expr &>
  229. : Expr::proto_arity
  230. {};
  231. namespace result_of
  232. {
  233. /// \brief A metafunction that computes the return type of the \c as_expr()
  234. /// function.
  235. template<typename T, typename Domain /*= default_domain*/>
  236. struct as_expr
  237. {
  238. typedef typename Domain::template as_expr<T>::result_type type;
  239. };
  240. /// \brief A metafunction that computes the return type of the \c as_child()
  241. /// function.
  242. template<typename T, typename Domain /*= default_domain*/>
  243. struct as_child
  244. {
  245. typedef typename Domain::template as_child<T>::result_type type;
  246. };
  247. /// \brief A metafunction that returns the type of the Nth child
  248. /// of a Proto expression, where N is an MPL Integral Constant.
  249. ///
  250. /// <tt>result_of::child\<Expr, N\></tt> is equivalent to
  251. /// <tt>result_of::child_c\<Expr, N::value\></tt>.
  252. template<typename Expr, typename N /* = mpl::long_<0>*/>
  253. struct child
  254. : child_c<Expr, N::value>
  255. {};
  256. /// \brief A metafunction that returns the type of the value
  257. /// of a terminal Proto expression.
  258. ///
  259. template<typename Expr>
  260. struct value
  261. {
  262. /// Verify that we are actually operating on a terminal
  263. BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
  264. /// The raw type of the Nth child as it is stored within
  265. /// \c Expr. This may be a value or a reference
  266. typedef typename Expr::proto_child0 value_type;
  267. /// The "value" type of the child, suitable for storage by value,
  268. /// computed as follows:
  269. /// \li <tt>T const(&)[N]</tt> becomes <tt>T[N]</tt>
  270. /// \li <tt>T[N]</tt> becomes <tt>T[N]</tt>
  271. /// \li <tt>T(&)[N]</tt> becomes <tt>T[N]</tt>
  272. /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
  273. /// \li <tt>T const &</tt> becomes <tt>T</tt>
  274. /// \li <tt>T &</tt> becomes <tt>T</tt>
  275. /// \li <tt>T</tt> becomes <tt>T</tt>
  276. typedef typename detail::term_traits<typename Expr::proto_child0>::value_type type;
  277. };
  278. template<typename Expr>
  279. struct value<Expr &>
  280. {
  281. /// Verify that we are actually operating on a terminal
  282. BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
  283. /// The raw type of the Nth child as it is stored within
  284. /// \c Expr. This may be a value or a reference
  285. typedef typename Expr::proto_child0 value_type;
  286. /// The "reference" type of the child, suitable for storage by
  287. /// reference, computed as follows:
  288. /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
  289. /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
  290. /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
  291. /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
  292. /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
  293. /// \li <tt>T &</tt> becomes <tt>T &</tt>
  294. /// \li <tt>T</tt> becomes <tt>T &</tt>
  295. typedef typename detail::term_traits<typename Expr::proto_child0>::reference type;
  296. };
  297. template<typename Expr>
  298. struct value<Expr const &>
  299. {
  300. /// Verify that we are actually operating on a terminal
  301. BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
  302. /// The raw type of the Nth child as it is stored within
  303. /// \c Expr. This may be a value or a reference
  304. typedef typename Expr::proto_child0 value_type;
  305. /// The "const reference" type of the child, suitable for storage by
  306. /// const reference, computed as follows:
  307. /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
  308. /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt>
  309. /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
  310. /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
  311. /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
  312. /// \li <tt>T &</tt> becomes <tt>T &</tt>
  313. /// \li <tt>T</tt> becomes <tt>T const &</tt>
  314. typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type;
  315. };
  316. /// \brief A metafunction that returns the type of the left child
  317. /// of a binary Proto expression.
  318. ///
  319. /// <tt>result_of::left\<Expr\></tt> is equivalent to
  320. /// <tt>result_of::child_c\<Expr, 0\></tt>.
  321. template<typename Expr>
  322. struct left
  323. : child_c<Expr, 0>
  324. {};
  325. /// \brief A metafunction that returns the type of the right child
  326. /// of a binary Proto expression.
  327. ///
  328. /// <tt>result_of::right\<Expr\></tt> is equivalent to
  329. /// <tt>result_of::child_c\<Expr, 1\></tt>.
  330. template<typename Expr>
  331. struct right
  332. : child_c<Expr, 1>
  333. {};
  334. } // namespace result_of
  335. /// \brief A metafunction for generating terminal expression types,
  336. /// a grammar element for matching terminal expressions, and a
  337. /// PrimitiveTransform that returns the current expression unchanged.
  338. template<typename T>
  339. struct terminal
  340. : proto::transform<terminal<T>, int>
  341. {
  342. typedef proto::expr<proto::tag::terminal, term<T>, 0> type;
  343. typedef proto::basic_expr<proto::tag::terminal, term<T>, 0> proto_grammar;
  344. template<typename Expr, typename State, typename Data>
  345. struct impl : transform_impl<Expr, State, Data>
  346. {
  347. typedef Expr result_type;
  348. /// \param e The current expression
  349. /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true.
  350. /// \return \c e
  351. /// \throw nothrow
  352. BOOST_FORCEINLINE
  353. BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
  354. operator ()(
  355. typename impl::expr_param e
  356. , typename impl::state_param
  357. , typename impl::data_param
  358. ) const
  359. {
  360. return e;
  361. }
  362. };
  363. /// INTERNAL ONLY
  364. typedef proto::tag::terminal proto_tag;
  365. /// INTERNAL ONLY
  366. typedef T proto_child0;
  367. };
  368. /// \brief A metafunction for generating ternary conditional expression types,
  369. /// a grammar element for matching ternary conditional expressions, and a
  370. /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
  371. /// transform.
  372. template<typename T, typename U, typename V>
  373. struct if_else_
  374. : proto::transform<if_else_<T, U, V>, int>
  375. {
  376. typedef proto::expr<proto::tag::if_else_, list3<T, U, V>, 3> type;
  377. typedef proto::basic_expr<proto::tag::if_else_, list3<T, U, V>, 3> proto_grammar;
  378. template<typename Expr, typename State, typename Data>
  379. struct impl
  380. : detail::pass_through_impl<if_else_, deduce_domain, Expr, State, Data>
  381. {};
  382. /// INTERNAL ONLY
  383. typedef proto::tag::if_else_ proto_tag;
  384. /// INTERNAL ONLY
  385. typedef T proto_child0;
  386. /// INTERNAL ONLY
  387. typedef U proto_child1;
  388. /// INTERNAL ONLY
  389. typedef V proto_child2;
  390. };
  391. /// \brief A metafunction for generating nullary expression types with a
  392. /// specified tag type,
  393. /// a grammar element for matching nullary expressions, and a
  394. /// PrimitiveTransform that returns the current expression unchanged.
  395. ///
  396. /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any
  397. /// nullary expression.
  398. template<typename Tag, typename T>
  399. struct nullary_expr
  400. : proto::transform<nullary_expr<Tag, T>, int>
  401. {
  402. typedef proto::expr<Tag, term<T>, 0> type;
  403. typedef proto::basic_expr<Tag, term<T>, 0> proto_grammar;
  404. template<typename Expr, typename State, typename Data>
  405. struct impl : transform_impl<Expr, State, Data>
  406. {
  407. typedef Expr result_type;
  408. /// \param e The current expression
  409. /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true.
  410. /// \return \c e
  411. /// \throw nothrow
  412. BOOST_FORCEINLINE
  413. BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
  414. operator ()(
  415. typename impl::expr_param e
  416. , typename impl::state_param
  417. , typename impl::data_param
  418. ) const
  419. {
  420. return e;
  421. }
  422. };
  423. /// INTERNAL ONLY
  424. typedef Tag proto_tag;
  425. /// INTERNAL ONLY
  426. typedef T proto_child0;
  427. };
  428. /// \brief A metafunction for generating unary expression types with a
  429. /// specified tag type,
  430. /// a grammar element for matching unary expressions, and a
  431. /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
  432. /// transform.
  433. ///
  434. /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
  435. /// unary expression.
  436. template<typename Tag, typename T>
  437. struct unary_expr
  438. : proto::transform<unary_expr<Tag, T>, int>
  439. {
  440. typedef proto::expr<Tag, list1<T>, 1> type;
  441. typedef proto::basic_expr<Tag, list1<T>, 1> proto_grammar;
  442. template<typename Expr, typename State, typename Data>
  443. struct impl
  444. : detail::pass_through_impl<unary_expr, deduce_domain, Expr, State, Data>
  445. {};
  446. /// INTERNAL ONLY
  447. typedef Tag proto_tag;
  448. /// INTERNAL ONLY
  449. typedef T proto_child0;
  450. };
  451. /// \brief A metafunction for generating binary expression types with a
  452. /// specified tag type,
  453. /// a grammar element for matching binary expressions, and a
  454. /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
  455. /// transform.
  456. ///
  457. /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
  458. /// binary expression.
  459. template<typename Tag, typename T, typename U>
  460. struct binary_expr
  461. : proto::transform<binary_expr<Tag, T, U>, int>
  462. {
  463. typedef proto::expr<Tag, list2<T, U>, 2> type;
  464. typedef proto::basic_expr<Tag, list2<T, U>, 2> proto_grammar;
  465. template<typename Expr, typename State, typename Data>
  466. struct impl
  467. : detail::pass_through_impl<binary_expr, deduce_domain, Expr, State, Data>
  468. {};
  469. /// INTERNAL ONLY
  470. typedef Tag proto_tag;
  471. /// INTERNAL ONLY
  472. typedef T proto_child0;
  473. /// INTERNAL ONLY
  474. typedef U proto_child1;
  475. };
  476. #define BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(Op) \
  477. template<typename T> \
  478. struct Op \
  479. : proto::transform<Op<T>, int> \
  480. { \
  481. typedef proto::expr<proto::tag::Op, list1<T>, 1> type; \
  482. typedef proto::basic_expr<proto::tag::Op, list1<T>, 1> proto_grammar; \
  483. \
  484. template<typename Expr, typename State, typename Data> \
  485. struct impl \
  486. : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \
  487. {}; \
  488. \
  489. typedef proto::tag::Op proto_tag; \
  490. typedef T proto_child0; \
  491. }; \
  492. /**/
  493. #define BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(Op) \
  494. template<typename T, typename U> \
  495. struct Op \
  496. : proto::transform<Op<T, U>, int> \
  497. { \
  498. typedef proto::expr<proto::tag::Op, list2<T, U>, 2> type; \
  499. typedef proto::basic_expr<proto::tag::Op, list2<T, U>, 2> proto_grammar; \
  500. \
  501. template<typename Expr, typename State, typename Data> \
  502. struct impl \
  503. : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \
  504. {}; \
  505. \
  506. typedef proto::tag::Op proto_tag; \
  507. typedef T proto_child0; \
  508. typedef U proto_child1; \
  509. }; \
  510. /**/
  511. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(unary_plus)
  512. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(negate)
  513. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(dereference)
  514. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(complement)
  515. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(address_of)
  516. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(logical_not)
  517. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_inc)
  518. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_dec)
  519. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_inc)
  520. BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_dec)
  521. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left)
  522. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right)
  523. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies)
  524. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides)
  525. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus)
  526. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus)
  527. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus)
  528. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less)
  529. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater)
  530. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less_equal)
  531. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater_equal)
  532. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(equal_to)
  533. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(not_equal_to)
  534. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_or)
  535. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_and)
  536. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or)
  537. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and)
  538. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor)
  539. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(comma)
  540. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(mem_ptr)
  541. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(assign)
  542. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left_assign)
  543. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right_assign)
  544. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies_assign)
  545. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides_assign)
  546. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus_assign)
  547. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus_assign)
  548. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus_assign)
  549. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign)
  550. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign)
  551. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign)
  552. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(subscript)
  553. BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(member)
  554. #undef BOOST_PROTO_DEFINE_UNARY_METAFUNCTION
  555. #undef BOOST_PROTO_DEFINE_BINARY_METAFUNCTION
  556. #include <boost/proto/detail/traits.hpp>
  557. namespace functional
  558. {
  559. /// \brief A callable PolymorphicFunctionObject that is
  560. /// equivalent to the \c as_expr() function.
  561. template<typename Domain /* = default_domain*/>
  562. struct as_expr
  563. {
  564. BOOST_PROTO_CALLABLE()
  565. template<typename Sig>
  566. struct result;
  567. template<typename This, typename T>
  568. struct result<This(T)>
  569. {
  570. typedef typename Domain::template as_expr<T>::result_type type;
  571. };
  572. template<typename This, typename T>
  573. struct result<This(T &)>
  574. {
  575. typedef typename Domain::template as_expr<T>::result_type type;
  576. };
  577. /// \brief Wrap an object in a Proto terminal if it isn't a
  578. /// Proto expression already.
  579. /// \param t The object to wrap.
  580. /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
  581. template<typename T>
  582. BOOST_FORCEINLINE
  583. typename add_const<typename result<as_expr(T &)>::type>::type
  584. operator ()(T &t) const
  585. {
  586. return typename Domain::template as_expr<T>()(t);
  587. }
  588. /// \overload
  589. ///
  590. template<typename T>
  591. BOOST_FORCEINLINE
  592. typename add_const<typename result<as_expr(T const &)>::type>::type
  593. operator ()(T const &t) const
  594. {
  595. return typename Domain::template as_expr<T const>()(t);
  596. }
  597. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
  598. template<typename T, std::size_t N_>
  599. BOOST_FORCEINLINE
  600. typename add_const<typename result<as_expr(T (&)[N_])>::type>::type
  601. operator ()(T (&t)[N_]) const
  602. {
  603. return typename Domain::template as_expr<T[N_]>()(t);
  604. }
  605. template<typename T, std::size_t N_>
  606. BOOST_FORCEINLINE
  607. typename add_const<typename result<as_expr(T const (&)[N_])>::type>::type
  608. operator ()(T const (&t)[N_]) const
  609. {
  610. return typename Domain::template as_expr<T const[N_]>()(t);
  611. }
  612. #endif
  613. };
  614. /// \brief A callable PolymorphicFunctionObject that is
  615. /// equivalent to the \c as_child() function.
  616. template<typename Domain /* = default_domain*/>
  617. struct as_child
  618. {
  619. BOOST_PROTO_CALLABLE()
  620. template<typename Sig>
  621. struct result;
  622. template<typename This, typename T>
  623. struct result<This(T)>
  624. {
  625. typedef typename Domain::template as_child<T>::result_type type;
  626. };
  627. template<typename This, typename T>
  628. struct result<This(T &)>
  629. {
  630. typedef typename Domain::template as_child<T>::result_type type;
  631. };
  632. /// \brief Wrap an object in a Proto terminal if it isn't a
  633. /// Proto expression already.
  634. /// \param t The object to wrap.
  635. /// \return <tt>proto::as_child\<Domain\>(t)</tt>
  636. template<typename T>
  637. BOOST_FORCEINLINE
  638. typename add_const<typename result<as_child(T &)>::type>::type
  639. operator ()(T &t) const
  640. {
  641. return typename Domain::template as_child<T>()(t);
  642. }
  643. /// \overload
  644. ///
  645. template<typename T>
  646. BOOST_FORCEINLINE
  647. typename add_const<typename result<as_child(T const &)>::type>::type
  648. operator ()(T const &t) const
  649. {
  650. return typename Domain::template as_child<T const>()(t);
  651. }
  652. };
  653. /// \brief A callable PolymorphicFunctionObject that is
  654. /// equivalent to the \c child_c() function.
  655. template<long N>
  656. struct child_c
  657. {
  658. BOOST_PROTO_CALLABLE()
  659. template<typename Sig>
  660. struct result;
  661. template<typename This, typename Expr>
  662. struct result<This(Expr)>
  663. {
  664. typedef typename result_of::child_c<Expr, N>::type type;
  665. };
  666. /// \brief Return the Nth child of the given expression.
  667. /// \param expr The expression node.
  668. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
  669. /// \pre <tt>N \< Expr::proto_arity::value</tt>
  670. /// \return <tt>proto::child_c\<N\>(expr)</tt>
  671. /// \throw nothrow
  672. template<typename Expr>
  673. BOOST_FORCEINLINE
  674. typename result_of::child_c<Expr &, N>::type
  675. operator ()(Expr &e) const
  676. {
  677. return result_of::child_c<Expr &, N>::call(e);
  678. }
  679. /// \overload
  680. ///
  681. template<typename Expr>
  682. BOOST_FORCEINLINE
  683. typename result_of::child_c<Expr const &, N>::type
  684. operator ()(Expr const &e) const
  685. {
  686. return result_of::child_c<Expr const &, N>::call(e);
  687. }
  688. };
  689. /// \brief A callable PolymorphicFunctionObject that is
  690. /// equivalent to the \c child() function.
  691. ///
  692. /// A callable PolymorphicFunctionObject that is
  693. /// equivalent to the \c child() function. \c N is required
  694. /// to be an MPL Integral Constant.
  695. template<typename N /* = mpl::long_<0>*/>
  696. struct child
  697. {
  698. BOOST_PROTO_CALLABLE()
  699. template<typename Sig>
  700. struct result;
  701. template<typename This, typename Expr>
  702. struct result<This(Expr)>
  703. {
  704. typedef typename result_of::child<Expr, N>::type type;
  705. };
  706. /// \brief Return the Nth child of the given expression.
  707. /// \param expr The expression node.
  708. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
  709. /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
  710. /// \return <tt>proto::child\<N\>(expr)</tt>
  711. /// \throw nothrow
  712. template<typename Expr>
  713. BOOST_FORCEINLINE
  714. typename result_of::child<Expr &, N>::type
  715. operator ()(Expr &e) const
  716. {
  717. return result_of::child<Expr &, N>::call(e);
  718. }
  719. /// \overload
  720. ///
  721. template<typename Expr>
  722. BOOST_FORCEINLINE
  723. typename result_of::child<Expr const &, N>::type
  724. operator ()(Expr const &e) const
  725. {
  726. return result_of::child<Expr const &, N>::call(e);
  727. }
  728. };
  729. /// \brief A callable PolymorphicFunctionObject that is
  730. /// equivalent to the \c value() function.
  731. struct value
  732. {
  733. BOOST_PROTO_CALLABLE()
  734. template<typename Sig>
  735. struct result;
  736. template<typename This, typename Expr>
  737. struct result<This(Expr)>
  738. {
  739. typedef typename result_of::value<Expr>::type type;
  740. };
  741. /// \brief Return the value of the given terminal expression.
  742. /// \param expr The terminal expression node.
  743. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
  744. /// \pre <tt>0 == Expr::proto_arity::value</tt>
  745. /// \return <tt>proto::value(expr)</tt>
  746. /// \throw nothrow
  747. template<typename Expr>
  748. BOOST_FORCEINLINE
  749. typename result_of::value<Expr &>::type
  750. operator ()(Expr &e) const
  751. {
  752. return e.proto_base().child0;
  753. }
  754. /// \overload
  755. ///
  756. template<typename Expr>
  757. BOOST_FORCEINLINE
  758. typename result_of::value<Expr const &>::type
  759. operator ()(Expr const &e) const
  760. {
  761. return e.proto_base().child0;
  762. }
  763. };
  764. /// \brief A callable PolymorphicFunctionObject that is
  765. /// equivalent to the \c left() function.
  766. struct left
  767. {
  768. BOOST_PROTO_CALLABLE()
  769. template<typename Sig>
  770. struct result;
  771. template<typename This, typename Expr>
  772. struct result<This(Expr)>
  773. {
  774. typedef typename result_of::left<Expr>::type type;
  775. };
  776. /// \brief Return the left child of the given binary expression.
  777. /// \param expr The expression node.
  778. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
  779. /// \pre <tt>2 == Expr::proto_arity::value</tt>
  780. /// \return <tt>proto::left(expr)</tt>
  781. /// \throw nothrow
  782. template<typename Expr>
  783. BOOST_FORCEINLINE
  784. typename result_of::left<Expr &>::type
  785. operator ()(Expr &e) const
  786. {
  787. return e.proto_base().child0;
  788. }
  789. /// \overload
  790. ///
  791. template<typename Expr>
  792. BOOST_FORCEINLINE
  793. typename result_of::left<Expr const &>::type
  794. operator ()(Expr const &e) const
  795. {
  796. return e.proto_base().child0;
  797. }
  798. };
  799. /// \brief A callable PolymorphicFunctionObject that is
  800. /// equivalent to the \c right() function.
  801. struct right
  802. {
  803. BOOST_PROTO_CALLABLE()
  804. template<typename Sig>
  805. struct result;
  806. template<typename This, typename Expr>
  807. struct result<This(Expr)>
  808. {
  809. typedef typename result_of::right<Expr>::type type;
  810. };
  811. /// \brief Return the right child of the given binary expression.
  812. /// \param expr The expression node.
  813. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
  814. /// \pre <tt>2 == Expr::proto_arity::value</tt>
  815. /// \return <tt>proto::right(expr)</tt>
  816. /// \throw nothrow
  817. template<typename Expr>
  818. BOOST_FORCEINLINE
  819. typename result_of::right<Expr &>::type
  820. operator ()(Expr &e) const
  821. {
  822. return e.proto_base().child1;
  823. }
  824. template<typename Expr>
  825. BOOST_FORCEINLINE
  826. typename result_of::right<Expr const &>::type
  827. operator ()(Expr const &e) const
  828. {
  829. return e.proto_base().child1;
  830. }
  831. };
  832. }
  833. /// \brief A function that wraps non-Proto expression types in Proto
  834. /// terminals and leaves Proto expression types alone.
  835. ///
  836. /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
  837. /// they are not Proto expression types already. Non-Proto types are
  838. /// held by value, if possible. Types which are already Proto types are
  839. /// left alone and returned by reference.
  840. ///
  841. /// This function can be called either with an explicitly specified
  842. /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
  843. /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
  844. /// specified, \c default_domain is assumed.
  845. ///
  846. /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
  847. /// returned unmodified, by reference. Otherwise, the argument is wrapped
  848. /// in a Proto terminal expression node according to the following rules.
  849. /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
  850. /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
  851. /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>.
  852. ///
  853. /// \param t The object to wrap.
  854. template<typename T>
  855. BOOST_FORCEINLINE
  856. typename add_const<typename result_of::as_expr<T, default_domain>::type>::type
  857. as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
  858. {
  859. return default_domain::as_expr<T>()(t);
  860. }
  861. /// \overload
  862. ///
  863. template<typename T>
  864. BOOST_FORCEINLINE
  865. typename add_const<typename result_of::as_expr<T const, default_domain>::type>::type
  866. as_expr(T const &t)
  867. {
  868. return default_domain::as_expr<T const>()(t);
  869. }
  870. /// \overload
  871. ///
  872. template<typename Domain, typename T>
  873. BOOST_FORCEINLINE
  874. typename add_const<typename result_of::as_expr<T, Domain>::type>::type
  875. as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
  876. {
  877. return typename Domain::template as_expr<T>()(t);
  878. }
  879. /// \overload
  880. ///
  881. template<typename Domain, typename T>
  882. BOOST_FORCEINLINE
  883. typename add_const<typename result_of::as_expr<T const, Domain>::type>::type
  884. as_expr(T const &t)
  885. {
  886. return typename Domain::template as_expr<T const>()(t);
  887. }
  888. /// \brief A function that wraps non-Proto expression types in Proto
  889. /// terminals (by reference) and returns Proto expression types by
  890. /// reference
  891. ///
  892. /// The <tt>as_child()</tt> function turns objects into Proto terminals if
  893. /// they are not Proto expression types already. Non-Proto types are
  894. /// held by reference. Types which are already Proto types are simply
  895. /// returned as-is.
  896. ///
  897. /// This function can be called either with an explicitly specified
  898. /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or
  899. /// without (i.e., <tt>as_child(t)</tt>). If no domain is
  900. /// specified, \c default_domain is assumed.
  901. ///
  902. /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
  903. /// returned as-is. Otherwise, \c as_child() returns
  904. /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>.
  905. ///
  906. /// \param t The object to wrap.
  907. template<typename T>
  908. BOOST_FORCEINLINE
  909. typename add_const<typename result_of::as_child<T, default_domain>::type>::type
  910. as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
  911. {
  912. return default_domain::as_child<T>()(t);
  913. }
  914. /// \overload
  915. ///
  916. template<typename T>
  917. BOOST_FORCEINLINE
  918. typename add_const<typename result_of::as_child<T const, default_domain>::type>::type
  919. as_child(T const &t)
  920. {
  921. return default_domain::as_child<T const>()(t);
  922. }
  923. /// \overload
  924. ///
  925. template<typename Domain, typename T>
  926. BOOST_FORCEINLINE
  927. typename add_const<typename result_of::as_child<T, Domain>::type>::type
  928. as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
  929. {
  930. return typename Domain::template as_child<T>()(t);
  931. }
  932. /// \overload
  933. ///
  934. template<typename Domain, typename T>
  935. BOOST_FORCEINLINE
  936. typename add_const<typename result_of::as_child<T const, Domain>::type>::type
  937. as_child(T const &t)
  938. {
  939. return typename Domain::template as_child<T const>()(t);
  940. }
  941. /// \brief Return the Nth child of the specified Proto expression.
  942. ///
  943. /// Return the Nth child of the specified Proto expression. If
  944. /// \c N is not specified, as in \c child(expr), then \c N is assumed
  945. /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
  946. /// reference.
  947. ///
  948. /// \param expr The Proto expression.
  949. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
  950. /// \pre \c N is an MPL Integral Constant.
  951. /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
  952. /// \throw nothrow
  953. /// \return A reference to the Nth child
  954. template<typename N, typename Expr>
  955. BOOST_FORCEINLINE
  956. typename result_of::child<Expr &, N>::type
  957. child(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
  958. {
  959. return result_of::child<Expr &, N>::call(e);
  960. }
  961. /// \overload
  962. ///
  963. template<typename N, typename Expr>
  964. BOOST_FORCEINLINE
  965. typename result_of::child<Expr const &, N>::type
  966. child(Expr const &e)
  967. {
  968. return result_of::child<Expr const &, N>::call(e);
  969. }
  970. /// \overload
  971. ///
  972. template<typename Expr2>
  973. BOOST_FORCEINLINE
  974. typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::reference
  975. child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
  976. {
  977. return expr2.proto_base().child0;
  978. }
  979. /// \overload
  980. ///
  981. template<typename Expr2>
  982. BOOST_FORCEINLINE
  983. typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::const_reference
  984. child(Expr2 const &expr2)
  985. {
  986. return expr2.proto_base().child0;
  987. }
  988. /// \brief Return the Nth child of the specified Proto expression.
  989. ///
  990. /// Return the Nth child of the specified Proto expression. The child
  991. /// is returned by reference.
  992. ///
  993. /// \param expr The Proto expression.
  994. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
  995. /// \pre <tt>N \< Expr::proto_arity::value</tt>
  996. /// \throw nothrow
  997. /// \return A reference to the Nth child
  998. template<long N, typename Expr>
  999. BOOST_FORCEINLINE
  1000. typename result_of::child_c<Expr &, N>::type
  1001. child_c(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
  1002. {
  1003. return result_of::child_c<Expr &, N>::call(e);
  1004. }
  1005. /// \overload
  1006. ///
  1007. template<long N, typename Expr>
  1008. BOOST_FORCEINLINE
  1009. typename result_of::child_c<Expr const &, N>::type
  1010. child_c(Expr const &e)
  1011. {
  1012. return result_of::child_c<Expr const &, N>::call(e);
  1013. }
  1014. /// \brief Return the value stored within the specified Proto
  1015. /// terminal expression.
  1016. ///
  1017. /// Return the value stored within the specified Proto
  1018. /// terminal expression. The value is returned by
  1019. /// reference.
  1020. ///
  1021. /// \param expr The Proto terminal expression.
  1022. /// \pre <tt>N::value == 0</tt>
  1023. /// \throw nothrow
  1024. /// \return A reference to the terminal's value
  1025. template<typename Expr>
  1026. BOOST_FORCEINLINE
  1027. typename result_of::value<Expr &>::type
  1028. value(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
  1029. {
  1030. return e.proto_base().child0;
  1031. }
  1032. /// \overload
  1033. ///
  1034. template<typename Expr>
  1035. BOOST_FORCEINLINE
  1036. typename result_of::value<Expr const &>::type
  1037. value(Expr const &e)
  1038. {
  1039. return e.proto_base().child0;
  1040. }
  1041. /// \brief Return the left child of the specified binary Proto
  1042. /// expression.
  1043. ///
  1044. /// Return the left child of the specified binary Proto expression. The
  1045. /// child is returned by reference.
  1046. ///
  1047. /// \param expr The Proto expression.
  1048. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
  1049. /// \pre <tt>2 == Expr::proto_arity::value</tt>
  1050. /// \throw nothrow
  1051. /// \return A reference to the left child
  1052. template<typename Expr>
  1053. BOOST_FORCEINLINE
  1054. typename result_of::left<Expr &>::type
  1055. left(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
  1056. {
  1057. return e.proto_base().child0;
  1058. }
  1059. /// \overload
  1060. ///
  1061. template<typename Expr>
  1062. BOOST_FORCEINLINE
  1063. typename result_of::left<Expr const &>::type
  1064. left(Expr const &e)
  1065. {
  1066. return e.proto_base().child0;
  1067. }
  1068. /// \brief Return the right child of the specified binary Proto
  1069. /// expression.
  1070. ///
  1071. /// Return the right child of the specified binary Proto expression. The
  1072. /// child is returned by reference.
  1073. ///
  1074. /// \param expr The Proto expression.
  1075. /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
  1076. /// \pre <tt>2 == Expr::proto_arity::value</tt>
  1077. /// \throw nothrow
  1078. /// \return A reference to the right child
  1079. template<typename Expr>
  1080. BOOST_FORCEINLINE
  1081. typename result_of::right<Expr &>::type
  1082. right(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
  1083. {
  1084. return e.proto_base().child1;
  1085. }
  1086. /// \overload
  1087. ///
  1088. template<typename Expr>
  1089. BOOST_FORCEINLINE
  1090. typename result_of::right<Expr const &>::type
  1091. right(Expr const &e)
  1092. {
  1093. return e.proto_base().child1;
  1094. }
  1095. /// INTERNAL ONLY
  1096. ///
  1097. template<typename Domain>
  1098. struct is_callable<functional::as_expr<Domain> >
  1099. : mpl::true_
  1100. {};
  1101. /// INTERNAL ONLY
  1102. ///
  1103. template<typename Domain>
  1104. struct is_callable<functional::as_child<Domain> >
  1105. : mpl::true_
  1106. {};
  1107. /// INTERNAL ONLY
  1108. ///
  1109. template<long N>
  1110. struct is_callable<functional::child_c<N> >
  1111. : mpl::true_
  1112. {};
  1113. /// INTERNAL ONLY
  1114. ///
  1115. template<typename N>
  1116. struct is_callable<functional::child<N> >
  1117. : mpl::true_
  1118. {};
  1119. }}
  1120. #if defined(_MSC_VER)
  1121. # pragma warning(pop)
  1122. #endif
  1123. #endif