]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/xpressive/include/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / xpressive / include / boost / xpressive / detail / core / matcher / lookbehind_matcher.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////////////////////
2// lookbehind_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_LOOKBEHIND_MATCHER_HPP_EAN_10_04_2005
9#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOOKBEHIND_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/regex_error.hpp>
18#include <boost/xpressive/regex_constants.hpp>
19#include <boost/xpressive/detail/detail_fwd.hpp>
20#include <boost/xpressive/detail/core/quant_style.hpp>
21#include <boost/xpressive/detail/core/state.hpp>
22#include <boost/xpressive/detail/utility/algorithm.hpp>
23#include <boost/xpressive/detail/utility/save_restore.hpp>
24#include <boost/xpressive/detail/utility/ignore_unused.hpp>
25
26namespace boost { namespace xpressive { namespace detail
27{
28
29 ///////////////////////////////////////////////////////////////////////////////
30 // lookbehind_matcher
31 // Xpr can be either a static_xpression or a shared_matchable
32 template<typename Xpr>
33 struct lookbehind_matcher
34 : quant_style<quant_none, 0, Xpr::pure>
35 {
36 lookbehind_matcher(Xpr const &xpr, std::size_t wid, bool no, bool pure = Xpr::pure)
37 : xpr_(xpr)
38 , not_(no)
39 , pure_(pure)
40 , width_(wid)
41 {
42 BOOST_XPR_ENSURE_(!is_unknown(this->width_), regex_constants::error_badlookbehind,
43 "Variable-width look-behind assertions are not supported");
44 }
45
46 void inverse()
47 {
48 this->not_ = !this->not_;
49 }
50
51 template<typename BidiIter, typename Next>
52 bool match(match_state<BidiIter> &state, Next const &next) const
53 {
54 return Xpr::pure || this->pure_
55 ? this->match_(state, next, mpl::true_())
56 : this->match_(state, next, mpl::false_());
57 }
58
59 template<typename BidiIter, typename Next>
60 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const
61 {
62 typedef typename iterator_difference<BidiIter>::type difference_type;
63 BidiIter const tmp = state.cur_;
64 if(!detail::advance_to(state.cur_, -static_cast<difference_type>(this->width_), state.begin_))
65 {
66 state.cur_ = tmp;
67 return this->not_ ? next.match(state) : false;
68 }
69
70 if(this->not_)
71 {
72 if(this->xpr_.match(state))
73 {
74 BOOST_ASSERT(state.cur_ == tmp);
75 return false;
76 }
77 state.cur_ = tmp;
78 if(next.match(state))
79 {
80 return true;
81 }
82 }
83 else
84 {
85 if(!this->xpr_.match(state))
86 {
87 state.cur_ = tmp;
88 return false;
89 }
90 BOOST_ASSERT(state.cur_ == tmp);
91 if(next.match(state))
92 {
93 return true;
94 }
95 }
96
97 BOOST_ASSERT(state.cur_ == tmp);
98 return false;
99 }
100
101 template<typename BidiIter, typename Next>
102 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
103 {
104 typedef typename iterator_difference<BidiIter>::type difference_type;
105 BidiIter const tmp = state.cur_;
106 if(!detail::advance_to(state.cur_, -static_cast<difference_type>(this->width_), state.begin_))
107 {
108 state.cur_ = tmp;
109 return this->not_ ? next.match(state) : false;
110 }
111
112 // matching xpr could produce side-effects, save state
113 memento<BidiIter> mem = save_sub_matches(state);
114
115 if(this->not_)
116 {
117 // negative look-ahead assertions do not trigger partial matches.
118 save_restore<bool> partial_match(state.found_partial_match_);
119 detail::ignore_unused(partial_match);
120
121 if(this->xpr_.match(state))
122 {
123 restore_action_queue(mem, state);
124 restore_sub_matches(mem, state);
125 BOOST_ASSERT(state.cur_ == tmp);
126 return false;
127 }
128 state.cur_ = tmp;
129 restore_action_queue(mem, state);
130 if(next.match(state))
131 {
132 reclaim_sub_matches(mem, state, true);
133 return true;
134 }
135 reclaim_sub_matches(mem, state, false);
136 }
137 else
138 {
139 if(!this->xpr_.match(state))
140 {
141 state.cur_ = tmp;
142 restore_action_queue(mem, state);
143 reclaim_sub_matches(mem, state, false);
144 return false;
145 }
146 BOOST_ASSERT(state.cur_ == tmp);
147 restore_action_queue(mem, state);
148 if(next.match(state))
149 {
150 reclaim_sub_matches(mem, state, true);
151 return true;
152 }
153 restore_sub_matches(mem, state);
154 }
155
156 BOOST_ASSERT(state.cur_ == tmp);
157 return false;
158 }
159
160 Xpr xpr_;
161 bool not_;
162 bool pure_; // false if matching xpr_ could modify the sub-matches
163 std::size_t width_;
164 };
165
166}}}
167
168#endif