Warning, file /include/boost/xpressive/regex_iterator.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
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 
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 
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         
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 } 
0092 
0093 
0094 
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     
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()) 
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()) 
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_) 
0151     {
0152     }
0153 
0154     regex_iterator<BidiIter> &operator =(regex_iterator<BidiIter> const &that)
0155     {
0156         this->impl_ = that.impl_; 
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     
0186     
0187     
0188     
0189     
0190     
0191     
0192     
0193     
0194     
0195     
0196     
0197     
0198     
0199     
0200     
0201     
0202     
0203     
0204     
0205     
0206     
0207     regex_iterator<BidiIter> &operator ++()
0208     {
0209         this->fork_(); 
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     
0224     void fork_()
0225     {
0226         if(1 != this->impl_->use_count())
0227         {
0228             
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     
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 }} 
0259 
0260 #endif