is_pure.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // is_pure.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_IS_PURE_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_STATIC_IS_PURE_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/ref.hpp>
  14. #include <boost/mpl/and.hpp>
  15. #include <boost/mpl/bool.hpp>
  16. #include <boost/mpl/assert.hpp>
  17. #include <boost/mpl/not_equal_to.hpp>
  18. #include <boost/xpressive/detail/detail_fwd.hpp>
  19. #include <boost/xpressive/detail/static/width_of.hpp>
  20. namespace boost { namespace xpressive { namespace detail
  21. {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // use_simple_repeat_terminal
  24. //
  25. template<typename Expr, typename Char, bool IsXpr = is_xpr<Expr>::value>
  26. struct use_simple_repeat_terminal
  27. : mpl::bool_<
  28. Expr::quant == quant_fixed_width
  29. || (Expr::width != unknown_width::value && Expr::pure)
  30. >
  31. {};
  32. template<typename Expr, typename Char>
  33. struct use_simple_repeat_terminal<Expr, Char, false>
  34. : mpl::true_ // char literals, string literals, etc.
  35. {};
  36. template<typename BidiIter, typename Char>
  37. struct use_simple_repeat_terminal<tracking_ptr<regex_impl<BidiIter> >, Char, false>
  38. : mpl::false_ // basic_regex
  39. {};
  40. template<typename BidiIter, typename Char>
  41. struct use_simple_repeat_terminal<reference_wrapper<basic_regex<BidiIter> >, Char, false>
  42. : mpl::false_ // basic_regex
  43. {};
  44. template<typename BidiIter, typename Char>
  45. struct use_simple_repeat_terminal<reference_wrapper<basic_regex<BidiIter> const>, Char, false>
  46. : mpl::false_ // basic_regex
  47. {};
  48. ///////////////////////////////////////////////////////////////////////////////
  49. // use_simple_repeat_
  50. //
  51. template<typename Expr, typename Char, typename Tag = typename Expr::proto_tag>
  52. struct use_simple_repeat_
  53. {};
  54. template<typename Expr, typename Char>
  55. struct use_simple_repeat_<Expr, Char, proto::tag::terminal>
  56. : use_simple_repeat_terminal<typename proto::result_of::value<Expr>::type, Char>
  57. {};
  58. template<typename Expr, typename Char>
  59. struct use_simple_repeat_<Expr, Char, proto::tag::shift_right>
  60. : mpl::and_<
  61. use_simple_repeat_<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
  62. , use_simple_repeat_<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
  63. >
  64. {};
  65. template<typename Expr, typename Char>
  66. struct use_simple_repeat_<Expr, Char, proto::tag::bitwise_or>
  67. : mpl::and_<
  68. mpl::not_equal_to<unknown_width, width_of<Expr, Char> >
  69. , use_simple_repeat_<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
  70. , use_simple_repeat_<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
  71. >
  72. {};
  73. template<typename Left>
  74. struct use_simple_repeat_assign
  75. {};
  76. template<>
  77. struct use_simple_repeat_assign<mark_placeholder>
  78. : mpl::false_
  79. {};
  80. template<>
  81. struct use_simple_repeat_assign<set_initializer>
  82. : mpl::true_
  83. {};
  84. template<typename Nbr>
  85. struct use_simple_repeat_assign<attribute_placeholder<Nbr> >
  86. : mpl::false_
  87. {};
  88. // either (s1 = ...) or (a1 = ...) or (set = ...)
  89. template<typename Expr, typename Char>
  90. struct use_simple_repeat_<Expr, Char, proto::tag::assign>
  91. : use_simple_repeat_assign<
  92. typename proto::result_of::value<
  93. typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr
  94. >::type
  95. >
  96. {};
  97. template<typename Expr, typename Char>
  98. struct use_simple_repeat_<Expr, Char, modifier_tag>
  99. : use_simple_repeat_<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
  100. {};
  101. template<typename Expr, typename Char>
  102. struct use_simple_repeat_<Expr, Char, lookahead_tag>
  103. : mpl::false_
  104. {};
  105. template<typename Expr, typename Char>
  106. struct use_simple_repeat_<Expr, Char, lookbehind_tag>
  107. : mpl::false_
  108. {};
  109. template<typename Expr, typename Char>
  110. struct use_simple_repeat_<Expr, Char, keeper_tag>
  111. : mpl::false_
  112. {};
  113. // when complementing a set or an assertion, the purity is that of the set (true) or the assertion
  114. template<typename Expr, typename Char>
  115. struct use_simple_repeat_<Expr, Char, proto::tag::complement>
  116. : use_simple_repeat_<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
  117. {};
  118. // The comma is used in list-initialized sets, which are pure
  119. template<typename Expr, typename Char>
  120. struct use_simple_repeat_<Expr, Char, proto::tag::comma>
  121. : mpl::true_
  122. {};
  123. // The subscript operator[] is used for sets, as in set['a' | range('b','h')]
  124. // It is also used for actions, which by definition have side-effects and thus are impure
  125. template<typename Expr, typename Char, typename Left>
  126. struct use_simple_repeat_subscript
  127. : mpl::false_
  128. {};
  129. template<typename Expr, typename Char>
  130. struct use_simple_repeat_subscript<Expr, Char, set_initializer_type>
  131. : mpl::true_
  132. {};
  133. template<typename Expr, typename Char>
  134. struct use_simple_repeat_<Expr, Char, proto::tag::subscript>
  135. : use_simple_repeat_subscript<Expr, Char, typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr>
  136. {};
  137. // Quantified expressions are variable-width and cannot use the simple quantifier
  138. template<typename Expr, typename Char>
  139. struct use_simple_repeat_<Expr, Char, proto::tag::unary_plus>
  140. : mpl::false_
  141. {};
  142. template<typename Expr, typename Char>
  143. struct use_simple_repeat_<Expr, Char, proto::tag::dereference>
  144. : mpl::false_
  145. {};
  146. template<typename Expr, typename Char>
  147. struct use_simple_repeat_<Expr, Char, proto::tag::logical_not>
  148. : mpl::false_
  149. {};
  150. template<typename Expr, typename Char, uint_t Min, uint_t Max>
  151. struct use_simple_repeat_<Expr, Char, generic_quant_tag<Min, Max> >
  152. : mpl::false_
  153. {};
  154. template<typename Expr, typename Char, uint_t Count>
  155. struct use_simple_repeat_<Expr, Char, generic_quant_tag<Count, Count> >
  156. : use_simple_repeat_<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
  157. {};
  158. template<typename Expr, typename Char>
  159. struct use_simple_repeat_<Expr, Char, proto::tag::negate>
  160. : use_simple_repeat_<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
  161. {};
  162. ///////////////////////////////////////////////////////////////////////////////
  163. // use_simple_repeat
  164. //
  165. template<typename Expr, typename Char>
  166. struct use_simple_repeat
  167. : use_simple_repeat_<Expr, Char>
  168. {
  169. // should never try to repeat something of 0-width
  170. BOOST_MPL_ASSERT_RELATION(0, !=, (width_of<Expr, Char>::value));
  171. };
  172. template<typename Expr, typename Char>
  173. struct use_simple_repeat<Expr &, Char>
  174. : use_simple_repeat_<Expr, Char>
  175. {
  176. // should never try to repeat something of 0-width
  177. BOOST_MPL_ASSERT_RELATION(0, !=, (width_of<Expr, Char>::value));
  178. };
  179. }}} // namespace boost::xpressive::detail
  180. #endif