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;
49 // silence MSVC warning C4512: assignment operator could not be generated
50 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&))
53 template <typename Expr, typename Skipper, typename Attribute>
54 struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute>
56 match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
57 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
59 match_manip(Expr const& xpr, Skipper const& s
60 , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
61 : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
64 Skipper const& skipper;
66 BOOST_SCOPED_ENUM(skip_flag) const post_skip;
68 // silence MSVC warning C4512: assignment operator could not be generated
69 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&))
72 template <typename Expr, typename Skipper, typename Attribute>
73 struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute>
75 match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
76 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
78 match_manip(Expr const& xpr, Skipper const& s
79 , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
80 : expr(xpr), skipper(s), attr(a), post_skip(ps) {}
83 Skipper const& skipper;
85 BOOST_SCOPED_ENUM(skip_flag) const post_skip;
87 // silence MSVC warning C4512: assignment operator could not be generated
88 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&))
91 ///////////////////////////////////////////////////////////////////////////
92 template <typename Expr, typename Enable = void>
95 // Report invalid expression error as early as possible.
96 // If you got an error_invalid_expression error message here,
97 // then the expression (expr) is not a valid spirit qi expression.
98 // Did you intend to use the auto_ facilities while forgetting to
99 // #include <boost/spirit/include/qi_match_auto.hpp>?
100 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
103 template <typename Expr>
105 , typename enable_if<traits::matches<qi::domain, Expr> >::type>
107 typedef match_manip<Expr> type;
109 static type call(Expr const& expr)
111 return type(expr, unused, unused);
115 ///////////////////////////////////////////////////////////////////////////
116 template <typename Expr, typename Skipper, typename Enable = void>
119 // Report invalid expression error as early as possible.
120 // If you got an error_invalid_expression error message here,
121 // then the expression (expr) is not a valid spirit qi expression.
122 // Did you intend to use the auto_ facilities while forgetting to
123 // #include <boost/spirit/include/qi_match_auto.hpp>?
124 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
127 template <typename Expr, typename Skipper>
128 struct phrase_match<Expr, Skipper
129 , typename enable_if<traits::matches<qi::domain, Expr> >::type>
131 typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type;
135 , Skipper const& skipper
136 , BOOST_SCOPED_ENUM(skip_flag) post_skip)
138 // Report invalid expression error as early as possible.
139 // If you got an error_invalid_expression error message here,
140 // then the delimiter is not a valid spirit karma expression.
141 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
142 return type(expr, skipper, post_skip, unused);
146 ///////////////////////////////////////////////////////////////////////////
147 template<typename Char, typename Traits, typename Expr
148 , typename CopyExpr, typename CopyAttr>
149 inline std::basic_istream<Char, Traits> &
150 operator>>(std::basic_istream<Char, Traits> &is,
151 match_manip<Expr, CopyExpr, CopyAttr> const& fm)
153 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
155 input_iterator f(is);
157 if (!qi::parse(f, l, fm.expr))
159 is.setstate(std::ios_base::failbit);
164 ///////////////////////////////////////////////////////////////////////////
165 template<typename Char, typename Traits, typename Expr
166 , typename CopyExpr, typename CopyAttr
167 , typename Attribute>
168 inline std::basic_istream<Char, Traits> &
169 operator>>(std::basic_istream<Char, Traits> &is,
170 match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
172 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
174 input_iterator f(is);
176 if (!qi::parse(f, l, fm.expr, fm.attr))
178 is.setstate(std::ios_base::failbit);
183 ///////////////////////////////////////////////////////////////////////////
184 template<typename Char, typename Traits, typename Expr
185 , typename CopyExpr, typename CopyAttr
187 inline std::basic_istream<Char, Traits> &
188 operator>>(std::basic_istream<Char, Traits> &is,
189 match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
191 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
193 input_iterator f(is);
195 if (!qi::phrase_parse(
196 f, l, fm.expr, fm.skipper, fm.post_skip))
198 is.setstate(std::ios_base::failbit);
203 ///////////////////////////////////////////////////////////////////////////
204 template<typename Char, typename Traits, typename Expr
205 , typename CopyExpr, typename CopyAttr
206 , typename Attribute, typename Skipper
208 inline std::basic_istream<Char, Traits> &
210 std::basic_istream<Char, Traits> &is,
211 match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
213 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
215 input_iterator f(is);
217 if (!qi::phrase_parse(
218 f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr))
220 is.setstate(std::ios_base::failbit);