Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:48

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // lookahead_matcher.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // MS compatible compilers support #pragma once
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     // lookahead_matcher
0029     //   Xpr can be either a static_xpression, or a shared_matchable
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                 // negative look-ahead assertions do not trigger partial matches.
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             // matching xpr could produce side-effects, save state
0099             memento<BidiIter> mem = save_sub_matches(state);
0100 
0101             if(this->not_)
0102             {
0103                 // negative look-ahead assertions do not trigger partial matches.
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_; // false if matching xpr_ could modify the sub-matches
0147     };
0148 
0149 }}}
0150 
0151 #endif