Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:54

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file regex_iterator.hpp
0003 /// Contains the definition of the regex_iterator type, an STL-compatible iterator
0004 /// for stepping through all the matches in a sequence.
0005 //
0006 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0007 //  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 #ifndef BOOST_XPRESSIVE_REGEX_ITERATOR_HPP_EAN_10_04_2005
0011 #define BOOST_XPRESSIVE_REGEX_ITERATOR_HPP_EAN_10_04_2005
0012 
0013 // MS compatible compilers support #pragma once
0014 #if defined(_MSC_VER)
0015 # pragma once
0016 #endif
0017 
0018 #include <boost/noncopyable.hpp>
0019 #include <boost/intrusive_ptr.hpp>
0020 #include <boost/iterator/iterator_traits.hpp>
0021 #include <boost/xpressive/detail/detail_fwd.hpp>
0022 #include <boost/xpressive/detail/core/access.hpp>
0023 #include <boost/xpressive/detail/utility/counted_base.hpp>
0024 
0025 namespace boost { namespace xpressive { namespace detail
0026 {
0027 
0028 //////////////////////////////////////////////////////////////////////////
0029 // regex_iterator_impl
0030 //
0031 template<typename BidiIter>
0032 struct regex_iterator_impl
0033   : counted_base<regex_iterator_impl<BidiIter> >
0034 {
0035     typedef detail::core_access<BidiIter> access;
0036 
0037     regex_iterator_impl
0038     (
0039         BidiIter begin
0040       , BidiIter cur
0041       , BidiIter end
0042       , BidiIter next_search
0043       , basic_regex<BidiIter> const &rex
0044       , regex_constants::match_flag_type flags
0045       , bool not_null = false
0046     )
0047       : rex_(rex)
0048       , what_()
0049       , state_(begin, end, what_, *access::get_regex_impl(rex_), flags)
0050       , flags_(flags)
0051       , not_null_(not_null)
0052     {
0053         this->state_.cur_ = cur;
0054         this->state_.next_search_ = next_search;
0055     }
0056 
0057     bool next()
0058     {
0059         this->state_.reset(this->what_, *access::get_regex_impl(this->rex_));
0060         if(!regex_search_impl(this->state_, this->rex_, this->not_null_))
0061         {
0062             return false;
0063         }
0064 
0065         // Report position() correctly by setting the base different from prefix().first
0066         access::set_base(this->what_, this->state_.begin_);
0067 
0068         this->state_.cur_ = this->state_.next_search_ = this->what_[0].second;
0069         this->not_null_ = (0 == this->what_.length());
0070 
0071         return true;
0072     }
0073 
0074     bool equal_to(regex_iterator_impl<BidiIter> const &that) const
0075     {
0076         return this->rex_.regex_id()    == that.rex_.regex_id()
0077             && this->state_.begin_      == that.state_.begin_
0078             && this->state_.cur_        == that.state_.cur_
0079             && this->state_.end_        == that.state_.end_
0080             && this->flags_             == that.flags_
0081             ;
0082     }
0083 
0084     basic_regex<BidiIter> rex_;
0085     match_results<BidiIter> what_;
0086     match_state<BidiIter> state_;
0087     regex_constants::match_flag_type const flags_;
0088     bool not_null_;
0089 };
0090 
0091 } // namespace detail
0092 
0093 //////////////////////////////////////////////////////////////////////////
0094 // regex_iterator
0095 //
0096 template<typename BidiIter>
0097 struct regex_iterator
0098 {
0099     typedef basic_regex<BidiIter> regex_type;
0100     typedef match_results<BidiIter> value_type;
0101     typedef typename iterator_difference<BidiIter>::type difference_type;
0102     typedef value_type const *pointer;
0103     typedef value_type const &reference;
0104     typedef std::forward_iterator_tag iterator_category;
0105 
0106     /// INTERNAL ONLY
0107     typedef detail::regex_iterator_impl<BidiIter> impl_type_;
0108 
0109     regex_iterator()
0110       : impl_()
0111     {
0112     }
0113 
0114     regex_iterator
0115     (
0116         BidiIter begin
0117       , BidiIter end
0118       , basic_regex<BidiIter> const &rex
0119       , regex_constants::match_flag_type flags = regex_constants::match_default
0120     )
0121       : impl_()
0122     {
0123         if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
0124         {
0125           this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
0126           this->next_();
0127         }
0128     }
0129 
0130     template<typename LetExpr>
0131     regex_iterator
0132     (
0133         BidiIter begin
0134       , BidiIter end
0135       , basic_regex<BidiIter> const &rex
0136       , detail::let_<LetExpr> const &args
0137       , regex_constants::match_flag_type flags = regex_constants::match_default
0138     )
0139       : impl_()
0140     {
0141         if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
0142         {
0143           this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
0144           detail::bind_args(args, this->impl_->what_);
0145           this->next_();
0146         }
0147     }
0148 
0149     regex_iterator(regex_iterator<BidiIter> const &that)
0150       : impl_(that.impl_) // COW
0151     {
0152     }
0153 
0154     regex_iterator<BidiIter> &operator =(regex_iterator<BidiIter> const &that)
0155     {
0156         this->impl_ = that.impl_; // COW
0157         return *this;
0158     }
0159 
0160     friend bool operator ==(regex_iterator<BidiIter> const &left, regex_iterator<BidiIter> const &right)
0161     {
0162         if(!left.impl_ || !right.impl_)
0163         {
0164             return !left.impl_ && !right.impl_;
0165         }
0166 
0167         return left.impl_->equal_to(*right.impl_);
0168     }
0169 
0170     friend bool operator !=(regex_iterator<BidiIter> const &left, regex_iterator<BidiIter> const &right)
0171     {
0172         return !(left == right);
0173     }
0174 
0175     value_type const &operator *() const
0176     {
0177         return this->impl_->what_;
0178     }
0179 
0180     value_type const *operator ->() const
0181     {
0182         return &this->impl_->what_;
0183     }
0184 
0185     /// If what.prefix().first != what[0].second and if the element match_prev_avail is not set in
0186     /// flags then sets it. Then behaves as if by calling regex_search(what[0].second, end, what, *pre, flags),
0187     /// with the following variation: in the event that the previous match found was of zero length
0188     /// (what[0].length() == 0) then attempts to find a non-zero length match starting at what[0].second,
0189     /// only if that fails and provided what[0].second != suffix().second does it look for a (possibly
0190     /// zero length) match starting from what[0].second + 1.  If no further match is found then sets
0191     /// *this equal to the end of sequence iterator.
0192     /// \post (*this)-\>size() == pre-\>mark_count() + 1
0193     /// \post (*this)-\>empty() == false
0194     /// \post (*this)-\>prefix().first == An iterator denoting the end point of the previous match found
0195     /// \post (*this)-\>prefix().last == (**this)[0].first
0196     /// \post (*this)-\>prefix().matched == (*this)-\>prefix().first != (*this)-\>prefix().second
0197     /// \post (*this)-\>suffix().first == (**this)[0].second
0198     /// \post (*this)-\>suffix().last == end
0199     /// \post (*this)-\>suffix().matched == (*this)-\>suffix().first != (*this)-\>suffix().second
0200     /// \post (**this)[0].first == The starting iterator for this match.
0201     /// \post (**this)[0].second == The ending iterator for this match.
0202     /// \post (**this)[0].matched == true if a full match was found, and false if it was a partial match (found as a result of the match_partial flag being set).
0203     /// \post (**this)[n].first == For all integers n \< (*this)-\>size(), the start of the sequence that matched sub-expression n. Alternatively, if sub-expression n did not participate in the match, then end.
0204     /// \post (**this)[n].second == For all integers n \< (*this)-\>size(), the end of the sequence that matched sub-expression n. Alternatively, if sub-expression n did not participate in the match, then end.
0205     /// \post (**this)[n].matched == For all integers n \< (*this)-\>size(), true if sub-expression n participated in the match, false otherwise.
0206     /// \post (*this)-\>position() == The distance from the start of the original sequence being iterated, to the start of this match.
0207     regex_iterator<BidiIter> &operator ++()
0208     {
0209         this->fork_(); // un-share the implementation
0210         this->next_();
0211         return *this;
0212     }
0213 
0214     regex_iterator<BidiIter> operator ++(int)
0215     {
0216         regex_iterator<BidiIter> tmp(*this);
0217         ++*this;
0218         return tmp;
0219     }
0220 
0221 private:
0222 
0223     /// INTERNAL ONLY
0224     void fork_()
0225     {
0226         if(1 != this->impl_->use_count())
0227         {
0228             // This is OK, the use_count is > 1
0229             impl_type_ *that = this->impl_.get();
0230             this->impl_ = new impl_type_
0231             (
0232                 that->state_.begin_
0233               , that->state_.cur_
0234               , that->state_.end_
0235               , that->state_.next_search_
0236               , that->rex_
0237               , that->flags_
0238               , that->not_null_
0239             );
0240             detail::core_access<BidiIter>::get_action_args(this->impl_->what_)
0241                 = detail::core_access<BidiIter>::get_action_args(that->what_);
0242         }
0243     }
0244 
0245     /// INTERNAL ONLY
0246     void next_()
0247     {
0248         BOOST_ASSERT(this->impl_ && 1 == this->impl_->use_count());
0249         if(!this->impl_->next())
0250         {
0251             this->impl_ = 0;
0252         }
0253     }
0254 
0255     intrusive_ptr<impl_type_> impl_;
0256 };
0257 
0258 }} // namespace boost::xpressive
0259 
0260 #endif