as_expr.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file as_expr.hpp
  3. /// Contains definition of the as_expr\<\> and as_child\<\> helper class
  4. /// templates used to implement proto::domain's as_expr\<\> and as_child\<\>
  5. /// member templates.
  6. //
  7. // Copyright 2010 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_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
  11. #define BOOST_PROTO_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
  12. #include <boost/config.hpp>
  13. #include <boost/detail/workaround.hpp>
  14. #include <boost/type_traits/remove_const.hpp>
  15. #include <boost/proto/proto_fwd.hpp>
  16. #include <boost/proto/args.hpp>
  17. #if defined(_MSC_VER)
  18. # pragma warning(push)
  19. # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
  20. #endif
  21. namespace boost { namespace proto { namespace detail
  22. {
  23. ////////////////////////////////////////////////////////////////////////////////////////////////
  24. template<typename Generator>
  25. struct base_generator
  26. {
  27. typedef Generator type;
  28. };
  29. template<typename Generator>
  30. struct base_generator<use_basic_expr<Generator> >
  31. {
  32. typedef Generator type;
  33. };
  34. ////////////////////////////////////////////////////////////////////////////////////////////////
  35. template<typename T, typename Generator, bool WantsBasicExpr>
  36. struct as_expr;
  37. ////////////////////////////////////////////////////////////////////////////////////////////////
  38. template<typename T, typename Generator>
  39. struct as_expr<T, Generator, false>
  40. {
  41. typedef typename term_traits<T &>::value_type value_type;
  42. typedef proto::expr<proto::tag::terminal, term<value_type>, 0> expr_type;
  43. typedef typename Generator::template result<Generator(expr_type)>::type result_type;
  44. BOOST_FORCEINLINE
  45. result_type operator()(T &t) const
  46. {
  47. return Generator()(expr_type::make(t));
  48. }
  49. };
  50. ////////////////////////////////////////////////////////////////////////////////////////////////
  51. template<typename T, typename Generator>
  52. struct as_expr<T, Generator, true>
  53. {
  54. typedef typename term_traits<T &>::value_type value_type;
  55. typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> expr_type;
  56. typedef typename Generator::template result<Generator(expr_type)>::type result_type;
  57. BOOST_FORCEINLINE
  58. result_type operator()(T &t) const
  59. {
  60. return Generator()(expr_type::make(t));
  61. }
  62. };
  63. ////////////////////////////////////////////////////////////////////////////////////////////////
  64. template<typename T>
  65. struct as_expr<T, proto::default_generator, false>
  66. {
  67. typedef typename term_traits<T &>::value_type value_type;
  68. typedef proto::expr<proto::tag::terminal, term<value_type>, 0> result_type;
  69. BOOST_FORCEINLINE
  70. result_type operator()(T &t) const
  71. {
  72. return result_type::make(t);
  73. }
  74. };
  75. ////////////////////////////////////////////////////////////////////////////////////////////////
  76. template<typename T>
  77. struct as_expr<T, proto::default_generator, true>
  78. {
  79. typedef typename term_traits<T &>::value_type value_type;
  80. typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> result_type;
  81. BOOST_FORCEINLINE
  82. result_type operator()(T &t) const
  83. {
  84. return result_type::make(t);
  85. }
  86. };
  87. ////////////////////////////////////////////////////////////////////////////////////////////////
  88. template<typename T, typename Generator, bool WantsBasicExpr>
  89. struct as_child;
  90. ////////////////////////////////////////////////////////////////////////////////////////////////
  91. template<typename T, typename Generator>
  92. struct as_child<T, Generator, false>
  93. {
  94. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
  95. typedef typename term_traits<T &>::reference reference;
  96. #else
  97. typedef T &reference;
  98. #endif
  99. typedef proto::expr<proto::tag::terminal, term<reference>, 0> expr_type;
  100. typedef typename Generator::template result<Generator(expr_type)>::type result_type;
  101. BOOST_FORCEINLINE
  102. result_type operator()(T &t) const
  103. {
  104. return Generator()(expr_type::make(t));
  105. }
  106. };
  107. ////////////////////////////////////////////////////////////////////////////////////////////////
  108. template<typename T, typename Generator>
  109. struct as_child<T, Generator, true>
  110. {
  111. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
  112. typedef typename term_traits<T &>::reference reference;
  113. #else
  114. typedef T &reference;
  115. #endif
  116. typedef proto::basic_expr<proto::tag::terminal, term<reference>, 0> expr_type;
  117. typedef typename Generator::template result<Generator(expr_type)>::type result_type;
  118. BOOST_FORCEINLINE
  119. result_type operator()(T &t) const
  120. {
  121. return Generator()(expr_type::make(t));
  122. }
  123. };
  124. ////////////////////////////////////////////////////////////////////////////////////////////////
  125. template<typename T>
  126. struct as_child<T, proto::default_generator, false>
  127. {
  128. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
  129. typedef typename term_traits<T &>::reference reference;
  130. #else
  131. typedef T &reference;
  132. #endif
  133. typedef proto::expr<proto::tag::terminal, term<reference>, 0> result_type;
  134. BOOST_FORCEINLINE
  135. result_type operator()(T &t) const
  136. {
  137. return result_type::make(t);
  138. }
  139. };
  140. ////////////////////////////////////////////////////////////////////////////////////////////////
  141. template<typename T>
  142. struct as_child<T, proto::default_generator, true>
  143. {
  144. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
  145. typedef typename term_traits<T &>::reference reference;
  146. #else
  147. typedef T &reference;
  148. #endif
  149. typedef proto::basic_expr<proto::tag::terminal, term<reference>, 0> result_type;
  150. BOOST_FORCEINLINE
  151. result_type operator()(T &t) const
  152. {
  153. return result_type::make(t);
  154. }
  155. };
  156. }}}
  157. #if defined(_MSC_VER)
  158. # pragma warning(pop)
  159. #endif
  160. #endif