• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 // repeat_end_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_REPEAT_BEGIN_MATCHER_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_REPEAT_BEGIN_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/xpressive/detail/detail_fwd.hpp>
17 #include <boost/xpressive/detail/core/quant_style.hpp>
18 #include <boost/xpressive/detail/core/state.hpp>
19 
20 namespace boost { namespace xpressive { namespace detail
21 {
22 
23     //
24     // Note: here is the variable-width xpression quantifier. It always
25     // matches at least once, so if the min is 0, it is the responsibility
26     // of the parser to make it alternate with an epsilon matcher.
27     //
28 
29     ///////////////////////////////////////////////////////////////////////////////
30     // repeat_begin_matcher
31     //
32     struct repeat_begin_matcher
33       : quant_style<quant_variable_width, unknown_width::value, false>
34     {
35         int mark_number_;
36 
repeat_begin_matcherboost::xpressive::detail::repeat_begin_matcher37         repeat_begin_matcher(int mark_number)
38           : mark_number_(mark_number)
39         {
40         }
41 
42         template<typename BidiIter, typename Next>
matchboost::xpressive::detail::repeat_begin_matcher43         bool match(match_state<BidiIter> &state, Next const &next) const
44         {
45             sub_match_impl<BidiIter> &br = state.sub_match(this->mark_number_);
46 
47             unsigned int old_repeat_count = br.repeat_count_;
48             bool old_zero_width = br.zero_width_;
49 
50             br.repeat_count_ = 1;
51             br.zero_width_ = false;
52 
53             // "push" next onto the stack, so it can be "popped" in
54             // repeat_end_matcher and used to loop back.
55             if(next.BOOST_NESTED_TEMPLATE push_match<Next>(state))
56             {
57                 return true;
58             }
59 
60             br.repeat_count_ = old_repeat_count;
61             br.zero_width_ = old_zero_width;
62 
63             return false;
64         }
65     };
66 
67 }}}
68 
69 #endif
70