diff --git a/libcxx/include/sstream b/libcxx/include/sstream --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -36,7 +36,7 @@ // [stringbuf.assign] Assign and swap: basic_stringbuf& operator=(basic_stringbuf&& rhs); - void swap(basic_stringbuf& rhs); + void swap(basic_stringbuf& rhs) noexcept(see below); // conditionally noexcept since C++20 // [stringbuf.members] Member functions: basic_string str() const; @@ -57,8 +57,8 @@ // [stringbuf.assign] non member swap template - void swap(basic_stringbuf& x, - basic_stringbuf& y); +void swap(basic_stringbuf& x, + basic_stringbuf& y); // conditionally noexcept since C++20 typedef basic_stringbuf stringbuf; typedef basic_stringbuf wstringbuf; @@ -97,8 +97,8 @@ }; template - void swap(basic_istringstream& x, - basic_istringstream& y); +void swap(basic_istringstream& x, + basic_istringstream& y); typedef basic_istringstream istringstream; typedef basic_istringstream wistringstream; @@ -138,8 +138,8 @@ }; template - void swap(basic_ostringstream& x, - basic_ostringstream& y); +void swap(basic_ostringstream& x, + basic_ostringstream& y); typedef basic_ostringstream ostringstream; typedef basic_ostringstream wostringstream; @@ -179,8 +179,8 @@ }; template - void swap(basic_stringstream& x, - basic_stringstream& y); +void swap(basic_stringstream& x, + basic_stringstream& y); typedef basic_stringstream stringstream; typedef basic_stringstream wstringstream; @@ -252,7 +252,12 @@ // [stringbuf.assign] Assign and swap: basic_stringbuf& operator=(basic_stringbuf&& __rhs); - void swap(basic_stringbuf& __rhs); + void swap(basic_stringbuf& __rhs) +#if _LIBCPP_STD_VER >= 20 + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value) +#endif + ; // [stringbuf.members] Member functions: string_type str() const; @@ -368,6 +373,10 @@ template void basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs) +#if _LIBCPP_STD_VER >= 20 + noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value || + allocator_traits<_Allocator>::is_always_equal::value) +#endif { char_type* __p = const_cast(__rhs.__str_.data()); ptrdiff_t __rbinp = -1; @@ -447,6 +456,9 @@ void swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, basic_stringbuf<_CharT, _Traits, _Allocator>& __y) +#if _LIBCPP_STD_VER >= 20 + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } diff --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap_noexcept.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap_noexcept.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap_noexcept.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template , class Allocator = allocator > +// class basic_stringbuf + +// void swap(basic_stringbuf& rhs) +// noexcept(allocator_traits::propagate_on_container_swap::value || +// allocator_traits::is_always_equal::value); + +#include +#include + +#include "test_macros.h" + +template +struct test_alloc { + using value_type = T; + + [[nodiscard]] constexpr T* allocate(std::size_t) { return nullptr; } + void deallocate(void*, unsigned) {} +}; + +template +struct test_alloc_propagate_on_container_swap : test_alloc { + using propagate_on_container_swap = std::true_type; +}; + +template +struct test_alloc_is_always_equal : test_alloc { + using is_always_equal = std::true_type; +}; + +template +struct test_alloc_propagate_on_container_swap_is_always_equal : test_alloc { + using propagate_on_container_swap = std::true_type; + using is_always_equal = std::true_type; +}; + +template +struct test_alloc_not_empty : test_alloc { + bool dummy; +}; + +template +struct test_alloc_propagate_on_container_swap_not_empty : test_alloc { + using propagate_on_container_swap = std::true_type; + bool dummy; +}; + +template +static void test() { + { + std::basic_stringbuf, test_alloc> buf1; + std::basic_stringbuf, test_alloc> buf; + static_assert(noexcept(buf.swap(buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap> buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap> buf; + static_assert(noexcept(buf.swap(buf1))); + } + { + std::basic_stringbuf, test_alloc_is_always_equal> buf1; + std::basic_stringbuf, test_alloc_is_always_equal> buf; + static_assert(noexcept(buf.swap(buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap_is_always_equal> + buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap_is_always_equal> + buf; + static_assert(noexcept(buf.swap(buf1))); + } + { + std::basic_stringbuf, test_alloc_not_empty> buf1; + std::basic_stringbuf, test_alloc_not_empty> buf; + static_assert(!noexcept(buf.swap(buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap_not_empty> buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap_not_empty> buf; + static_assert(noexcept(buf.swap(buf1))); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap_noexcept.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap_noexcept.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap_noexcept.pass.cpp @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template +// void swap(basic_stringbuf& x, +// basic_stringbuf& y) +// noexcept(allocator_traits::propagate_on_container_swap::value || +// allocator_traits::is_always_equal::value); + +#include +#include + +#include "test_macros.h" + +template +struct test_alloc { + using value_type = T; + + [[nodiscard]] constexpr T* allocate(std::size_t) { return nullptr; } + void deallocate(void*, unsigned) {} +}; + +template +struct test_alloc_propagate_on_container_swap : test_alloc { + using propagate_on_container_swap = std::true_type; +}; + +template +struct test_alloc_is_always_equal : test_alloc { + using is_always_equal = std::true_type; +}; + +template +struct test_alloc_propagate_on_container_swap_is_always_equal : test_alloc { + using propagate_on_container_swap = std::true_type; + using is_always_equal = std::true_type; +}; + +template +struct test_alloc_not_empty : test_alloc { + bool dummy; +}; + +template +struct test_alloc_propagate_on_container_swap_not_empty : test_alloc { + using propagate_on_container_swap = std::true_type; + bool dummy; +}; + +template +static void test() { + { + std::basic_stringbuf, test_alloc> buf1; + std::basic_stringbuf, test_alloc> buf; + static_assert(noexcept(swap(buf, buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap> buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap> buf; + static_assert(noexcept(swap(buf, buf1))); + } + { + std::basic_stringbuf, test_alloc_is_always_equal> buf1; + std::basic_stringbuf, test_alloc_is_always_equal> buf; + static_assert(noexcept(swap(buf, buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap_is_always_equal> + buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap_is_always_equal> + buf; + static_assert(noexcept(swap(buf, buf1))); + } + { + std::basic_stringbuf, test_alloc_not_empty> buf1; + std::basic_stringbuf, test_alloc_not_empty> buf; + static_assert(!noexcept(swap(buf, buf1))); + } + { + std::basic_stringbuf, test_alloc_propagate_on_container_swap_not_empty> buf1; + std::basic_stringbuf, test_alloc_propagate_on_container_swap_not_empty> buf; + static_assert(noexcept(swap(buf, buf1))); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +}