[libcxx-commits] [libcxx] [libc++] Simplify a bunch of noexcept specifications (PR #166397)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 8 07:23:16 PDT 2026


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/166397

>From 9e75b0c7393d2b529779871c8d5491ea966da78e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 4 Nov 2025 17:33:32 +0100
Subject: [PATCH] [libc++] Simplify a bunch of noexcept specifications

---
 libcxx/include/CMakeLists.txt                 |   1 -
 libcxx/include/__hash_table                   |  60 ++-----
 libcxx/include/__memory/allocator_traits.h    |   4 +
 .../__memory/noexcept_move_assign_container.h |  37 -----
 libcxx/include/__split_buffer                 |  37 ++---
 libcxx/include/__tree                         |  40 ++---
 libcxx/include/__vector/vector.h              |  64 ++------
 libcxx/include/__vector/vector_bool.h         |  70 ++------
 libcxx/include/deque                          |  51 ++----
 libcxx/include/forward_list                   |  65 ++------
 libcxx/include/list                           |  61 ++-----
 libcxx/include/queue                          |   1 +
 libcxx/include/stack                          |   1 +
 libcxx/include/string                         |  50 ++----
 .../associative/map/noexcept.compile.pass.cpp | 116 +++++++++++++
 .../move_noexcept.compile.pass.cpp}           |  29 +---
 .../move_noexcept.compile.pass.cpp}           |  29 +---
 .../list.cons/move_noexcept.compile.pass.cpp} |  26 +--
 .../move_noexcept.compile.pass.cpp            |  32 ++++
 .../vector.bool/noexcept.compile.pass.cpp     |  38 +++++
 .../vector/noexcept.compile.pass.cpp          |  38 +++++
 .../unord/unord.map/noexcept.compile.pass.cpp | 154 +++++++++++++++++
 .../unord.multimap/noexcept.compile.pass.cpp  | 155 ++++++++++++++++++
 .../unord.multiset/noexcept.compile.pass.cpp  | 154 +++++++++++++++++
 .../unord/unord.set/noexcept.compile.pass.cpp | 154 +++++++++++++++++
 .../flat.map.cons/move_noexcept.pass.cpp      |  29 ----
 .../flat.multimap.cons/move_noexcept.pass.cpp |  31 ----
 .../flat.multiset.cons/move.pass.cpp          |  19 ---
 .../flat.set/flat.set.cons/move.pass.cpp      |  16 +-
 .../deque.special/swap_noexcept.pass.cpp      |   6 +-
 .../swap_noexcept.compile.pass.cpp            |   6 +-
 .../list/list.special/swap_noexcept.pass.cpp  |   6 +-
 .../vector.bool/move_noexcept.pass.cpp        |  60 -------
 .../vector.bool/swap_noexcept.pass.cpp        |  11 --
 .../vector/vector.cons/move_noexcept.pass.cpp |   5 +-
 .../string.cons/move_noexcept.pass.cpp        |   4 +-
 36 files changed, 1008 insertions(+), 652 deletions(-)
 delete mode 100644 libcxx/include/__memory/noexcept_move_assign_container.h
 create mode 100644 libcxx/test/libcxx/containers/associative/map/noexcept.compile.pass.cpp
 rename libcxx/test/{std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp => libcxx/containers/sequences/deque/deque.cons/move_noexcept.compile.pass.cpp} (53%)
 rename libcxx/test/{std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp => libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp} (53%)
 rename libcxx/test/{std/containers/sequences/list/list.cons/move_noexcept.pass.cpp => libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp} (55%)
 create mode 100644 libcxx/test/libcxx/containers/sequences/vector.bool/move_noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/vector.bool/noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/vector/noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/unord/unord.map/noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/unord/unord.multimap/noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/unord/unord.multiset/noexcept.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/unord/unord.set/noexcept.compile.pass.cpp
 delete mode 100644 libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index b40f586161e62..32726900fa3fd 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -605,7 +605,6 @@ set(files
   __memory/destruct_n.h
   __memory/inout_ptr.h
   __memory/is_sufficiently_aligned.h
-  __memory/noexcept_move_assign_container.h
   __memory/out_ptr.h
   __memory/pointer_traits.h
   __memory/ranges_construct_at.h
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 0ce4cf3edd6fd..fa7503d45e712 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -522,13 +522,13 @@ public:
   _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
       : __size_(0) {}
 
-  _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size)
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-      : __size_(__size), __alloc_(__a) {}
+  _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size) _NOEXCEPT
+      : __size_(__size),
+        __alloc_(__a) {}
 
-  _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-      : __size_(std::__exchange(__x.__size_, 0)), __alloc_(std::move(__x.__alloc_)) {}
+  _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x) _NOEXCEPT
+      : __size_(std::__exchange(__x.__size_, 0)),
+        __alloc_(std::move(__x.__alloc_)) {}
 
   _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __size_; }
   _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
@@ -754,17 +754,14 @@ public:
   _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a);
   _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) _NOEXCEPT_(
       is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
-          is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
-              is_nothrow_move_constructible<key_equal>::value);
+          is_nothrow_move_constructible<hasher>::value&& is_nothrow_move_constructible<key_equal>::value);
   _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
   _LIBCPP_HIDE_FROM_ABI ~__hash_table();
 
   _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
   _LIBCPP_HIDE_FROM_ABI __hash_table& 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));
+      _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value&&
+                     __is_allocator_aware_container_move_nothrow_v<allocator_type>);
   template <class _InputIterator>
   _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
   template <class _InputIterator>
@@ -958,14 +955,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
 
   _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
-#if _LIBCPP_STD_VER <= 11
-      _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
-                 (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
-                  __is_nothrow_swappable_v<__pointer_allocator>) &&
-                 (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
-#else
       _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>);
-#endif
 
   _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return max_size(); }
   _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
@@ -1025,15 +1015,11 @@ private:
 
   _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type);
   _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
-                     is_nothrow_move_assignable<key_equal>::value);
-  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT_(
-      !__node_traits::propagate_on_container_move_assignment::value ||
-      (is_nothrow_move_assignable<__pointer_allocator>::value && is_nothrow_move_assignable<__node_allocator>::value)) {
+      _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value);
+  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT {
     __move_assign_alloc(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
   }
-  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT_(
-      is_nothrow_move_assignable<__pointer_allocator>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT {
     __bucket_list_.get_deleter().__alloc() = std::move(__u.__bucket_list_.get_deleter().__alloc());
     __node_alloc()                         = std::move(__u.__node_alloc());
   }
@@ -1146,8 +1132,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_(
     is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
-        is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
-            is_nothrow_move_constructible<key_equal>::value)
+        is_nothrow_move_constructible<hasher>::value&& is_nothrow_move_constructible<key_equal>::value)
     : __bucket_list_(std::move(__u.__bucket_list_)),
       __first_node_(std::move(__u.__first_node_)),
       __node_alloc_(std::move(__u.__node_alloc_)),
@@ -1292,8 +1277,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT {
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, true_type)
-    _NOEXCEPT_(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) {
   clear();
   __bucket_list_.reset(__u.__bucket_list_.release());
   __bucket_list_.get_deleter().size()     = __u.__bucket_list_.get_deleter().size();
@@ -1338,10 +1322,8 @@ 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_(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)) {
+    _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value&&
+                   __is_allocator_aware_container_move_nothrow_v<allocator_type>) {
   __move_assign(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
   return *this;
 }
@@ -2074,15 +2056,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) c
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
-#if _LIBCPP_STD_VER <= 11
-    _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
-               (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
-                __is_nothrow_swappable_v<__pointer_allocator>) &&
-               (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
-#else
-    _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>)
-#endif
-{
+    _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>) {
   _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
       __node_traits::propagate_on_container_swap::value || this->__node_alloc() == __u.__node_alloc(),
       "unordered container::swap: Either propagate_on_container_swap "
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 7038885a8b24f..d32e167ed833f 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -436,6 +436,10 @@ inline const bool __is_cpp17_copy_insertable_v =
      (!__is_std_allocator_v<_Alloc> &&
       __has_construct_v<_Alloc, typename _Alloc::value_type*, const typename _Alloc::value_type&>));
 
+template <typename _Alloc, typename _Traits = allocator_traits<_Alloc> >
+inline const bool __is_allocator_aware_container_move_nothrow_v =
+    _Traits::propagate_on_container_move_assignment::value || _Traits::is_always_equal::value;
+
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/__memory/noexcept_move_assign_container.h b/libcxx/include/__memory/noexcept_move_assign_container.h
deleted file mode 100644
index b0063516aaafc..0000000000000
--- a/libcxx/include/__memory/noexcept_move_assign_container.h
+++ /dev/null
@@ -1,37 +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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___MEMORY_NOEXCEPT_MOVE_ASSIGN_CONTAINER_H
-#define _LIBCPP___MEMORY_NOEXCEPT_MOVE_ASSIGN_CONTAINER_H
-
-#include <__config>
-#include <__memory/allocator_traits.h>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_nothrow_assignable.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <typename _Alloc, typename _Traits = allocator_traits<_Alloc> >
-struct __noexcept_move_assign_container
-    : public integral_constant<bool,
-                               _Traits::propagate_on_container_move_assignment::value
-#if _LIBCPP_STD_VER >= 17
-                                   || _Traits::is_always_equal::value
-#else
-                                   && is_nothrow_move_assignable<_Alloc>::value
-#endif
-                               > {
-};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___MEMORY_NOEXCEPT_MOVE_ASSIGN_CONTAINER_H
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 1d50486947f08..31915540f06b9 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -29,8 +29,6 @@
 #include <__type_traits/conditional.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_nothrow_assignable.h>
-#include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_swappable.h>
 #include <__type_traits/is_trivially_destructible.h>
 #include <__type_traits/is_trivially_relocatable.h>
@@ -181,8 +179,7 @@ public:
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __copy_without_alloc(__split_buffer_pointer_layout const& __other)
-      _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
+  __copy_without_alloc(__split_buffer_pointer_layout const& __other) _NOEXCEPT {
     __front_cap_ = __other.__front_cap_;
     __begin_     = __other.__begin_;
     __end_       = __other.__end_;
@@ -388,8 +385,7 @@ public:
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __copy_without_alloc(__split_buffer_size_layout const& __other)
-      _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
+  __copy_without_alloc(__split_buffer_size_layout const& __other) _NOEXCEPT {
     __front_cap_ = __other.__front_cap_;
     __begin_     = __other.__begin_;
     __cap_       = __other.__cap_;
@@ -607,15 +603,11 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   __split_buffer(size_type __cap, size_type __start, allocator_type& __a);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c) _NOEXCEPT;
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const allocator_type& __a);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __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);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c) _NOEXCEPT;
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
 
@@ -669,8 +661,7 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x) _NOEXCEPT;
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
     if (__front_cap() == nullptr) {
@@ -704,8 +695,8 @@ public:
   }
 
 private:
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+  __move_assign_alloc(__split_buffer& __c, true_type) _NOEXCEPT {
     __get_allocator() = std::move(__c.__get_allocator());
   }
 
@@ -850,8 +841,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::~__split
 }
 
 template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c)
-    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c) _NOEXCEPT
     : __base_type(std::move(__c)) {
   __c.__reset();
 }
@@ -877,10 +867,7 @@ __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c, c
 
 template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>&
-__split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __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) {
+__split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c) _NOEXCEPT {
   clear();
   shrink_to_fit();
   __copy_without_alloc(__c);
@@ -890,8 +877,7 @@ __split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c)
 }
 
 template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x)
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x) _NOEXCEPT {
   __base_type::swap(__x);
 }
 
@@ -962,8 +948,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::emp
 
 template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
-swap(__split_buffer<_Tp, _Allocator, _Layout>& __x, __split_buffer<_Tp, _Allocator, _Layout>& __y)
-    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+swap(__split_buffer<_Tp, _Allocator, _Layout>& __x, __split_buffer<_Tp, _Allocator, _Layout>& __y) _NOEXCEPT {
   __x.swap(__y);
 }
 
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index dafeff3e2e019..4965e35571b47 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -1021,15 +1021,13 @@ public:
   template <class _ForwardIterator>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
   __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(__tree&& __t) _NOEXCEPT_(
-      is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(__tree&& __t)
+      _NOEXCEPT_(is_nothrow_move_constructible<value_compare>::value);
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(__tree&& __t, const allocator_type& __a);
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __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)) {
+      _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&&
+                     __is_allocator_aware_container_move_nothrow_v<__node_allocator>) {
     __move_assign(__t,
                   integral_constant<bool,
                                     __node_traits::propagate_on_container_move_assignment::value ||
@@ -1058,12 +1056,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() _NOEXCEPT;
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(__tree& __t)
-#if _LIBCPP_STD_VER <= 11
-      _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
-                 (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
-#else
       _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
-#endif
 
   template <class... _Args>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace_multi(_Args&&... __args);
@@ -1472,17 +1465,14 @@ private:
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign(__tree& __t, false_type);
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
-      is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign(__tree& __t, true_type)
+      _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value);
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t)
-      _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t) _NOEXCEPT {
     __move_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
   }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t, true_type) _NOEXCEPT {
     __node_alloc() = std::move(__t.__node_alloc());
   }
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
@@ -1727,8 +1717,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(const __
 }
 
 template <class _Tp, class _Compare, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
-    is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
+    _NOEXCEPT_(is_nothrow_move_constructible<value_compare>::value)
     : __begin_node_(std::move(__t.__begin_node_)),
       __end_node_(std::move(__t.__end_node_)),
       __node_alloc_(std::move(__t.__node_alloc_)),
@@ -1771,7 +1761,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&&
 
 template <class _Tp, class _Compare, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
-    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
+    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value) {
   destroy(std::__static_fancy_pointer_cast<__node_pointer>(__end_node()->__left_));
   __begin_node_ = __t.__begin_node_;
   __end_node_   = __t.__end_node_;
@@ -1811,13 +1801,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::__move_ass
 
 template <class _Tp, class _Compare, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
-#if _LIBCPP_STD_VER <= 11
-    _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
-               (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
-#else
-    _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>)
-#endif
-{
+    _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>) {
   using std::swap;
   swap(__begin_node_, __t.__begin_node_);
   swap(__end_node_, __t.__end_node_);
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 2b9508ecafeac..c66b2fce60d06 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -36,7 +36,6 @@
 #include <__memory/allocator.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
-#include <__memory/noexcept_move_assign_container.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/temp_value.h>
@@ -52,7 +51,6 @@
 #include <__type_traits/is_allocator.h>
 #include <__type_traits/is_constant_evaluated.h>
 #include <__type_traits/is_constructible.h>
-#include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/is_pointer.h>
 #include <__type_traits/is_same.h>
@@ -135,14 +133,8 @@ class vector {
   //
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) {}
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)
-#if _LIBCPP_STD_VER <= 14
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-#else
-      noexcept
-#endif
-      : __layout_(__a) {
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20
+  _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a) _NOEXCEPT : __layout_(__a) {}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
@@ -290,17 +282,11 @@ class vector {
   }
 #endif // !_LIBCPP_CXX03_LANG
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(vector&& __x)
-#if _LIBCPP_STD_VER >= 17
-      noexcept;
-#else
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
-#endif
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20
-  _LIBCPP_HIDE_FROM_ABI vector(vector&& __x, const __type_identity_t<allocator_type>& __a);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(vector&& __x) _NOEXCEPT;
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  vector(vector&& __x, const __type_identity_t<allocator_type>& __a);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector& operator=(vector&& __x)
-      _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
+      _NOEXCEPT_(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
     __move_assign(__x, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
     return *this;
   }
@@ -566,12 +552,7 @@ class vector {
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&)
-#if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
-#endif
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&) _NOEXCEPT;
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const _NOEXCEPT {
     return __layout_.__invariants();
@@ -709,8 +690,7 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __move_range(pointer __from_s, pointer __from_e, pointer __to);
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type) _NOEXCEPT;
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type)
       _NOEXCEPT_(__alloc_traits::is_always_equal::value);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
@@ -783,9 +763,7 @@ class vector {
     __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c) _NOEXCEPT {
     __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
   }
 
@@ -805,8 +783,7 @@ class vector {
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const vector&, false_type) {}
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(vector& __c, true_type) _NOEXCEPT {
     this->__layout_.__alloc() = std::move(__c.__layout_.__alloc());
   }
 
@@ -912,14 +889,8 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x)
-#if _LIBCPP_STD_VER >= 17
-    noexcept
-#else
-    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-#endif
-    : __layout_(std::move(__x.__layout_)) {
-}
+_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x) _NOEXCEPT
+    : __layout_(std::move(__x.__layout_)) {}
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI
@@ -944,8 +915,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
-    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type) _NOEXCEPT {
   __vdeallocate();
   __move_assign_alloc(__c); // this can throw
   __layout_.__move_assign_without_allocator(__c.__layout_);
@@ -1338,13 +1308,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __n
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x)
-#if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#endif
-{
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x) _NOEXCEPT {
   _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
       __alloc_traits::propagate_on_container_swap::value || __layout_.__alloc() == __x.__layout_.__alloc(),
       "vector::swap: Either propagate_on_container_swap must be true"
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index f73e086478a70..84824239f8c54 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -127,12 +127,7 @@ class vector<bool, _Allocator> {
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(const allocator_type& __a)
-#if _LIBCPP_STD_VER <= 14
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
-#else
-      _NOEXCEPT;
-#endif
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(const allocator_type& __a) _NOEXCEPT;
 
 private:
   class __destroy_vector {
@@ -199,16 +194,11 @@ class vector<bool, _Allocator> {
 
 #endif // !_LIBCPP_CXX03_LANG
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(vector&& __v)
-#if _LIBCPP_STD_VER >= 17
-      noexcept;
-#else
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
-#endif
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(vector&& __v) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
   vector(vector&& __v, const __type_identity_t<allocator_type>& __a);
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(vector&& __v)
-      _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value);
+      _NOEXCEPT_(__is_allocator_aware_container_move_nothrow_v<allocator_type>);
 
   template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
   void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last);
@@ -393,12 +383,7 @@ class vector<bool, _Allocator> {
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT { __size_ = 0; }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
-#if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
-#endif
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void swap(reference __x, reference __y) _NOEXCEPT {
     std::swap(__x, __y);
   }
@@ -513,16 +498,12 @@ class vector<bool, _Allocator> {
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const vector&, false_type) {}
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, false_type);
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c)
-      _NOEXCEPT_(!__storage_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, true_type) _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c) _NOEXCEPT {
     __move_assign_alloc(
         __c, integral_constant<bool, __storage_traits::propagate_on_container_move_assignment::value>());
   }
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c, true_type) _NOEXCEPT {
     __alloc_ = std::move(__c.__alloc_);
   }
 
@@ -586,14 +567,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocat
     : __begin_(nullptr), __size_(0), __cap_(0) {}
 
 template <class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const allocator_type& __a)
-#if _LIBCPP_STD_VER <= 14
-    _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-#else
-        _NOEXCEPT
-#endif
-    : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) {
-}
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+vector<bool, _Allocator>::vector(const allocator_type& __a) _NOEXCEPT
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_(0),
+      __alloc_(static_cast<__storage_allocator>(__a)) {}
 
 template <class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n)
@@ -735,17 +714,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>& vector<bool, _Allocator>
 }
 
 template <class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v)
-#if _LIBCPP_STD_VER >= 17
-    _NOEXCEPT
-#else
-    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-#endif
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v) _NOEXCEPT
     : __begin_(std::__exchange(__v.__begin_, nullptr)),
       __size_(std::__exchange(__v.__size_, 0)),
       __cap_(std::__exchange(__v.__cap_, 0)),
-      __alloc_(std::move(__v.__alloc_)) {
-}
+      __alloc_(std::move(__v.__alloc_)) {}
 
 template <class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -765,7 +738,7 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
 template <class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>&
 vector<bool, _Allocator>::operator=(vector&& __v)
-    _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
+    _NOEXCEPT_(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
   __move_assign(__v, integral_constant<bool, __storage_traits::propagate_on_container_move_assignment::value>());
   return *this;
 }
@@ -779,8 +752,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__move_assign(vecto
 }
 
 template <class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
-    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__move_assign(vector& __c, true_type) _NOEXCEPT {
   __vdeallocate();
   __move_assign_alloc(__c);
   __begin_ = std::__exchange(__c.__begin_, nullptr);
@@ -1030,13 +1002,7 @@ vector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last) {
 }
 
 template <class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::swap(vector& __x)
-#if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#endif
-{
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::swap(vector& __x) _NOEXCEPT {
   std::swap(this->__begin_, __x.__begin_);
   std::swap(this->__size_, __x.__size_);
   std::swap(this->__cap_, __x.__cap_);
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 7aee552c63d37..dd06349d16a96 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -226,7 +226,6 @@ template <class T, class Allocator, class Predicate>
 #  include <__type_traits/enable_if.h>
 #  include <__type_traits/is_allocator.h>
 #  include <__type_traits/is_convertible.h>
-#  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_swappable.h>
@@ -553,9 +552,6 @@ public:
   static_assert(is_nothrow_default_constructible<allocator_type>::value ==
                     is_nothrow_default_constructible<__pointer_allocator>::value,
                 "rebinding an allocator should not change exception guarantees");
-  static_assert(is_nothrow_move_constructible<allocator_type>::value ==
-                    is_nothrow_move_constructible<typename __map::allocator_type>::value,
-                "rebinding an allocator should not change exception guarantees");
 
 private:
   struct __deque_block_range {
@@ -691,12 +687,10 @@ public:
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value);
+  _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept;
   _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) ||
-      __alloc_traits::is_always_equal::value);
+  _LIBCPP_HIDE_FROM_ABI deque&
+  operator=(deque&& __c) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>);
 
   _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); }
 #  endif // _LIBCPP_CXX03_LANG
@@ -888,12 +882,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
 
-  _LIBCPP_HIDE_FROM_ABI void swap(deque& __c)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#  else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
-#  endif
+  _LIBCPP_HIDE_FROM_ABI void swap(deque& __c) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
 
   _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
@@ -918,22 +907,18 @@ public:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) _NOEXCEPT {
     __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
   }
 
-  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) _NOEXCEPT {
     __alloc() = std::move(__c.__alloc());
   }
 
   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {}
 
   _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c)
-      _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&&
-                     is_nothrow_move_assignable<allocator_type>::value) {
+      _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value) {
     __map_   = std::move(__c.__map_);
     __start_ = __c.__start_;
     __size() = __c.size();
@@ -1286,8 +1271,7 @@ private:
 
   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {}
 
-  _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+  _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type);
 };
 
@@ -1397,7 +1381,7 @@ deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator
 }
 
 template <class _Tp, class _Allocator>
-inline deque<_Tp, _Allocator>::deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value)
+inline deque<_Tp, _Allocator>::deque(deque&& __c) noexcept
     : __map_(std::move(__c.__map_)),
       __start_(std::move(__c.__start_)),
       __size_(std::move(__c.__size_)),
@@ -1425,10 +1409,8 @@ 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::is_always_equal::value) {
+inline deque<_Tp, _Allocator>&
+deque<_Tp, _Allocator>::operator=(deque&& __c) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
   __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
   return *this;
 }
@@ -1443,8 +1425,7 @@ void deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) {
 }
 
 template <class _Tp, class _Allocator>
-void deque<_Tp, _Allocator>::__move_assign(deque& __c,
-                                           true_type) noexcept(is_nothrow_move_assignable<allocator_type>::value) {
+void deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) noexcept {
   clear();
   shrink_to_fit();
   __move_assign(__c);
@@ -2414,13 +2395,7 @@ void deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) {
 }
 
 template <class _Tp, class _Allocator>
-inline void deque<_Tp, _Allocator>::swap(deque& __c)
-#  if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#  else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#  endif
-{
+inline void deque<_Tp, _Allocator>::swap(deque& __c) _NOEXCEPT {
   __map_.swap(__c.__map_);
   std::swap(__start_, __c.__start_);
   std::swap(__size(), __c.__size());
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 6d86f7a8e5975..767a959bf8866 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -227,7 +227,6 @@ template <class T, class Allocator, class Predicate>
 #  include <__type_traits/enable_if.h>
 #  include <__type_traits/is_allocator.h>
 #  include <__type_traits/is_const.h>
-#  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_swappable.h>
@@ -499,8 +498,7 @@ protected:
 
 public:
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
-  __forward_list_base(__forward_list_base&& __x) noexcept(is_nothrow_move_constructible<__node_allocator>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_base(__forward_list_base&& __x) noexcept;
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
   __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
 #  endif // _LIBCPP_CXX03_LANG
@@ -515,9 +513,7 @@ protected:
     __copy_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x)
-      _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x) _NOEXCEPT {
     __move_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
   }
 
@@ -547,12 +543,7 @@ protected:
   }
 
 public:
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(__forward_list_base& __x)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#  else
-      _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>);
-#  endif
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(__forward_list_base& __x) _NOEXCEPT;
 
 protected:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
@@ -569,8 +560,8 @@ private:
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void
   __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT {}
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void
+  __move_assign_alloc(__forward_list_base& __x, true_type) _NOEXCEPT {
     __alloc_ = std::move(__x.__alloc_);
   }
 };
@@ -579,7 +570,7 @@ private:
 
 template <class _Tp, class _Alloc>
 _LIBCPP_CONSTEXPR_SINCE_CXX26 inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(
-    __forward_list_base&& __x) noexcept(is_nothrow_move_constructible<__node_allocator>::value)
+    __forward_list_base&& __x) noexcept
     : __before_begin_(std::move(__x.__before_begin_)), __alloc_(std::move(__x.__alloc_)) {
   __x.__before_begin()->__next_ = nullptr;
 }
@@ -602,13 +593,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 __forward_list_base<_Tp, _Alloc>::~__forward_list_
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
-#  if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#  else
-    _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
-#  endif
-{
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) _NOEXCEPT {
   std::__swap_allocator(__alloc_, __x.__alloc_);
   using std::swap;
   swap(__before_begin()->__next_, __x.__before_begin()->__next_);
@@ -699,8 +684,7 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
 
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
-  forward_list(forward_list&& __x) noexcept(is_nothrow_move_constructible<__base>::value)
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x) noexcept
       : __base(std::move(__x)) {}
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
   forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
@@ -709,10 +693,8 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
   forward_list(initializer_list<value_type> __il, const allocator_type& __a);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _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) ||
-      allocator_traits<allocator_type>::is_always_equal::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list&
+  operator=(forward_list&& __x) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>);
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list& operator=(initializer_list<value_type> __il);
 
@@ -838,15 +820,7 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(forward_list& __x)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT
-#  else
-      _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
-#  endif
-  {
-    __base::swap(__x);
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(forward_list& __x) _NOEXCEPT { __base::swap(__x); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
@@ -885,8 +859,7 @@ public:
 
 private:
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type) _NOEXCEPT;
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type);
 #  endif // _LIBCPP_CXX03_LANG
 
@@ -1019,8 +992,7 @@ forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, const
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
-    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) _NOEXCEPT {
   clear();
   __base::__move_assign_alloc(__x);
   __base::__before_begin()->__next_ = std::__exchange(__x.__before_begin()->__next_, nullptr);
@@ -1037,11 +1009,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void forward_list<_Tp, _Alloc>::__move_assign(forw
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 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) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(
+    forward_list&& __x) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
   __move_assign(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
   return *this;
 }
@@ -1558,8 +1527,8 @@ operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _A
 #  endif // #if _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI void
-swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline
+    _LIBCPP_HIDE_FROM_ABI void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) _NOEXCEPT {
   __x.swap(__y);
 }
 
diff --git a/libcxx/include/list b/libcxx/include/list
index 3223f25e1cfba..7b631554d0ed7 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -231,7 +231,6 @@ template <class T, class Allocator, class Predicate>
 #  include <__type_traits/container_traits.h>
 #  include <__type_traits/enable_if.h>
 #  include <__type_traits/is_allocator.h>
-#  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/type_identity.h>
@@ -535,21 +534,14 @@ protected:
     return const_iterator(__end_as_link());
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#  else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
-#  endif
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c) _NOEXCEPT;
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp& __c) {
     __copy_assign_alloc(
         __c, integral_constant<bool, __node_alloc_traits::propagate_on_container_copy_assignment::value>());
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c)
-      _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c) _NOEXCEPT {
     __move_assign_alloc(
         __c, integral_constant<bool, __node_alloc_traits::propagate_on_container_move_assignment::value>());
   }
@@ -589,8 +581,7 @@ private:
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp&, false_type) {}
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c, true_type) _NOEXCEPT {
     __node_alloc_ = std::move(__c.__node_alloc_);
   }
 
@@ -646,13 +637,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT {
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 void __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
-#  if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#  else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#  endif
-{
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) _NOEXCEPT {
   _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
       __alloc_traits::propagate_on_container_swap::value || this->__node_alloc_ == __c.__node_alloc_,
       "list::swap: Either propagate_on_container_swap must be true"
@@ -744,13 +729,10 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
   list(initializer_list<value_type> __il, const allocator_type& __a);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(list&& __c)
-      _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(list&& __c) noexcept;
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(list&& __c, const __type_identity_t<allocator_type>& __a);
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _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_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list&
+  operator=(list&& __c) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>);
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list& operator=(initializer_list<value_type> __il) {
     assign(__il.begin(), __il.end());
@@ -915,15 +897,7 @@ public:
   }
 #  endif
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(list& __c)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT
-#  else
-      _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
-#  endif
-  {
-    __base::swap(__c);
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(list& __c) _NOEXCEPT { __base::swap(__c); }
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __base::clear(); }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void pop_front();
@@ -995,8 +969,7 @@ private:
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDDEN static iterator
   __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);
+  _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type);
   _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type);
 };
 
@@ -1125,8 +1098,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(initializer_list<value_typ
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>::list(list&& __c) noexcept(
-    is_nothrow_move_constructible<__node_allocator>::value)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>::list(list&& __c) noexcept
     : __base(std::move(__c.__node_alloc_)) {
   splice(end(), __c);
 }
@@ -1143,10 +1115,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>::list(list&& __c, const _
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 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) ||
-    allocator_traits<allocator_type>::is_always_equal::value) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>&
+list<_Tp, _Alloc>::operator=(list&& __c) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
   __move_assign(__c, integral_constant<bool, __node_alloc_traits::propagate_on_container_move_assignment::value>());
   return *this;
 }
@@ -1161,8 +1131,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::__move_assign(list& __c, f
 }
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 void
-list<_Tp, _Alloc>::__move_assign(list& __c, true_type) noexcept(is_nothrow_move_assignable<__node_allocator>::value) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::__move_assign(list& __c, true_type) {
   clear();
   __base::__move_assign_alloc(__c);
   splice(end(), __c);
@@ -1762,8 +1731,8 @@ operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y)
 #  endif // _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
-    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline
+    _LIBCPP_HIDE_FROM_ABI void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) _NOEXCEPT {
   __x.swap(__y);
 }
 
diff --git a/libcxx/include/queue b/libcxx/include/queue
index b469240cc94f9..b2c4c01a6eb62 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -272,6 +272,7 @@ template <class T, class Container, class Compare>
 #  include <__ranges/concepts.h>
 #  include <__ranges/container_compatible_range.h>
 #  include <__ranges/from_range.h>
+#  include <__type_traits/is_nothrow_assignable.h>
 #  include <__utility/forward.h>
 #  include <deque>
 #  include <vector>
diff --git a/libcxx/include/stack b/libcxx/include/stack
index 313c305dd8088..84da311dbf89a 100644
--- a/libcxx/include/stack
+++ b/libcxx/include/stack
@@ -126,6 +126,7 @@ template <class T, class Container>
 #  include <__ranges/concepts.h>
 #  include <__ranges/container_compatible_range.h>
 #  include <__ranges/from_range.h>
+#  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_same.h>
 #  include <__utility/forward.h>
 #  include <deque>
diff --git a/libcxx/include/string b/libcxx/include/string
index a297a05813cee..94457f45f4add 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -946,13 +946,9 @@ public:
     __annotate_new(0);
   }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
-#  if _LIBCPP_STD_VER <= 14
-      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
-#  else
-      _NOEXCEPT
-#  endif
-      : __rep_(), __alloc_(__a) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a) _NOEXCEPT
+      : __rep_(),
+        __alloc_(__a) {
     __annotate_new(0);
   }
 
@@ -974,13 +970,9 @@ public:
   }
 
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
-#    if _LIBCPP_STD_VER <= 14
-      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
-#    else
-      _NOEXCEPT
-#    endif
-      : __rep_(std::move(__str.__rep_)), __alloc_(std::move(__str.__alloc_)) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str) _NOEXCEPT
+      : __rep_(std::move(__str.__rep_)),
+        __alloc_(std::move(__str.__alloc_)) {
     __str.__rep_ = __rep();
     __str.__annotate_new(0);
     if (!__is_long())
@@ -1144,7 +1136,7 @@ public:
 
 #  ifndef _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  operator=(basic_string&& __str) noexcept(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
+  operator=(basic_string&& __str) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
     __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
     return *this;
   }
@@ -1449,7 +1441,7 @@ public:
   }
 #  ifndef _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  assign(basic_string&& __str) noexcept(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) {
+  assign(basic_string&& __str) noexcept(__is_allocator_aware_container_move_nothrow_v<allocator_type>) {
     *this = std::move(__str);
     return *this;
   }
@@ -1704,12 +1696,7 @@ public:
   }
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(basic_string& __str)
-#  if _LIBCPP_STD_VER >= 14
-      _NOEXCEPT;
-#  else
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
-#  endif
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(basic_string& __str) _NOEXCEPT;
 
   // [string.ops]
   // ------------
@@ -2422,15 +2409,12 @@ private:
 #    endif
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __str)
-      _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
-                 is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __str) _NOEXCEPT {
     __move_assign_alloc(
         __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
   }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __c, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __c, true_type) _NOEXCEPT {
     __alloc_ = std::move(__c.__alloc_);
   }
 
@@ -3436,13 +3420,8 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n,
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
-#  if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT
-#  else
-    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)
-#  endif
-{
+inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) _NOEXCEPT {
   _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
       __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||
           __alloc_ == __str.__alloc_,
@@ -3786,8 +3765,7 @@ operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs)
-    _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) {
+swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
   __lhs.swap(__rhs);
 }
 
diff --git a/libcxx/test/libcxx/containers/associative/map/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/associative/map/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..6da2fd33fc169
--- /dev/null
+++ b/libcxx/test/libcxx/containers/associative/map/noexcept.compile.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <unordered_map>
+
+#include <type_traits>
+#include <map>
+
+#include "test_allocator.h"
+
+template <class... Args>
+inline constexpr bool is_constructible_but_throws =
+    std::is_constructible<Args...>::value && !std::is_nothrow_constructible<Args...>::value;
+
+namespace std_allocator {
+using map        = std::map<int, int>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map, const std::less<int>&, const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          const std::less<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(
+    is_constructible_but_throws<map, std::from_range_t, map, const std::less<int>&, const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, map&&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+
+using multimap = std::multimap<int, int>;
+
+static_assert(std::is_nothrow_constructible<multimap>::value);
+static_assert(is_constructible_but_throws<multimap, const std::less<int>&, const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<multimap,
+                                          value_type*,
+                                          value_type*,
+                                          const std::less<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<multimap,
+                                          std::from_range_t,
+                                          multimap,
+                                          const std::less<int>&,
+                                          const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<multimap, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<multimap, const multimap&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<multimap, multimap&&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<multimap, multimap&&>::value);
+
+static_assert(std::is_nothrow_assignable<multimap&, multimap&&>::value);
+static_assert(std::is_nothrow_swappable<multimap>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using map        = std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map, const std::less<int>&, const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          const std::less<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(
+    is_constructible_but_throws<map, std::from_range_t, map, const std::less<int>&, const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, map&&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(!std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+
+using multimap = std::multimap<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>;
+
+static_assert(std::is_nothrow_constructible<multimap>::value);
+static_assert(is_constructible_but_throws<multimap, const std::less<int>&, const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<multimap,
+                                          value_type*,
+                                          value_type*,
+                                          const std::less<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<multimap,
+                                          std::from_range_t,
+                                          multimap,
+                                          const std::less<int>&,
+                                          const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<multimap, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<multimap, const multimap&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<multimap, multimap&&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<multimap, multimap&&>::value);
+
+static_assert(!std::is_nothrow_assignable<multimap&, multimap&&>::value);
+static_assert(std::is_nothrow_swappable<multimap>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp b/libcxx/test/libcxx/containers/sequences/deque/deque.cons/move_noexcept.compile.pass.cpp
similarity index 53%
rename from libcxx/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp
rename to libcxx/test/libcxx/containers/sequences/deque/deque.cons/move_noexcept.compile.pass.cpp
index 37e8a801e9d71..d38d1d05db033 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/deque/deque.cons/move_noexcept.compile.pass.cpp
@@ -15,10 +15,9 @@
 
 // UNSUPPORTED: c++03
 
-#include <deque>
 #include <cassert>
+#include <deque>
 
-#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -29,25 +28,7 @@ struct some_alloc {
   void allocate(std::size_t);
 };
 
-int main(int, char**) {
-#if defined(_LIBCPP_VERSION)
-  {
-    typedef std::deque<MoveOnly> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::deque<MoveOnly, test_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::deque<MoveOnly, other_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C;
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
-  }
-#endif // _LIBCPP_VERSION
-
-  return 0;
-}
+static_assert(std::is_nothrow_move_constructible<std::deque<MoveOnly>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::deque<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::deque<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::deque<MoveOnly, some_alloc<MoveOnly>>>::value, "");
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp
similarity index 53%
rename from libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp
rename to libcxx/test/libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp
index 8dcf00b49c78b..5e692a183440f 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp
@@ -15,10 +15,9 @@
 
 // UNSUPPORTED: c++03
 
-#include <forward_list>
 #include <cassert>
+#include <forward_list>
 
-#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -29,25 +28,7 @@ struct some_alloc {
   void allocate(std::size_t);
 };
 
-int main(int, char**) {
-#if defined(_LIBCPP_VERSION)
-  {
-    typedef std::forward_list<MoveOnly> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::forward_list<MoveOnly, test_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::forward_list<MoveOnly, other_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C;
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
-  }
-#endif // _LIBCPP_VERSION
-
-  return 0;
-}
+static_assert(std::is_nothrow_move_constructible<std::forward_list<MoveOnly>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::forward_list<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::forward_list<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::forward_list<MoveOnly, some_alloc<MoveOnly>>>::value, "");
diff --git a/libcxx/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp b/libcxx/test/libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp
similarity index 55%
rename from libcxx/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp
rename to libcxx/test/libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp
index c33ef906be400..23b647693937a 100644
--- a/libcxx/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp
@@ -29,25 +29,7 @@ struct some_alloc {
   void allocate(std::size_t);
 };
 
-int main(int, char**) {
-#if defined(_LIBCPP_VERSION)
-  {
-    typedef std::list<MoveOnly> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::list<MoveOnly, test_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::list<MoveOnly, other_allocator<MoveOnly>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-#endif // _LIBCPP_VERSION
-  {
-    typedef std::list<MoveOnly, some_alloc<MoveOnly>> C;
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
-  }
-
-  return 0;
-}
+static_assert(std::is_nothrow_move_constructible<std::list<MoveOnly>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::list<MoveOnly, test_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::list<MoveOnly, other_allocator<MoveOnly>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::list<MoveOnly, some_alloc<MoveOnly>>>::value, "");
diff --git a/libcxx/test/libcxx/containers/sequences/vector.bool/move_noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector.bool/move_noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..642ce4d966eff
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector.bool/move_noexcept.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// vector(vector&&)
+//        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+
+// This tests a conforming extension
+
+// UNSUPPORTED: c++03
+
+#include <vector>
+#include <cassert>
+
+#include "test_allocator.h"
+
+template <class T>
+struct some_alloc {
+  typedef T value_type;
+  some_alloc(const some_alloc&);
+};
+
+static_assert(std::is_nothrow_move_constructible<std::vector<bool>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::vector<bool, test_allocator<bool>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::vector<bool, other_allocator<bool>>>::value, "");
+static_assert(std::is_nothrow_move_constructible<std::vector<bool, some_alloc<bool>>>::value, "");
diff --git a/libcxx/test/libcxx/containers/sequences/vector.bool/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector.bool/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..a3881e9401f46
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector.bool/noexcept.compile.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <vector>
+
+#include <type_traits>
+#include <vector>
+
+#include "test_allocator.h"
+
+namespace std_allocator {
+using vec = std::vector<bool>;
+
+static_assert(std::is_nothrow_constructible<vec>::value);
+static_assert(std::is_nothrow_constructible<vec, const std::allocator<bool>&>::value);
+static_assert(std::is_nothrow_constructible<vec, vec&&>::value);
+
+static_assert(std::is_nothrow_assignable<vec&, vec&&>::value);
+static_assert(std::is_nothrow_swappable<vec>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using vec = std::vector<bool, test_allocator<bool>>;
+
+static_assert(std::is_nothrow_constructible<vec>::value);
+static_assert(std::is_nothrow_constructible<vec, const test_allocator<bool>&>::value);
+static_assert(std::is_nothrow_constructible<vec, vec&&>::value);
+
+static_assert(!std::is_nothrow_assignable<vec&, vec&&>::value);
+static_assert(std::is_nothrow_swappable<vec>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/libcxx/containers/sequences/vector/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..92734fd995232
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector/noexcept.compile.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <vector>
+
+#include <type_traits>
+#include <vector>
+
+#include "test_allocator.h"
+
+namespace std_allocator {
+using vec = std::vector<int>;
+
+static_assert(std::is_nothrow_constructible<vec>::value);
+static_assert(std::is_nothrow_constructible<vec, const std::allocator<int>&>::value);
+static_assert(std::is_nothrow_constructible<vec, vec&&>::value);
+
+static_assert(std::is_nothrow_assignable<vec&, vec&&>::value);
+static_assert(std::is_nothrow_swappable<vec>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using vec = std::vector<int, test_allocator<int>>;
+
+static_assert(std::is_nothrow_constructible<vec>::value);
+static_assert(std::is_nothrow_constructible<vec, const test_allocator<int>&>::value);
+static_assert(std::is_nothrow_constructible<vec, vec&&>::value);
+
+static_assert(!std::is_nothrow_assignable<vec&, vec&&>::value);
+static_assert(std::is_nothrow_swappable<vec>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/libcxx/containers/unord/unord.map/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..f283f2593f140
--- /dev/null
+++ b/libcxx/test/libcxx/containers/unord/unord.map/noexcept.compile.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <unordered_map>
+
+#include <type_traits>
+#include <unordered_map>
+
+#include "test_allocator.h"
+
+template <class... Args>
+inline constexpr bool is_constructible_but_throws =
+    std::is_constructible<Args...>::value && !std::is_nothrow_constructible<Args...>::value;
+
+namespace std_allocator {
+using map        = std::unordered_map<int, int>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using map = std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(!std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..43f17772de236
--- /dev/null
+++ b/libcxx/test/libcxx/containers/unord/unord.multimap/noexcept.compile.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <unordered_map>
+
+#include <type_traits>
+#include <unordered_map>
+
+#include "test_allocator.h"
+
+template <class... Args>
+inline constexpr bool is_constructible_but_throws =
+    std::is_constructible<Args...>::value && !std::is_nothrow_constructible<Args...>::value;
+
+namespace std_allocator {
+using map        = std::unordered_multimap<int, int>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using map =
+    std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(!std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..38780139ff417
--- /dev/null
+++ b/libcxx/test/libcxx/containers/unord/unord.multiset/noexcept.compile.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <unordered_set>
+
+#include <type_traits>
+#include <unordered_set>
+
+#include "test_allocator.h"
+
+template <class... Args>
+inline constexpr bool is_constructible_but_throws =
+    std::is_constructible<Args...>::value && !std::is_nothrow_constructible<Args...>::value;
+
+namespace std_allocator {
+using map        = std::unordered_multiset<int>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using map        = std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(!std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/libcxx/containers/unord/unord.set/noexcept.compile.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..df0d87f74292b
--- /dev/null
+++ b/libcxx/test/libcxx/containers/unord/unord.set/noexcept.compile.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <unordered_set>
+
+#include <type_traits>
+#include <unordered_set>
+
+#include "test_allocator.h"
+
+template <class... Args>
+inline constexpr bool is_constructible_but_throws =
+    std::is_constructible<Args...>::value && !std::is_nothrow_constructible<Args...>::value;
+
+namespace std_allocator {
+using map        = std::unordered_set<int>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const std::allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const std::allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace std_allocator
+
+namespace test_alloc {
+using map        = std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>;
+using value_type = typename map::value_type;
+
+static_assert(std::is_nothrow_constructible<map>::value);
+static_assert(is_constructible_but_throws<map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          map,
+                                          int,
+                                          const std::hash<int>&,
+                                          const std::equal_to<int>&,
+                                          const test_allocator<value_type>&>);
+#endif
+static_assert(is_constructible_but_throws<map, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, const map&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, int, const std::hash<int>&, const test_allocator<std::pair<const int, int>>&>);
+static_assert(
+    is_constructible_but_throws<map, value_type*, value_type*, int, const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          value_type*,
+                                          value_type*,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#if TEST_STD_VER >= 23
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::from_range_t,
+                                          const map&,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+#endif
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(is_constructible_but_throws<map,
+                                          std::initializer_list<value_type>,
+                                          int,
+                                          const std::hash<int>&,
+                                          const test_allocator<std::pair<const int, int>>&>);
+static_assert(std::is_nothrow_constructible<map, map&&>::value);
+
+static_assert(!std::is_nothrow_assignable<map&, map&&>::value);
+static_assert(std::is_nothrow_swappable<map>::value);
+} // namespace test_alloc
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp
index d281dafbcf72d..5ad42e8734f8c 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp
@@ -29,17 +29,6 @@
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
-template <class T>
-struct ThrowingMoveAllocator {
-  using value_type                                    = T;
-  explicit ThrowingMoveAllocator()                    = default;
-  ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default;
-  ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {}
-  T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
-  void deallocate(T* p, std::ptrdiff_t n) { return std::allocator<T>().deallocate(p, n); }
-  friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default;
-};
-
 struct ThrowingMoveComp {
   ThrowingMoveComp() = default;
   ThrowingMoveComp(const ThrowingMoveComp&) noexcept(true) {}
@@ -73,24 +62,6 @@ int main(int, char**) {
     C c;
     C d = std::move(c);
   }
-#if _LIBCPP_VERSION
-  {
-    // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C = std::flat_map<int, int, std::less<int>, std::deque<int, ThrowingMoveAllocator<int>>, std::vector<int>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
-    C c;
-    C d = std::move(c);
-  }
-  {
-    // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C = std::flat_map<int, int, std::less<int>, std::vector<int>, std::deque<int, ThrowingMoveAllocator<int>>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
-    C c;
-    C d = std::move(c);
-  }
-#endif // _LIBCPP_VERSION
   {
     // Comparator fails to be nothrow-move-constructible
     using C = std::flat_map<int, int, ThrowingMoveComp>;
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp
index e038902e26d52..f5d18ac331378 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp
@@ -29,17 +29,6 @@
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
-template <class T>
-struct ThrowingMoveAllocator {
-  using value_type                                    = T;
-  explicit ThrowingMoveAllocator()                    = default;
-  ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default;
-  ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {}
-  T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
-  void deallocate(T* p, std::ptrdiff_t n) { return std::allocator<T>().deallocate(p, n); }
-  friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default;
-};
-
 struct ThrowingMoveComp {
   ThrowingMoveComp() = default;
   ThrowingMoveComp(const ThrowingMoveComp&) noexcept(true) {}
@@ -73,26 +62,6 @@ int main(int, char**) {
     C c;
     C d = std::move(c);
   }
-#if _LIBCPP_VERSION
-  {
-    // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C =
-        std::flat_multimap<int, int, std::less<int>, std::deque<int, ThrowingMoveAllocator<int>>, std::vector<int>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
-    C c;
-    C d = std::move(c);
-  }
-  {
-    // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C =
-        std::flat_multimap<int, int, std::less<int>, std::vector<int>, std::deque<int, ThrowingMoveAllocator<int>>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
-    C c;
-    C d = std::move(c);
-  }
-#endif // _LIBCPP_VERSION
   {
     // Comparator fails to be nothrow-move-constructible
     using C = std::flat_multimap<int, int, ThrowingMoveComp>;
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
index f9fea737254d3..113a7e36259f5 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
@@ -92,17 +92,6 @@ constexpr bool test() {
   return true;
 }
 
-template <class T>
-struct ThrowingMoveAllocator {
-  using value_type                                    = T;
-  explicit ThrowingMoveAllocator()                    = default;
-  ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default;
-  ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {}
-  T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
-  void deallocate(T* p, std::ptrdiff_t n) { return std::allocator<T>().deallocate(p, n); }
-  friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default;
-};
-
 struct ThrowingMoveComp {
   ThrowingMoveComp() = default;
   ThrowingMoveComp(const ThrowingMoveComp&) noexcept(true) {}
@@ -137,14 +126,6 @@ void test_move_noexcept() {
     C d = std::move(c);
   }
 #if _LIBCPP_VERSION
-  {
-    // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C = std::flat_multiset<int, std::less<int>, std::deque<int, ThrowingMoveAllocator<int>>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
-    C c;
-    C d = std::move(c);
-  }
   {
     // Comparator fails to be nothrow-move-constructible
     using C = std::flat_multiset<int, ThrowingMoveComp>;
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
index 1d7a3589cc109..5d6ab501cc38f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
@@ -83,14 +83,14 @@ constexpr void test() {
 }
 
 template <class T>
-struct ThrowingMoveAllocator {
+struct PotentiallyThrowingMoveAllocator {
   using value_type                                    = T;
-  explicit ThrowingMoveAllocator()                    = default;
-  ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default;
-  constexpr ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {}
+  explicit PotentiallyThrowingMoveAllocator()                    = default;
+  PotentiallyThrowingMoveAllocator(const PotentiallyThrowingMoveAllocator&) = default;
+  constexpr PotentiallyThrowingMoveAllocator(PotentiallyThrowingMoveAllocator&&) noexcept(false) {}
   constexpr T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
   constexpr void deallocate(T* p, std::ptrdiff_t n) { return std::allocator<T>().deallocate(p, n); }
-  friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default;
+  friend bool operator==(PotentiallyThrowingMoveAllocator, PotentiallyThrowingMoveAllocator) = default;
 };
 
 struct ThrowingMoveComp {
@@ -117,9 +117,9 @@ constexpr void test_move_noexcept() {
 #if _LIBCPP_VERSION
   if (!TEST_IS_CONSTANT_EVALUATED) {
     // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
-    using C = std::flat_set<int, std::less<int>, std::deque<int, ThrowingMoveAllocator<int>>>;
-    static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
-    static_assert(!std::is_nothrow_move_constructible_v<C>);
+    using C = std::flat_set<int, std::less<int>, std::deque<int, PotentiallyThrowingMoveAllocator<int>>>;
+    static_assert(std::is_nothrow_move_constructible_v<std::deque<int, PotentiallyThrowingMoveAllocator<int>>>);
+    static_assert(std::is_nothrow_move_constructible_v<C>);
     C c;
     C d = std::move(c);
   }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
index 6347496d67c15..96195bf13da67 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
@@ -69,14 +69,12 @@ int main(int, char**) {
 #endif // _LIBCPP_VERSION
   {
     typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C;
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
     //  In C++14, if POCS is set, swapping the allocator is required not to throw
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
-#else
-    static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
 #endif
   }
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
   {
     typedef std::deque<MoveOnly, some_alloc2<MoveOnly>> C;
     //  if the allocators are always equal, then the swap can be noexcept
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.compile.pass.cpp
index 02b7b471a1ae8..978727f9418bf 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.compile.pass.cpp
@@ -69,14 +69,12 @@ void f() {
 #endif // _LIBCPP_VERSION
   {
     typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C;
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
     //  In C++14, if POCS is set, swapping the allocator is required not to throw
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
-#else
-    static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
 #endif
   }
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
   {
     typedef std::forward_list<MoveOnly, some_alloc2<MoveOnly>> C;
     //  if the allocators are always equal, then the swap can be noexcept
diff --git a/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
index 037c7d07c4cb8..f528b7ebad074 100644
--- a/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
@@ -69,14 +69,12 @@ TEST_CONSTEXPR_CXX26 bool test() {
 #endif // _LIBCPP_VERSION
   {
     typedef std::list<MoveOnly, some_alloc<MoveOnly>> C;
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
     //  In C++14, if POCS is set, swapping the allocator is required not to throw
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
-#else
-    static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
 #endif
   }
-#if TEST_STD_VER >= 14
+#if TEST_STD_VER >= 14 || defined(_LIBCPP_VERSION)
   {
     typedef std::list<MoveOnly, some_alloc2<MoveOnly>> C;
     //  if the allocators are always equal, then the swap can be noexcept
diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
deleted file mode 100644
index 5bdae01f871f9..0000000000000
--- a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
+++ /dev/null
@@ -1,60 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <vector>
-
-// vector(vector&&)
-//        noexcept(is_nothrow_move_constructible<allocator_type>::value);
-
-// This tests a conforming extension
-
-// UNSUPPORTED: c++03
-
-#include <cassert>
-#include <vector>
-#include <type_traits>
-
-#include "test_macros.h"
-#include "test_allocator.h"
-
-template <class T>
-struct some_alloc {
-  typedef T value_type;
-  some_alloc(const some_alloc&);
-};
-
-int main(int, char**) {
-#if defined(_LIBCPP_VERSION)
-  {
-    typedef std::vector<bool> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::vector<bool, test_allocator<bool>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-  {
-    typedef std::vector<bool, other_allocator<bool>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-  }
-#endif // _LIBCPP_VERSION
-  {
-    //  In C++17, move constructors for allocators are not allowed to throw
-#if TEST_STD_VER > 14
-#  if defined(_LIBCPP_VERSION)
-    typedef std::vector<bool, some_alloc<bool>> C;
-    static_assert(std::is_nothrow_move_constructible<C>::value, "");
-#  endif // _LIBCPP_VERSION
-#else
-    typedef std::vector<bool, some_alloc<bool>> C;
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
-#endif
-  }
-
-  return 0;
-}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
index 1683191403709..5c65510a203c0 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
@@ -64,27 +64,16 @@ int main(int, char**) {
     typedef std::vector<bool, other_allocator<bool>> C;
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
   }
-#endif // _LIBCPP_VERSION
   {
-#if TEST_STD_VER >= 14
-#  if defined(_LIBCPP_VERSION)
     //  In C++14, if POCS is set, swapping the allocator is required not to throw
     typedef std::vector<bool, some_alloc<bool>> C;
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
-#  endif // _LIBCPP_VERSION
-#else
-    typedef std::vector<bool, some_alloc<bool>> C;
-    static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
-#endif
   }
-#if TEST_STD_VER >= 14
-#  if defined(_LIBCPP_VERSION)
   {
     typedef std::vector<bool, some_alloc2<bool>> C;
     //  if the allocators are always equal, then the swap can be noexcept
     static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
   }
-#  endif // _LIBCPP_VERSION
 #endif
 
   return 0;
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
index 13dc6d41684fa..21b14a76260cb 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
@@ -44,11 +44,8 @@ int main(int, char**) {
   }
   {
     typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C;
-    //  In C++17, move constructors for allocators are not allowed to throw
-#if TEST_STD_VER > 14
+#if TEST_STD_VER > 14 || defined(_LIBCPP_VERSION)
     static_assert(std::is_nothrow_move_constructible<C>::value, "");
-#else
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
 #endif
   }
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
index d807cac2c72c8..ba7f93e2a52cb 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
@@ -32,9 +32,7 @@ int main(int, char**) {
   }
   {
     typedef std::basic_string<char, std::char_traits<char>, limited_allocator<char, 10>> C;
-#if TEST_STD_VER <= 14
-    static_assert(!std::is_nothrow_move_constructible<C>::value, "");
-#else
+#if TEST_STD_VER >= 17 || defined(_LIBCPP_VERSION)
     static_assert(std::is_nothrow_move_constructible<C>::value, "");
 #endif
   }



More information about the libcxx-commits mailing list