match_manip.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Hartmut Kaiser
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM)
  7. #define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/parse.hpp>
  12. #include <boost/spirit/home/support/iterators/istream_iterator.hpp>
  13. #include <boost/spirit/home/support/unused.hpp>
  14. #include <boost/core/enable_if.hpp>
  15. #include <boost/mpl/bool.hpp>
  16. #include <iosfwd>
  17. #include <iterator>
  18. #include <string>
  19. ///////////////////////////////////////////////////////////////////////////////
  20. namespace boost { namespace spirit { namespace qi { namespace detail
  21. {
  22. ///////////////////////////////////////////////////////////////////////////
  23. #ifdef _MSC_VER
  24. # pragma warning(push)
  25. # pragma warning(disable: 4512) // assignment operator could not be generated.
  26. #endif
  27. template <typename Expr
  28. , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
  29. , typename Skipper = unused_type, typename Attribute = unused_type const>
  30. struct match_manip
  31. {
  32. // This assertion makes sure we don't hit the only code path which is
  33. // not implemented (because it isn't needed), where both, the
  34. // expression and the attribute need to be held as a copy.
  35. BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
  36. , error_invalid_should_not_happen, ());
  37. match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
  38. : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
  39. match_manip(Expr const& xpr, Skipper const& s
  40. , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
  41. : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
  42. Expr const& expr;
  43. Skipper const& skipper;
  44. Attribute& attr;
  45. BOOST_SCOPED_ENUM(skip_flag) const post_skip;
  46. };
  47. template <typename Expr, typename Skipper, typename Attribute>
  48. struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute>
  49. {
  50. match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
  51. : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
  52. match_manip(Expr const& xpr, Skipper const& s
  53. , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
  54. : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
  55. Expr const& expr;
  56. Skipper const& skipper;
  57. Attribute attr;
  58. BOOST_SCOPED_ENUM(skip_flag) const post_skip;
  59. };
  60. template <typename Expr, typename Skipper, typename Attribute>
  61. struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute>
  62. {
  63. match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
  64. : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
  65. match_manip(Expr const& xpr, Skipper const& s
  66. , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
  67. : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
  68. Expr expr;
  69. Skipper const& skipper;
  70. Attribute& attr;
  71. BOOST_SCOPED_ENUM(skip_flag) const post_skip;
  72. };
  73. #ifdef _MSC_VER
  74. # pragma warning(pop)
  75. #endif
  76. ///////////////////////////////////////////////////////////////////////////
  77. template <typename Expr, typename Enable = void>
  78. struct match
  79. {
  80. // Report invalid expression error as early as possible.
  81. // If you got an error_invalid_expression error message here,
  82. // then the expression (expr) is not a valid spirit qi expression.
  83. // Did you intend to use the auto_ facilities while forgetting to
  84. // #include <boost/spirit/include/qi_match_auto.hpp>?
  85. BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
  86. };
  87. template <typename Expr>
  88. struct match<Expr
  89. , typename enable_if<traits::matches<qi::domain, Expr> >::type>
  90. {
  91. typedef match_manip<Expr> type;
  92. static type call(Expr const& expr)
  93. {
  94. return type(expr, unused, unused);
  95. }
  96. };
  97. ///////////////////////////////////////////////////////////////////////////
  98. template <typename Expr, typename Skipper, typename Enable = void>
  99. struct phrase_match
  100. {
  101. // Report invalid expression error as early as possible.
  102. // If you got an error_invalid_expression error message here,
  103. // then the expression (expr) is not a valid spirit qi expression.
  104. // Did you intend to use the auto_ facilities while forgetting to
  105. // #include <boost/spirit/include/qi_match_auto.hpp>?
  106. BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
  107. };
  108. template <typename Expr, typename Skipper>
  109. struct phrase_match<Expr, Skipper
  110. , typename enable_if<traits::matches<qi::domain, Expr> >::type>
  111. {
  112. typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type;
  113. static type call(
  114. Expr const& expr
  115. , Skipper const& skipper
  116. , BOOST_SCOPED_ENUM(skip_flag) post_skip)
  117. {
  118. // Report invalid expression error as early as possible.
  119. // If you got an error_invalid_expression error message here,
  120. // then the delimiter is not a valid spirit karma expression.
  121. BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
  122. return type(expr, skipper, post_skip, unused);
  123. }
  124. };
  125. ///////////////////////////////////////////////////////////////////////////
  126. template<typename Char, typename Traits, typename Expr
  127. , typename CopyExpr, typename CopyAttr>
  128. inline std::basic_istream<Char, Traits> &
  129. operator>>(std::basic_istream<Char, Traits> &is,
  130. match_manip<Expr, CopyExpr, CopyAttr> const& fm)
  131. {
  132. typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
  133. input_iterator f(is);
  134. input_iterator l;
  135. if (!qi::parse(f, l, fm.expr))
  136. {
  137. is.setstate(std::basic_istream<Char, Traits>::failbit);
  138. }
  139. return is;
  140. }
  141. ///////////////////////////////////////////////////////////////////////////
  142. template<typename Char, typename Traits, typename Expr
  143. , typename CopyExpr, typename CopyAttr
  144. , typename Attribute>
  145. inline std::basic_istream<Char, Traits> &
  146. operator>>(std::basic_istream<Char, Traits> &is,
  147. match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
  148. {
  149. typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
  150. input_iterator f(is);
  151. input_iterator l;
  152. if (!qi::parse(f, l, fm.expr, fm.attr))
  153. {
  154. is.setstate(std::basic_istream<Char, Traits>::failbit);
  155. }
  156. return is;
  157. }
  158. ///////////////////////////////////////////////////////////////////////////
  159. template<typename Char, typename Traits, typename Expr
  160. , typename CopyExpr, typename CopyAttr
  161. , typename Skipper>
  162. inline std::basic_istream<Char, Traits> &
  163. operator>>(std::basic_istream<Char, Traits> &is,
  164. match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
  165. {
  166. typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
  167. input_iterator f(is);
  168. input_iterator l;
  169. if (!qi::phrase_parse(
  170. f, l, fm.expr, fm.skipper, fm.post_skip))
  171. {
  172. is.setstate(std::basic_istream<Char, Traits>::failbit);
  173. }
  174. return is;
  175. }
  176. ///////////////////////////////////////////////////////////////////////////
  177. template<typename Char, typename Traits, typename Expr
  178. , typename CopyExpr, typename CopyAttr
  179. , typename Attribute, typename Skipper
  180. >
  181. inline std::basic_istream<Char, Traits> &
  182. operator>>(
  183. std::basic_istream<Char, Traits> &is,
  184. match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
  185. {
  186. typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
  187. input_iterator f(is);
  188. input_iterator l;
  189. if (!qi::phrase_parse(
  190. f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr))
  191. {
  192. is.setstate(std::basic_istream<Char, Traits>::failbit);
  193. }
  194. return is;
  195. }
  196. }}}}
  197. #endif