From bc2738455bf4e405cf0ad3d61482b49cd4382113 Mon Sep 17 00:00:00 2001 From: Tim Shen Date: Sat, 13 Dec 2014 22:19:18 +0000 Subject: [PATCH] re PR libstdc++/64239 (regex_iterator::operator= should copy match_results::position) PR libstdc++/64239 * include/bits/regex.h (match_results<>::match_results, match_results<>::operator=, match_results<>::position, match_results<>::swap): Remove match_results::_M_in_iterator. Fix ctor/assign/swap. * include/bits/regex.tcc: (__regex_algo_impl<>, regex_iterator<>::operator++): Set match_results::_M_begin as "start position". * testsuite/28_regex/iterators/regex_iterator/char/ string_position_01.cc: Test cases. From-SVN: r218710 --- libstdc++-v3/ChangeLog | 13 ++++++ libstdc++-v3/include/bits/regex.h | 37 +++++---------- libstdc++-v3/include/bits/regex.tcc | 5 ++- .../regex_iterator/char/string_position_01.cc | 45 +++++++++++++++++++ 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0df6b3b9107..4e79925ff0f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2014-12-13 Tim Shen + + PR libstdc++/64239 + * include/bits/regex.h (match_results<>::match_results, + match_results<>::operator=, match_results<>::position, + match_results<>::swap): Remove match_results::_M_in_iterator. + Fix ctor/assign/swap. + * include/bits/regex.tcc: (__regex_algo_impl<>, + regex_iterator<>::operator++): Set match_results::_M_begin as + "start position". + * testsuite/28_regex/iterators/regex_iterator/char/ + string_position_01.cc: Test cases. + 2014-12-13 Jonathan Wakely * include/experimental/any (any): Remove allocator support and update diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index cb6bc93251a..3afec37ab16 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -1563,42 +1563,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ explicit match_results(const _Alloc& __a = _Alloc()) - : _Base_type(__a), _M_in_iterator(false) + : _Base_type(__a) { } /** * @brief Copy constructs a %match_results. */ - match_results(const match_results& __rhs) - : _Base_type(__rhs), _M_in_iterator(false) - { } + match_results(const match_results& __rhs) = default; /** * @brief Move constructs a %match_results. */ - match_results(match_results&& __rhs) noexcept - : _Base_type(std::move(__rhs)), _M_in_iterator(false) - { } + match_results(match_results&& __rhs) noexcept = default; /** * @brief Assigns rhs to *this. */ match_results& - operator=(const match_results& __rhs) - { - match_results(__rhs).swap(*this); - return *this; - } + operator=(const match_results& __rhs) = default; /** * @brief Move-assigns rhs to *this. */ match_results& - operator=(match_results&& __rhs) - { - match_results(std::move(__rhs)).swap(*this); - return *this; - } + operator=(match_results&& __rhs) = default; /** * @brief Destroys a %match_results object. @@ -1685,13 +1673,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION difference_type position(size_type __sub = 0) const { - // [28.12.1.4.5] - if (_M_in_iterator) - return __sub < size() ? std::distance(_M_begin, - (*this)[__sub].first) : -1; - else - return __sub < size() ? std::distance(this->prefix().first, - (*this)[__sub].first) : -1; + return __sub < size() ? std::distance(_M_begin, + (*this)[__sub].first) : -1; } /** @@ -1876,7 +1859,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ void swap(match_results& __that) - { _Base_type::swap(__that); } + { + _Base_type::swap(__that); + swap(_M_begin, __that._M_begin); + } //@} private: @@ -1894,7 +1880,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION regex_constants::match_flag_type); _Bi_iter _M_begin; - bool _M_in_iterator; }; typedef match_results cmatch; diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index 96924024c90..b6764288d19 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -62,6 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m; + __m._M_begin = __s; __res.resize(__re._M_automaton->_M_sub_count() + 2); for (auto& __it : __res) __it.matched = false; @@ -572,7 +573,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto& __prefix = _M_match.at(_M_match.size()); __prefix.first = __prefix_first; __prefix.matched = __prefix.first != __prefix.second; - _M_match._M_in_iterator = true; + // [28.12.1.4.5] _M_match._M_begin = _M_begin; return *this; } @@ -587,7 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto& __prefix = _M_match.at(_M_match.size()); __prefix.first = __prefix_first; __prefix.matched = __prefix.first != __prefix.second; - _M_match._M_in_iterator = true; + // [28.12.1.4.5] _M_match._M_begin = _M_begin; } else diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc index 5fa4ea77492..91aa06137f5 100644 --- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc +++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc @@ -24,6 +24,7 @@ // Tests iter->position() behavior #include +#include #include void @@ -41,9 +42,53 @@ test01() } } +// PR libstdc++/64239 +void +test02() +{ + bool test __attribute__((unused)) = true; + + std::regex re("\\w+"); + std::string s("-a-b-c-"); + + std::tuple expected[] = + { + std::make_tuple(1, 1, "a"), + std::make_tuple(3, 1, "b"), + std::make_tuple(5, 1, "c"), + }; + + int i = 0; + for (auto it1 = std::sregex_iterator(s.begin(), s.end(), re), + end = std::sregex_iterator(); it1 != end; ++it1, i++) + { + auto it2 = it1; + VERIFY(it1->position() == std::get<0>(expected[i])); + VERIFY(it1->length() == std::get<1>(expected[i])); + VERIFY(it1->str() == std::get<2>(expected[i])); + VERIFY(it2->position() == std::get<0>(expected[i])); + VERIFY(it2->length() == std::get<1>(expected[i])); + VERIFY(it2->str() == std::get<2>(expected[i])); + } +} + +void +test03() +{ + bool test __attribute__((unused)) = true; + + std::smatch m; + std::string s = "abcde"; + std::regex_search(s, m, std::regex("bcd")); + VERIFY(m.position() == 1); + VERIFY(m.position() == m.prefix().length()); +} + int main() { test01(); + test02(); + test03(); return 0; } -- 2.30.2