File indexing completed on 2025-01-18 09:53:54
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