diff --git a/stl/inc/regex b/stl/inc/regex index 2b0e47f68e0..dc5c484cf54 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -627,6 +627,11 @@ public: return _Compare(_Ptr, _Traits::length(_Ptr)); } + void swap(sub_match& _Other) noexcept(_Is_nothrow_swappable<_BidIt>::value) { + this->_Mybase::swap(_Other); + _STD swap(matched, _Other.matched); + } + int _Compare(const value_type* const _Ptr, const _Size_type _Count) const { // compare *this to array [_Ptr, _Ptr + _Count) const _Mybase _Range(_Effective_range()); diff --git a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp index 203cbb82438..f74e3eaefcf 100644 --- a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp +++ b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp @@ -1,15 +1,19 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include +#include #include #include #include using namespace std; +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + #pragma warning(disable : 28251) // Inconsistent annotation for 'new': this instance has no annotations. const int N = 1000; @@ -166,6 +170,31 @@ void test(const char* s) { } } +// Also test LWG-3204: sub_match::swap only swaps the base class +void test_lwg3204() { + csub_match sm1{}; + sm1.first = "hello"; + sm1.second = "world"; + sm1.matched = true; + + csub_match sm2{}; + sm2.first = "fluffy"; + sm2.second = "cat"; + sm2.matched = false; + + sm1.swap(sm2); + + assert(strcmp(sm1.first, "fluffy") == 0); + assert(strcmp(sm1.second, "cat") == 0); + assert(!sm1.matched); + + assert(strcmp(sm2.first, "hello") == 0); + assert(strcmp(sm2.second, "world") == 0); + assert(sm2.matched); + + STATIC_ASSERT(noexcept(sm1.swap(sm2))); +} + int main() { // Perform any locale allocations before we begin the tests. @@ -207,4 +236,6 @@ int main() { test("Huck[[:alpha:]]+"); test("Tom|Sawyer|Huckleberry|Finn"); test("Twain"); + + test_lwg3204(); }