• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 // mark_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_MARK_MATCHER_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_MARK_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/assert.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 #include <boost/xpressive/detail/utility/traits_utils.hpp>
21 
22 namespace boost { namespace xpressive { namespace detail
23 {
24 
25     // TODO: the mark matcher is acually a fixed-width matcher, but the width is
26     // not known until pattern match time.
27 
28     ///////////////////////////////////////////////////////////////////////////////
29     // mark_matcher
30     //
31     template<typename Traits, typename ICase>
32     struct mark_matcher
33       : quant_style_variable_width
34     {
35         typedef ICase icase_type;
36         int mark_number_;
37 
mark_matcherboost::xpressive::detail::mark_matcher38         mark_matcher(int mark_number, Traits const &)
39           : mark_number_(mark_number)
40         {
41         }
42 
43         template<typename BidiIter, typename Next>
matchboost::xpressive::detail::mark_matcher44         bool match(match_state<BidiIter> &state, Next const &next) const
45         {
46             BOOST_ASSERT(this->mark_number_ < static_cast<int>(state.mark_count_));
47             sub_match_impl<BidiIter> const &br = state.sub_match(this->mark_number_);
48 
49             if(!br.matched)
50             {
51                 return false;
52             }
53 
54             BidiIter const tmp = state.cur_;
55             for(BidiIter begin = br.first, end = br.second; begin != end; ++begin, ++state.cur_)
56             {
57                 if(state.eos()
58                     || detail::translate(*state.cur_, traits_cast<Traits>(state), icase_type())
59                     != detail::translate(*begin, traits_cast<Traits>(state), icase_type()))
60                 {
61                     state.cur_ = tmp;
62                     return false;
63                 }
64             }
65 
66             if(next.match(state))
67             {
68                 return true;
69             }
70 
71             state.cur_ = tmp;
72             return false;
73         }
74     };
75 
76 }}}
77 
78 #endif
79