diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -257,7 +257,7 @@ "`3811 `__","``views::as_const`` on ``ref_view`` should return ``ref_view``","February 2023","","","|ranges|" "`3820 `__","``cartesian_product_view::iterator::prev`` is not quite right","February 2023","","","|ranges|" "`3825 `__","Missing compile-time argument ``id`` check in ``basic_format_parse_context::next_arg_id``","February 2023","","","|format|" -"`3204 `__","``sub_match::swap`` only swaps the base class","February 2023","","","" +"`3204 `__","``sub_match::swap`` only swaps the base class","February 2023","|Complete|","17.0","" "`3733 `__","``ranges::to`` misuses ``cpp17-input-iterator``","February 2023","","","|ranges|" "`3742 `__","``deque::prepend_range`` needs to permute","February 2023","","","|ranges|" "`3790 `__","`P1467 `__ accidentally changed ``nexttoward``'s signature","February 2023","","","" diff --git a/libcxx/include/regex b/libcxx/include/regex --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -225,6 +225,8 @@ int compare(const sub_match& s) const; int compare(const string_type& s) const; int compare(const value_type* s) const; + + void swap(sub_match& s) noexcept(see below); }; typedef sub_match csub_match; @@ -770,6 +772,7 @@ #include <__iterator/wrap_iter.h> #include <__locale> #include <__memory_resource/polymorphic_allocator.h> +#include <__type_traits/is_swappable.h> #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/swap.h> @@ -5008,6 +5011,16 @@ _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {return str().compare(__s);} + + _LIBCPP_HIDE_FROM_ABI + void swap(sub_match& __s) +#ifndef _LIBCPP_CXX03_LANG + _NOEXCEPT(__is_nothrow_swappable<_BidirectionalIterator>::value) +#endif // _LIBCPP_CXX03_LANG + { + this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s); + std::swap(matched, __s.matched); + } }; template diff --git a/libcxx/test/std/re/re.submatch/re.submatch.members/swap.pass.cpp b/libcxx/test/std/re/re.submatch/re.submatch.members/swap.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/re/re.submatch/re.submatch.members/swap.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// void swap(sub_match& s) noexcept(see below); + +#include +#include +#include "test_macros.h" + +int main(int, char**) { + { + using CharT = char; + using SM = std::sub_match; + const CharT s1[] = {'1', '2', '3', 0}; + SM sm1; + sm1.first = s1; + sm1.second = s1 + 3; + sm1.matched = true; + + SM sm2; + const CharT s2[] = {'c', 'a', 't', 0}; + sm2.first = s2; + sm2.second = s2 + 3; + sm2.matched = false; + + sm1.swap(sm2); + + assert(sm1.first == s2); + assert(sm1.second == s2 + 3); + assert(!sm1.matched); + + assert(sm2.first == s1); + assert(sm2.second == s1 + 3); + assert(sm2.matched); + + ASSERT_NOEXCEPT(sm1.swap(sm2)); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + using CharT = wchar_t; + using SM = std::sub_match; + const CharT s1[] = {L'1', L'2', L'3', 0}; + SM sm1; + sm1.first = s1; + sm1.second = s1 + 3; + sm1.matched = true; + + SM sm2; + const CharT s2[] = {L'c', L'a', L't', 0}; + sm2.first = s2; + sm2.second = s2 + 3; + sm2.matched = false; + + sm1.swap(sm2); + + assert(sm1.first == s2); + assert(sm1.second == s2 + 3); + assert(!sm1.matched); + + assert(sm2.first == s1); + assert(sm2.second == s1 + 3); + assert(sm2.matched); + + ASSERT_NOEXCEPT(sm1.swap(sm2)); + } +#endif +}