[libcxx-commits] [libcxx] c0a5b14 - [libc++] Add noexcept clauses to swap per P0408R7 (Efficient Access to basic_stringbuf's Buffer)
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jun 24 09:29:29 PDT 2023
Author: Piotr Fusik
Date: 2023-06-24T18:29:21+02:00
New Revision: c0a5b147fae97198cefd719f50fc655220985f22
URL: https://github.com/llvm/llvm-project/commit/c0a5b147fae97198cefd719f50fc655220985f22
DIFF: https://github.com/llvm/llvm-project/commit/c0a5b147fae97198cefd719f50fc655220985f22.diff
LOG: [libc++] Add noexcept clauses to swap per P0408R7 (Efficient Access to basic_stringbuf's Buffer)
Reviewed By: #libc, Mordante
Differential Revision: https://reviews.llvm.org/D153427
Added:
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap_noexcept.pass.cpp
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap_noexcept.pass.cpp
Modified:
libcxx/include/sstream
Removed:
################################################################################
diff --git a/libcxx/include/sstream b/libcxx/include/sstream
index 26c8992153225..05756eb28164e 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -36,7 +36,7 @@ public:
// [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<char_type, traits_type, allocator_type> str() const;
@@ -57,8 +57,8 @@ protected:
// [stringbuf.assign] non member swap
template <class charT, class traits, class Allocator>
- void swap(basic_stringbuf<charT, traits, Allocator>& x,
- basic_stringbuf<charT, traits, Allocator>& y);
+void swap(basic_stringbuf<charT, traits, Allocator>& x,
+ basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20
typedef basic_stringbuf<char> stringbuf;
typedef basic_stringbuf<wchar_t> wstringbuf;
@@ -97,8 +97,8 @@ public:
};
template <class charT, class traits, class Allocator>
- void swap(basic_istringstream<charT, traits, Allocator>& x,
- basic_istringstream<charT, traits, Allocator>& y);
+void swap(basic_istringstream<charT, traits, Allocator>& x,
+ basic_istringstream<charT, traits, Allocator>& y);
typedef basic_istringstream<char> istringstream;
typedef basic_istringstream<wchar_t> wistringstream;
@@ -138,8 +138,8 @@ public:
};
template <class charT, class traits, class Allocator>
- void swap(basic_ostringstream<charT, traits, Allocator>& x,
- basic_ostringstream<charT, traits, Allocator>& y);
+void swap(basic_ostringstream<charT, traits, Allocator>& x,
+ basic_ostringstream<charT, traits, Allocator>& y);
typedef basic_ostringstream<char> ostringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
@@ -179,8 +179,8 @@ public:
};
template <class charT, class traits, class Allocator>
- void swap(basic_stringstream<charT, traits, Allocator>& x,
- basic_stringstream<charT, traits, Allocator>& y);
+void swap(basic_stringstream<charT, traits, Allocator>& x,
+ basic_stringstream<charT, traits, Allocator>& y);
typedef basic_stringstream<char> stringstream;
typedef basic_stringstream<wchar_t> wstringstream;
@@ -252,7 +252,12 @@ public:
// [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<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value)
+#endif
+ ;
// [stringbuf.members] Member functions:
string_type str() const;
@@ -368,6 +373,10 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
template <class _CharT, class _Traits, class _Allocator>
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<char_type*>(__rhs.__str_.data());
ptr
diff _t __rbinp = -1;
@@ -447,6 +456,9 @@ inline _LIBCPP_INLINE_VISIBILITY
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
index 0000000000000..cdb09df7c7a9a
--- /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
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringbuf
+
+// void swap(basic_stringbuf& rhs)
+// noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+// allocator_traits<allocator_type>::is_always_equal::value);
+
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+struct test_alloc {
+ using value_type = T;
+
+ [[nodiscard]] constexpr T* allocate(std::size_t) { return nullptr; }
+ void deallocate(void*, unsigned) {}
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+};
+
+template <class T>
+struct test_alloc_is_always_equal : test_alloc<T> {
+ using is_always_equal = std::true_type;
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap_is_always_equal : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+ using is_always_equal = std::true_type;
+};
+
+template <class T>
+struct test_alloc_not_empty : test_alloc<T> {
+ bool dummy;
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap_not_empty : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+ bool dummy;
+};
+
+template <class CharT>
+static void test() {
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc<CharT>> buf;
+ static_assert(noexcept(buf.swap(buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap<CharT>> buf;
+ static_assert(noexcept(buf.swap(buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_is_always_equal<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_is_always_equal<CharT>> buf;
+ static_assert(noexcept(buf.swap(buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_is_always_equal<CharT>>
+ buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_is_always_equal<CharT>>
+ buf;
+ static_assert(noexcept(buf.swap(buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf;
+ static_assert(!noexcept(buf.swap(buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf;
+ static_assert(noexcept(buf.swap(buf1)));
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#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
index 0000000000000..fdefc5ebe9af0
--- /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
+
+// <sstream>
+
+// template <class charT, class traits, class Allocator>
+// void swap(basic_stringbuf<charT, traits, Allocator>& x,
+// basic_stringbuf<charT, traits, Allocator>& y)
+// noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+// allocator_traits<allocator_type>::is_always_equal::value);
+
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+struct test_alloc {
+ using value_type = T;
+
+ [[nodiscard]] constexpr T* allocate(std::size_t) { return nullptr; }
+ void deallocate(void*, unsigned) {}
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+};
+
+template <class T>
+struct test_alloc_is_always_equal : test_alloc<T> {
+ using is_always_equal = std::true_type;
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap_is_always_equal : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+ using is_always_equal = std::true_type;
+};
+
+template <class T>
+struct test_alloc_not_empty : test_alloc<T> {
+ bool dummy;
+};
+
+template <class T>
+struct test_alloc_propagate_on_container_swap_not_empty : test_alloc<T> {
+ using propagate_on_container_swap = std::true_type;
+ bool dummy;
+};
+
+template <class CharT>
+static void test() {
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc<CharT>> buf;
+ static_assert(noexcept(swap(buf, buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap<CharT>> buf;
+ static_assert(noexcept(swap(buf, buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_is_always_equal<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_is_always_equal<CharT>> buf;
+ static_assert(noexcept(swap(buf, buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_is_always_equal<CharT>>
+ buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_is_always_equal<CharT>>
+ buf;
+ static_assert(noexcept(swap(buf, buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf;
+ static_assert(!noexcept(swap(buf, buf1)));
+ }
+ {
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf1;
+ std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf;
+ static_assert(noexcept(swap(buf, buf1)));
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
+ return 0;
+}
More information about the libcxx-commits
mailing list