]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/xpressive/include/boost/xpressive/detail/core/linker.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / xpressive / include / boost / xpressive / detail / core / linker.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // linker.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_LINKER_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_LINKER_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/config.hpp>
17 #ifndef BOOST_NO_STD_LOCALE
18 # include <locale>
19 #endif
20 #include <stack>
21 #include <limits>
22 #include <typeinfo>
23 #include <boost/shared_ptr.hpp>
24 #include <boost/type_traits/is_same.hpp>
25 #include <boost/version.hpp>
26
27 #if BOOST_VERSION >= 103500
28 # include <boost/fusion/include/for_each.hpp>
29 #else
30 # include <boost/spirit/fusion/algorithm/for_each.hpp>
31 #endif
32
33 #include <boost/xpressive/detail/detail_fwd.hpp>
34 #include <boost/xpressive/detail/dynamic/matchable.hpp>
35 #include <boost/xpressive/detail/core/matchers.hpp>
36 #include <boost/xpressive/detail/core/peeker.hpp>
37 #include <boost/xpressive/detail/utility/never_true.hpp>
38
39 namespace boost { namespace xpressive { namespace detail
40 {
41
42 ///////////////////////////////////////////////////////////////////////////////
43 // icase_modifier
44 //
45 // wrapped by the modifier<> template and inserted into the xpression
46 // template with the icase() helper function. icase_modifier morphs
47 // a case-sensitive visitor into a case-insensitive visitor, which
48 // causes all matchers visited to become case-insensitive.
49 //
50 struct icase_modifier
51 {
52 template<typename Visitor>
53 struct apply {};
54
55 template<typename BidiIter, typename ICase, typename Traits>
56 struct apply<xpression_visitor<BidiIter, ICase, Traits> >
57 {
58 typedef xpression_visitor<BidiIter, mpl::true_, Traits> type;
59 };
60
61 template<typename Visitor>
62 static typename apply<Visitor>::type
63 call(Visitor &visitor)
64 {
65 return typename apply<Visitor>::type(visitor.traits(), visitor.self());
66 }
67 };
68
69 ///////////////////////////////////////////////////////////////////////////////
70 // regex_traits_type : wrap a locale in the appropriate regex_traits
71 //
72 template<typename Locale, typename BidiIter>
73 struct regex_traits_type
74 {
75 #ifndef BOOST_NO_STD_LOCALE
76
77 typedef typename iterator_value<BidiIter>::type char_type;
78
79 // if Locale is std::locale, wrap it in a cpp_regex_traits<Char>
80 typedef typename mpl::if_c
81 <
82 is_same<Locale, std::locale>::value
83 , cpp_regex_traits<char_type>
84 , Locale
85 >::type type;
86
87 #else
88
89 typedef Locale type;
90
91 #endif
92 };
93
94 ///////////////////////////////////////////////////////////////////////////////
95 // locale_modifier
96 //
97 // wrapped by the modifier<> template and inserted into the xpression
98 // template with the imbue() helper function. Causes a sub-xpression to
99 // use the specified Locale
100 //
101 template<typename Locale>
102 struct locale_modifier
103 {
104 typedef Locale locale_type;
105
106 locale_modifier(Locale const &loc)
107 : loc_(loc)
108 {
109 }
110
111 template<typename Visitor>
112 struct apply {};
113
114 template<typename BidiIter, typename ICase, typename OtherTraits>
115 struct apply<xpression_visitor<BidiIter, ICase, OtherTraits> >
116 {
117 typedef typename regex_traits_type<Locale, BidiIter>::type traits_type;
118 typedef xpression_visitor<BidiIter, ICase, traits_type> type;
119 };
120
121 template<typename Visitor>
122 typename apply<Visitor>::type
123 call(Visitor &visitor) const
124 {
125 return typename apply<Visitor>::type(this->loc_, visitor.self());
126 }
127
128 Locale getloc() const
129 {
130 return this->loc_;
131 }
132
133 private:
134 Locale loc_;
135 };
136
137 ///////////////////////////////////////////////////////////////////////////////
138 // xpression_linker
139 //
140 template<typename Char>
141 struct xpression_linker
142 {
143 template<typename Traits>
144 explicit xpression_linker(Traits const &tr)
145 : back_stack_()
146 , traits_(&tr)
147 , traits_type_(&typeid(Traits))
148 , has_backrefs_(false)
149 {
150 }
151
152 template<typename Matcher>
153 void accept(Matcher const &, void const *)
154 {
155 // no-op
156 }
157
158 template<typename Traits, typename ICase>
159 void accept(mark_matcher<Traits, ICase> const &, void const *)
160 {
161 this->has_backrefs_ = true;
162 }
163
164 template<typename Action>
165 void accept(action_matcher<Action> const &, void const *)
166 {
167 this->has_backrefs_ = true;
168 }
169
170 template<typename Predicate>
171 void accept(predicate_matcher<Predicate> const &, void const *)
172 {
173 this->has_backrefs_ = true;
174 }
175
176 void accept(repeat_begin_matcher const &, void const *next)
177 {
178 this->back_stack_.push(next);
179 }
180
181 template<typename Greedy>
182 void accept(repeat_end_matcher<Greedy> const &matcher, void const *)
183 {
184 matcher.back_ = this->back_stack_.top();
185 this->back_stack_.pop();
186 }
187
188 template<typename Alternates, typename Traits>
189 void accept(alternate_matcher<Alternates, Traits> const &matcher, void const *next)
190 {
191 xpression_peeker<Char> peeker(matcher.bset_, this->get_traits<Traits>());
192 this->alt_link(matcher.alternates_, next, &peeker);
193 }
194
195 void accept(alternate_end_matcher const &matcher, void const *)
196 {
197 matcher.back_ = this->back_stack_.top();
198 this->back_stack_.pop();
199 }
200
201 template<typename Xpr, typename Greedy>
202 void accept(optional_matcher<Xpr, Greedy> const &matcher, void const *next)
203 {
204 this->back_stack_.push(next);
205 matcher.xpr_.link(*this);
206 }
207
208 template<typename Xpr, typename Greedy>
209 void accept(optional_mark_matcher<Xpr, Greedy> const &matcher, void const *next)
210 {
211 this->back_stack_.push(next);
212 matcher.xpr_.link(*this);
213 }
214
215 template<typename Xpr>
216 void accept(keeper_matcher<Xpr> const &matcher, void const *)
217 {
218 matcher.xpr_.link(*this);
219 }
220
221 template<typename Xpr>
222 void accept(lookahead_matcher<Xpr> const &matcher, void const *)
223 {
224 matcher.xpr_.link(*this);
225 }
226
227 template<typename Xpr>
228 void accept(lookbehind_matcher<Xpr> const &matcher, void const *)
229 {
230 matcher.xpr_.link(*this);
231 }
232
233 template<typename Xpr, typename Greedy>
234 void accept(simple_repeat_matcher<Xpr, Greedy> const &matcher, void const *)
235 {
236 matcher.xpr_.link(*this);
237 }
238
239 // accessors
240 bool has_backrefs() const
241 {
242 return this->has_backrefs_;
243 }
244
245 // for use by alt_link_pred below
246 template<typename Xpr>
247 void alt_branch_link(Xpr const &xpr, void const *next, xpression_peeker<Char> *peeker)
248 {
249 this->back_stack_.push(next);
250 xpr.link(*this);
251 xpr.peek(*peeker);
252 }
253
254 private:
255
256 ///////////////////////////////////////////////////////////////////////////////
257 // alt_link_pred
258 //
259 struct alt_link_pred
260 {
261 xpression_linker<Char> *linker_;
262 xpression_peeker<Char> *peeker_;
263 void const *next_;
264
265 alt_link_pred
266 (
267 xpression_linker<Char> *linker
268 , xpression_peeker<Char> *peeker
269 , void const *next
270 )
271 : linker_(linker)
272 , peeker_(peeker)
273 , next_(next)
274 {
275 }
276
277 template<typename Xpr>
278 void operator ()(Xpr const &xpr) const
279 {
280 this->linker_->alt_branch_link(xpr, this->next_, this->peeker_);
281 }
282 };
283
284 template<typename BidiIter>
285 void alt_link
286 (
287 alternates_vector<BidiIter> const &alternates
288 , void const *next
289 , xpression_peeker<Char> *peeker
290 )
291 {
292 std::for_each(alternates.begin(), alternates.end(), alt_link_pred(this, peeker, next));
293 }
294
295 template<typename Alternates>
296 void alt_link
297 (
298 fusion::sequence_base<Alternates> const &alternates
299 , void const *next
300 , xpression_peeker<Char> *peeker
301 )
302 {
303 #if BOOST_VERSION >= 103500
304 fusion::for_each(alternates.derived(), alt_link_pred(this, peeker, next));
305 #else
306 fusion::for_each(alternates.cast(), alt_link_pred(this, peeker, next));
307 #endif
308 }
309
310 template<typename Traits>
311 Traits const &get_traits() const
312 {
313 BOOST_ASSERT(*this->traits_type_ == typeid(Traits));
314 return *static_cast<Traits const *>(this->traits_);
315 }
316
317 std::stack<void const *> back_stack_;
318 void const *traits_;
319 std::type_info const *traits_type_;
320 bool has_backrefs_;
321 };
322
323 }}} // namespace boost::xpressive::detail
324
325 #endif