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

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 19 06:51:40 PST 2025


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

>From 11fccc6c14870a5520e22e5983ccc3d87baeabfa 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/__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                         | 42 +++---------
 libcxx/include/__vector/vector.h              | 56 +++-------------
 libcxx/include/__vector/vector_bool.h         | 67 +++++--------------
 libcxx/include/deque                          | 51 ++++----------
 libcxx/include/forward_list                   | 65 +++++-------------
 libcxx/include/list                           | 61 +++++------------
 libcxx/include/queue                          |  1 +
 libcxx/include/stack                          |  1 +
 libcxx/include/string                         | 52 ++++----------
 .../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 +++++++++
 .../flat.map.cons/move_noexcept.pass.cpp      | 29 --------
 .../flat.multimap.cons/move_noexcept.pass.cpp | 31 ---------
 .../flat.multiset.cons/move.pass.cpp          | 21 ------
 .../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 +-
 28 files changed, 194 insertions(+), 651 deletions(-)
 delete mode 100644 libcxx/include/__memory/noexcept_move_assign_container.h
 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
 delete mode 100644 libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp

diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index ef487fb06dd5e..12e73487d71c7 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -518,13 +518,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::move(__x.__size_)), __alloc_(std::move(__x.__alloc_)) {
+  _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x) _NOEXCEPT
+      : __size_(std::move(__x.__size_)),
+        __alloc_(std::move(__x.__alloc_)) {
     __x.size() = 0;
   }
 
@@ -740,17 +740,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>
@@ -944,14 +941,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;
@@ -1011,15 +1001,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());
   }
@@ -1132,8 +1118,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_)),
@@ -1278,8 +1263,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();
@@ -1324,10 +1308,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;
 }
@@ -2060,15 +2042,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 46c247f7040e0..33b2bdb7a95fc 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -374,6 +374,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 1e05e4df8ba0f..e25a4cc997577 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -28,8 +28,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>
@@ -184,8 +182,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_;
@@ -341,8 +338,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_;
@@ -497,15 +493,11 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   __split_buffer(size_type __cap, size_type __start, __alloc_rr& __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 __alloc_rr& __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();
 
@@ -559,8 +551,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<__alloc_rr>);
+  _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) {
@@ -594,8 +585,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());
   }
 
@@ -740,8 +731,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();
 }
@@ -767,10 +757,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);
@@ -780,8 +767,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<__alloc_rr>) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x) _NOEXCEPT {
   __base_type::swap(__x);
 }
 
@@ -852,8 +838,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 ceae22bb48702..871fa88e98883 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -904,15 +904,12 @@ public:
   _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
   template <class _InputIterator>
   _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
-  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
-      is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
+  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(is_nothrow_move_constructible<value_compare>::value);
   _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
 
   _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
-      _NOEXCEPT_(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>());
     return *this;
   }
@@ -933,13 +930,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
 
-  _LIBCPP_HIDE_FROM_ABI 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
+  _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t) _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
 
   template <class... _Args>
   _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
@@ -1281,17 +1272,14 @@ private:
   _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }
 
   _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
-  _LIBCPP_HIDE_FROM_ABI 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 void __move_assign(__tree& __t, true_type)
+      _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value);
 
-  _LIBCPP_HIDE_FROM_ABI 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 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 void __move_assign_alloc(__tree& __t, true_type)
-      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
+  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type) _NOEXCEPT {
     __node_alloc() = std::move(__t.__node_alloc());
   }
   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
@@ -1605,8 +1593,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
 }
 
 template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
-    is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value)
+__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_)),
@@ -1649,7 +1636,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __
 
 template <class _Tp, class _Compare, class _Allocator>
 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(static_cast<__node_pointer>(__end_node()->__left_));
   __begin_node_ = __t.__begin_node_;
   __end_node_   = __t.__end_node_;
@@ -1687,14 +1674,7 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
 }
 
 template <class _Tp, class _Compare, class _Allocator>
-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
-{
+void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) _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 7051e044314ea..1fd44f387ddf6 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -51,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>
@@ -132,14 +131,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
-      : __alloc_(__a) {
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20
+  _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a) _NOEXCEPT : __alloc_(__a) {}
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n) {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
@@ -286,17 +279,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) _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;
   }
@@ -553,12 +540,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;
 
@@ -697,8 +679,7 @@ class vector {
   __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
   _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 {
@@ -771,9 +752,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>());
   }
 
@@ -793,8 +772,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->__alloc_ = std::move(__c.__alloc_);
   }
 
@@ -964,12 +942,7 @@ 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
+_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x) _NOEXCEPT
     : __alloc_(std::move(__x.__alloc_)) {
   this->__begin_ = __x.__begin_;
   this->__end_   = __x.__end_;
@@ -1003,8 +976,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
   this->__begin_ = __c.__begin_;
@@ -1396,13 +1368,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 || this->__alloc_ == __x.__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 6cb8f2a7fb012..59ffa709410b2 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -126,12 +126,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 {
@@ -198,16 +193,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);
@@ -392,12 +382,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);
   }
@@ -512,16 +497,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_);
   }
 
@@ -585,14 +566,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)
@@ -734,12 +713,7 @@ _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_(__v.__begin_),
       __size_(__v.__size_),
       __cap_(__v.__cap_),
@@ -768,7 +742,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;
 }
@@ -782,8 +756,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);
   this->__begin_ = __c.__begin_;
@@ -1034,13 +1007,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 08bf8141eb782..ae4a3137e33e4 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -225,7 +225,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>
@@ -534,9 +533,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 {
@@ -672,12 +668,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
@@ -849,12 +843,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 {
@@ -879,22 +868,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();
@@ -1247,8 +1232,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);
 };
 
@@ -1358,7 +1342,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_)),
@@ -1386,10 +1370,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;
 }
@@ -1404,8 +1386,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);
@@ -2393,13 +2374,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 272e52d68f46a..c892b84a4311e 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>
@@ -498,8 +497,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
@@ -514,9 +512,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>());
   }
 
@@ -546,12 +542,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;
@@ -568,8 +559,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_);
   }
 };
@@ -578,7 +569,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;
 }
@@ -601,13 +592,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_);
@@ -698,8 +683,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);
@@ -708,10 +692,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);
 
@@ -835,15 +817,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);
@@ -882,8 +856,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
 
@@ -1016,8 +989,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_ = __x.__before_begin()->__next_;
@@ -1035,11 +1007,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;
 }
@@ -1556,8 +1525,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 2898a45da0029..51818ac39e0b0 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());
@@ -901,15 +883,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();
@@ -981,8 +955,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);
 };
 
@@ -1111,8 +1084,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);
 }
@@ -1129,10 +1101,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;
 }
@@ -1147,8 +1117,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);
@@ -1748,8 +1717,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 b4b79fb25a35f..2d0a68ec3f639 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 a2f285c1994b9..950c7786efc1f 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 c4806069d0b44..53f2eac5e1ca4 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -984,12 +984,7 @@ 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
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a) _NOEXCEPT
 #  if _LIBCPP_STD_VER >= 20 // TODO(LLVM 23): Remove this condition; this is a workaround for https://llvm.org/PR154567
       : __rep_(__short()),
 #  else
@@ -1019,20 +1014,15 @@ 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
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str) _NOEXCEPT
       // Turning off ASan instrumentation for variable initialization with _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
       // does not work consistently during initialization of __r_, so we instead unpoison __str's memory manually first.
       // __str's memory needs to be unpoisoned only in the case where it's a short string.
       : __rep_([](basic_string& __s) -> decltype(__s.__rep_)&& {
-          if (!__s.__is_long())
-            __s.__annotate_delete();
-          return std::move(__s.__rep_);
-        }(__str)),
+        if (!__s.__is_long())
+          __s.__annotate_delete();
+        return std::move(__s.__rep_);
+      }(__str)),
         __alloc_(std::move(__str.__alloc_)) {
     __str.__rep_ = __rep();
     __str.__annotate_new(0);
@@ -1227,7 +1217,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;
   }
@@ -1531,7 +1521,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;
   }
@@ -1784,12 +1774,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]
   // ------------
@@ -2489,15 +2474,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_);
   }
 
@@ -3491,13 +3473,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_,
@@ -3841,8 +3818,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/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/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 7fb0c0e9c3fd0..9055f727c6ee4 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) {}
@@ -136,16 +125,6 @@ void test_move_noexcept() {
     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_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);
-  }
-#endif // _LIBCPP_VERSION
   {
     // 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 fcc15edc2935b..5ffab4f0cce8b 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