[libcxx-commits] [libcxx] [libc++] Implement N4258(Cleaning-up noexcept in the Library) (PR #120312)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Dec 17 14:03:03 PST 2024
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/120312
None
>From 1818c0259b596ad1d4b9e96532d9b30c3b93ddb4 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 17 Dec 2024 23:02:40 +0100
Subject: [PATCH] [libc++] Implement N4258(Cleaning-up noexcept in the Library)
---
libcxx/docs/ReleaseNotes/20.rst | 1 +
libcxx/docs/Status/Cxx17Papers.csv | 2 +-
libcxx/include/__hash_table | 28 +++++--
libcxx/include/__tree | 29 +++++--
libcxx/include/deque | 17 +++--
libcxx/include/forward_list | 16 +++-
libcxx/include/list | 18 +++--
.../move_assign_noexcept.compile.pass.cpp | 58 ++++++++++++++
.../map.cons/move_assign_noexcept.pass.cpp | 59 --------------
.../move_assign_noexcept.compile.pass.cpp | 59 ++++++++++++++
.../move_assign_noexcept.pass.cpp | 59 --------------
.../move_assign_noexcept.compile.pass.cpp | 58 ++++++++++++++
.../move_assign_noexcept.pass.cpp | 58 --------------
.../move_assign_noexcept.compile.pass.cpp | 58 ++++++++++++++
.../set.cons/move_assign_noexcept.pass.cpp | 56 +++++++-------
.../move_assign_noexcept.compile.pass.cpp | 46 +++++++++++
.../deque.cons/move_assign_noexcept.pass.cpp | 57 --------------
.../move_assign_noexcept.compile.pass.cpp | 47 ++++++++++++
.../move_assign_noexcept.pass.cpp | 57 --------------
.../move_assign_noexcept.compile.pass.cpp | 46 +++++++++++
.../list.cons/move_assign_noexcept.pass.cpp | 57 --------------
.../move_assign_noexcept.compile.pass.cpp | 75 ++++++++++++++++++
.../move_assign_noexcept.pass.cpp | 76 -------------------
.../move_assign_noexcept.compile.pass.cpp | 75 ++++++++++++++++++
.../move_assign_noexcept.pass.cpp | 75 ------------------
.../move_assign_noexcept.compile.pass.cpp | 71 +++++++++++++++++
.../move_assign_noexcept.pass.cpp | 75 ------------------
.../move_assign_noexcept.compile.pass.cpp | 69 +++++++++++++++++
.../move_assign_noexcept.pass.cpp | 75 ------------------
29 files changed, 772 insertions(+), 705 deletions(-)
create mode 100644 libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp
create mode 100644 libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp
create mode 100644 libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.pass.cpp
delete mode 100644 libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index c8a07fb8b73348..935bfde56fc51c 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -45,6 +45,7 @@ Implemented Papers
- ``std::jthread`` and ``<stop_token>`` are not guarded behind ``-fexperimental-library`` anymore
- P2674R1: A trait for implicit lifetime types (`Github <https://github.com/llvm/llvm-project/issues/105259>`__)
- P0429R9: A Standard ``flat_map`` is partially implemented and ``flat_map`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105190>`__)
+- N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv
index a589207085d36f..0ec385cecf27f0 100644
--- a/libcxx/docs/Status/Cxx17Papers.csv
+++ b/libcxx/docs/Status/Cxx17Papers.csv
@@ -3,7 +3,7 @@
"`N4089 <https://wg21.link/N4089>`__","Safe conversions in ``unique_ptr<T[]>``\ .","2014-11 (Urbana)","|In Progress|","3.9",""
"`N4169 <https://wg21.link/N4169>`__","A proposal to add invoke function template","2014-11 (Urbana)","|Complete|","3.7",""
"`N4190 <https://wg21.link/N4190>`__","Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.","2014-11 (Urbana)","|Complete|","15",""
-"`N4258 <https://wg21.link/N4258>`__","Cleaning-up noexcept in the Library.","2014-11 (Urbana)","|In Progress|","3.7",""
+"`N4258 <https://wg21.link/N4258>`__","Cleaning-up noexcept in the Library.","2014-11 (Urbana)","|Complete|","20",""
"`N4259 <https://wg21.link/N4259>`__","Wording for std::uncaught_exceptions","2014-11 (Urbana)","|Complete|","3.7","``std::uncaught_exception`` is deprecated since LLVM 20"
"`N4277 <https://wg21.link/N4277>`__","TriviallyCopyable ``reference_wrapper``\ .","2014-11 (Urbana)","|Complete|","3.2",""
"`N4279 <https://wg21.link/N4279>`__","Improved insertion interface for unique-key maps.","2014-11 (Urbana)","|Complete|","3.7",""
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index fe7465a84c4024..24c9df60620be6 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -772,9 +772,16 @@ public:
_LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
_LIBCPP_HIDE_FROM_ABI __hash_table& operator=(__hash_table&& __u)
- _NOEXCEPT_(__node_traits::propagate_on_container_move_assignment::value&&
- is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
- is_nothrow_move_assignable<key_equal>::value);
+#ifndef _LIBCPP_CXX03_LANG
+ noexcept(is_nothrow_move_assignable<hasher>::value && is_nothrow_move_assignable<key_equal>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<__node_allocator>::is_always_equal::value
+# endif
+ ))
+#endif
+ ;
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
template <class _InputIterator>
@@ -1240,10 +1247,17 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u,
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline __hash_table<_Tp, _Hash, _Equal, _Alloc>&
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) _NOEXCEPT_(
- __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<__node_allocator>::value&&
- is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value) {
+inline __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
+#ifndef _LIBCPP_CXX03_LANG
+ noexcept(is_nothrow_move_assignable<hasher>::value && is_nothrow_move_assignable<key_equal>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<__node_allocator>::is_always_equal::value
+# endif
+ ))
+#endif
+{
__move_assign(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
return *this;
}
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index f6ef21cdaa5b98..1c170b999afc37 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -989,9 +989,18 @@ public:
_LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
_LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
- _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t) _NOEXCEPT_(
- __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<value_compare>::value&&
- is_nothrow_move_assignable<__node_allocator>::value);
+ _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
+#ifndef _LIBCPP_CXX03_LANG
+ noexcept(is_nothrow_move_assignable<value_compare>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<__node_allocator>::is_always_equal::value)
+# endif
+ )
+#endif
+ ;
+
_LIBCPP_HIDE_FROM_ABI ~__tree();
_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node()); }
@@ -1522,10 +1531,16 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
}
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) _NOEXCEPT_(
- __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<value_compare>::value&&
- is_nothrow_move_assignable<__node_allocator>::value)
-
+__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
+#ifndef _LIBCPP_CXX03_LANG
+ noexcept(is_nothrow_move_assignable<value_compare>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<__node_allocator>::is_always_equal::value)
+# endif
+ )
+#endif
{
__move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
return *this;
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 63eb8365531069..21bfad2201c9c1 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -672,9 +672,13 @@ public:
_LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value);
_LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
- _LIBCPP_HIDE_FROM_ABI deque&
- operator=(deque&& __c) noexcept(__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ _LIBCPP_HIDE_FROM_ABI deque& operator=(deque&& __c) noexcept(
+ (__alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+ );
_LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); }
# endif // _LIBCPP_CXX03_LANG
@@ -1377,8 +1381,11 @@ inline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<alloca
template <class _Tp, class _Allocator>
inline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) noexcept(
- __alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value) {
+ (__alloc_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<allocator_type>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+) {
__move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
return *this;
}
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 23e8e51632171e..295ba8c5340ef9 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -714,8 +714,12 @@ public:
_LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a);
_LIBCPP_HIDE_FROM_ABI forward_list& operator=(forward_list&& __x) noexcept(
- __node_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ (__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+ );
_LIBCPP_HIDE_FROM_ABI forward_list& operator=(initializer_list<value_type> __il);
@@ -1000,8 +1004,12 @@ void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) {
}
template <class _Tp, class _Alloc>
-inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) _NOEXCEPT_(
- __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<allocator_type>::value) {
+inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) noexcept(
+ (__node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<allocator_type>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+) {
__move_assign(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
return *this;
}
diff --git a/libcxx/include/list b/libcxx/include/list
index a9d14272742bd4..2b3006aa4067dc 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -727,9 +727,13 @@ public:
_LIBCPP_HIDE_FROM_ABI list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
_LIBCPP_HIDE_FROM_ABI list(list&& __c, const __type_identity_t<allocator_type>& __a);
- _LIBCPP_HIDE_FROM_ABI list& operator=(list&& __c)
- _NOEXCEPT_(__node_alloc_traits::propagate_on_container_move_assignment::value&&
- is_nothrow_move_assignable<__node_allocator>::value);
+ _LIBCPP_HIDE_FROM_ABI list& operator=(list&& __c) noexcept(
+ (__node_alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+ );
_LIBCPP_HIDE_FROM_ABI list& operator=(initializer_list<value_type> __il) {
assign(__il.begin(), __il.end());
@@ -1066,8 +1070,12 @@ inline list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t<allocator_typ
template <class _Tp, class _Alloc>
inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) noexcept(
- __node_alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<__node_allocator>::value) {
+ (__node_alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value)
+# if _LIBCPP_STD_VER >= 17
+ || allocator_traits<allocator_type>::is_always_equal::value
+# endif
+) {
__move_assign(__c, integral_constant<bool, __node_alloc_traits::propagate_on_container_move_assignment::value>());
return *this;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..3f00129915a9bf
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// map& operator=(map&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <map>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using multimap_alloc = std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, Alloc<std::pair<const MoveOnly, MoveOnly>>>;
+
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<multimap_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<multimap_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::map<int, int, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 82a5dbac126102..00000000000000
--- a/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <map>
-
-// map& operator=(map&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <map>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-int main(int, char**)
-{
- typedef std::pair<const MoveOnly, MoveOnly> V;
- {
- typedef std::map<MoveOnly, MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..d5db96e4ca57be
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// multimap& operator=(multimap&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <map>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using multimap_alloc =
+ std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, Alloc<std::pair<const MoveOnly, MoveOnly>>>;
+
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<multimap_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<multimap_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::multimap<int, int, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 4cd8c19fce5f9d..00000000000000
--- a/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <map>
-
-// multimap& operator=(multimap&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <map>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-int main(int, char**)
-{
- typedef std::pair<const MoveOnly, MoveOnly> V;
- {
- typedef std::multimap<MoveOnly, MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..7565c50363a1e9
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// multiset& operator=(multiset&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <set>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc = std::set<MoveOnly, std::less<MoveOnly>, Alloc<MoveOnly>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::set<int, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index a94b5b1abf1e5c..00000000000000
--- a/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <set>
-
-// multiset& operator=(multiset&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <set>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-int main(int, char**)
-{
- {
- typedef std::multiset<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::multiset<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::multiset<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..4115c44a2e92cf
--- /dev/null
+++ b/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// set& operator=(set&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <set>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_map_alloc = std::set<MoveOnly, std::less<MoveOnly>, Alloc<MoveOnly>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_map_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_map_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_map_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_map_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_map_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::set<int, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp
index 9c177f219dc7b2..2768d3f46d06f4 100644
--- a/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp
@@ -19,40 +19,40 @@
// UNSUPPORTED: c++03
#include <set>
-#include <cassert>
-#include "test_macros.h"
#include "MoveOnly.h"
#include "test_allocator.h"
template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
};
-int main(int, char**)
-{
- {
- typedef std::set<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::set<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc = std::set<MoveOnly, std::less<MoveOnly>, Alloc<MoveOnly>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
#if defined(_LIBCPP_VERSION)
- {
- typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
#endif // _LIBCPP_VERSION
- {
- typedef std::set<MoveOnly, some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
+static_assert(!std::is_nothrow_move_assignable<std::set<int, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..b1d512fdfd6b6e
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// deque& operator=(deque&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <deque>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+static_assert(std::is_nothrow_move_assignable<std::deque<MoveOnly>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::deque<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_assignable<std::deque<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::deque<MoveOnly, not_always_equal_alloc<MoveOnly>>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<std::deque<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+#endif // _LIBCPP_VERSION
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index cbefbf6dae9129..00000000000000
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <deque>
-
-// deque& operator=(deque&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <deque>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_alloc
-{
- typedef T value_type;
- some_alloc(const some_alloc&);
- void allocate(std::size_t);
-};
-
-int main(int, char**)
-{
- {
- typedef std::deque<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::deque<MoveOnly, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::deque<MoveOnly, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..b173876a7c6a37
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// forward_list& operator=(forward_list&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <forward_list>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+static_assert(std::is_nothrow_move_assignable<std::forward_list<MoveOnly>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::forward_list<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_assignable<std::forward_list<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::forward_list<MoveOnly, not_always_equal_alloc<MoveOnly>>>::value,
+ "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<std::forward_list<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+#endif // _LIBCPP_VERSION
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index f361e373d23ffc..00000000000000
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <forward_list>
-
-// forward_list& operator=(forward_list&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <forward_list>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_alloc
-{
- typedef T value_type;
- some_alloc(const some_alloc&);
- void allocate(std::size_t);
-};
-
-int main(int, char**)
-{
- {
- typedef std::forward_list<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::forward_list<MoveOnly, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::forward_list<MoveOnly, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..b7bdbddc802e62
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// list& operator=(list&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <list>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+static_assert(std::is_nothrow_move_assignable<std::list<MoveOnly>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::list<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_assignable<std::list<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::list<MoveOnly, not_always_equal_alloc<MoveOnly>>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<std::list<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+#endif // _LIBCPP_VERSION
diff --git a/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 9df8413bb19c4c..00000000000000
--- a/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <list>
-
-// list& operator=(list&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <list>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_alloc
-{
- typedef T value_type;
- some_alloc(const some_alloc&);
- void allocate(std::size_t);
-};
-
-int main(int, char**)
-{
- {
- typedef std::list<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::list<MoveOnly, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::list<MoveOnly, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::list<MoveOnly, some_alloc<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..aca0c094b60921
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// unordered_map& operator=(unordered_map&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <unordered_map>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_hash {
+ using value_type = T;
+ some_hash();
+ some_hash(const some_hash&);
+ some_hash& operator=(const some_hash&);
+
+ std::size_t operator()(T const&) const;
+};
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc =
+ std::unordered_map<MoveOnly,
+ MoveOnly,
+ std::hash<MoveOnly>,
+ std::equal_to<MoveOnly>,
+ Alloc<std::pair<const MoveOnly, MoveOnly>>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::unordered_map<int, int, some_hash<int>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::unordered_map<int, int, std::hash<int>, some_comp<int>>>::value,
+ "");
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 9d50537216716a..00000000000000
--- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_map>
-
-// unordered_map& operator=(unordered_map&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <unordered_map>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-template <class T>
-struct some_hash
-{
- typedef T value_type;
- some_hash();
- some_hash(const some_hash&);
- some_hash& operator=(const some_hash&);
-
- std::size_t operator()(T const&) const;
-};
-
-int main(int, char**)
-{
- {
- typedef std::unordered_map<MoveOnly, MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..41f0831a1281ee
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// unordered_multimap& operator=(unordered_multimap&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <unordered_map>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_hash {
+ using value_type = T;
+ some_hash();
+ some_hash(const some_hash&);
+ some_hash& operator=(const some_hash&);
+
+ std::size_t operator()(T const&) const;
+};
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc =
+ std::unordered_multimap<MoveOnly,
+ MoveOnly,
+ std::hash<MoveOnly>,
+ std::equal_to<MoveOnly>,
+ Alloc<std::pair<const MoveOnly, MoveOnly>>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::unordered_map<int, int, some_hash<int>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::unordered_map<int, int, std::hash<int>, some_comp<int>>>::value,
+ "");
diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 2cd99546e5bd2a..00000000000000
--- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_map>
-
-// unordered_multimap& operator=(unordered_multimap&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <unordered_map>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-template <class T>
-struct some_hash
-{
- typedef T value_type;
- some_hash();
- some_hash(const some_hash&);
- some_hash& operator=(const some_hash&);
- std::size_t operator()(T const&) const;
-};
-
-int main(int, char**)
-{
- {
- typedef std::unordered_multimap<MoveOnly, MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..ca79c3d8978c0d
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// unordered_multiset& operator=(unordered_multiset&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <unordered_set>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_hash {
+ using value_type = T;
+ some_hash();
+ some_hash(const some_hash&);
+ some_hash& operator=(const some_hash&);
+
+ std::size_t operator()(T const&) const;
+};
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc =
+ std::unordered_multiset<MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, Alloc<MoveOnly>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::unordered_multiset<int, some_hash<int>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::unordered_multiset<int, std::hash<int>, some_comp<int>>>::value,
+ "");
diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 9dbca6e3e86744..00000000000000
--- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_set>
-
-// unordered_multiset& operator=(unordered_multiset&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <unordered_set>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-template <class T>
-struct some_hash
-{
- typedef T value_type;
- some_hash();
- some_hash(const some_hash&);
- some_hash& operator=(const some_hash&);
- std::size_t operator()(T const&) const;
-};
-
-int main(int, char**)
-{
- {
- typedef std::unordered_multiset<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::unordered_multiset<MoveOnly, some_hash<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>,
- some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.pass.cpp
new file mode 100644
index 00000000000000..6e2ea79d122ac1
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// unordered_set& operator=(unordered_set&& c)
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value &&
+// is_nothrow_move_assignable<key_compare>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <unordered_set>
+
+#include "MoveOnly.h"
+#include "test_allocator.h"
+
+template <class T>
+struct some_hash {
+ using value_type = T;
+ some_hash();
+ some_hash(const some_hash&);
+ some_hash& operator=(const some_hash&);
+
+ std::size_t operator()(T const&) const;
+};
+
+template <class T>
+struct some_comp {
+ using value_type = T;
+ some_comp& operator=(const some_comp&);
+ bool operator()(const T&, const T&) const { return false; }
+};
+
+template <class T>
+struct always_equal_alloc {
+ using value_type = T;
+ always_equal_alloc(const always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <class T>
+struct not_always_equal_alloc {
+ int i;
+ using value_type = T;
+ not_always_equal_alloc(const not_always_equal_alloc&);
+ void allocate(std::size_t);
+};
+
+template <template <class> class Alloc>
+using unordered_set_alloc = std::unordered_set<MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, Alloc<MoveOnly>>;
+
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<std::allocator>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<test_allocator>>::value, "");
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<unordered_set_alloc<not_always_equal_alloc>>::value, "");
+#if defined(_LIBCPP_VERSION)
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<other_allocator>>::value, "");
+#endif // _LIBCPP_VERSION
+static_assert(!std::is_nothrow_move_assignable<std::unordered_set<int, some_hash<int>>>::value, "");
+static_assert(!std::is_nothrow_move_assignable<std::unordered_set<int, std::hash<int>, some_comp<int>>>::value, "");
diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp
deleted file mode 100644
index 1ff2a7b471a1d7..00000000000000
--- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_set>
-
-// unordered_set& operator=(unordered_set&& c)
-// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value &&
-// is_nothrow_move_assignable<key_compare>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <unordered_set>
-#include <cassert>
-
-#include "test_macros.h"
-#include "MoveOnly.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_comp
-{
- typedef T value_type;
- some_comp& operator=(const some_comp&);
- bool operator()(const T&, const T&) const { return false; }
-};
-
-template <class T>
-struct some_hash
-{
- typedef T value_type;
- some_hash();
- some_hash(const some_hash&);
- some_hash& operator=(const some_hash&);
- std::size_t operator()(T const&) const;
-};
-
-int main(int, char**)
-{
- {
- typedef std::unordered_set<MoveOnly> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
- {
- typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>,
- some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
More information about the libcxx-commits
mailing list