os/ossrv/ossrv_pub/boost_apis/boost/xpressive/match_results.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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