reference.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2010 Thomas Heller
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef BOOST_PHOENIX_CORE_REFERENCE_HPP
  8. #define BOOST_PHOENIX_CORE_REFERENCE_HPP
  9. #include <boost/phoenix/core/limits.hpp>
  10. #include <boost/ref.hpp>
  11. #include <boost/phoenix/core/actor.hpp>
  12. #include <boost/phoenix/core/terminal.hpp>
  13. #include <boost/utility/result_of.hpp>
  14. namespace boost { namespace phoenix
  15. {
  16. /////////////////////////////////////////////////////////////////////////////
  17. //
  18. // reference
  19. //
  20. // function for evaluating references, e.g. ref(123)
  21. //
  22. /////////////////////////////////////////////////////////////////////////////
  23. namespace expression
  24. {
  25. template <typename T>
  26. struct reference
  27. : expression::terminal<reference_wrapper<T> >
  28. {
  29. typedef
  30. typename expression::terminal<reference_wrapper<T> >::type
  31. type;
  32. static const type make(T & t)
  33. {
  34. typename reference<T>::type const e = {{boost::ref(t)}};
  35. return e;
  36. }
  37. };
  38. template <typename T>
  39. struct reference<T const>
  40. : expression::terminal<reference_wrapper<T const> >
  41. {
  42. typedef
  43. typename expression::terminal<reference_wrapper<T const> >::type
  44. type;
  45. static const type make(T const & t)
  46. {
  47. typename reference<T const>::type const e = {{boost::cref(t)}};
  48. return e;
  49. }
  50. };
  51. }
  52. namespace rule
  53. {
  54. struct reference
  55. : expression::reference<proto::_>
  56. {};
  57. }
  58. template <typename T>
  59. inline
  60. typename expression::reference<T>::type const
  61. ref(T & t)
  62. {
  63. return expression::reference<T>::make(t);
  64. }
  65. template <typename T>
  66. inline
  67. typename expression::reference<T const>::type const
  68. cref(T const & t)
  69. {
  70. return expression::reference<T const>::make(t);
  71. }
  72. // Call out boost::reference_wrapper for special handling
  73. template<typename T>
  74. struct is_custom_terminal<boost::reference_wrapper<T> >
  75. : mpl::true_
  76. {};
  77. // Special handling for boost::reference_wrapper
  78. template<typename T>
  79. struct custom_terminal<boost::reference_wrapper<T> >
  80. {
  81. typedef T &result_type;
  82. template <typename Context>
  83. T &operator()(boost::reference_wrapper<T> r, Context &) const
  84. {
  85. return r;
  86. }
  87. };
  88. template<typename Expr>
  89. struct custom_terminal<boost::reference_wrapper<actor<Expr> > >
  90. {
  91. template <typename Sig>
  92. struct result;
  93. template <typename This, typename Context>
  94. struct result<This(boost::reference_wrapper<actor<Expr> > const &, Context)>
  95. : boost::result_of<evaluator(actor<Expr> &, Context)>
  96. {};
  97. template <typename This, typename Context>
  98. struct result<This(boost::reference_wrapper<actor<Expr> > &, Context)>
  99. : boost::result_of<evaluator(actor<Expr> &, Context)>
  100. {};
  101. template <typename Context>
  102. typename boost::result_of<evaluator(actor<Expr> &, Context const &)>::type
  103. operator()(boost::reference_wrapper<actor<Expr> > & r, Context const & ctx) const
  104. {
  105. return boost::phoenix::eval(r, ctx);
  106. }
  107. };
  108. template<typename Expr>
  109. struct custom_terminal<boost::reference_wrapper<actor<Expr> const> >
  110. {
  111. template <typename Sig>
  112. struct result;
  113. template <typename This, typename Context>
  114. struct result<This(boost::reference_wrapper<actor<Expr> const> const &, Context)>
  115. : boost::result_of<evaluator(actor<Expr> const&, Context)>
  116. {};
  117. template <typename This, typename Context>
  118. struct result<This(boost::reference_wrapper<actor<Expr> const> &, Context)>
  119. : boost::result_of<evaluator(actor<Expr> const&, Context)>
  120. {};
  121. template <typename Context>
  122. typename boost::result_of<evaluator(actor<Expr> const&, Context const &)>::type
  123. operator()(boost::reference_wrapper<actor<Expr> const> const & r, Context & ctx) const
  124. {
  125. return boost::phoenix::eval(unwrap_ref(r), ctx);
  126. }
  127. };
  128. }}
  129. #endif