[libcxx-commits] [libcxx] fcc4ceb - [libc++] Implement N4258(Cleaning-up noexcept in the Library) (#120312)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 30 12:11:01 PST 2025
Author: Nikolas Klauser
Date: 2025-01-30T21:10:56+01:00
New Revision: fcc4ceb331957dc6d1d6d0f4035bd2f48f2945bd
URL: https://github.com/llvm/llvm-project/commit/fcc4ceb331957dc6d1d6d0f4035bd2f48f2945bd
DIFF: https://github.com/llvm/llvm-project/commit/fcc4ceb331957dc6d1d6d0f4035bd2f48f2945bd.diff
LOG: [libc++] Implement N4258(Cleaning-up noexcept in the Library) (#120312)
Fixes #99937
Added:
libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp
libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.pass.cpp
Modified:
libcxx/docs/ReleaseNotes/21.rst
libcxx/docs/Status/Cxx17Papers.csv
libcxx/include/__hash_table
libcxx/include/__tree
libcxx/include/deque
libcxx/include/forward_list
libcxx/include/list
Removed:
libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp
libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp
################################################################################
diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index 29ecbf3f01c8a5..82f1de6bad3942 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -38,8 +38,7 @@ What's New in Libc++ 21.0.0?
Implemented Papers
------------------
-- TODO
-
+- 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 fbcac452adb8bf..24fc7f718c3608 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)","|Complete|","5",""
"`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|","21",""
"`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 9a82ec51daee78..d7b312f8774fce 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -770,9 +770,10 @@ 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);
+ _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) ||
+ allocator_traits<__node_allocator>::is_always_equal::value));
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
template <class _InputIterator>
@@ -1238,10 +1239,11 @@ 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)
+ _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) ||
+ allocator_traits<__node_allocator>::is_always_equal::value)) {
__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 acad6c33f8782a..c627641d5d86f1 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -987,9 +987,12 @@ 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)
+ _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value) ||
+ allocator_traits<__node_allocator>::is_always_equal::value));
+
_LIBCPP_HIDE_FROM_ABI ~__tree();
_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node()); }
@@ -1520,11 +1523,11 @@ 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)
+ _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
+ ((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value) ||
+ allocator_traits<__node_allocator>::is_always_equal::value)) {
__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 df3094cff7f89c..95200b4801d7ff 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -59,9 +59,9 @@ public:
deque& operator=(const deque& c);
deque& operator=(deque&& c)
- noexcept(
- allocator_type::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ noexcept((__alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
deque& operator=(initializer_list<value_type> il);
template <class InputIterator>
@@ -674,9 +674,10 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
_LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); }
# endif // _LIBCPP_CXX03_LANG
@@ -1379,8 +1380,9 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value) {
__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 f3b9617ab2e04d..4b6ca8ea8587c0 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -58,9 +58,9 @@ public:
forward_list& operator=(const forward_list& x);
forward_list& operator=(forward_list&& x)
- noexcept(
- allocator_type::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ noexcept((__node_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
forward_list& operator=(initializer_list<value_type> il);
template <class InputIterator>
@@ -717,8 +717,9 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
_LIBCPP_HIDE_FROM_ABI forward_list& operator=(initializer_list<value_type> __il);
@@ -1009,8 +1010,10 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value) {
__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 5e2fd40d6ee9d2..3fcf796ebc03d0 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -60,9 +60,9 @@ public:
list& operator=(const list& x);
list& operator=(list&& x)
- noexcept(
- allocator_type::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ noexcept((__node_alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<__node_allocator>::value) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
list& operator=(initializer_list<value_type>);
template <class Iter>
void assign(Iter first, Iter last);
@@ -728,9 +728,10 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value);
_LIBCPP_HIDE_FROM_ABI list& operator=(initializer_list<value_type> __il) {
assign(__il.begin(), __il.end());
@@ -1067,8 +1068,9 @@ 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) ||
+ allocator_traits<allocator_type>::is_always_equal::value) {
__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..a4c8ef1c5b4293
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<always_equal_alloc>>::value, "");
+#endif
+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..dd4c6f76fbcb62
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<multimap_alloc<always_equal_alloc>>::value, "");
+#endif
+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..930eae1bc9083f
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+#endif
+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..f8a0472fb069ce
--- /dev/null
+++ b/libcxx/test/std/containers/associative/set/set.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<unordered_map_alloc<always_equal_alloc>>::value, "");
+#endif
+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
deleted file mode 100644
index 9c177f219dc7b2..00000000000000
--- a/libcxx/test/std/containers/associative/set/set.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>
-
-// 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 <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::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, "");
- }
-#if defined(_LIBCPP_VERSION)
- {
- typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
- static_assert(std::is_nothrow_move_assignable<C>::value, "");
- }
-#endif // _LIBCPP_VERSION
- {
- typedef std::set<MoveOnly, some_comp<MoveOnly>> C;
- static_assert(!std::is_nothrow_move_assignable<C>::value, "");
- }
-
- return 0;
-}
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..417f44922d37d2
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<std::deque<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+#endif
+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..b73177a00d4660
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<std::forward_list<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+#endif
+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..8da5cfc4716e40
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/list/list.cons/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<std::list<MoveOnly, always_equal_alloc<MoveOnly>>>::value, "");
+#endif
+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..098e83d3521e5f
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+#endif
+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..1420250fad61cc
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+#endif
+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..814810d341e2bf
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.compile.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER > 17
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+#endif
+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..1b4df4e3f23b5b
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// <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 "test_macros.h"
+#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, "");
+#if TEST_STD_VER >= 17
+static_assert(std::is_nothrow_move_assignable<unordered_set_alloc<always_equal_alloc>>::value, "");
+#endif
+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