1 ///////////////////////////////////////////////////////////////////////////////
2 // flow_control.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_FLOW_CONTROL_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_FLOW_CONTROL_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/regex_impl.hpp>
18 #include <boost/xpressive/detail/core/state.hpp>
19 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
20 
21 namespace boost { namespace xpressive { namespace detail
22 {
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 // push_context_match
26 //
27 template<typename BidiIter>
push_context_match(regex_impl<BidiIter> const & impl,match_state<BidiIter> & state,matchable<BidiIter> const & next)28 inline bool push_context_match
29 (
30     regex_impl<BidiIter> const &impl
31   , match_state<BidiIter> &state
32   , matchable<BidiIter> const &next
33 )
34 {
35     // avoid infinite recursion
36     // BUGBUG this only catches direct infinite recursion, like sregex::compile("(?R)"), but
37     // not indirect infinite recursion where two rules invoke each other recursively.
38     if(state.is_active_regex(impl) && state.cur_ == state.sub_match(0).begin_)
39     {
40         return next.match(state);
41     }
42 
43     // save state
44     match_context<BidiIter> context = state.push_context(impl, next, context);
45     detail::ignore_unused(context);
46 
47     // match the nested regex and uninitialize the match context
48     // (reclaims the sub_match objects if necessary)
49     return state.pop_context(impl, impl.xpr_->match(state));
50 }
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 // pop_context_match
54 //
55 template<typename BidiIter>
pop_context_match(match_state<BidiIter> & state)56 inline bool pop_context_match(match_state<BidiIter> &state)
57 {
58     // save state
59     // BUGBUG nested regex could have changed state.traits_
60     match_context<BidiIter> &context(*state.context_.prev_context_);
61     state.swap_context(context);
62 
63     // Finished matching the nested regex; now match the rest of the enclosing regex
64     bool success = context.next_ptr_->match(state);
65 
66     // restore state
67     state.swap_context(context);
68     return success;
69 }
70 
71 }}} // namespace boost::xpressive::detail
72 
73 #endif
74 
75