From 79b0fee3c682dcc198e58a8ac7b5e1af5c03467f Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 9 Jan 2014 18:25:57 +0000 Subject: [PATCH] Fix PR18404 - 'Bug in regex_token_iterator::operator++(int) implementation'. Enhance the tests for regex_token_iterator and regex_iterator. llvm-svn: 198878 --- libcxx/include/regex | 32 ++++----- .../re.regiter/re.regiter.incr/post.pass.cpp | 55 +++++++++++++++ .../re.tokiter/re.tokiter.incr/post.pass.cpp | 81 +++++++++++++++++++--- 3 files changed, 142 insertions(+), 26 deletions(-) diff --git a/libcxx/include/regex b/libcxx/include/regex index ffe39cf..f8569f9 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -6188,6 +6188,12 @@ public: private: void __init(_BidirectionalIterator __a, _BidirectionalIterator __b); + void __establish_result () { + if (__subs_[_N_] == -1) + __result_ = &__position_->prefix(); + else + __result_ = &(*__position_)[__subs_[_N_]]; + } }; template @@ -6205,12 +6211,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: __init(_BidirectionalIterator __a, _BidirectionalIterator __b) { if (__position_ != _Position()) - { - if (__subs_[_N_] == -1) - __result_ = &__position_->prefix(); - else - __result_ = &(*__position_)[__subs_[_N_]]; - } + __establish_result (); else if (__subs_[_N_] == -1) { __suffix_.matched = true; @@ -6288,6 +6289,8 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: { if (__x.__result_ == &__x.__suffix_) __result_ == &__suffix_; + else if ( __result_ != nullptr ) + __establish_result (); } template @@ -6299,12 +6302,15 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: { __position_ = __x.__position_; if (__x.__result_ == &__x.__suffix_) - __result_ == &__suffix_; + __result_ = &__suffix_; else __result_ = __x.__result_; __suffix_ = __x.__suffix_; _N_ = __x._N_; __subs_ = __x.__subs_; + + if ( __result_ != nullptr && __result_ != &__suffix_ ) + __establish_result(); } return *this; } @@ -6337,22 +6343,14 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() else if (_N_ + 1 < __subs_.size()) { ++_N_; - if (__subs_[_N_] == -1) - __result_ = &__position_->prefix(); - else - __result_ = &(*__position_)[__subs_[_N_]]; + __establish_result(); } else { _N_ = 0; ++__position_; if (__position_ != _Position()) - { - if (__subs_[_N_] == -1) - __result_ = &__position_->prefix(); - else - __result_ = &(*__position_)[__subs_[_N_]]; - } + __establish_result(); else { if (_VSTD::find(__subs_.begin(), __subs_.end(), -1) != __subs_.end() diff --git a/libcxx/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp b/libcxx/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp index 9c6a264..3ec0d6c 100644 --- a/libcxx/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp +++ b/libcxx/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp @@ -22,21 +22,76 @@ int main() std::regex phone_numbers("\\d{3}-\\d{4}"); const char phone_book[] = "555-1234, 555-2345, 555-3456"; std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers); + std::cregex_iterator i2 = i; assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); assert((*i).size() == 1); assert((*i).position() == 0); assert((*i).str() == "555-1234"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); i++; assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); assert((*i).size() == 1); assert((*i).position() == 10); assert((*i).str() == "555-2345"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); i++; assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); assert((*i).size() == 1); assert((*i).position() == 20); assert((*i).str() == "555-3456"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); i++; assert(i == std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); + } + { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "555-1234, 555-2345, 555-3456"; + std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers); + std::cregex_iterator i2 = i; + assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 0); + assert((*i).str() == "555-1234"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); + ++i; + assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 10); + assert((*i).str() == "555-2345"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); + ++i; + assert(i != std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 20); + assert((*i).str() == "555-3456"); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); + ++i; + assert(i == std::cregex_iterator()); + assert(i2!= std::cregex_iterator()); + assert((*i2).size() == 1); + assert((*i2).position() == 0); + assert((*i2).str() == "555-1234"); } } diff --git a/libcxx/test/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp b/libcxx/test/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp index d179195..727ab7a 100644 --- a/libcxx/test/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp +++ b/libcxx/test/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp @@ -23,19 +23,82 @@ int main() const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, phone_numbers, -1); - assert(i != std::cregex_token_iterator()); + std::cregex_token_iterator i2 = i; + std::cregex_token_iterator i3; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); assert(i->str() == "start "); - i++; - assert(i != std::cregex_token_iterator()); + assert(i2->str() == "start "); + i3 = i++; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); assert(i->str() == ", "); - i++; - assert(i != std::cregex_token_iterator()); + assert(i2->str() == "start "); + assert(i3->str() == "start "); + i3 = i++; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); assert(i->str() == ", "); - i++; - assert(i != std::cregex_token_iterator()); + assert(i2->str() == "start "); + assert(i3->str() == ", "); + i3 = i++; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); assert(i->str() == " end"); - i++; - assert(i == std::cregex_token_iterator()); + assert(i2->str() == "start "); + assert(i3->str() == ", "); + i3 = i++; + assert(i == std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); + assert(i2->str() == "start "); + assert(i3->str() == " end"); + } + { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; + std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, + phone_numbers, -1); + std::cregex_token_iterator i2 = i; + std::cregex_token_iterator i3; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i->str() == "start "); + assert(i2->str() == "start "); + i3 = i; + ++i; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); + assert(i->str() == ", "); + assert(i2->str() == "start "); + assert(i3->str() == "start "); + i3 = i; + ++i; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); + assert(i->str() == ", "); + assert(i2->str() == "start "); + assert(i3->str() == ", "); + i3 = i; + ++i; + assert(i != std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); + assert(i->str() == " end"); + assert(i2->str() == "start "); + assert(i3->str() == ", "); + i3 = i; + ++i; + assert(i == std::cregex_token_iterator()); + assert(i2 != std::cregex_token_iterator()); + assert(i3 != std::cregex_token_iterator()); + assert(i2->str() == "start "); + assert(i3->str() == " end"); } { std::regex phone_numbers("\\d{3}-\\d{4}"); -- 2.7.4