9
3

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