1 /*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
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 #if !defined(BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM)
8 #define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM
14 #include <boost/spirit/home/qi/parse.hpp>
15 #include <boost/spirit/home/support/iterators/istream_iterator.hpp>
16 #include <boost/spirit/home/support/unused.hpp>
17 #include <boost/mpl/bool.hpp>
22 ///////////////////////////////////////////////////////////////////////////////
23 namespace boost { namespace spirit { namespace qi { namespace detail
25 ///////////////////////////////////////////////////////////////////////////
26 template <typename Expr
27 , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
28 , typename Skipper = unused_type, typename Attribute = unused_type const>
31 // This assertion makes sure we don't hit the only code path which is
32 // not implemented (because it isn't needed), where both, the
33 // expression and the attribute need to be held as a copy.
34 BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
35 , 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) {}
40 match_manip(Expr const& xpr, Skipper const& s
41 , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
42 : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
45 Skipper const& skipper;
47 BOOST_SCOPED_ENUM(skip_flag) const post_skip;
50 // silence MSVC warning C4512: assignment operator could not be generated
51 match_manip& operator= (match_manip const&);
54 template <typename Expr, typename Skipper, typename Attribute>
55 struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute>
57 match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
58 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
60 match_manip(Expr const& xpr, Skipper const& s
61 , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
62 : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
65 Skipper const& skipper;
67 BOOST_SCOPED_ENUM(skip_flag) const post_skip;
70 // silence MSVC warning C4512: assignment operator could not be generated
71 match_manip& operator= (match_manip const&);
74 template <typename Expr, typename Skipper, typename Attribute>
75 struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute>
77 match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
78 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
80 match_manip(Expr const& xpr, Skipper const& s
81 , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
82 : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
85 Skipper const& skipper;
87 BOOST_SCOPED_ENUM(skip_flag) const post_skip;
90 // silence MSVC warning C4512: assignment operator could not be generated
91 match_manip& operator= (match_manip const&);
94 ///////////////////////////////////////////////////////////////////////////
95 template <typename Expr, typename Enable = void>
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);
106 template <typename Expr>
108 , typename enable_if<traits::matches<qi::domain, Expr> >::type>
110 typedef match_manip<Expr> type;
112 static type call(Expr const& expr)
114 return type(expr, unused, unused);
118 ///////////////////////////////////////////////////////////////////////////
119 template <typename Expr, typename Skipper, typename Enable = void>
122 // Report invalid expression error as early as possible.
123 // If you got an error_invalid_expression error message here,
124 // then the expression (expr) is not a valid spirit qi expression.
125 // Did you intend to use the auto_ facilities while forgetting to
126 // #include <boost/spirit/include/qi_match_auto.hpp>?
127 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
130 template <typename Expr, typename Skipper>
131 struct phrase_match<Expr, Skipper
132 , typename enable_if<traits::matches<qi::domain, Expr> >::type>
134 typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type;
138 , Skipper const& skipper
139 , BOOST_SCOPED_ENUM(skip_flag) post_skip)
141 // Report invalid expression error as early as possible.
142 // If you got an error_invalid_expression error message here,
143 // then the delimiter is not a valid spirit karma expression.
144 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
145 return type(expr, skipper, post_skip, unused);
149 ///////////////////////////////////////////////////////////////////////////
150 template<typename Char, typename Traits, typename Expr
151 , typename CopyExpr, typename CopyAttr>
152 inline std::basic_istream<Char, Traits> &
153 operator>>(std::basic_istream<Char, Traits> &is,
154 match_manip<Expr, CopyExpr, CopyAttr> const& fm)
156 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
158 input_iterator f(is);
160 if (!qi::parse(f, l, fm.expr))
162 is.setstate(std::ios_base::failbit);
167 ///////////////////////////////////////////////////////////////////////////
168 template<typename Char, typename Traits, typename Expr
169 , typename CopyExpr, typename CopyAttr
170 , typename Attribute>
171 inline std::basic_istream<Char, Traits> &
172 operator>>(std::basic_istream<Char, Traits> &is,
173 match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
175 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
177 input_iterator f(is);
179 if (!qi::parse(f, l, fm.expr, fm.attr))
181 is.setstate(std::ios_base::failbit);
186 ///////////////////////////////////////////////////////////////////////////
187 template<typename Char, typename Traits, typename Expr
188 , typename CopyExpr, typename CopyAttr
190 inline std::basic_istream<Char, Traits> &
191 operator>>(std::basic_istream<Char, Traits> &is,
192 match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
194 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
196 input_iterator f(is);
198 if (!qi::phrase_parse(
199 f, l, fm.expr, fm.skipper, fm.post_skip))
201 is.setstate(std::ios_base::failbit);
206 ///////////////////////////////////////////////////////////////////////////
207 template<typename Char, typename Traits, typename Expr
208 , typename CopyExpr, typename CopyAttr
209 , typename Attribute, typename Skipper
211 inline std::basic_istream<Char, Traits> &
213 std::basic_istream<Char, Traits> &is,
214 match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
216 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
218 input_iterator f(is);
220 if (!qi::phrase_parse(
221 f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr))
223 is.setstate(std::ios_base::failbit);