eval.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file eval.hpp
  3. /// Contains the eval() expression evaluator.
  4. //
  5. // Copyright 2008 Eric Niebler. Distributed under the Boost
  6. // Software License, Version 1.0. (See accompanying file
  7. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
  9. #define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
  10. #include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
  11. #include <boost/type_traits/remove_reference.hpp>
  12. namespace boost { namespace proto
  13. {
  14. namespace result_of
  15. {
  16. /// \brief A metafunction for calculating the return type
  17. /// of \c proto::eval() given a certain \c Expr and \c Context
  18. /// types.
  19. ///
  20. /// \note The types \c Expr and \c Context should not be
  21. /// reference types. They may be cv-qualified, but the
  22. /// cv-qualification on the \c Context parameter is ignored.
  23. template<typename Expr, typename Context>
  24. struct eval
  25. {
  26. typedef typename Context::template eval<Expr>::result_type type;
  27. };
  28. }
  29. namespace functional
  30. {
  31. /// \brief A PolymorphicFunctionObject type for
  32. /// evaluating a given Proto expression with a given
  33. /// context.
  34. struct eval
  35. {
  36. BOOST_PROTO_CALLABLE()
  37. template<typename Sig>
  38. struct result;
  39. template<typename This, typename Expr, typename Context>
  40. struct result<This(Expr, Context)>
  41. {
  42. typedef
  43. typename proto::result_of::eval<
  44. typename remove_reference<Expr>::type
  45. , typename remove_reference<Context>::type
  46. >::type
  47. type;
  48. };
  49. /// \brief Evaluate a given Proto expression with a given
  50. /// context.
  51. /// \param expr The Proto expression to evaluate
  52. /// \param context The context in which the expression should be
  53. /// evaluated.
  54. /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
  55. template<typename Expr, typename Context>
  56. typename proto::result_of::eval<Expr, Context>::type
  57. operator ()(Expr &e, Context &ctx) const
  58. {
  59. return typename Context::template eval<Expr>()(e, ctx);
  60. }
  61. /// \overload
  62. ///
  63. template<typename Expr, typename Context>
  64. typename proto::result_of::eval<Expr, Context>::type
  65. operator ()(Expr &e, Context const &ctx) const
  66. {
  67. return typename Context::template eval<Expr>()(e, ctx);
  68. }
  69. /// \overload
  70. ///
  71. template<typename Expr, typename Context>
  72. typename proto::result_of::eval<Expr const, Context>::type
  73. operator ()(Expr const &e, Context &ctx) const
  74. {
  75. return typename Context::template eval<Expr const>()(e, ctx);
  76. }
  77. /// \overload
  78. ///
  79. template<typename Expr, typename Context>
  80. typename proto::result_of::eval<Expr const, Context>::type
  81. operator ()(Expr const &e, Context const &ctx) const
  82. {
  83. return typename Context::template eval<Expr const>()(e, ctx);
  84. }
  85. };
  86. }
  87. /// \brief Evaluate a given Proto expression with a given
  88. /// context.
  89. /// \param expr The Proto expression to evaluate
  90. /// \param context The context in which the expression should be
  91. /// evaluated.
  92. /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
  93. template<typename Expr, typename Context>
  94. typename proto::result_of::eval<Expr, Context>::type
  95. eval(Expr &e, Context &ctx)
  96. {
  97. return typename Context::template eval<Expr>()(e, ctx);
  98. }
  99. /// \overload
  100. ///
  101. template<typename Expr, typename Context>
  102. typename proto::result_of::eval<Expr, Context>::type
  103. eval(Expr &e, Context const &ctx)
  104. {
  105. return typename Context::template eval<Expr>()(e, ctx);
  106. }
  107. /// \overload
  108. ///
  109. template<typename Expr, typename Context>
  110. typename proto::result_of::eval<Expr const, Context>::type
  111. eval(Expr const &e, Context &ctx)
  112. {
  113. return typename Context::template eval<Expr const>()(e, ctx);
  114. }
  115. /// \overload
  116. ///
  117. template<typename Expr, typename Context>
  118. typename proto::result_of::eval<Expr const, Context>::type
  119. eval(Expr const &e, Context const &ctx)
  120. {
  121. return typename Context::template eval<Expr const>()(e, ctx);
  122. }
  123. }}
  124. #endif