1
///////////////////////////////////////////////////////////////////////////////
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)
8
#ifndef BOOST_XPRESSIVE_DETAIL_CORE_LINKER_HPP_EAN_10_04_2005
9
#define BOOST_XPRESSIVE_DETAIL_CORE_LINKER_HPP_EAN_10_04_2005
11
// MS compatible compilers support #pragma once
12
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
16
#include <boost/config.hpp>
17
#ifndef BOOST_NO_STD_LOCALE
23
#include <boost/shared_ptr.hpp>
24
#include <boost/type_traits/is_same.hpp>
25
#include <boost/version.hpp>
27
#if BOOST_VERSION >= 103500
28
# include <boost/fusion/include/for_each.hpp>
30
# include <boost/spirit/fusion/algorithm/for_each.hpp>
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>
39
namespace boost { namespace xpressive { namespace detail
42
///////////////////////////////////////////////////////////////////////////////
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.
52
template<typename Visitor>
55
template<typename BidiIter, typename ICase, typename Traits>
56
struct apply<xpression_visitor<BidiIter, ICase, Traits> >
58
typedef xpression_visitor<BidiIter, mpl::true_, Traits> type;
61
template<typename Visitor>
62
static typename apply<Visitor>::type
63
call(Visitor &visitor)
65
return typename apply<Visitor>::type(visitor.traits(), visitor.self());
69
///////////////////////////////////////////////////////////////////////////////
70
// regex_traits_type : wrap a locale in the appropriate regex_traits
72
template<typename Locale, typename BidiIter>
73
struct regex_traits_type
75
#ifndef BOOST_NO_STD_LOCALE
77
typedef typename iterator_value<BidiIter>::type char_type;
79
// if Locale is std::locale, wrap it in a cpp_regex_traits<Char>
80
typedef typename mpl::if_c
82
is_same<Locale, std::locale>::value
83
, cpp_regex_traits<char_type>
94
///////////////////////////////////////////////////////////////////////////////
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
101
template<typename Locale>
102
struct locale_modifier
104
typedef Locale locale_type;
106
locale_modifier(Locale const &loc)
111
template<typename Visitor>
114
template<typename BidiIter, typename ICase, typename OtherTraits>
115
struct apply<xpression_visitor<BidiIter, ICase, OtherTraits> >
117
typedef typename regex_traits_type<Locale, BidiIter>::type traits_type;
118
typedef xpression_visitor<BidiIter, ICase, traits_type> type;
121
template<typename Visitor>
122
typename apply<Visitor>::type
123
call(Visitor &visitor) const
125
return typename apply<Visitor>::type(this->loc_, visitor.self());
128
Locale getloc() const
137
///////////////////////////////////////////////////////////////////////////////
140
template<typename Char>
141
struct xpression_linker
143
template<typename Traits>
144
explicit xpression_linker(Traits const &tr)
147
, traits_type_(&typeid(Traits))
148
, has_backrefs_(false)
152
template<typename Matcher>
153
void accept(Matcher const &, void const *)
158
template<typename Traits, typename ICase>
159
void accept(mark_matcher<Traits, ICase> const &, void const *)
161
this->has_backrefs_ = true;
164
template<typename Action>
165
void accept(action_matcher<Action> const &, void const *)
167
this->has_backrefs_ = true;
170
template<typename Predicate>
171
void accept(predicate_matcher<Predicate> const &, void const *)
173
this->has_backrefs_ = true;
176
void accept(repeat_begin_matcher const &, void const *next)
178
this->back_stack_.push(next);
181
template<typename Greedy>
182
void accept(repeat_end_matcher<Greedy> const &matcher, void const *)
184
matcher.back_ = this->back_stack_.top();
185
this->back_stack_.pop();
188
template<typename Alternates, typename Traits>
189
void accept(alternate_matcher<Alternates, Traits> const &matcher, void const *next)
191
xpression_peeker<Char> peeker(matcher.bset_, this->get_traits<Traits>());
192
this->alt_link(matcher.alternates_, next, &peeker);
195
void accept(alternate_end_matcher const &matcher, void const *)
197
matcher.back_ = this->back_stack_.top();
198
this->back_stack_.pop();
201
template<typename Xpr, typename Greedy>
202
void accept(optional_matcher<Xpr, Greedy> const &matcher, void const *next)
204
this->back_stack_.push(next);
205
matcher.xpr_.link(*this);
208
template<typename Xpr, typename Greedy>
209
void accept(optional_mark_matcher<Xpr, Greedy> const &matcher, void const *next)
211
this->back_stack_.push(next);
212
matcher.xpr_.link(*this);
215
template<typename Xpr>
216
void accept(keeper_matcher<Xpr> const &matcher, void const *)
218
matcher.xpr_.link(*this);
221
template<typename Xpr>
222
void accept(lookahead_matcher<Xpr> const &matcher, void const *)
224
matcher.xpr_.link(*this);
227
template<typename Xpr>
228
void accept(lookbehind_matcher<Xpr> const &matcher, void const *)
230
matcher.xpr_.link(*this);
233
template<typename Xpr, typename Greedy>
234
void accept(simple_repeat_matcher<Xpr, Greedy> const &matcher, void const *)
236
matcher.xpr_.link(*this);
240
bool has_backrefs() const
242
return this->has_backrefs_;
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)
249
this->back_stack_.push(next);
256
///////////////////////////////////////////////////////////////////////////////
261
xpression_linker<Char> *linker_;
262
xpression_peeker<Char> *peeker_;
267
xpression_linker<Char> *linker
268
, xpression_peeker<Char> *peeker
277
template<typename Xpr>
278
void operator ()(Xpr const &xpr) const
280
this->linker_->alt_branch_link(xpr, this->next_, this->peeker_);
284
template<typename BidiIter>
287
alternates_vector<BidiIter> const &alternates
289
, xpression_peeker<Char> *peeker
292
std::for_each(alternates.begin(), alternates.end(), alt_link_pred(this, peeker, next));
295
template<typename Alternates>
298
fusion::sequence_base<Alternates> const &alternates
300
, xpression_peeker<Char> *peeker
303
#if BOOST_VERSION >= 103500
304
fusion::for_each(alternates.derived(), alt_link_pred(this, peeker, next));
306
fusion::for_each(alternates.cast(), alt_link_pred(this, peeker, next));
310
template<typename Traits>
311
Traits const &get_traits() const
313
BOOST_ASSERT(*this->traits_type_ == typeid(Traits));
314
return *static_cast<Traits const *>(this->traits_);
317
std::stack<void const *> back_stack_;
319
std::type_info const *traits_type_;
323
}}} // namespace boost::xpressive::detail