File indexing completed on 2025-01-18 09:53:48
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOOKAHEAD_MATCHER_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOOKAHEAD_MATCHER_HPP_EAN_10_04_2005
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/assert.hpp>
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/core/quant_style.hpp>
0020 #include <boost/xpressive/detail/core/state.hpp>
0021 #include <boost/xpressive/detail/utility/save_restore.hpp>
0022 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
0023
0024 namespace boost { namespace xpressive { namespace detail
0025 {
0026
0027
0028
0029
0030
0031 template<typename Xpr>
0032 struct lookahead_matcher
0033 : quant_style<quant_none, 0, Xpr::pure>
0034 {
0035 lookahead_matcher(Xpr const &xpr, bool no, bool pure = Xpr::pure)
0036 : xpr_(xpr)
0037 , not_(no)
0038 , pure_(pure)
0039 {
0040 }
0041
0042 void inverse()
0043 {
0044 this->not_ = !this->not_;
0045 }
0046
0047 template<typename BidiIter, typename Next>
0048 bool match(match_state<BidiIter> &state, Next const &next) const
0049 {
0050 return Xpr::pure || this->pure_
0051 ? this->match_(state, next, mpl::true_())
0052 : this->match_(state, next, mpl::false_());
0053 }
0054
0055 template<typename BidiIter, typename Next>
0056 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const
0057 {
0058 BidiIter const tmp = state.cur_;
0059
0060 if(this->not_)
0061 {
0062
0063 save_restore<bool> partial_match(state.found_partial_match_);
0064 detail::ignore_unused(partial_match);
0065
0066 if(this->xpr_.match(state))
0067 {
0068 state.cur_ = tmp;
0069 return false;
0070 }
0071 else if(next.match(state))
0072 {
0073 return true;
0074 }
0075 }
0076 else
0077 {
0078 if(!this->xpr_.match(state))
0079 {
0080 return false;
0081 }
0082 state.cur_ = tmp;
0083 if(next.match(state))
0084 {
0085 return true;
0086 }
0087 }
0088
0089 BOOST_ASSERT(state.cur_ == tmp);
0090 return false;
0091 }
0092
0093 template<typename BidiIter, typename Next>
0094 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
0095 {
0096 BidiIter const tmp = state.cur_;
0097
0098
0099 memento<BidiIter> mem = save_sub_matches(state);
0100
0101 if(this->not_)
0102 {
0103
0104 save_restore<bool> partial_match(state.found_partial_match_);
0105 detail::ignore_unused(partial_match);
0106
0107 if(this->xpr_.match(state))
0108 {
0109 restore_action_queue(mem, state);
0110 restore_sub_matches(mem, state);
0111 state.cur_ = tmp;
0112 return false;
0113 }
0114 restore_action_queue(mem, state);
0115 if(next.match(state))
0116 {
0117 reclaim_sub_matches(mem, state, true);
0118 return true;
0119 }
0120 reclaim_sub_matches(mem, state, false);
0121 }
0122 else
0123 {
0124 if(!this->xpr_.match(state))
0125 {
0126 restore_action_queue(mem, state);
0127 reclaim_sub_matches(mem, state, false);
0128 return false;
0129 }
0130 state.cur_ = tmp;
0131 restore_action_queue(mem, state);
0132 if(next.match(state))
0133 {
0134 reclaim_sub_matches(mem, state, true);
0135 return true;
0136 }
0137 restore_sub_matches(mem, state);
0138 }
0139
0140 BOOST_ASSERT(state.cur_ == tmp);
0141 return false;
0142 }
0143
0144 Xpr xpr_;
0145 bool not_;
0146 bool pure_;
0147 };
0148
0149 }}}
0150
0151 #endif