Tested x86_64-linux. Pushed to trunk. -- >8 --
This was approved at the C++ meeting in February. libstdc++-v3/ChangeLog: * include/bits/regex.h (sub_match::swap): New function. * testsuite/28_regex/sub_match/lwg3204.cc: New test. --- libstdc++-v3/include/bits/regex.h | 10 +++++ .../testsuite/28_regex/sub_match/lwg3204.cc | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 libstdc++-v3/testsuite/28_regex/sub_match/lwg3204.cc diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 79903fad1e5..26ac6a21c31 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -1006,6 +1006,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->_M_str().compare({__s, __n}); } /// @endcond + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3204. sub_match::swap only swaps the base class + /// Swap the values of two sub_match objects. + void + swap(sub_match& __s) noexcept(__is_nothrow_swappable<_BiIter>::value) + { + this->pair<_BiIter, _BiIter>::swap(__s); + std::swap(matched, __s.matched); + } + private: // Simplified basic_string_view for C++11 struct __string_view diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/lwg3204.cc b/libstdc++-v3/testsuite/28_regex/sub_match/lwg3204.cc new file mode 100644 index 00000000000..58ef0df58a1 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/sub_match/lwg3204.cc @@ -0,0 +1,38 @@ +// { dg-do run { target c++11 } } +#include <regex> +#include <testsuite_hooks.h> + +// LWG 3204. sub_match::swap only swaps the base class + +int main() +{ + std::sub_match<const char*> a, b; + a.matched = true; + a.swap(b); + VERIFY( ! a.matched ); + VERIFY( b.matched ); +} + +struct iter +{ + using value_type = char; + using difference_type = long; + using pointer = const char*; + using reference = const char&; + using iterator_category = std::bidirectional_iterator_tag; + + iter(); + iter(const iter&) noexcept(false); + + iter& operator++(); + iter operator++(int); + iter& operator--(); + iter operator--(int); + reference operator*() const; + pointer operator->() const; +}; + +using CS = std::csub_match; +static_assert( noexcept(std::declval<CS&>().swap(std::declval<CS&>())) ); +using IS = std::sub_match<iter>; +static_assert( ! noexcept(std::declval<IS&>().swap(std::declval<IS&>())) ); -- 2.39.2