sl@0
|
1 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
2 |
/// \file match_results.hpp
|
sl@0
|
3 |
/// Contains the definition of the match_results type and associated helpers.
|
sl@0
|
4 |
/// The match_results type holds the results of a regex_match() or
|
sl@0
|
5 |
/// regex_search() operation.
|
sl@0
|
6 |
//
|
sl@0
|
7 |
// Copyright 2004 Eric Niebler. Distributed under the Boost
|
sl@0
|
8 |
// Software License, Version 1.0. (See accompanying file
|
sl@0
|
9 |
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
sl@0
|
10 |
|
sl@0
|
11 |
#ifndef BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005
|
sl@0
|
12 |
#define BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005
|
sl@0
|
13 |
|
sl@0
|
14 |
// MS compatible compilers support #pragma once
|
sl@0
|
15 |
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
sl@0
|
16 |
# pragma once
|
sl@0
|
17 |
#endif
|
sl@0
|
18 |
|
sl@0
|
19 |
#include <iterator>
|
sl@0
|
20 |
#include <boost/assert.hpp>
|
sl@0
|
21 |
#include <boost/shared_ptr.hpp>
|
sl@0
|
22 |
#include <boost/iterator_adaptors.hpp>
|
sl@0
|
23 |
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
|
sl@0
|
24 |
# include <boost/iterator/filter_iterator.hpp>
|
sl@0
|
25 |
#endif
|
sl@0
|
26 |
#include <boost/xpressive/regex_constants.hpp>
|
sl@0
|
27 |
#include <boost/xpressive/detail/detail_fwd.hpp>
|
sl@0
|
28 |
#include <boost/xpressive/detail/core/sub_match_vector.hpp>
|
sl@0
|
29 |
#include <boost/xpressive/detail/utility/sequence_stack.hpp>
|
sl@0
|
30 |
#include <boost/xpressive/detail/core/results_cache.hpp>
|
sl@0
|
31 |
#include <boost/xpressive/detail/core/action_state.hpp>
|
sl@0
|
32 |
#include <boost/xpressive/detail/utility/literals.hpp>
|
sl@0
|
33 |
#include <boost/xpressive/detail/utility/algorithm.hpp>
|
sl@0
|
34 |
|
sl@0
|
35 |
namespace boost { namespace xpressive { namespace detail
|
sl@0
|
36 |
{
|
sl@0
|
37 |
|
sl@0
|
38 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
39 |
// results_extras
|
sl@0
|
40 |
//
|
sl@0
|
41 |
template<typename BidiIter>
|
sl@0
|
42 |
struct results_extras
|
sl@0
|
43 |
{
|
sl@0
|
44 |
sequence_stack<sub_match_impl<BidiIter> > sub_match_stack_;
|
sl@0
|
45 |
results_cache<BidiIter> results_cache_;
|
sl@0
|
46 |
};
|
sl@0
|
47 |
|
sl@0
|
48 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
49 |
// results_traits
|
sl@0
|
50 |
//
|
sl@0
|
51 |
template<typename Char>
|
sl@0
|
52 |
struct results_traits
|
sl@0
|
53 |
{
|
sl@0
|
54 |
static int value(Char ch, int radix = 10)
|
sl@0
|
55 |
{
|
sl@0
|
56 |
BOOST_ASSERT(10 == radix);
|
sl@0
|
57 |
if(ch >= BOOST_XPR_CHAR_(Char, '0') && ch <= BOOST_XPR_CHAR_(Char, '9'))
|
sl@0
|
58 |
{
|
sl@0
|
59 |
return ch - BOOST_XPR_CHAR_(Char, '0');
|
sl@0
|
60 |
}
|
sl@0
|
61 |
return -1;
|
sl@0
|
62 |
}
|
sl@0
|
63 |
};
|
sl@0
|
64 |
|
sl@0
|
65 |
} // namespace detail
|
sl@0
|
66 |
|
sl@0
|
67 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
68 |
// match_results
|
sl@0
|
69 |
/// \brief Class template match_results\<\> holds the results of a regex_match() or a
|
sl@0
|
70 |
/// regex_search() as a collection of sub_match objects.
|
sl@0
|
71 |
///
|
sl@0
|
72 |
/// Class template match_results\<\> denotes a collection of sequences representing the result of
|
sl@0
|
73 |
/// a regular expression match. Storage for the collection is allocated and freed as necessary by
|
sl@0
|
74 |
/// the member functions of class match_results\<\>.
|
sl@0
|
75 |
///
|
sl@0
|
76 |
/// The class template match_results\<\> conforms to the requirements of a Sequence, as specified
|
sl@0
|
77 |
/// in (lib.sequence.reqmts), except that only operations defined for const-qualified Sequences are
|
sl@0
|
78 |
/// supported.
|
sl@0
|
79 |
template<typename BidiIter>
|
sl@0
|
80 |
struct match_results
|
sl@0
|
81 |
{
|
sl@0
|
82 |
private:
|
sl@0
|
83 |
struct dummy { int i_; };
|
sl@0
|
84 |
typedef int dummy::*bool_type;
|
sl@0
|
85 |
|
sl@0
|
86 |
public:
|
sl@0
|
87 |
typedef typename iterator_value<BidiIter>::type char_type;
|
sl@0
|
88 |
typedef std::basic_string<char_type> string_type;
|
sl@0
|
89 |
typedef std::size_t size_type;
|
sl@0
|
90 |
typedef sub_match<BidiIter> value_type;
|
sl@0
|
91 |
typedef typename iterator_difference<BidiIter>::type difference_type;
|
sl@0
|
92 |
typedef value_type const &reference;
|
sl@0
|
93 |
typedef value_type const &const_reference;
|
sl@0
|
94 |
|
sl@0
|
95 |
typedef typename detail::sub_match_vector<BidiIter>::iterator iterator;
|
sl@0
|
96 |
typedef typename detail::sub_match_vector<BidiIter>::const_iterator const_iterator;
|
sl@0
|
97 |
typedef typename detail::nested_results<BidiIter> nested_results_type;
|
sl@0
|
98 |
|
sl@0
|
99 |
/// \post regex_id() == 0
|
sl@0
|
100 |
/// \post size() == 0
|
sl@0
|
101 |
/// \post empty() == true
|
sl@0
|
102 |
match_results()
|
sl@0
|
103 |
: regex_id_(0)
|
sl@0
|
104 |
, sub_matches_()
|
sl@0
|
105 |
, base_()
|
sl@0
|
106 |
, prefix_()
|
sl@0
|
107 |
, suffix_()
|
sl@0
|
108 |
, nested_results_()
|
sl@0
|
109 |
, action_state_()
|
sl@0
|
110 |
, extras_ptr_()
|
sl@0
|
111 |
{
|
sl@0
|
112 |
}
|
sl@0
|
113 |
|
sl@0
|
114 |
/// \param that The match_results object to copy
|
sl@0
|
115 |
/// \post regex_id() == that.regex_id().
|
sl@0
|
116 |
/// \post size() == that.size().
|
sl@0
|
117 |
/// \post empty() == that.empty().
|
sl@0
|
118 |
/// \post str(n) == that.str(n) for all positive integers n \< that.size().
|
sl@0
|
119 |
/// \post prefix() == that.prefix().
|
sl@0
|
120 |
/// \post suffix() == that.suffix().
|
sl@0
|
121 |
/// \post (*this)[n] == that[n] for all positive integers n \< that.size().
|
sl@0
|
122 |
/// \post length(n) == that.length(n) for all positive integers n \< that.size().
|
sl@0
|
123 |
/// \post position(n) == that.position(n) for all positive integers n \< that.size().
|
sl@0
|
124 |
match_results(match_results<BidiIter> const &that)
|
sl@0
|
125 |
: regex_id_(that.regex_id_)
|
sl@0
|
126 |
, sub_matches_()
|
sl@0
|
127 |
, base_()
|
sl@0
|
128 |
, prefix_()
|
sl@0
|
129 |
, suffix_()
|
sl@0
|
130 |
, nested_results_()
|
sl@0
|
131 |
, action_state_(that.action_state_)
|
sl@0
|
132 |
, extras_ptr_()
|
sl@0
|
133 |
{
|
sl@0
|
134 |
if(that)
|
sl@0
|
135 |
{
|
sl@0
|
136 |
extras_type &extras = this->get_extras_();
|
sl@0
|
137 |
std::size_t size = that.sub_matches_.size();
|
sl@0
|
138 |
detail::sub_match_impl<BidiIter> *sub_matches = extras.sub_match_stack_.push_sequence(size);
|
sl@0
|
139 |
detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size, that.sub_matches_);
|
sl@0
|
140 |
|
sl@0
|
141 |
// BUGBUG this doesn't share the extras::sequence_stack
|
sl@0
|
142 |
this->nested_results_ = that.nested_results_;
|
sl@0
|
143 |
this->prefix_ = that.prefix_;
|
sl@0
|
144 |
this->suffix_ = that.suffix_;
|
sl@0
|
145 |
this->base_ = that.base_;
|
sl@0
|
146 |
}
|
sl@0
|
147 |
}
|
sl@0
|
148 |
|
sl@0
|
149 |
~match_results()
|
sl@0
|
150 |
{
|
sl@0
|
151 |
}
|
sl@0
|
152 |
|
sl@0
|
153 |
/// \param that The match_results object to copy.
|
sl@0
|
154 |
/// \post regex_id() == that.regex_id().
|
sl@0
|
155 |
/// \post size() == that.size().
|
sl@0
|
156 |
/// \post empty() == that.empty().
|
sl@0
|
157 |
/// \post str(n) == that.str(n) for all positive integers n \< that.size().
|
sl@0
|
158 |
/// \post prefix() == that.prefix().
|
sl@0
|
159 |
/// \post suffix() == that.suffix().
|
sl@0
|
160 |
/// \post (*this)[n] == that[n] for all positive integers n \< that.size().
|
sl@0
|
161 |
/// \post length(n) == that.length(n) for all positive integers n \< that.size().
|
sl@0
|
162 |
/// \post position(n) == that.position(n) for all positive integers n \< that.size().
|
sl@0
|
163 |
match_results<BidiIter> &operator =(match_results<BidiIter> const &that)
|
sl@0
|
164 |
{
|
sl@0
|
165 |
match_results<BidiIter>(that).swap(*this);
|
sl@0
|
166 |
return *this;
|
sl@0
|
167 |
}
|
sl@0
|
168 |
|
sl@0
|
169 |
/// Returns the number of sub_match elements stored in *this.
|
sl@0
|
170 |
///
|
sl@0
|
171 |
size_type size() const
|
sl@0
|
172 |
{
|
sl@0
|
173 |
return this->sub_matches_.size();
|
sl@0
|
174 |
}
|
sl@0
|
175 |
|
sl@0
|
176 |
/// Returns size() == 0.
|
sl@0
|
177 |
///
|
sl@0
|
178 |
bool empty() const
|
sl@0
|
179 |
{
|
sl@0
|
180 |
return 0 == this->size();
|
sl@0
|
181 |
}
|
sl@0
|
182 |
|
sl@0
|
183 |
/// Returns (*this)[sub].length().
|
sl@0
|
184 |
///
|
sl@0
|
185 |
difference_type length(size_type sub = 0) const
|
sl@0
|
186 |
{
|
sl@0
|
187 |
return (*this)[ sub ].length();
|
sl@0
|
188 |
}
|
sl@0
|
189 |
|
sl@0
|
190 |
/// If !(*this)[sub].matched then returns -1. Otherwise returns std::distance(base, (*this)[sub].first),
|
sl@0
|
191 |
/// where base is the start iterator of the sequence that was searched. [Note – unless this is part
|
sl@0
|
192 |
/// of a repeated search with a regex_iterator then base is the same as prefix().first – end note]
|
sl@0
|
193 |
difference_type position(size_type sub = 0) const
|
sl@0
|
194 |
{
|
sl@0
|
195 |
return (*this)[ sub ].matched ? std::distance(this->base_, (*this)[ sub ].first) : -1;
|
sl@0
|
196 |
}
|
sl@0
|
197 |
|
sl@0
|
198 |
/// Returns string_type((*this)[sub]).
|
sl@0
|
199 |
///
|
sl@0
|
200 |
string_type str(size_type sub = 0) const
|
sl@0
|
201 |
{
|
sl@0
|
202 |
return (*this)[ sub ].str();
|
sl@0
|
203 |
}
|
sl@0
|
204 |
|
sl@0
|
205 |
/// Returns a reference to the sub_match object representing the sequence that
|
sl@0
|
206 |
/// matched marked sub-expression sub. If sub == 0 then returns a reference to a sub_match object
|
sl@0
|
207 |
/// representing the sequence that matched the whole regular expression.
|
sl@0
|
208 |
/// \pre sub \< (*this).size().
|
sl@0
|
209 |
const_reference operator [](size_type sub) const
|
sl@0
|
210 |
{
|
sl@0
|
211 |
return this->sub_matches_[ sub ];
|
sl@0
|
212 |
}
|
sl@0
|
213 |
|
sl@0
|
214 |
/// \overload
|
sl@0
|
215 |
///
|
sl@0
|
216 |
const_reference operator [](detail::mark_tag const &mark) const
|
sl@0
|
217 |
{
|
sl@0
|
218 |
return this->sub_matches_[ detail::get_mark_number(mark) ];
|
sl@0
|
219 |
}
|
sl@0
|
220 |
|
sl@0
|
221 |
/// Returns a reference to the sub_match object representing the character sequence from
|
sl@0
|
222 |
/// the start of the string being matched/searched, to the start of the match found.
|
sl@0
|
223 |
///
|
sl@0
|
224 |
const_reference prefix() const
|
sl@0
|
225 |
{
|
sl@0
|
226 |
return this->prefix_;
|
sl@0
|
227 |
}
|
sl@0
|
228 |
|
sl@0
|
229 |
/// Returns a reference to the sub_match object representing the character sequence from
|
sl@0
|
230 |
/// the end of the match found to the end of the string being matched/searched.
|
sl@0
|
231 |
///
|
sl@0
|
232 |
const_reference suffix() const
|
sl@0
|
233 |
{
|
sl@0
|
234 |
return this->suffix_;
|
sl@0
|
235 |
}
|
sl@0
|
236 |
|
sl@0
|
237 |
/// Returns a starting iterator that enumerates over all the marked sub-expression matches
|
sl@0
|
238 |
/// stored in *this.
|
sl@0
|
239 |
///
|
sl@0
|
240 |
const_iterator begin() const
|
sl@0
|
241 |
{
|
sl@0
|
242 |
return this->sub_matches_.begin();
|
sl@0
|
243 |
}
|
sl@0
|
244 |
|
sl@0
|
245 |
/// Returns a terminating iterator that enumerates over all the marked sub-expression
|
sl@0
|
246 |
/// matches stored in *this.
|
sl@0
|
247 |
///
|
sl@0
|
248 |
const_iterator end() const
|
sl@0
|
249 |
{
|
sl@0
|
250 |
return this->sub_matches_.end();
|
sl@0
|
251 |
}
|
sl@0
|
252 |
|
sl@0
|
253 |
/// Returns a true value if(*this)[0].matched, else returns a false value.
|
sl@0
|
254 |
///
|
sl@0
|
255 |
operator bool_type() const
|
sl@0
|
256 |
{
|
sl@0
|
257 |
return (*this)[ 0 ].matched ? &dummy::i_ : 0;
|
sl@0
|
258 |
}
|
sl@0
|
259 |
|
sl@0
|
260 |
/// Returns true if empty() || !(*this)[0].matched, else returns false.
|
sl@0
|
261 |
///
|
sl@0
|
262 |
bool operator !() const
|
sl@0
|
263 |
{
|
sl@0
|
264 |
return this->empty() || !(*this)[ 0 ].matched;
|
sl@0
|
265 |
}
|
sl@0
|
266 |
|
sl@0
|
267 |
/// Returns the id of the basic_regex object most recently used with this match_results object.
|
sl@0
|
268 |
///
|
sl@0
|
269 |
regex_id_type regex_id() const
|
sl@0
|
270 |
{
|
sl@0
|
271 |
return this->regex_id_;
|
sl@0
|
272 |
}
|
sl@0
|
273 |
|
sl@0
|
274 |
/// Returns a Sequence of nested match_results elements.
|
sl@0
|
275 |
///
|
sl@0
|
276 |
nested_results_type const &nested_results() const
|
sl@0
|
277 |
{
|
sl@0
|
278 |
return this->nested_results_;
|
sl@0
|
279 |
}
|
sl@0
|
280 |
|
sl@0
|
281 |
/// Copies the character sequence [fmt.begin(), fmt.end()) to OutputIterator out. For each format
|
sl@0
|
282 |
/// specifier or escape sequence in fmt, replace that sequence with either the character(s) it
|
sl@0
|
283 |
/// represents, or the sequence within *this to which it refers. The bitmasks specified in flags
|
sl@0
|
284 |
/// determines what format specifiers or escape sequences are recognized, by default this is the
|
sl@0
|
285 |
/// format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
|
sl@0
|
286 |
template<typename OutputIterator>
|
sl@0
|
287 |
OutputIterator format
|
sl@0
|
288 |
(
|
sl@0
|
289 |
OutputIterator out
|
sl@0
|
290 |
, const string_type &fmt
|
sl@0
|
291 |
, regex_constants::match_flag_type flags = regex_constants::format_default
|
sl@0
|
292 |
) const
|
sl@0
|
293 |
{
|
sl@0
|
294 |
detail::results_traits<char_type> traits;
|
sl@0
|
295 |
typename string_type::const_iterator cur = fmt.begin(), end = fmt.end();
|
sl@0
|
296 |
|
sl@0
|
297 |
if(0 != (regex_constants::format_literal & flags))
|
sl@0
|
298 |
{
|
sl@0
|
299 |
out = std::copy(cur, end, out);
|
sl@0
|
300 |
}
|
sl@0
|
301 |
else while(cur != end)
|
sl@0
|
302 |
{
|
sl@0
|
303 |
if(BOOST_XPR_CHAR_(char_type, '$') != *cur)
|
sl@0
|
304 |
{
|
sl@0
|
305 |
*out++ = *cur++;
|
sl@0
|
306 |
}
|
sl@0
|
307 |
else if(++cur == end)
|
sl@0
|
308 |
{
|
sl@0
|
309 |
*out++ = BOOST_XPR_CHAR_(char_type, '$');
|
sl@0
|
310 |
}
|
sl@0
|
311 |
else if(BOOST_XPR_CHAR_(char_type, '$') == *cur)
|
sl@0
|
312 |
{
|
sl@0
|
313 |
*out++ = *cur++;
|
sl@0
|
314 |
}
|
sl@0
|
315 |
else if(BOOST_XPR_CHAR_(char_type, '&') == *cur) // whole match
|
sl@0
|
316 |
{
|
sl@0
|
317 |
++cur;
|
sl@0
|
318 |
out = std::copy((*this)[ 0 ].first, (*this)[ 0 ].second, out);
|
sl@0
|
319 |
}
|
sl@0
|
320 |
else if(BOOST_XPR_CHAR_(char_type, '`') == *cur) // prefix
|
sl@0
|
321 |
{
|
sl@0
|
322 |
++cur;
|
sl@0
|
323 |
out = std::copy(this->prefix().first, this->prefix().second, out);
|
sl@0
|
324 |
}
|
sl@0
|
325 |
else if(BOOST_XPR_CHAR_(char_type, '\'') == *cur) // suffix
|
sl@0
|
326 |
{
|
sl@0
|
327 |
++cur;
|
sl@0
|
328 |
out = std::copy(this->suffix().first, this->suffix().second, out);
|
sl@0
|
329 |
}
|
sl@0
|
330 |
else if(-1 != traits.value(*cur, 10)) // a sub-match
|
sl@0
|
331 |
{
|
sl@0
|
332 |
int max = static_cast<int>(this->size() - 1);
|
sl@0
|
333 |
int br_nbr = detail::toi(cur, end, traits, 10, max);
|
sl@0
|
334 |
detail::ensure(0 != br_nbr, regex_constants::error_subreg, "invalid back-reference");
|
sl@0
|
335 |
out = std::copy((*this)[ br_nbr ].first, (*this)[ br_nbr ].second, out);
|
sl@0
|
336 |
}
|
sl@0
|
337 |
else
|
sl@0
|
338 |
{
|
sl@0
|
339 |
*out++ = BOOST_XPR_CHAR_(char_type, '$');
|
sl@0
|
340 |
*out++ = *cur++;
|
sl@0
|
341 |
}
|
sl@0
|
342 |
}
|
sl@0
|
343 |
|
sl@0
|
344 |
return out;
|
sl@0
|
345 |
}
|
sl@0
|
346 |
|
sl@0
|
347 |
/// Returns a copy of the string fmt. For each format specifier or escape sequence in fmt,
|
sl@0
|
348 |
/// replace that sequence with either the character(s) it represents, or the sequence within
|
sl@0
|
349 |
/// *this to which it refers. The bitmasks specified in flags determines what format specifiers
|
sl@0
|
350 |
/// or escape sequences are recognized, by default this is the format used by ECMA-262,
|
sl@0
|
351 |
/// ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
|
sl@0
|
352 |
string_type format(const string_type &fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const
|
sl@0
|
353 |
{
|
sl@0
|
354 |
string_type result;
|
sl@0
|
355 |
result.reserve(fmt.length() * 2);
|
sl@0
|
356 |
this->format(std::back_inserter(result), fmt, flags);
|
sl@0
|
357 |
return result;
|
sl@0
|
358 |
}
|
sl@0
|
359 |
|
sl@0
|
360 |
/// Swaps the contents of two match_results objects. Guaranteed not to throw.
|
sl@0
|
361 |
/// \param that The match_results object to swap with.
|
sl@0
|
362 |
/// \post *this contains the sequence of matched sub-expressions that were in that,
|
sl@0
|
363 |
/// that contains the sequence of matched sub-expressions that were in *this.
|
sl@0
|
364 |
/// \throw nothrow
|
sl@0
|
365 |
void swap(match_results<BidiIter> &that) // throw()
|
sl@0
|
366 |
{
|
sl@0
|
367 |
std::swap(this->regex_id_, that.regex_id_);
|
sl@0
|
368 |
this->sub_matches_.swap(that.sub_matches_);
|
sl@0
|
369 |
std::swap(this->base_, that.base_);
|
sl@0
|
370 |
std::swap(this->prefix_, that.prefix_);
|
sl@0
|
371 |
std::swap(this->suffix_, that.suffix_);
|
sl@0
|
372 |
this->nested_results_.swap(that.nested_results_);
|
sl@0
|
373 |
std::swap(this->action_state_, that.action_state_);
|
sl@0
|
374 |
this->extras_ptr_.swap(that.extras_ptr_);
|
sl@0
|
375 |
}
|
sl@0
|
376 |
|
sl@0
|
377 |
/// INTERNAL ONLY
|
sl@0
|
378 |
match_results<BidiIter> const &operator ()(regex_id_type regex_id, size_type index = 0) const
|
sl@0
|
379 |
{
|
sl@0
|
380 |
// BUGBUG this is linear, make it O(1)
|
sl@0
|
381 |
static match_results<BidiIter> const s_null;
|
sl@0
|
382 |
|
sl@0
|
383 |
regex_id_filter_predicate<BidiIter> pred(regex_id);
|
sl@0
|
384 |
typename nested_results_type::const_iterator
|
sl@0
|
385 |
begin = this->nested_results_.begin()
|
sl@0
|
386 |
, end = this->nested_results_.end()
|
sl@0
|
387 |
, cur = detail::find_nth_if(begin, end, index, pred);
|
sl@0
|
388 |
|
sl@0
|
389 |
return (cur == end) ? s_null : *cur;
|
sl@0
|
390 |
}
|
sl@0
|
391 |
|
sl@0
|
392 |
/// INTERNAL ONLY
|
sl@0
|
393 |
match_results<BidiIter> const &operator ()(basic_regex<BidiIter> const &rex, std::size_t index = 0) const
|
sl@0
|
394 |
{
|
sl@0
|
395 |
return (*this)(rex.regex_id(), index);
|
sl@0
|
396 |
}
|
sl@0
|
397 |
|
sl@0
|
398 |
// state:
|
sl@0
|
399 |
/// INTERNAL ONLY
|
sl@0
|
400 |
template<typename State>
|
sl@0
|
401 |
void set_action_state(State &state)
|
sl@0
|
402 |
{
|
sl@0
|
403 |
this->action_state_.set(state);
|
sl@0
|
404 |
}
|
sl@0
|
405 |
|
sl@0
|
406 |
/// INTERNAL ONLY
|
sl@0
|
407 |
template<typename State>
|
sl@0
|
408 |
State &get_action_state() const
|
sl@0
|
409 |
{
|
sl@0
|
410 |
return this->action_state_.BOOST_NESTED_TEMPLATE get<State>();
|
sl@0
|
411 |
}
|
sl@0
|
412 |
|
sl@0
|
413 |
private:
|
sl@0
|
414 |
|
sl@0
|
415 |
friend struct detail::core_access<BidiIter>;
|
sl@0
|
416 |
typedef detail::results_extras<BidiIter> extras_type;
|
sl@0
|
417 |
|
sl@0
|
418 |
/// INTERNAL ONLY
|
sl@0
|
419 |
void init_
|
sl@0
|
420 |
(
|
sl@0
|
421 |
regex_id_type regex_id
|
sl@0
|
422 |
, detail::sub_match_impl<BidiIter> *sub_matches
|
sl@0
|
423 |
, size_type size
|
sl@0
|
424 |
)
|
sl@0
|
425 |
{
|
sl@0
|
426 |
this->regex_id_ = regex_id;
|
sl@0
|
427 |
detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size);
|
sl@0
|
428 |
}
|
sl@0
|
429 |
|
sl@0
|
430 |
/// INTERNAL ONLY
|
sl@0
|
431 |
extras_type &get_extras_()
|
sl@0
|
432 |
{
|
sl@0
|
433 |
if(!this->extras_ptr_)
|
sl@0
|
434 |
{
|
sl@0
|
435 |
this->extras_ptr_.reset(new extras_type);
|
sl@0
|
436 |
}
|
sl@0
|
437 |
|
sl@0
|
438 |
return *this->extras_ptr_;
|
sl@0
|
439 |
}
|
sl@0
|
440 |
|
sl@0
|
441 |
/// INTERNAL ONLY
|
sl@0
|
442 |
void set_prefix_suffix_(BidiIter begin, BidiIter end)
|
sl@0
|
443 |
{
|
sl@0
|
444 |
this->base_ = begin;
|
sl@0
|
445 |
|
sl@0
|
446 |
this->prefix_.first = begin;
|
sl@0
|
447 |
this->prefix_.second = (*this)[ 0 ].first;
|
sl@0
|
448 |
this->prefix_.matched = this->prefix_.first != this->prefix_.second;
|
sl@0
|
449 |
|
sl@0
|
450 |
this->suffix_.first = (*this)[ 0 ].second;
|
sl@0
|
451 |
this->suffix_.second = end;
|
sl@0
|
452 |
this->suffix_.matched = this->suffix_.first != this->suffix_.second;
|
sl@0
|
453 |
|
sl@0
|
454 |
typename nested_results_type::iterator ibegin = this->nested_results_.begin();
|
sl@0
|
455 |
typename nested_results_type::iterator iend = this->nested_results_.end();
|
sl@0
|
456 |
for( ; ibegin != iend; ++ibegin )
|
sl@0
|
457 |
{
|
sl@0
|
458 |
ibegin->set_prefix_suffix_(begin, end);
|
sl@0
|
459 |
}
|
sl@0
|
460 |
}
|
sl@0
|
461 |
|
sl@0
|
462 |
/// INTERNAL ONLY
|
sl@0
|
463 |
void reset_()
|
sl@0
|
464 |
{
|
sl@0
|
465 |
detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, 0, 0);
|
sl@0
|
466 |
}
|
sl@0
|
467 |
|
sl@0
|
468 |
/// INTERNAL ONLY
|
sl@0
|
469 |
void set_base_(BidiIter base)
|
sl@0
|
470 |
{
|
sl@0
|
471 |
this->base_ = base;
|
sl@0
|
472 |
|
sl@0
|
473 |
typename nested_results_type::iterator ibegin = this->nested_results_.begin();
|
sl@0
|
474 |
typename nested_results_type::iterator iend = this->nested_results_.end();
|
sl@0
|
475 |
for( ; ibegin != iend; ++ibegin )
|
sl@0
|
476 |
{
|
sl@0
|
477 |
ibegin->set_base_(base);
|
sl@0
|
478 |
}
|
sl@0
|
479 |
}
|
sl@0
|
480 |
|
sl@0
|
481 |
regex_id_type regex_id_;
|
sl@0
|
482 |
detail::sub_match_vector<BidiIter> sub_matches_;
|
sl@0
|
483 |
BidiIter base_;
|
sl@0
|
484 |
sub_match<BidiIter> prefix_;
|
sl@0
|
485 |
sub_match<BidiIter> suffix_;
|
sl@0
|
486 |
nested_results_type nested_results_;
|
sl@0
|
487 |
detail::action_state action_state_;
|
sl@0
|
488 |
shared_ptr<extras_type> extras_ptr_;
|
sl@0
|
489 |
};
|
sl@0
|
490 |
|
sl@0
|
491 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
492 |
// action_state_cast
|
sl@0
|
493 |
/// INTERNAL ONLY
|
sl@0
|
494 |
template<typename State, typename BidiIter>
|
sl@0
|
495 |
inline State &action_state_cast(match_results<BidiIter> const &what)
|
sl@0
|
496 |
{
|
sl@0
|
497 |
return what.BOOST_NESTED_TEMPLATE get_action_state<State>();
|
sl@0
|
498 |
}
|
sl@0
|
499 |
|
sl@0
|
500 |
///////////////////////////////////////////////////////////////////////////////
|
sl@0
|
501 |
// regex_id_filter_predicate
|
sl@0
|
502 |
//
|
sl@0
|
503 |
template<typename BidiIter>
|
sl@0
|
504 |
struct regex_id_filter_predicate
|
sl@0
|
505 |
: std::unary_function<match_results<BidiIter>, bool>
|
sl@0
|
506 |
{
|
sl@0
|
507 |
regex_id_filter_predicate(regex_id_type regex_id)
|
sl@0
|
508 |
: regex_id_(regex_id)
|
sl@0
|
509 |
{
|
sl@0
|
510 |
}
|
sl@0
|
511 |
|
sl@0
|
512 |
bool operator ()(match_results<BidiIter> const &res) const
|
sl@0
|
513 |
{
|
sl@0
|
514 |
return this->regex_id_ == res.regex_id();
|
sl@0
|
515 |
}
|
sl@0
|
516 |
|
sl@0
|
517 |
private:
|
sl@0
|
518 |
|
sl@0
|
519 |
regex_id_type regex_id_;
|
sl@0
|
520 |
};
|
sl@0
|
521 |
|
sl@0
|
522 |
}} // namespace boost::xpressive
|
sl@0
|
523 |
|
sl@0
|
524 |
#endif
|