Index: libcxx/docs/Status/Cxx2bIssues.csv =================================================================== --- libcxx/docs/Status/Cxx2bIssues.csv +++ 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","","","" Index: libcxx/include/regex =================================================================== --- libcxx/include/regex +++ 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,13 @@ _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {return str().compare(__s);} + + _LIBCPP_INLINE_VISIBILITY + void swap(sub_match& __s) noexcept(__is_nothrow_swappable<_BidirectionalIterator>::value) + { + this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s); + std::swap(matched, __s.matched); + } }; template Index: libcxx/test/std/re/re.submatch/re.submatch.members/swap.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/re/re.submatch/re.submatch.members/swap.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include "test_macros.h" + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +int main(int, char**) +{ + { + std::csub_match sm1; + sm1.first = "hello"; + sm1.second = "world"; + sm1.matched = true; + + std::csub_match sm2; + sm2.first = "fluffy"; + sm2.second = "cat"; + sm2.matched = false; + + sm1.swap(sm2); + + assert(std::strcmp(sm1.first, "fluffy") == 0); + assert(std::strcmp(sm1.second, "cat") == 0); + assert(!sm1.matched); + + assert(std::strcmp(sm2.first, "hello") == 0); + assert(std::strcmp(sm2.second, "world") == 0); + assert(sm2.matched); + + STATIC_ASSERT(noexcept(sm1.swap(sm2))); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + std::wcsub_match sm1; + sm1.first = L"hello"; + sm1.second = L"world"; + sm1.matched = true; + + std::wcsub_match sm2; + sm2.first = L"fluffy"; + sm2.second = L"cat"; + sm2.matched = false; + + sm1.swap(sm2); + + assert(std::wcscmp(sm1.first, L"fluffy") == 0); + assert(std::wcscmp(sm1.second, L"cat") == 0); + assert(!sm1.matched); + + assert(std::wcscmp(sm2.first, L"hello") == 0); + assert(std::wcscmp(sm2.second, L"world") == 0); + assert(sm2.matched); + + STATIC_ASSERT(noexcept(sm1.swap(sm2))); + } +#endif +}