Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:59:27

0001 /*
0002  *
0003  * Copyright (c) 1998-2009
0004  * John Maddock
0005  *
0006  * Use, modification and distribution are subject to the 
0007  * Boost Software License, Version 1.0. (See accompanying file 
0008  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009  *
0010  */
0011 
0012  /*
0013   *   LOCATION:    see http://www.boost.org for most recent version.
0014   *   FILE         match_results.cpp
0015   *   VERSION      see <boost/version.hpp>
0016   *   DESCRIPTION: Declares template class match_results.
0017   */
0018 
0019 #ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
0020 #define BOOST_REGEX_V4_MATCH_RESULTS_HPP
0021 
0022 #ifdef BOOST_MSVC
0023 #pragma warning(push)
0024 #pragma warning(disable: 4103)
0025 #endif
0026 #ifdef BOOST_HAS_ABI_HEADERS
0027 #  include BOOST_ABI_PREFIX
0028 #endif
0029 #ifdef BOOST_MSVC
0030 #pragma warning(pop)
0031 #endif
0032 
0033 namespace boost{
0034 #ifdef BOOST_MSVC
0035 #pragma warning(push)
0036 #pragma warning(disable : 4251)
0037 #if BOOST_MSVC < 1700
0038 #     pragma warning(disable : 4231)
0039 #endif
0040 #  if BOOST_MSVC < 1600
0041 #     pragma warning(disable : 4660)
0042 #  endif
0043 #endif
0044 
0045 namespace BOOST_REGEX_DETAIL_NS{
0046 
0047 class named_subexpressions;
0048 
0049 }
0050 
0051 template <class BidiIterator, class Allocator>
0052 class match_results
0053 { 
0054 private:
0055 #ifndef BOOST_NO_STD_ALLOCATOR
0056    typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;
0057 #else
0058    typedef          std::vector<sub_match<BidiIterator> >           vector_type;
0059 #endif
0060 public: 
0061    typedef          sub_match<BidiIterator>                         value_type;
0062 #ifndef BOOST_NO_CXX11_ALLOCATOR
0063    typedef typename std::allocator_traits<Allocator>::value_type const &    const_reference;
0064 #elif  !defined(BOOST_NO_STD_ALLOCATOR) && !(defined(BOOST_MSVC) && defined(_STLPORT_VERSION))
0065    typedef typename Allocator::const_reference                              const_reference;
0066 #else
0067    typedef          const value_type&                                       const_reference;
0068 #endif
0069    typedef          const_reference                                         reference;
0070    typedef typename vector_type::const_iterator                             const_iterator;
0071    typedef          const_iterator                                          iterator;
0072    typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<
0073                                     BidiIterator>::difference_type          difference_type;
0074 #ifdef BOOST_NO_CXX11_ALLOCATOR
0075    typedef typename Allocator::size_type                                    size_type;
0076 #else
0077    typedef typename std::allocator_traits<Allocator>::size_type             size_type;
0078 #endif
0079    typedef          Allocator                                               allocator_type;
0080    typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<
0081                                     BidiIterator>::value_type               char_type;
0082    typedef          std::basic_string<char_type>                            string_type;
0083    typedef          BOOST_REGEX_DETAIL_NS::named_subexpressions                         named_sub_type;
0084 
0085    // construct/copy/destroy:
0086    explicit match_results(const Allocator& a = Allocator())
0087 #ifndef BOOST_NO_STD_ALLOCATOR
0088       : m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}
0089 #else
0090       : m_subs(), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }
0091 #endif
0092    //
0093    // IMPORTANT: in the code below, the crazy looking checks around m_is_singular are
0094    // all required because it is illegal to copy a singular iterator.
0095    // See https://svn.boost.org/trac/boost/ticket/3632.
0096    //
0097    match_results(const match_results& m)
0098       : m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
0099    {
0100       if(!m_is_singular)
0101       {
0102          m_base = m.m_base;
0103          m_null = m.m_null;
0104       }
0105    }
0106    match_results& operator=(const match_results& m)
0107    {
0108       m_subs = m.m_subs;
0109       m_named_subs = m.m_named_subs;
0110       m_last_closed_paren = m.m_last_closed_paren;
0111       m_is_singular = m.m_is_singular;
0112       if(!m_is_singular)
0113       {
0114          m_base = m.m_base;
0115          m_null = m.m_null;
0116       }
0117       return *this;
0118    }
0119    ~match_results(){}
0120 
0121    // size:
0122    size_type size() const
0123    { return empty() ? 0 : m_subs.size() - 2; }
0124    size_type max_size() const
0125    { return m_subs.max_size(); }
0126    bool empty() const
0127    { return m_subs.size() < 2; }
0128    // element access:
0129    difference_type length(int sub = 0) const
0130    {
0131       if(m_is_singular)
0132          raise_logic_error();
0133       sub += 2;
0134       if((sub < (int)m_subs.size()) && (sub > 0))
0135          return m_subs[sub].length();
0136       return 0;
0137    }
0138    difference_type length(const char_type* sub) const
0139    {
0140       if(m_is_singular)
0141          raise_logic_error();
0142       const char_type* sub_end = sub;
0143       while(*sub_end) ++sub_end;
0144       return length(named_subexpression_index(sub, sub_end));
0145    }
0146    template <class charT>
0147    difference_type length(const charT* sub) const
0148    {
0149       if(m_is_singular)
0150          raise_logic_error();
0151       const charT* sub_end = sub;
0152       while(*sub_end) ++sub_end;
0153       return length(named_subexpression_index(sub, sub_end));
0154    }
0155    template <class charT, class Traits, class A>
0156    difference_type length(const std::basic_string<charT, Traits, A>& sub) const
0157    {
0158       return length(sub.c_str());
0159    }
0160    difference_type position(size_type sub = 0) const
0161    {
0162       if(m_is_singular)
0163          raise_logic_error();
0164       sub += 2;
0165       if(sub < m_subs.size())
0166       {
0167          const sub_match<BidiIterator>& s = m_subs[sub];
0168          if(s.matched || (sub == 2))
0169          {
0170             return ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
0171          }
0172       }
0173       return ~static_cast<difference_type>(0);
0174    }
0175    difference_type position(const char_type* sub) const
0176    {
0177       const char_type* sub_end = sub;
0178       while(*sub_end) ++sub_end;
0179       return position(named_subexpression_index(sub, sub_end));
0180    }
0181    template <class charT>
0182    difference_type position(const charT* sub) const
0183    {
0184       const charT* sub_end = sub;
0185       while(*sub_end) ++sub_end;
0186       return position(named_subexpression_index(sub, sub_end));
0187    }
0188    template <class charT, class Traits, class A>
0189    difference_type position(const std::basic_string<charT, Traits, A>& sub) const
0190    {
0191       return position(sub.c_str());
0192    }
0193    string_type str(int sub = 0) const
0194    {
0195       if(m_is_singular)
0196          raise_logic_error();
0197       sub += 2;
0198       string_type result;
0199       if(sub < (int)m_subs.size() && (sub > 0))
0200       {
0201          const sub_match<BidiIterator>& s = m_subs[sub];
0202          if(s.matched)
0203          {
0204             result = s.str();
0205          }
0206       }
0207       return result;
0208    }
0209    string_type str(const char_type* sub) const
0210    {
0211       return (*this)[sub].str();
0212    }
0213    template <class Traits, class A>
0214    string_type str(const std::basic_string<char_type, Traits, A>& sub) const
0215    {
0216       return (*this)[sub].str();
0217    }
0218    template <class charT>
0219    string_type str(const charT* sub) const
0220    {
0221       return (*this)[sub].str();
0222    }
0223    template <class charT, class Traits, class A>
0224    string_type str(const std::basic_string<charT, Traits, A>& sub) const
0225    {
0226       return (*this)[sub].str();
0227    }
0228    const_reference operator[](int sub) const
0229    {
0230       if(m_is_singular && m_subs.empty())
0231          raise_logic_error();
0232       sub += 2;
0233       if(sub < (int)m_subs.size() && (sub >= 0))
0234       {
0235          return m_subs[sub];
0236       }
0237       return m_null;
0238    }
0239    //
0240    // Named sub-expressions:
0241    //
0242    const_reference named_subexpression(const char_type* i, const char_type* j) const
0243    {
0244       //
0245       // Scan for the leftmost *matched* subexpression with the specified named:
0246       //
0247       if(m_is_singular)
0248          raise_logic_error();
0249       BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
0250       while((r.first != r.second) && ((*this)[r.first->index].matched == false))
0251          ++r.first;
0252       return r.first != r.second ? (*this)[r.first->index] : m_null;
0253    }
0254    template <class charT>
0255    const_reference named_subexpression(const charT* i, const charT* j) const
0256    {
0257       BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0258       if(i == j)
0259          return m_null;
0260       std::vector<char_type> s;
0261       while(i != j)
0262          s.insert(s.end(), *i++);
0263       return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0264    }
0265    int named_subexpression_index(const char_type* i, const char_type* j) const
0266    {
0267       //
0268       // Scan for the leftmost *matched* subexpression with the specified named.
0269       // If none found then return the leftmost expression with that name,
0270       // otherwise an invalid index:
0271       //
0272       if(m_is_singular)
0273          raise_logic_error();
0274       BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;
0275       s = r = m_named_subs->equal_range(i, j);
0276       while((r.first != r.second) && ((*this)[r.first->index].matched == false))
0277          ++r.first;
0278       if(r.first == r.second)
0279          r = s;
0280       return r.first != r.second ? r.first->index : -20;
0281    }
0282    template <class charT>
0283    int named_subexpression_index(const charT* i, const charT* j) const
0284    {
0285       BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0286       if(i == j)
0287          return -20;
0288       std::vector<char_type> s;
0289       while(i != j)
0290          s.insert(s.end(), *i++);
0291       return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
0292    }
0293    template <class Traits, class A>
0294    const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
0295    {
0296       return named_subexpression(s.c_str(), s.c_str() + s.size());
0297    }
0298    const_reference operator[](const char_type* p) const
0299    {
0300       const char_type* e = p;
0301       while(*e) ++e;
0302       return named_subexpression(p, e);
0303    }
0304 
0305    template <class charT>
0306    const_reference operator[](const charT* p) const
0307    {
0308       BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0309       if(*p == 0)
0310          return m_null;
0311       std::vector<char_type> s;
0312       while(*p)
0313          s.insert(s.end(), *p++);
0314       return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0315    }
0316    template <class charT, class Traits, class A>
0317    const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
0318    {
0319       BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0320       if(ns.empty())
0321          return m_null;
0322       std::vector<char_type> s;
0323       for(unsigned i = 0; i < ns.size(); ++i)
0324          s.insert(s.end(), ns[i]);
0325       return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0326    }
0327 
0328    const_reference prefix() const
0329    {
0330       if(m_is_singular)
0331          raise_logic_error();
0332       return (*this)[-1];
0333    }
0334 
0335    const_reference suffix() const
0336    {
0337       if(m_is_singular)
0338          raise_logic_error();
0339       return (*this)[-2];
0340    }
0341    const_iterator begin() const
0342    {
0343       return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
0344    }
0345    const_iterator end() const
0346    {
0347       return m_subs.end();
0348    }
0349    // format:
0350    template <class OutputIterator, class Functor>
0351    OutputIterator format(OutputIterator out,
0352                          Functor fmt,
0353                          match_flag_type flags = format_default) const
0354    {
0355       if(m_is_singular)
0356          raise_logic_error();
0357       typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
0358       F func(fmt);
0359       return func(*this, out, flags);
0360    }
0361    template <class Functor>
0362    string_type format(Functor fmt, match_flag_type flags = format_default) const
0363    {
0364       if(m_is_singular)
0365          raise_logic_error();
0366       std::basic_string<char_type> result;
0367       BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
0368 
0369       typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;
0370       F func(fmt);
0371 
0372       func(*this, i, flags);
0373       return result;
0374    }
0375    // format with locale:
0376    template <class OutputIterator, class Functor, class RegexT>
0377    OutputIterator format(OutputIterator out,
0378                          Functor fmt,
0379                          match_flag_type flags,
0380                          const RegexT& re) const
0381    {
0382       if(m_is_singular)
0383          raise_logic_error();
0384       typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
0385       typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
0386       F func(fmt);
0387       return func(*this, out, flags, re.get_traits());
0388    }
0389    template <class RegexT, class Functor>
0390    string_type format(Functor fmt,
0391                       match_flag_type flags,
0392                       const RegexT& re) const
0393    {
0394       if(m_is_singular)
0395          raise_logic_error();
0396       typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
0397       std::basic_string<char_type> result;
0398       BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
0399 
0400       typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
0401       F func(fmt);
0402 
0403       func(*this, i, flags, re.get_traits());
0404       return result;
0405    }
0406 
0407    const_reference get_last_closed_paren()const
0408    {
0409       if(m_is_singular)
0410          raise_logic_error();
0411       return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
0412    }
0413 
0414    allocator_type get_allocator() const
0415    {
0416 #ifndef BOOST_NO_STD_ALLOCATOR
0417       return m_subs.get_allocator();
0418 #else
0419      return allocator_type();
0420 #endif
0421    }
0422    void swap(match_results& that)
0423    {
0424       std::swap(m_subs, that.m_subs);
0425       std::swap(m_named_subs, that.m_named_subs);
0426       std::swap(m_last_closed_paren, that.m_last_closed_paren);
0427       if(m_is_singular)
0428       {
0429          if(!that.m_is_singular)
0430          {
0431             m_base = that.m_base;
0432             m_null = that.m_null;
0433          }
0434       }
0435       else if(that.m_is_singular)
0436       {
0437          that.m_base = m_base;
0438          that.m_null = m_null;
0439       }
0440       else
0441       {
0442          std::swap(m_base, that.m_base);
0443          std::swap(m_null, that.m_null);
0444       }
0445       std::swap(m_is_singular, that.m_is_singular);
0446    }
0447    bool operator==(const match_results& that)const
0448    {
0449       if(m_is_singular)
0450       {
0451          return that.m_is_singular;
0452       }
0453       else if(that.m_is_singular)
0454       {
0455          return false;
0456       }
0457       return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
0458    }
0459    bool operator!=(const match_results& that)const
0460    { return !(*this == that); }
0461 
0462 #ifdef BOOST_REGEX_MATCH_EXTRA
0463    typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
0464 
0465    const capture_sequence_type& captures(int i)const
0466    {
0467       if(m_is_singular)
0468          raise_logic_error();
0469       return (*this)[i].captures();
0470    }
0471 #endif
0472 
0473    //
0474    // private access functions:
0475    void BOOST_REGEX_CALL set_second(BidiIterator i)
0476    {
0477       BOOST_REGEX_ASSERT(m_subs.size() > 2);
0478       m_subs[2].second = i;
0479       m_subs[2].matched = true;
0480       m_subs[0].first = i;
0481       m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
0482       m_null.first = i;
0483       m_null.second = i;
0484       m_null.matched = false;
0485       m_is_singular = false;
0486    }
0487 
0488    void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
0489    {
0490       if(pos)
0491          m_last_closed_paren = static_cast<int>(pos);
0492       pos += 2;
0493       BOOST_REGEX_ASSERT(m_subs.size() > pos);
0494       m_subs[pos].second = i;
0495       m_subs[pos].matched = m;
0496       if((pos == 2) && !escape_k)
0497       {
0498          m_subs[0].first = i;
0499          m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
0500          m_null.first = i;
0501          m_null.second = i;
0502          m_null.matched = false;
0503          m_is_singular = false;
0504       }
0505    }
0506    void BOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
0507    {
0508       value_type v(j);
0509       size_type len = m_subs.size();
0510       if(len > n + 2)
0511       {
0512          m_subs.erase(m_subs.begin()+n+2, m_subs.end());
0513          std::fill(m_subs.begin(), m_subs.end(), v);
0514       }
0515       else
0516       {
0517          std::fill(m_subs.begin(), m_subs.end(), v);
0518          if(n+2 != len)
0519             m_subs.insert(m_subs.end(), n+2-len, v);
0520       }
0521       m_subs[1].first = i;
0522       m_last_closed_paren = 0;
0523    }
0524    void BOOST_REGEX_CALL set_base(BidiIterator pos)
0525    {
0526       m_base = pos;
0527    }
0528    BidiIterator base()const
0529    {
0530       return m_base;
0531    }
0532    void BOOST_REGEX_CALL set_first(BidiIterator i)
0533    {
0534       BOOST_REGEX_ASSERT(m_subs.size() > 2);
0535       // set up prefix:
0536       m_subs[1].second = i;
0537       m_subs[1].matched = (m_subs[1].first != i);
0538       // set up $0:
0539       m_subs[2].first = i;
0540       // zero out everything else:
0541       for(size_type n = 3; n < m_subs.size(); ++n)
0542       {
0543          m_subs[n].first = m_subs[n].second = m_subs[0].second;
0544          m_subs[n].matched = false;
0545       }
0546    }
0547    void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
0548    {
0549       BOOST_REGEX_ASSERT(pos+2 < m_subs.size());
0550       if(pos || escape_k)
0551       {
0552          m_subs[pos+2].first = i;
0553          if(escape_k)
0554          {
0555             m_subs[1].second = i;
0556             m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
0557          }
0558       }
0559       else
0560          set_first(i);
0561    }
0562    void BOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);
0563 
0564    void BOOST_REGEX_CALL set_named_subs(boost::shared_ptr<named_sub_type> subs)
0565    {
0566       m_named_subs = subs;
0567    }
0568 
0569 private:
0570    //
0571    // Error handler called when an uninitialized match_results is accessed:
0572    //
0573    static void raise_logic_error()
0574    {
0575       std::logic_error e("Attempt to access an uninitialized boost::match_results<> class.");
0576       boost::throw_exception(e);
0577    }
0578 
0579 
0580    vector_type            m_subs;                      // subexpressions
0581    BidiIterator   m_base;                              // where the search started from
0582    sub_match<BidiIterator> m_null;                     // a null match
0583    boost::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object
0584    int m_last_closed_paren;                            // Last ) to be seen - used for formatting
0585    bool m_is_singular;                                 // True if our stored iterators are singular
0586 };
0587 
0588 template <class BidiIterator, class Allocator>
0589 void BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
0590 {
0591    if(m_is_singular)
0592    {
0593       *this = m;
0594       return;
0595    }
0596    const_iterator p1, p2;
0597    p1 = begin();
0598    p2 = m.begin();
0599    //
0600    // Distances are measured from the start of *this* match, unless this isn't
0601    // a valid match in which case we use the start of the whole sequence.  Note that
0602    // no subsequent match-candidate can ever be to the left of the first match found.
0603    // This ensures that when we are using bidirectional iterators, that distances 
0604    // measured are as short as possible, and therefore as efficient as possible
0605    // to compute.  Finally note that we don't use the "matched" data member to test
0606    // whether a sub-expression is a valid match, because partial matches set this
0607    // to false for sub-expression 0.
0608    //
0609    BidiIterator l_end = this->suffix().second;
0610    BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
0611    difference_type len1 = 0;
0612    difference_type len2 = 0;
0613    difference_type base1 = 0;
0614    difference_type base2 = 0;
0615    std::size_t i;
0616    for(i = 0; i < size(); ++i, ++p1, ++p2)
0617    {
0618       //
0619       // Leftmost takes priority over longest; handle special cases
0620       // where distances need not be computed first (an optimisation
0621       // for bidirectional iterators: ensure that we don't accidently
0622       // compute the length of the whole sequence, as this can be really
0623       // expensive).
0624       //
0625       if(p1->first == l_end)
0626       {
0627          if(p2->first != l_end)
0628          {
0629             // p2 must be better than p1, and no need to calculate
0630             // actual distances:
0631             base1 = 1;
0632             base2 = 0;
0633             break;
0634          }
0635          else
0636          {
0637             // *p1 and *p2 are either unmatched or match end-of sequence,
0638             // either way no need to calculate distances:
0639             if((p1->matched == false) && (p2->matched == true))
0640                break;
0641             if((p1->matched == true) && (p2->matched == false))
0642                return;
0643             continue;
0644          }
0645       }
0646       else if(p2->first == l_end)
0647       {
0648          // p1 better than p2, and no need to calculate distances:
0649          return;
0650       }
0651       base1 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p1->first);
0652       base2 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p2->first);
0653       BOOST_REGEX_ASSERT(base1 >= 0);
0654       BOOST_REGEX_ASSERT(base2 >= 0);
0655       if(base1 < base2) return;
0656       if(base2 < base1) break;
0657 
0658       len1 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
0659       len2 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
0660       BOOST_REGEX_ASSERT(len1 >= 0);
0661       BOOST_REGEX_ASSERT(len2 >= 0);
0662       if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
0663          break;
0664       if((p1->matched == true) && (p2->matched == false))
0665          return;
0666    }
0667    if(i == size())
0668       return;
0669    if(base2 < base1)
0670       *this = m;
0671    else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
0672       *this = m;
0673 }
0674 
0675 template <class BidiIterator, class Allocator>
0676 void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
0677 {
0678    a.swap(b);
0679 }
0680 
0681 #ifndef BOOST_NO_STD_LOCALE
0682 template <class charT, class traits, class BidiIterator, class Allocator>
0683 std::basic_ostream<charT, traits>&
0684    operator << (std::basic_ostream<charT, traits>& os,
0685                 const match_results<BidiIterator, Allocator>& s)
0686 {
0687    return (os << s.str());
0688 }
0689 #else
0690 template <class BidiIterator, class Allocator>
0691 std::ostream& operator << (std::ostream& os,
0692                            const match_results<BidiIterator, Allocator>& s)
0693 {
0694    return (os << s.str());
0695 }
0696 #endif
0697 
0698 #ifdef BOOST_MSVC
0699 #pragma warning(pop)
0700 #endif
0701 } // namespace boost
0702 
0703 #ifdef BOOST_MSVC
0704 #pragma warning(push)
0705 #pragma warning(disable: 4103)
0706 #endif
0707 #ifdef BOOST_HAS_ABI_HEADERS
0708 #  include BOOST_ABI_SUFFIX
0709 #endif
0710 #ifdef BOOST_MSVC
0711 #pragma warning(pop)
0712 #endif
0713 
0714 #endif
0715 
0716