annotate DEPENDENCIES/generic/include/boost/xpressive/regex_iterator.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file regex_iterator.hpp
Chris@16 3 /// Contains the definition of the regex_iterator type, an STL-compatible iterator
Chris@16 4 /// for stepping through all the matches in a sequence.
Chris@16 5 //
Chris@16 6 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 7 // Software License, Version 1.0. (See accompanying file
Chris@16 8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9
Chris@16 10 #ifndef BOOST_XPRESSIVE_REGEX_ITERATOR_HPP_EAN_10_04_2005
Chris@16 11 #define BOOST_XPRESSIVE_REGEX_ITERATOR_HPP_EAN_10_04_2005
Chris@16 12
Chris@16 13 // MS compatible compilers support #pragma once
Chris@101 14 #if defined(_MSC_VER)
Chris@16 15 # pragma once
Chris@16 16 #endif
Chris@16 17
Chris@16 18 #include <boost/noncopyable.hpp>
Chris@16 19 #include <boost/intrusive_ptr.hpp>
Chris@16 20 #include <boost/iterator/iterator_traits.hpp>
Chris@16 21 #include <boost/xpressive/detail/detail_fwd.hpp>
Chris@16 22 #include <boost/xpressive/detail/core/access.hpp>
Chris@16 23 #include <boost/xpressive/detail/utility/counted_base.hpp>
Chris@16 24
Chris@16 25 namespace boost { namespace xpressive { namespace detail
Chris@16 26 {
Chris@16 27
Chris@16 28 //////////////////////////////////////////////////////////////////////////
Chris@16 29 // regex_iterator_impl
Chris@16 30 //
Chris@16 31 template<typename BidiIter>
Chris@16 32 struct regex_iterator_impl
Chris@16 33 : counted_base<regex_iterator_impl<BidiIter> >
Chris@16 34 {
Chris@16 35 typedef detail::core_access<BidiIter> access;
Chris@16 36
Chris@16 37 regex_iterator_impl
Chris@16 38 (
Chris@16 39 BidiIter begin
Chris@16 40 , BidiIter cur
Chris@16 41 , BidiIter end
Chris@16 42 , BidiIter next_search
Chris@16 43 , basic_regex<BidiIter> const &rex
Chris@16 44 , regex_constants::match_flag_type flags
Chris@16 45 , bool not_null = false
Chris@16 46 )
Chris@16 47 : rex_(rex)
Chris@16 48 , what_()
Chris@16 49 , state_(begin, end, what_, *access::get_regex_impl(rex_), flags)
Chris@16 50 , flags_(flags)
Chris@16 51 , not_null_(not_null)
Chris@16 52 {
Chris@16 53 this->state_.cur_ = cur;
Chris@16 54 this->state_.next_search_ = next_search;
Chris@16 55 }
Chris@16 56
Chris@16 57 bool next()
Chris@16 58 {
Chris@16 59 this->state_.reset(this->what_, *access::get_regex_impl(this->rex_));
Chris@16 60 if(!regex_search_impl(this->state_, this->rex_, this->not_null_))
Chris@16 61 {
Chris@16 62 return false;
Chris@16 63 }
Chris@16 64
Chris@16 65 // Report position() correctly by setting the base different from prefix().first
Chris@16 66 access::set_base(this->what_, this->state_.begin_);
Chris@16 67
Chris@16 68 this->state_.cur_ = this->state_.next_search_ = this->what_[0].second;
Chris@16 69 this->not_null_ = (0 == this->what_.length());
Chris@16 70
Chris@16 71 return true;
Chris@16 72 }
Chris@16 73
Chris@16 74 bool equal_to(regex_iterator_impl<BidiIter> const &that) const
Chris@16 75 {
Chris@16 76 return this->rex_.regex_id() == that.rex_.regex_id()
Chris@16 77 && this->state_.begin_ == that.state_.begin_
Chris@16 78 && this->state_.cur_ == that.state_.cur_
Chris@16 79 && this->state_.end_ == that.state_.end_
Chris@16 80 && this->flags_ == that.flags_
Chris@16 81 ;
Chris@16 82 }
Chris@16 83
Chris@16 84 basic_regex<BidiIter> rex_;
Chris@16 85 match_results<BidiIter> what_;
Chris@16 86 match_state<BidiIter> state_;
Chris@16 87 regex_constants::match_flag_type const flags_;
Chris@16 88 bool not_null_;
Chris@16 89 };
Chris@16 90
Chris@16 91 } // namespace detail
Chris@16 92
Chris@16 93 //////////////////////////////////////////////////////////////////////////
Chris@16 94 // regex_iterator
Chris@16 95 //
Chris@16 96 template<typename BidiIter>
Chris@16 97 struct regex_iterator
Chris@16 98 {
Chris@16 99 typedef basic_regex<BidiIter> regex_type;
Chris@16 100 typedef match_results<BidiIter> value_type;
Chris@16 101 typedef typename iterator_difference<BidiIter>::type difference_type;
Chris@16 102 typedef value_type const *pointer;
Chris@16 103 typedef value_type const &reference;
Chris@16 104 typedef std::forward_iterator_tag iterator_category;
Chris@16 105
Chris@16 106 /// INTERNAL ONLY
Chris@16 107 typedef detail::regex_iterator_impl<BidiIter> impl_type_;
Chris@16 108
Chris@16 109 regex_iterator()
Chris@16 110 : impl_()
Chris@16 111 {
Chris@16 112 }
Chris@16 113
Chris@16 114 regex_iterator
Chris@16 115 (
Chris@16 116 BidiIter begin
Chris@16 117 , BidiIter end
Chris@16 118 , basic_regex<BidiIter> const &rex
Chris@16 119 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 120 )
Chris@16 121 : impl_()
Chris@16 122 {
Chris@16 123 if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
Chris@16 124 {
Chris@16 125 this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
Chris@16 126 this->next_();
Chris@16 127 }
Chris@16 128 }
Chris@16 129
Chris@16 130 template<typename LetExpr>
Chris@16 131 regex_iterator
Chris@16 132 (
Chris@16 133 BidiIter begin
Chris@16 134 , BidiIter end
Chris@16 135 , basic_regex<BidiIter> const &rex
Chris@16 136 , detail::let_<LetExpr> const &args
Chris@16 137 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 138 )
Chris@16 139 : impl_()
Chris@16 140 {
Chris@16 141 if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
Chris@16 142 {
Chris@16 143 this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
Chris@16 144 detail::bind_args(args, this->impl_->what_);
Chris@16 145 this->next_();
Chris@16 146 }
Chris@16 147 }
Chris@16 148
Chris@16 149 regex_iterator(regex_iterator<BidiIter> const &that)
Chris@16 150 : impl_(that.impl_) // COW
Chris@16 151 {
Chris@16 152 }
Chris@16 153
Chris@16 154 regex_iterator<BidiIter> &operator =(regex_iterator<BidiIter> const &that)
Chris@16 155 {
Chris@16 156 this->impl_ = that.impl_; // COW
Chris@16 157 return *this;
Chris@16 158 }
Chris@16 159
Chris@16 160 friend bool operator ==(regex_iterator<BidiIter> const &left, regex_iterator<BidiIter> const &right)
Chris@16 161 {
Chris@16 162 if(!left.impl_ || !right.impl_)
Chris@16 163 {
Chris@16 164 return !left.impl_ && !right.impl_;
Chris@16 165 }
Chris@16 166
Chris@16 167 return left.impl_->equal_to(*right.impl_);
Chris@16 168 }
Chris@16 169
Chris@16 170 friend bool operator !=(regex_iterator<BidiIter> const &left, regex_iterator<BidiIter> const &right)
Chris@16 171 {
Chris@16 172 return !(left == right);
Chris@16 173 }
Chris@16 174
Chris@16 175 value_type const &operator *() const
Chris@16 176 {
Chris@16 177 return this->impl_->what_;
Chris@16 178 }
Chris@16 179
Chris@16 180 value_type const *operator ->() const
Chris@16 181 {
Chris@16 182 return &this->impl_->what_;
Chris@16 183 }
Chris@16 184
Chris@16 185 /// If what.prefix().first != what[0].second and if the element match_prev_avail is not set in
Chris@16 186 /// flags then sets it. Then behaves as if by calling regex_search(what[0].second, end, what, *pre, flags),
Chris@16 187 /// with the following variation: in the event that the previous match found was of zero length
Chris@16 188 /// (what[0].length() == 0) then attempts to find a non-zero length match starting at what[0].second,
Chris@16 189 /// only if that fails and provided what[0].second != suffix().second does it look for a (possibly
Chris@16 190 /// zero length) match starting from what[0].second + 1. If no further match is found then sets
Chris@16 191 /// *this equal to the end of sequence iterator.
Chris@16 192 /// \post (*this)-\>size() == pre-\>mark_count() + 1
Chris@16 193 /// \post (*this)-\>empty() == false
Chris@16 194 /// \post (*this)-\>prefix().first == An iterator denoting the end point of the previous match found
Chris@16 195 /// \post (*this)-\>prefix().last == (**this)[0].first
Chris@16 196 /// \post (*this)-\>prefix().matched == (*this)-\>prefix().first != (*this)-\>prefix().second
Chris@16 197 /// \post (*this)-\>suffix().first == (**this)[0].second
Chris@16 198 /// \post (*this)-\>suffix().last == end
Chris@16 199 /// \post (*this)-\>suffix().matched == (*this)-\>suffix().first != (*this)-\>suffix().second
Chris@16 200 /// \post (**this)[0].first == The starting iterator for this match.
Chris@16 201 /// \post (**this)[0].second == The ending iterator for this match.
Chris@16 202 /// \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).
Chris@16 203 /// \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.
Chris@16 204 /// \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.
Chris@16 205 /// \post (**this)[n].matched == For all integers n \< (*this)-\>size(), true if sub-expression n participated in the match, false otherwise.
Chris@16 206 /// \post (*this)-\>position() == The distance from the start of the original sequence being iterated, to the start of this match.
Chris@16 207 regex_iterator<BidiIter> &operator ++()
Chris@16 208 {
Chris@16 209 this->fork_(); // un-share the implementation
Chris@16 210 this->next_();
Chris@16 211 return *this;
Chris@16 212 }
Chris@16 213
Chris@16 214 regex_iterator<BidiIter> operator ++(int)
Chris@16 215 {
Chris@16 216 regex_iterator<BidiIter> tmp(*this);
Chris@16 217 ++*this;
Chris@16 218 return tmp;
Chris@16 219 }
Chris@16 220
Chris@16 221 private:
Chris@16 222
Chris@16 223 /// INTERNAL ONLY
Chris@16 224 void fork_()
Chris@16 225 {
Chris@16 226 if(1 != this->impl_->use_count())
Chris@16 227 {
Chris@16 228 // This is OK, the use_count is > 1
Chris@16 229 impl_type_ *that = this->impl_.get();
Chris@16 230 this->impl_ = new impl_type_
Chris@16 231 (
Chris@16 232 that->state_.begin_
Chris@16 233 , that->state_.cur_
Chris@16 234 , that->state_.end_
Chris@16 235 , that->state_.next_search_
Chris@16 236 , that->rex_
Chris@16 237 , that->flags_
Chris@16 238 , that->not_null_
Chris@16 239 );
Chris@16 240 detail::core_access<BidiIter>::get_action_args(this->impl_->what_)
Chris@16 241 = detail::core_access<BidiIter>::get_action_args(that->what_);
Chris@16 242 }
Chris@16 243 }
Chris@16 244
Chris@16 245 /// INTERNAL ONLY
Chris@16 246 void next_()
Chris@16 247 {
Chris@16 248 BOOST_ASSERT(this->impl_ && 1 == this->impl_->use_count());
Chris@16 249 if(!this->impl_->next())
Chris@16 250 {
Chris@16 251 this->impl_ = 0;
Chris@16 252 }
Chris@16 253 }
Chris@16 254
Chris@16 255 intrusive_ptr<impl_type_> impl_;
Chris@16 256 };
Chris@16 257
Chris@16 258 }} // namespace boost::xpressive
Chris@16 259
Chris@16 260 #endif