1 /////////////////////////////////////////////////////////////////////////////// 2 // optional_matcher.hpp 3 // 4 // Copyright 2008 Eric Niebler. Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_OPTIONAL_MATCHER_HPP_EAN_10_04_2005 9 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_OPTIONAL_MATCHER_HPP_EAN_10_04_2005 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/mpl/bool.hpp> 17 #include <boost/xpressive/detail/detail_fwd.hpp> 18 #include <boost/xpressive/detail/core/quant_style.hpp> 19 #include <boost/xpressive/detail/core/state.hpp> 20 21 namespace boost { namespace xpressive { namespace detail 22 { 23 24 /////////////////////////////////////////////////////////////////////////////// 25 // optional_matcher 26 template<typename Xpr, typename Greedy> 27 struct optional_matcher 28 : quant_style<quant_variable_width, unknown_width::value, Xpr::pure> 29 { 30 Xpr xpr_; 31 optional_matcherboost::xpressive::detail::optional_matcher32 explicit optional_matcher(Xpr const &xpr) 33 : xpr_(xpr) 34 { 35 } 36 37 template<typename BidiIter, typename Next> matchboost::xpressive::detail::optional_matcher38 bool match(match_state<BidiIter> &state, Next const &next) const 39 { 40 return this->match_(state, next, Greedy()); 41 } 42 43 private: 44 template<typename BidiIter, typename Next> match_boost::xpressive::detail::optional_matcher45 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const // Greedy 46 { 47 return this->xpr_.BOOST_NESTED_TEMPLATE push_match<Next>(state) 48 || next.match(state); 49 } 50 51 template<typename BidiIter, typename Next> match_boost::xpressive::detail::optional_matcher52 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const // Non-greedy 53 { 54 return next.match(state) 55 || this->xpr_.BOOST_NESTED_TEMPLATE push_match<Next>(state); 56 } 57 58 optional_matcher &operator =(optional_matcher const &); 59 }; 60 61 /////////////////////////////////////////////////////////////////////////////// 62 // optional_mark_matcher 63 template<typename BidiIter, typename Next> match_next(match_state<BidiIter> & state,Next const & next,int mark_number)64 inline bool match_next(match_state<BidiIter> &state, Next const &next, int mark_number) 65 { 66 sub_match_impl<BidiIter> &br = state.sub_match(mark_number); 67 68 bool old_matched = br.matched; 69 br.matched = false; 70 71 if(next.match(state)) 72 { 73 return true; 74 } 75 76 br.matched = old_matched; 77 return false; 78 } 79 80 /////////////////////////////////////////////////////////////////////////////// 81 // optional_mark_matcher 82 template<typename Xpr, typename Greedy> 83 struct optional_mark_matcher 84 : quant_style<quant_variable_width, unknown_width::value, Xpr::pure> 85 { 86 Xpr xpr_; 87 int mark_number_; 88 optional_mark_matcherboost::xpressive::detail::optional_mark_matcher89 explicit optional_mark_matcher(Xpr const &xpr, int mark_number) 90 : xpr_(xpr) 91 , mark_number_(mark_number) 92 { 93 } 94 95 template<typename BidiIter, typename Next> matchboost::xpressive::detail::optional_mark_matcher96 bool match(match_state<BidiIter> &state, Next const &next) const 97 { 98 return this->match_(state, next, Greedy()); 99 } 100 101 private: 102 template<typename BidiIter, typename Next> match_boost::xpressive::detail::optional_mark_matcher103 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const // Greedy 104 { 105 return this->xpr_.BOOST_NESTED_TEMPLATE push_match<Next>(state) 106 || match_next(state, next, this->mark_number_); 107 } 108 109 template<typename BidiIter, typename Next> match_boost::xpressive::detail::optional_mark_matcher110 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const // Non-greedy 111 { 112 return match_next(state, next, this->mark_number_) 113 || this->xpr_.BOOST_NESTED_TEMPLATE push_match<Next>(state); 114 } 115 116 optional_mark_matcher &operator =(optional_mark_matcher const &); 117 }; 118 119 }}} 120 121 #endif 122