1 /*============================================================================= 2 Copyright (c) 2001-2011 Hartmut Kaiser 3 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 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 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> 18 19 #include <iterator> 20 #include <string> 21 22 /////////////////////////////////////////////////////////////////////////////// 23 namespace boost { namespace spirit { namespace qi { namespace detail 24 { 25 /////////////////////////////////////////////////////////////////////////// 26 template <typename Expr 27 , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_ 28 , typename Skipper = unused_type, typename Attribute = unused_type const> 29 struct match_manip 30 { 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, ()); 36 match_manipboost::spirit::qi::detail::match_manip37 match_manip(Expr const& xpr, Skipper const& s, Attribute& a) 38 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} 39 match_manipboost::spirit::qi::detail::match_manip40 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) {} 43 44 Expr const& expr; 45 Skipper const& skipper; 46 Attribute& attr; 47 BOOST_SCOPED_ENUM(skip_flag) const post_skip; 48 49 // silence MSVC warning C4512: assignment operator could not be generated 50 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) 51 }; 52 53 template <typename Expr, typename Skipper, typename Attribute> 54 struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute> 55 { match_manipboost::spirit::qi::detail::match_manip56 match_manip(Expr const& xpr, Skipper const& s, Attribute& a) 57 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} 58 match_manipboost::spirit::qi::detail::match_manip59 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) {} 62 63 Expr const& expr; 64 Skipper const& skipper; 65 Attribute attr; 66 BOOST_SCOPED_ENUM(skip_flag) const post_skip; 67 68 // silence MSVC warning C4512: assignment operator could not be generated 69 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) 70 }; 71 72 template <typename Expr, typename Skipper, typename Attribute> 73 struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute> 74 { match_manipboost::spirit::qi::detail::match_manip75 match_manip(Expr const& xpr, Skipper const& s, Attribute& a) 76 : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} 77 match_manipboost::spirit::qi::detail::match_manip78 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) {} 81 82 Expr expr; 83 Skipper const& skipper; 84 Attribute& attr; 85 BOOST_SCOPED_ENUM(skip_flag) const post_skip; 86 87 // silence MSVC warning C4512: assignment operator could not be generated 88 BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) 89 }; 90 91 /////////////////////////////////////////////////////////////////////////// 92 template <typename Expr, typename Enable = void> 93 struct match 94 { 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); 101 }; 102 103 template <typename Expr> 104 struct match<Expr 105 , typename enable_if<traits::matches<qi::domain, Expr> >::type> 106 { 107 typedef match_manip<Expr> type; 108 callboost::spirit::qi::detail::match109 static type call(Expr const& expr) 110 { 111 return type(expr, unused, unused); 112 } 113 }; 114 115 /////////////////////////////////////////////////////////////////////////// 116 template <typename Expr, typename Skipper, typename Enable = void> 117 struct phrase_match 118 { 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); 125 }; 126 127 template <typename Expr, typename Skipper> 128 struct phrase_match<Expr, Skipper 129 , typename enable_if<traits::matches<qi::domain, Expr> >::type> 130 { 131 typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type; 132 callboost::spirit::qi::detail::phrase_match133 static type call( 134 Expr const& expr 135 , Skipper const& skipper 136 , BOOST_SCOPED_ENUM(skip_flag) post_skip) 137 { 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); 143 } 144 }; 145 146 /////////////////////////////////////////////////////////////////////////// 147 template<typename Char, typename Traits, typename Expr 148 , typename CopyExpr, typename CopyAttr> 149 inline std::basic_istream<Char, Traits> & operator >>(std::basic_istream<Char,Traits> & is,match_manip<Expr,CopyExpr,CopyAttr> const & fm)150 operator>>(std::basic_istream<Char, Traits> &is, 151 match_manip<Expr, CopyExpr, CopyAttr> const& fm) 152 { 153 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; 154 155 input_iterator f(is); 156 input_iterator l; 157 if (!qi::parse(f, l, fm.expr)) 158 { 159 is.setstate(std::ios_base::failbit); 160 } 161 return is; 162 } 163 164 /////////////////////////////////////////////////////////////////////////// 165 template<typename Char, typename Traits, typename Expr 166 , typename CopyExpr, typename CopyAttr 167 , typename Attribute> 168 inline std::basic_istream<Char, Traits> & operator >>(std::basic_istream<Char,Traits> & is,match_manip<Expr,CopyExpr,CopyAttr,unused_type,Attribute> const & fm)169 operator>>(std::basic_istream<Char, Traits> &is, 170 match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm) 171 { 172 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; 173 174 input_iterator f(is); 175 input_iterator l; 176 if (!qi::parse(f, l, fm.expr, fm.attr)) 177 { 178 is.setstate(std::ios_base::failbit); 179 } 180 return is; 181 } 182 183 /////////////////////////////////////////////////////////////////////////// 184 template<typename Char, typename Traits, typename Expr 185 , typename CopyExpr, typename CopyAttr 186 , typename Skipper> 187 inline std::basic_istream<Char, Traits> & operator >>(std::basic_istream<Char,Traits> & is,match_manip<Expr,CopyExpr,CopyAttr,Skipper> const & fm)188 operator>>(std::basic_istream<Char, Traits> &is, 189 match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm) 190 { 191 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; 192 193 input_iterator f(is); 194 input_iterator l; 195 if (!qi::phrase_parse( 196 f, l, fm.expr, fm.skipper, fm.post_skip)) 197 { 198 is.setstate(std::ios_base::failbit); 199 } 200 return is; 201 } 202 203 /////////////////////////////////////////////////////////////////////////// 204 template<typename Char, typename Traits, typename Expr 205 , typename CopyExpr, typename CopyAttr 206 , typename Attribute, typename Skipper 207 > 208 inline std::basic_istream<Char, Traits> & operator >>(std::basic_istream<Char,Traits> & is,match_manip<Expr,CopyExpr,CopyAttr,Attribute,Skipper> const & fm)209 operator>>( 210 std::basic_istream<Char, Traits> &is, 211 match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm) 212 { 213 typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; 214 215 input_iterator f(is); 216 input_iterator l; 217 if (!qi::phrase_parse( 218 f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr)) 219 { 220 is.setstate(std::ios_base::failbit); 221 } 222 return is; 223 } 224 225 }}}} 226 227 #endif 228