Commit 5d4439cc3e

Andrew Kelley <andrew@ziglang.org>
2023-08-12 02:34:16
libcxx: update to LLVM 17
release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba8 This adds the flag `-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL`. A future enhancement could possibly pass something different if there is a compelling parallel implementation. That libdispatch one might be worth looking into.
1 parent 9ddfacd
Changed files (940)
lib
libcxx
include
__algorithm
pstl_backends
__atomic
__bit
__charconv
__chrono
__compare
__concepts
__condition_variable
__coroutine
__debug_utils
__exception
__expected
__filesystem
__format
__functional
__fwd
__iterator
__locale_dir
__mdspan
__memory
__memory_resource
__mutex
__numeric
__pstl
__random
__ranges
__stop_token
__string
__support
__system_error
__thread
__tuple
__tuple_dir
__type_traits
__utility
__variant
experimental
ext
src
src
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
+
+#include <__algorithm/any_of.h>
+#include <__algorithm/find_if.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__atomic/atomic.h>
+#include <__atomic/memory_order.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/pair.h>
+#include <__utility/terminate_on_exception.h>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Index, class _Brick>
+_LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) {
+  std::atomic<bool> __found(false);
+  __par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) {
+    if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) {
+      __found.store(true, std::memory_order_relaxed);
+      __par_backend::__cancel_execution();
+    }
+  });
+  return __found;
+}
+
+// TODO: check whether __simd_first() can be used here
+template <class _Index, class _DifferenceType, class _Pred>
+_LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept {
+  _DifferenceType __block_size = 4 < __n ? 4 : __n;
+  const _Index __last          = __first + __n;
+  while (__last != __first) {
+    int32_t __flag = 1;
+    _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
+    for (_DifferenceType __i = 0; __i < __block_size; ++__i)
+      if (__pred(*(__first + __i)))
+        __flag = 0;
+    if (!__flag)
+      return true;
+
+    __first += __block_size;
+    if (__last - __first >= __block_size << 1) {
+      // Double the block _Size.  Any unnecessary iterations can be amortized against work done so far.
+      __block_size <<= 1;
+    } else {
+      __block_size = __last - __first;
+    }
+  }
+  return false;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+_LIBCPP_HIDE_FROM_ABI bool
+__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value) {
+    return std::__terminate_on_exception([&] {
+      return std::__parallel_or(
+          __first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+            return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
+          });
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value) {
+    return std::__simd_or(__first, __last - __first, __pred);
+  } else {
+    return std::any_of(__first, __last, __pred);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
+
+#include <__config>
+#include <cstddef>
+
+#if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
+#  include <__algorithm/pstl_backends/cpu_backends/serial.h>
+#elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
+#  include <__algorithm/pstl_backends/cpu_backends/thread.h>
+#elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
+#  include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
+#else
+#  error "Invalid CPU backend choice"
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __cpu_backend_tag {};
+
+inline constexpr size_t __lane_size = 64;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
+
+#include <__algorithm/fill.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Index, class _DifferenceType, class _Tp>
+_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
+  _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+  _PSTL_PRAGMA_SIMD
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __first[__i] = __value;
+  return __first + __n;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+_LIBCPP_HIDE_FROM_ABI void
+__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value) {
+    std::__terminate_on_exception([&] {
+      __par_backend::__parallel_for(
+          __first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+            std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{}, __brick_first, __brick_last, __value);
+          });
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value) {
+    std::__simd_fill_n(__first, __last - __first, __value);
+  } else {
+    std::fill(__first, __last, __value);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
+
+#include <__algorithm/find_if.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__atomic/atomic.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/pair.h>
+#include <__utility/terminate_on_exception.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Index, class _Brick, class _Compare>
+_LIBCPP_HIDE_FROM_ABI _Index
+__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) {
+  typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
+  const _DifferenceType __n      = __last - __first;
+  _DifferenceType __initial_dist = __b_first ? __n : -1;
+  std::atomic<_DifferenceType> __extremum(__initial_dist);
+  // TODO: find out what is better here: parallel_for or parallel_reduce
+  __par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
+    // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
+    // why using a shared variable scales fairly well in this situation.
+    if (__comp(__i - __first, __extremum)) {
+      _Index __res = __f(__i, __j);
+      // If not '__last' returned then we found what we want so put this to extremum
+      if (__res != __j) {
+        const _DifferenceType __k = __res - __first;
+        for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) {
+          __extremum.compare_exchange_weak(__old, __k);
+        }
+      }
+    }
+  });
+  return __extremum != __initial_dist ? __first + __extremum : __last;
+}
+
+template <class _Index, class _DifferenceType, class _Compare>
+_LIBCPP_HIDE_FROM_ABI _Index
+__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept {
+  // Experiments show good block sizes like this
+  const _DifferenceType __block_size                        = 8;
+  alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
+  while (__end - __begin >= __block_size) {
+    _DifferenceType __found = 0;
+    _PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) {
+      const _DifferenceType __t = __comp(__first, __i);
+      __lane[__i - __begin]     = __t;
+      __found |= __t;
+    }
+    if (__found) {
+      _DifferenceType __i;
+      // This will vectorize
+      for (__i = 0; __i < __block_size; ++__i) {
+        if (__lane[__i]) {
+          break;
+        }
+      }
+      return __first + __begin + __i;
+    }
+    __begin += __block_size;
+  }
+
+  // Keep remainder scalar
+  while (__begin != __end) {
+    if (__comp(__first, __begin)) {
+      return __first + __begin;
+    }
+    ++__begin;
+  }
+  return __first + __end;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value) {
+    return std::__terminate_on_exception([&] {
+      return std::__parallel_find(
+          __first,
+          __last,
+          [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+            return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
+          },
+          less<>{},
+          true);
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value) {
+    using __diff_t = __iter_diff_t<_ForwardIterator>;
+    return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
+      return __pred(__iter[__i]);
+    });
+  } else {
+    return std::find_if(__first, __last, __pred);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
+
+#include <__algorithm/for_each.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iterator, class _DifferenceType, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
+  _PSTL_PRAGMA_SIMD
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __f(__first[__i]);
+
+  return __first + __n;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
+_LIBCPP_HIDE_FROM_ABI void
+__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value) {
+    std::__terminate_on_exception([&] {
+      std::__par_backend::__parallel_for(
+          __first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+            std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{}, __brick_first, __brick_last, __func);
+          });
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value) {
+    std::__simd_walk_1(__first, __last - __first, __func);
+  } else {
+    std::for_each(__first, __last, __func);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
+
+#include <__algorithm/lower_bound.h>
+#include <__algorithm/max.h>
+#include <__algorithm/upper_bound.h>
+#include <__atomic/atomic.h>
+#include <__config>
+#include <__exception/terminate.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/move_iterator.h>
+#include <__memory/allocator.h>
+#include <__memory/construct_at.h>
+#include <__memory/unique_ptr.h>
+#include <__numeric/reduce.h>
+#include <__utility/exception_guard.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <__utility/terminate_on_exception.h>
+#include <cstddef>
+#include <new>
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __par_backend {
+inline namespace __libdispatch {
+
+// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
+// we.
+// TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]?
+_LIBCPP_EXPORTED_FROM_ABI void
+__dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __context, size_t __chunk)) noexcept;
+
+template <class _Func>
+_LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept {
+  __libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
+    (*static_cast<_Func*>(__context))(__chunk);
+  });
+}
+
+struct __chunk_partitions {
+  ptrdiff_t __chunk_count_; // includes the first chunk
+  ptrdiff_t __chunk_size_;
+  ptrdiff_t __first_chunk_size_;
+};
+
+[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI __chunk_partitions __partition_chunks(ptrdiff_t __size);
+
+template <class _RandomAccessIterator, class _Functor>
+_LIBCPP_HIDE_FROM_ABI void
+__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
+  auto __partitions = __libdispatch::__partition_chunks(__last - __first);
+
+  // Perform the chunked execution.
+  __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
+    auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
+    auto __index =
+        __chunk == 0
+            ? 0
+            : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
+    __func(__first + __index, __first + __index + __this_chunk_size);
+  });
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
+struct __merge_range {
+  __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
+      : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
+
+  _RandomAccessIterator1 __mid1_;
+  _RandomAccessIterator2 __mid2_;
+  _RandomAccessIteratorOut __result_;
+};
+
+template <typename _RandomAccessIterator1,
+          typename _RandomAccessIterator2,
+          typename _RandomAccessIterator3,
+          typename _Compare,
+          typename _LeafMerge>
+_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp,
+    _LeafMerge __leaf_merge) {
+  __chunk_partitions __partitions =
+      __libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
+
+  if (__partitions.__chunk_count_ == 0)
+    return;
+
+  if (__partitions.__chunk_count_ == 1) {
+    __leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
+    return;
+  }
+
+  using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
+  auto const __n_ranges = __partitions.__chunk_count_ + 1;
+
+  // TODO: use __uninitialized_buffer
+  auto __destroy = [=](__merge_range_t* __ptr) {
+    std::destroy_n(__ptr, __n_ranges);
+    std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
+  };
+  unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
+      std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy);
+
+  // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
+  std::__terminate_on_exception([&] {
+    __merge_range_t* __r = __ranges.get();
+    std::__construct_at(__r++, __first1, __first2, __result);
+
+    bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
+
+    auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
+      auto [__mid1, __mid2] = [&] {
+        if (__iterate_first_range) {
+          auto __m1 = __first1 + __chunk_size;
+          auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
+          return std::make_pair(__m1, __m2);
+        } else {
+          auto __m2 = __first2 + __chunk_size;
+          auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
+          return std::make_pair(__m1, __m2);
+        }
+      }();
+
+      __result += (__mid1 - __first1) + (__mid2 - __first2);
+      __first1 = __mid1;
+      __first2 = __mid2;
+      return {std::move(__mid1), std::move(__mid2), __result};
+    };
+
+    // handle first chunk
+    std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
+
+    // handle 2 -> N - 1 chunks
+    for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
+      std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
+
+    // handle last chunk
+    std::__construct_at(__r, __last1, __last2, __result);
+
+    __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
+      auto __first_iters = __ranges[__index];
+      auto __last_iters  = __ranges[__index + 1];
+      __leaf_merge(
+          __first_iters.__mid1_,
+          __last_iters.__mid1_,
+          __first_iters.__mid2_,
+          __last_iters.__mid2_,
+          __first_iters.__result_,
+          __comp);
+    });
+  });
+}
+
+template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
+_LIBCPP_HIDE_FROM_ABI _Value __parallel_transform_reduce(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Transform __transform,
+    _Value __init,
+    _Combiner __combiner,
+    _Reduction __reduction) {
+  if (__first == __last)
+    return __init;
+
+  auto __partitions = __libdispatch::__partition_chunks(__last - __first);
+
+  auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
+    std::destroy_n(__ptr, __count);
+    std::allocator<_Value>().deallocate(__ptr, __count);
+  };
+
+  // TODO: use __uninitialized_buffer
+  // TODO: allocate one element per worker instead of one element per chunk
+  unique_ptr<_Value[], decltype(__destroy)> __values(
+      std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
+
+  // __dispatch_apply is noexcept
+  __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
+    auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
+    auto __index =
+        __chunk == 0
+            ? 0
+            : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
+    if (__this_chunk_size != 1) {
+      std::__construct_at(
+          __values.get() + __chunk,
+          __reduction(__first + __index + 2,
+                      __first + __index + __this_chunk_size,
+                      __combiner(__transform(__first + __index), __transform(__first + __index + 1))));
+    } else {
+      std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
+    }
+  });
+
+  return std::__terminate_on_exception([&] {
+    return std::reduce(
+        std::make_move_iterator(__values.get()),
+        std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
+        std::move(__init),
+        __combiner);
+  });
+}
+
+// TODO: parallelize this
+template <class _RandomAccessIterator, class _Comp, class _LeafSort>
+_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
+  __leaf_sort(__first, __last, __comp);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
+
+} // namespace __libdispatch
+} // namespace __par_backend
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
+
+#include <__algorithm/merge.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardOutIterator,
+          class _Comp>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge(
+    __cpu_backend_tag,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardOutIterator __result,
+    _Comp __comp) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator1>::value &&
+                __has_random_access_iterator_category<_ForwardIterator2>::value &&
+                __has_random_access_iterator_category<_ForwardOutIterator>::value) {
+    return std::__terminate_on_exception([&] {
+      __par_backend::__parallel_merge(
+          __first1,
+          __last1,
+          __first2,
+          __last2,
+          __result,
+          __comp,
+          [](_ForwardIterator1 __g_first1,
+             _ForwardIterator1 __g_last1,
+             _ForwardIterator2 __g_first2,
+             _ForwardIterator2 __g_last2,
+             _ForwardOutIterator __g_result,
+             _Comp __g_comp) {
+            return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{},
+                std::move(__g_first1),
+                std::move(__g_last1),
+                std::move(__g_first2),
+                std::move(__g_last2),
+                std::move(__g_result),
+                std::move(__g_comp));
+          });
+      return __result + (__last1 - __first1) + (__last2 - __first2);
+    });
+  } else {
+    return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
+
+#include <__config>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __par_backend {
+inline namespace __serial_cpu_backend {
+
+template <class _RandomAccessIterator, class _Fp>
+_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
+  __f(__first, __last);
+}
+
+template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
+  return __reduce(std::move(__first), std::move(__last), std::move(__init));
+}
+
+template <class _RandomAccessIterator, class _Compare, class _LeafSort>
+_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
+  __leaf_sort(__first, __last, __comp);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
+
+template <class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Compare,
+          class _LeafMerge>
+_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __outit,
+    _Compare __comp,
+    _LeafMerge __leaf_merge) {
+  __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
+}
+
+// TODO: Complete this list
+
+} // namespace __serial_cpu_backend
+} // namespace __par_backend
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
+
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__algorithm/stable_sort.h>
+#include <__config>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
+_LIBCPP_HIDE_FROM_ABI void
+__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
+    std::__terminate_on_exception([&] {
+      __par_backend::__parallel_stable_sort(
+          __first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
+            std::stable_sort(__g_first, __g_last, __g_comp);
+          });
+    });
+  } else {
+    std::stable_sort(__first, __last, __comp);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
+
+#include <__assert>
+#include <__config>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
+// by a proper implementation once the PSTL implementation is somewhat stable.
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __par_backend {
+inline namespace __thread_cpu_backend {
+
+template <class _RandomAccessIterator, class _Fp>
+_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
+  __f(__first, __last);
+}
+
+template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
+  return __reduce(std::move(__first), std::move(__last), std::move(__init));
+}
+
+template <class _RandomAccessIterator, class _Compare, class _LeafSort>
+_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
+  __leaf_sort(__first, __last, __comp);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
+
+template <class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Compare,
+          class _LeafMerge>
+_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __outit,
+    _Compare __comp,
+    _LeafMerge __leaf_merge) {
+  __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
+}
+
+} // namespace __thread_cpu_backend
+} // namespace __par_backend
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
+
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__algorithm/transform.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator2
+__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
+  _PSTL_PRAGMA_SIMD
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __f(__first1[__i], __first2[__i]);
+  return __first2 + __n;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
+    __cpu_backend_tag,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _ForwardOutIterator __result,
+    _UnaryOperation __op) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value &&
+                __has_random_access_iterator_category<_ForwardOutIterator>::value) {
+    std::__terminate_on_exception([&] {
+      std::__par_backend::__parallel_for(
+          __first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+            return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
+          });
+    });
+    return __result + (__last - __first);
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value &&
+                       __has_random_access_iterator_category<_ForwardOutIterator>::value) {
+    return std::__simd_walk_2(
+        __first,
+        __last - __first,
+        __result,
+        [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
+          __out_value = __op(__in_value);
+        });
+  } else {
+    return std::transform(__first, __last, __result, __op);
+  }
+}
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3(
+    _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
+  _PSTL_PRAGMA_SIMD
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __f(__first1[__i], __first2[__i], __first3[__i]);
+  return __first3 + __n;
+}
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardOutIterator,
+          class _BinaryOperation,
+          enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
+    __cpu_backend_tag,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardOutIterator __result,
+    _BinaryOperation __op) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator1>::value &&
+                __has_random_access_iterator_category<_ForwardIterator2>::value &&
+                __has_random_access_iterator_category<_ForwardOutIterator>::value) {
+    std::__terminate_on_exception([&] {
+      std::__par_backend::__parallel_for(
+          __first1,
+          __last1,
+          [__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
+            return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{},
+                __brick_first,
+                __brick_last,
+                __first2 + (__brick_first - __first1),
+                __result + (__brick_first - __first1),
+                __op);
+          });
+    });
+    return __result + (__last1 - __first1);
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator1>::value &&
+                       __has_random_access_iterator_category<_ForwardIterator2>::value &&
+                       __has_random_access_iterator_category<_ForwardOutIterator>::value) {
+    return std::__simd_walk_3(
+        __first1,
+        __last1 - __first1,
+        __first2,
+        __result,
+        [&](__iter_reference<_ForwardIterator1> __in1,
+            __iter_reference<_ForwardIterator2> __in2,
+            __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
+  } else {
+    return std::transform(__first1, __last1, __first2, __result, __op);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -0,0 +1,194 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
+
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__numeric/transform_reduce.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/operation_traits.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <
+    typename _DifferenceType,
+    typename _Tp,
+    typename _BinaryOperation,
+    typename _UnaryOperation,
+    __enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
+  _PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __init += __f(__i);
+  return __init;
+}
+
+template <
+    typename _Size,
+    typename _Tp,
+    typename _BinaryOperation,
+    typename _UnaryOperation,
+    __enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
+  const _Size __block_size = __lane_size / sizeof(_Tp);
+  if (__n > 2 * __block_size && __block_size > 1) {
+    alignas(__lane_size) char __lane_buffer[__lane_size];
+    _Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
+
+    // initializer
+    _PSTL_PRAGMA_SIMD
+    for (_Size __i = 0; __i < __block_size; ++__i) {
+      ::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
+    }
+    // main loop
+    _Size __i                    = 2 * __block_size;
+    const _Size __last_iteration = __block_size * (__n / __block_size);
+    for (; __i < __last_iteration; __i += __block_size) {
+      _PSTL_PRAGMA_SIMD
+      for (_Size __j = 0; __j < __block_size; ++__j) {
+        __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
+      }
+    }
+    // remainder
+    _PSTL_PRAGMA_SIMD
+    for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
+      __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
+    }
+    // combiner
+    for (_Size __j = 0; __j < __block_size; ++__j) {
+      __init = __binary_op(std::move(__init), std::move(__lane[__j]));
+    }
+    // destroyer
+    _PSTL_PRAGMA_SIMD
+    for (_Size __j = 0; __j < __block_size; ++__j) {
+      __lane[__j].~_Tp();
+    }
+  } else {
+    for (_Size __i = 0; __i < __n; ++__i) {
+      __init = __binary_op(std::move(__init), __f(__i));
+    }
+  }
+  return __init;
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _Tp,
+          class _BinaryOperation1,
+          class _BinaryOperation2>
+_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
+    __cpu_backend_tag,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _Tp __init,
+    _BinaryOperation1 __reduce,
+    _BinaryOperation2 __transform) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator1>::value &&
+                __has_random_access_iterator_category<_ForwardIterator2>::value) {
+    return std::__terminate_on_exception([&] {
+      return __par_backend::__parallel_transform_reduce(
+          __first1,
+          std::move(__last1),
+          [__first1, __first2, __transform](_ForwardIterator1 __iter) {
+            return __transform(*__iter, *(__first2 + (__iter - __first1)));
+          },
+          std::move(__init),
+          std::move(__reduce),
+          [__first1, __first2, __reduce, __transform](
+              _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
+            return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{},
+                __brick_first,
+                std::move(__brick_last),
+                __first2 + (__brick_first - __first1),
+                std::move(__brick_init),
+                std::move(__reduce),
+                std::move(__transform));
+          });
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator1>::value &&
+                       __has_random_access_iterator_category<_ForwardIterator2>::value) {
+    return std::__simd_transform_reduce(
+        __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
+          return __transform(__first1[__i], __first2[__i]);
+        });
+  } else {
+    return std::transform_reduce(
+        std::move(__first1),
+        std::move(__last1),
+        std::move(__first2),
+        std::move(__init),
+        std::move(__reduce),
+        std::move(__transform));
+  }
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
+    __cpu_backend_tag,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Tp __init,
+    _BinaryOperation __reduce,
+    _UnaryOperation __transform) {
+  if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
+                __has_random_access_iterator_category<_ForwardIterator>::value) {
+    return std::__terminate_on_exception([&] {
+      return __par_backend::__parallel_transform_reduce(
+          std::move(__first),
+          std::move(__last),
+          [__transform](_ForwardIterator __iter) { return __transform(*__iter); },
+          std::move(__init),
+          __reduce,
+          [__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
+            return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
+                __cpu_backend_tag{},
+                std::move(__brick_first),
+                std::move(__brick_last),
+                std::move(__brick_init),
+                std::move(__reduce),
+                std::move(__transform));
+          });
+    });
+  } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
+                       __has_random_access_iterator_category<_ForwardIterator>::value) {
+    return std::__simd_transform_reduce(
+        __last - __first,
+        std::move(__init),
+        std::move(__reduce),
+        [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
+  } else {
+    return std::transform_reduce(
+        std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
+
+#include <__config>
+
+/*
+
+  // _Functor takes a subrange for [__first, __last) that should be executed in serial
+  template <class _RandomAccessIterator, class _Functor>
+  void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
+
+  template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
+  _Tp __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
+
+  // Cancel the execution of other jobs - they aren't needed anymore
+  void __cancel_execution();
+
+  template <class _RandomAccessIterator1,
+            class _RandomAccessIterator2,
+            class _RandomAccessIterator3,
+            class _Compare,
+            class _LeafMerge>
+  void __parallel_merge(
+      _RandomAccessIterator1 __first1,
+      _RandomAccessIterator1 __last1,
+      _RandomAccessIterator2 __first2,
+      _RandomAccessIterator2 __last2,
+      _RandomAccessIterator3 __outit,
+      _Compare __comp,
+      _LeafMerge __leaf_merge);
+
+  template <class _RandomAccessIterator, class _Comp, class _LeafSort>
+  void __parallel_stable_sort(_RandomAccessIterator __first,
+                              _RandomAccessIterator __last,
+                              _Comp __comp,
+                              _LeafSort __leaf_sort);
+
+  TODO: Document the parallel backend
+*/
+
+#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
+#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__algorithm/pstl_backends/cpu_backends/fill.h>
+#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
+#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
+#include <__algorithm/pstl_backends/cpu_backends/merge.h>
+#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
+#include <__algorithm/pstl_backends/cpu_backends/transform.h>
+#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
lib/libcxx/include/__algorithm/adjacent_find.h
@@ -20,6 +20,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter, class _Sent, class _BinaryPredicate>
@@ -50,4 +53,6 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
lib/libcxx/include/__algorithm/all_of.h
@@ -19,7 +19,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator, class _Predicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
   for (; __first != __last; ++__first)
     if (!__pred(*__first))
lib/libcxx/include/__algorithm/binary_search.h
@@ -37,8 +37,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool
 binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
 {
-    return std::binary_search(__first, __last, __value,
-                              __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+    return std::binary_search(__first, __last, __value, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/clamp.h
@@ -19,14 +19,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Tp, class _Compare>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY constexpr
 const _Tp&
 clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
 {
-    _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
     return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
 
 }
@@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
 const _Tp&
 clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
 {
-    return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
+    return _VSTD::clamp(__v, __lo, __hi, __less<>());
 }
 #endif
 
lib/libcxx/include/__algorithm/comp.h
@@ -10,6 +10,8 @@
 #define _LIBCPP___ALGORITHM_COMP_H
 
 #include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/predicate_traits.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,41 +26,20 @@ struct __equal_to {
   }
 };
 
-template <class _T1, class _T2 = _T1>
-struct __less
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+template <class _Lhs, class _Rhs>
+struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
+// The definition is required because __less is part of the ABI, but it's empty
+// because all comparisons should be transparent.
+template <class _T1 = void, class _T2 = _T1>
+struct __less {};
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<const _T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, const _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+template <>
+struct __less<void, void> {
+  template <class _Tp, class _Up>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
+    return __lhs < __rhs;
+  }
 };
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/comp_ref_type.h
@@ -9,8 +9,8 @@
 #ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
 #define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
 
+#include <__assert>
 #include <__config>
-#include <__debug>
 #include <__utility/declval.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -23,11 +23,10 @@ template <class _Compare>
 struct __debug_less
 {
     _Compare &__comp_;
-    _LIBCPP_CONSTEXPR_SINCE_CXX14
-    __debug_less(_Compare& __c) : __comp_(__c) {}
+    _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
 
     template <class _Tp, class _Up>
-    _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
     bool operator()(const _Tp& __x,  const _Up& __y)
     {
         bool __r = __comp_(__x, __y);
@@ -37,7 +36,7 @@ struct __debug_less
     }
 
     template <class _Tp, class _Up>
-    _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
     bool operator()(_Tp& __x,  _Up& __y)
     {
         bool __r = __comp_(__x, __y);
@@ -52,7 +51,7 @@ struct __debug_less
     decltype((void)std::declval<_Compare&>()(
         std::declval<_LHS &>(), std::declval<_RHS &>()))
     __do_compare_assert(int, _LHS & __l, _RHS & __r) {
-        _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r),
+        _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r),
             "Comparator does not induce a strict weak ordering");
         (void)__l;
         (void)__r;
@@ -66,7 +65,7 @@ struct __debug_less
 
 // Pass the comparator by lvalue reference. Or in debug mode, using a
 // debugging wrapper that stores a reference.
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_ENABLE_DEBUG_MODE
 template <class _Comp>
 using __comp_ref_type = __debug_less<_Comp>;
 #else
lib/libcxx/include/__algorithm/copy.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___ALGORITHM_COPY_H
 
 #include <__algorithm/copy_move_common.h>
+#include <__algorithm/for_each_segment.h>
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/min.h>
 #include <__config>
@@ -44,36 +45,34 @@ struct __copy_loop {
     return std::make_pair(std::move(__first), std::move(__result));
   }
 
-  template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+  template <class _InIter, class _OutIter>
+  struct _CopySegment {
     using _Traits = __segmented_iterator_traits<_InIter>;
-    auto __sfirst = _Traits::__segment(__first);
-    auto __slast  = _Traits::__segment(__last);
-    if (__sfirst == __slast) {
-      auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
-      return std::make_pair(__last, std::move(__iters.second));
-    }
 
-    __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
-    ++__sfirst;
-    while (__sfirst != __slast) {
-      __result =
-          std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
-      ++__sfirst;
+    _OutIter& __result_;
+
+    _LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {}
+
+    _LIBCPP_HIDE_FROM_ABI void
+    operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
+      __result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
     }
-    __result =
-        std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+  };
+
+  template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+    std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
     return std::make_pair(__last, std::move(__result));
   }
 
   template <class _InIter,
             class _OutIter,
-            __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+            __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
                           int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) {
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits = __segmented_iterator_traits<_OutIter>;
     using _DiffT  = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
 
@@ -98,8 +97,7 @@ struct __copy_loop {
 
 struct __copy_trivial {
   // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
-  template <class _In, class _Out,
-            __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
+  template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
   operator()(_In* __first, _In* __last, _Out* __result) const {
     return std::__copy_trivial_impl(__first, __last, __result);
lib/libcxx/include/__algorithm/copy_backward.h
@@ -76,11 +76,11 @@ struct __copy_backward_loop {
 
   template <class _InIter,
             class _OutIter,
-            __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+            __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
                           int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) {
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits           = __segmented_iterator_traits<_OutIter>;
     auto __orig_last        = __last;
     auto __segment_iterator = _Traits::__segment(__result);
lib/libcxx/include/__algorithm/copy_move_common.h
@@ -15,6 +15,7 @@
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__memory/pointer_traits.h>
+#include <__string/constexpr_c_functions.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_always_bitcastable.h>
 #include <__type_traits/is_constant_evaluated.h>
@@ -61,7 +62,8 @@ template <class _In, class _Out>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
 __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
   const size_t __n = static_cast<size_t>(__last - __first);
-  ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
+
+  std::__constexpr_memmove(__result, __first, __element_count(__n));
 
   return std::make_pair(__last, __result + __n);
 }
@@ -72,7 +74,7 @@ __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
   const size_t __n = static_cast<size_t>(__last - __first);
   __result -= __n;
 
-  ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
+  std::__constexpr_memmove(__result, __first, __element_count(__n));
 
   return std::make_pair(__last, __result);
 }
@@ -119,16 +121,6 @@ __unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
   return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
 }
 
-template <class _IterOps, class _InValue, class _OutIter, class = void>
-struct __can_copy_without_conversion : false_type {};
-
-template <class _IterOps, class _InValue, class _OutIter>
-struct __can_copy_without_conversion<
-    _IterOps,
-    _InValue,
-    _OutIter,
-    __enable_if_t<is_same<_InValue, typename _IterOps::template __value_type<_OutIter> >::value> > : true_type {};
-
 template <class _AlgPolicy,
           class _NaiveAlgorithm,
           class _OptimizedAlgorithm,
@@ -137,23 +129,6 @@ template <class _AlgPolicy,
           class _OutIter>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
 __dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) {
-#ifdef _LIBCPP_COMPILER_GCC
-  // GCC doesn't support `__builtin_memmove` during constant evaluation.
-  if (__libcpp_is_constant_evaluated()) {
-    return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
-  }
-#else
-  // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is
-  // insufficient). Also, conversions are not supported.
-  if (__libcpp_is_constant_evaluated()) {
-    using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>;
-    if (!is_trivially_copyable<_InValue>::value ||
-        !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) {
-      return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
-    }
-  }
-#endif // _LIBCPP_COMPILER_GCC
-
   using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
   return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first));
 }
lib/libcxx/include/__algorithm/copy_n.h
@@ -12,8 +12,8 @@
 #include <__algorithm/copy.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
 #include <__utility/convert_to_integral.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -25,8 +25,8 @@ template<class _InputIterator, class _Size, class _OutputIterator>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
-    __is_cpp17_input_iterator<_InputIterator>::value &&
-   !__is_cpp17_random_access_iterator<_InputIterator>::value,
+    __has_input_iterator_category<_InputIterator>::value &&
+   !__has_random_access_iterator_category<_InputIterator>::value,
     _OutputIterator
 >::type
 copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
@@ -51,7 +51,7 @@ template<class _InputIterator, class _Size, class _OutputIterator>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
-    __is_cpp17_random_access_iterator<_InputIterator>::value,
+    __has_random_access_iterator_category<_InputIterator>::value,
     _OutputIterator
 >::type
 copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
lib/libcxx/include/__algorithm/equal.h
@@ -11,9 +11,20 @@
 #define _LIBCPP___ALGORITHM_EQUAL_H
 
 #include <__algorithm/comp.h>
+#include <__algorithm/unwrap_iter.h>
 #include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
+#include <__string/constexpr_c_functions.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_volatile.h>
+#include <__type_traits/predicate_traits.h>
+#include <__utility/move.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,23 +33,42 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
+    _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
   for (; __first1 != __last1; ++__first1, (void)++__first2)
     if (!__pred(*__first1, *__first2))
       return false;
   return true;
 }
 
+template <
+    class _Tp,
+    class _Up,
+    class _BinaryPredicate,
+    __enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
+                      !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+                  int> = 0>
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
+  return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
+}
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
+  return std::__equal_iter_impl(
+      std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
+}
+
 template <class _InputIterator1, class _InputIterator2>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
   return std::equal(__first1, __last1, __first2, __equal_to());
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
         _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
   for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
@@ -47,19 +77,52 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir
   return __first1 == __last1 && __first2 == __last2;
 }
 
+template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
+    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+  while (__first1 != __last1 && __first2 != __last2) {
+    if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
+      return false;
+    ++__first1;
+    ++__first2;
+  }
+  return __first1 == __last1 && __first2 == __last2;
+}
+
+template <class _Tp,
+          class _Up,
+          class _Pred,
+          class _Proj1,
+          class _Proj2,
+          __enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
+                            __is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
+                            __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+                        int> = 0>
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
+    _Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
+  return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
+}
+
 template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
         _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
         random_access_iterator_tag) {
   if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
     return false;
-  return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
-                      _BinaryPredicate&>(__first1, __last1, __first2, __pred);
+  __identity __proj;
+  return std::__equal_impl(
+      std::__unwrap_iter(__first1),
+      std::__unwrap_iter(__last1),
+      std::__unwrap_iter(__first2),
+      std::__unwrap_iter(__last2),
+      __pred,
+      __proj,
+      __proj);
 }
 
 template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
       _BinaryPredicate __pred) {
   return _VSTD::__equal<_BinaryPredicate&>(
@@ -68,7 +131,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
 }
 
 template <class _InputIterator1, class _InputIterator2>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
   return std::__equal(
       __first1,
lib/libcxx/include/__algorithm/equal_range.h
@@ -50,7 +50,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
     } else {
       _Iter __mp1 = __mid;
       return pair<_Iter, _Iter>(
-          std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
+          std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
           std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
     }
   }
@@ -75,11 +75,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
 template <class _ForwardIterator, class _Tp>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
 equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
-  return std::equal_range(
-      std::move(__first),
-      std::move(__last),
-      __value,
-      __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+  return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/fill.h
@@ -12,7 +12,6 @@
 #include <__algorithm/fill_n.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/fill_n.h
@@ -12,7 +12,6 @@
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__utility/convert_to_integral.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/find.h
@@ -10,7 +10,16 @@
 #ifndef _LIBCPP___ALGORITHM_FIND_H
 #define _LIBCPP___ALGORITHM_FIND_H
 
+#include <__algorithm/unwrap_iter.h>
 #include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__string/constexpr_c_functions.h>
+#include <__type_traits/is_same.h>
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  include <cwchar>
+#endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -18,15 +27,51 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _InputIterator, class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
-find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
+template <class _Iter, class _Sent, class _Tp, class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
+__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
   for (; __first != __last; ++__first)
-    if (*__first == __value)
+    if (std::__invoke(__proj, *__first) == __value)
       break;
   return __first;
 }
 
+template <class _Tp,
+          class _Up,
+          class _Proj,
+          __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
+                            sizeof(_Tp) == 1,
+                        int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
+__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
+  if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
+    return __ret;
+  return __last;
+}
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class _Tp,
+          class _Up,
+          class _Proj,
+          __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
+                            sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
+                        int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
+__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
+  if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
+    return __ret;
+  return __last;
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+template <class _InputIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
+find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
+  __identity __proj;
+  return std::__rewrap_iter(
+      __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
+}
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___ALGORITHM_FIND_H
lib/libcxx/include/__algorithm/find_end.h
@@ -15,12 +15,12 @@
 #include <__algorithm/search.h>
 #include <__config>
 #include <__functional/identity.h>
+#include <__functional/invoke.h>
 #include <__iterator/advance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
 #include <__iterator/reverse_iterator.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/for_each_n.h
@@ -12,7 +12,6 @@
 
 #include <__config>
 #include <__utility/convert_to_integral.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -20,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _InputIterator, class _Size, class _Function>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first,
lib/libcxx/include/__algorithm/for_each_segment.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_FOR_EACH_SEGMENT_H
+#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
+
+#include <__config>
+#include <__iterator/segmented_iterator.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
+// __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
+// Anything that is returned from __func is ignored.
+
+template <class _SegmentedIterator, class _Functor>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
+__for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
+  using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
+
+  auto __sfirst = _Traits::__segment(__first);
+  auto __slast  = _Traits::__segment(__last);
+
+  // We are in a single segment, so we might not be at the beginning or end
+  if (__sfirst == __slast) {
+    __func(_Traits::__local(__first), _Traits::__local(__last));
+    return;
+  }
+
+  // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
+  __func(_Traits::__local(__first), _Traits::__end(__sfirst));
+  ++__sfirst;
+  // iterate over the segments which are guaranteed to be completely in the range
+  while (__sfirst != __slast) {
+    __func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
+    ++__sfirst;
+  }
+  // iterate over the last segment
+  __func(_Traits::__begin(__sfirst), _Traits::__local(__last));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
lib/libcxx/include/__algorithm/generate_n.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__utility/convert_to_integral.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/half_positive.h
@@ -10,7 +10,9 @@
 #define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
 
 #include <__config>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/make_unsigned.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/in_found_result.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -44,6 +44,6 @@ struct in_found_result {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
lib/libcxx/include/__algorithm/in_fun_result.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 template <class _InIter1, class _Func1>
@@ -42,7 +42,7 @@ struct in_fun_result {
 };
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/in_in_out_result.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -49,7 +49,7 @@ struct in_in_out_result {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/in_in_result.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -46,7 +46,7 @@ struct in_in_result {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/in_out_out_result.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 template <class _InIter1, class _OutIter1, class _OutIter2>
@@ -47,7 +47,7 @@ struct in_out_out_result {
 };
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/in_out_result.h
@@ -18,9 +18,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -46,8 +49,10 @@ struct in_out_result {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
lib/libcxx/include/__algorithm/includes.h
@@ -61,13 +61,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 template <class _InputIterator1, class _InputIterator2>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
 includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
-  return std::includes(
-      std::move(__first1),
-      std::move(__last1),
-      std::move(__first2),
-      std::move(__last2),
-      __less<typename iterator_traits<_InputIterator1>::value_type,
-             typename iterator_traits<_InputIterator2>::value_type>());
+  return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/inplace_merge.h
@@ -246,8 +246,7 @@ inline _LIBCPP_HIDE_FROM_ABI
 void
 inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
 {
-    std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last),
-                        __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+    std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_heap.h
@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool
 is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
 {
-    return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+    return _VSTD::is_heap(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_heap_until.h
@@ -58,7 +58,7 @@ template<class _RandomAccessIterator>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
 is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
 {
-    return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+    return _VSTD::__is_heap_until(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_permutation.h
@@ -19,19 +19,22 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
+#include <__type_traits/is_callable.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
 struct _ConstTimeDistance : false_type {};
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
 struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t<
@@ -47,7 +50,7 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t<
     is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value
 > > : true_type {};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 // Internal functions
 
@@ -202,7 +205,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
   return std::is_permutation(__first1, __last1, __first2, __equal_to());
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 // 2+2 iterators
 template <class _ForwardIterator1, class _ForwardIterator2>
@@ -231,8 +234,10 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
       __pred, __identity(), __identity());
 }
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
lib/libcxx/include/__algorithm/is_sorted.h
@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool
 is_sorted(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return _VSTD::is_sorted(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_sorted_until.h
@@ -48,7 +48,7 @@ template<class _ForwardIterator>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
 is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return _VSTD::is_sorted_until(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/iterator_operations.h
@@ -33,11 +33,14 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy> struct _IterOps;
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 struct _RangeAlgPolicy {};
 
 template <>
@@ -172,4 +175,6 @@ struct _IterOps<_ClassicAlgPolicy> {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
lib/libcxx/include/__algorithm/lexicographical_compare.h
@@ -52,9 +52,7 @@ bool
 lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
                         _InputIterator2 __first2, _InputIterator2 __last2)
 {
-    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
-                                         __less<typename iterator_traits<_InputIterator1>::value_type,
-                                                typename iterator_traits<_InputIterator2>::value_type>());
+    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/lexicographical_compare_three_way.h
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
+#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
+
+#include <__algorithm/min.h>
+#include <__algorithm/three_way_comp_ref_type.h>
+#include <__compare/compare_three_way.h>
+#include <__compare/ordering.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// Fast path for random access iterators which computes the number of loop iterations up-front and
+// then skips the iterator comparisons inside the loop.
+template <class _InputIterator1, class _InputIterator2, class _Cmp>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
+    _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
+    -> decltype(__comp(*__first1, *__first2)) {
+  static_assert(
+      signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
+  static_assert(
+      signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
+
+  using _Len1   = __iter_diff_t<_InputIterator1>;
+  using _Len2   = __iter_diff_t<_InputIterator2>;
+  using _Common = common_type_t<_Len1, _Len2>;
+
+  _Len1 __len1      = __last1 - __first1;
+  _Len2 __len2      = __last2 - __first2;
+  _Common __min_len = std::min<_Common>(__len1, __len2);
+
+  for (_Common __i = 0; __i < __min_len; ++__i) {
+    auto __c = __comp(*__first1, *__first2);
+    if (__c != 0) {
+      return __c;
+    }
+    ++__first1;
+    ++__first2;
+  }
+
+  return __len1 <=> __len2;
+}
+
+// Unoptimized implementation which compares the iterators against the end in every loop iteration
+template <class _InputIterator1, class _InputIterator2, class _Cmp>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path(
+    _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
+    -> decltype(__comp(*__first1, *__first2)) {
+  while (true) {
+    bool __exhausted1 = __first1 == __last1;
+    bool __exhausted2 = __first2 == __last2;
+
+    if (__exhausted1 || __exhausted2) {
+      if (!__exhausted1)
+        return strong_ordering::greater;
+      if (!__exhausted2)
+        return strong_ordering::less;
+      return strong_ordering::equal;
+    }
+
+    auto __c = __comp(*__first1, *__first2);
+    if (__c != 0) {
+      return __c;
+    }
+
+    ++__first1;
+    ++__first2;
+  }
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Cmp>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
+    _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp)
+    -> decltype(__comp(*__first1, *__first2)) {
+  static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>,
+                "The comparator passed to lexicographical_compare_three_way must return a comparison category type.");
+  static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible.");
+  static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible.");
+  __three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp);
+  if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
+                __has_random_access_iterator_category<_InputIterator2>::value) {
+    return std::__lexicographical_compare_three_way_fast_path(
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
+  } else {
+    // Unoptimized implementation which compares the iterators against the end in every loop iteration
+    return std::__lexicographical_compare_three_way_slow_path(
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
+  }
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
+    _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
+  return std::lexicographical_compare_three_way(
+      std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way());
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
lib/libcxx/include/__algorithm/lower_bound.h
@@ -20,7 +20,6 @@
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_callable.h>
 #include <__type_traits/remove_reference.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -30,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
+_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
   auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
 
   while (__len != 0) {
@@ -53,14 +52,13 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
   static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
                 "The comparator has to be callable");
   auto __proj = std::__identity();
-  return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
+  return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
 }
 
 template <class _ForwardIterator, class _Tp>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
-  return std::lower_bound(__first, __last, __value,
-                          __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+  return std::lower_bound(__first, __last, __value, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/make_heap.h
@@ -21,6 +21,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
@@ -47,10 +50,11 @@ void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::make_heap(std::move(__first), std::move(__last),
-      __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::make_heap(std::move(__first), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
lib/libcxx/include/__algorithm/make_projected.h
@@ -32,13 +32,14 @@ struct _ProjectedPred {
   _Pred& __pred; // Can be a unary or a binary predicate.
   _Proj& __proj;
 
-  _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {}
+  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
+      : __pred(__pred_arg), __proj(__proj_arg) {}
 
   template <class _Tp>
   typename __invoke_of<_Pred&,
                        decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
   >::type
-  _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const {
+  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const {
     return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
   }
 
@@ -47,7 +48,7 @@ struct _ProjectedPred {
                        decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
                        decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
   >::type
-  _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const {
+  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const {
     return std::__invoke(__pred,
                       std::__invoke(__proj, std::forward<_T1>(__lhs)),
                       std::__invoke(__proj, std::forward<_T2>(__rhs)));
@@ -55,25 +56,12 @@ struct _ProjectedPred {
 
 };
 
-template <class _Pred, class _Proj, class = void>
-struct __can_use_pristine_comp : false_type {};
-
-template <class _Pred, class _Proj>
-struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t<
-    !is_member_pointer<typename decay<_Pred>::type>::value && (
-#if _LIBCPP_STD_VER > 17
-      is_same<typename decay<_Proj>::type, identity>::value ||
-#endif
-      is_same<typename decay<_Proj>::type, __identity>::value
-    )
-> > : true_type {};
-
-template <class _Pred, class _Proj>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
-__enable_if_t<
-    !__can_use_pristine_comp<_Pred, _Proj>::value,
-    _ProjectedPred<_Pred, _Proj>
->
+template <class _Pred,
+          class _Proj,
+          __enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value &&
+                            __is_identity<__decay_t<_Proj> >::value),
+                        int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
 __make_projected(_Pred& __pred, _Proj& __proj) {
   return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
 }
@@ -81,28 +69,27 @@ __make_projected(_Pred& __pred, _Proj& __proj) {
 // Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
 // optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
 // the call stack when the comparator is invoked, even in an unoptimized build.
-template <class _Pred, class _Proj>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
-__enable_if_t<
-    __can_use_pristine_comp<_Pred, _Proj>::value,
-    _Pred&
->
-__make_projected(_Pred& __pred, _Proj&) {
+template <class _Pred,
+          class _Proj,
+          __enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value &&
+                          __is_identity<__decay_t<_Proj> >::value,
+                        int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
   return __pred;
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
 template <class _Comp, class _Proj1, class _Proj2>
-_LIBCPP_HIDE_FROM_ABI constexpr static
+_LIBCPP_HIDE_FROM_ABI constexpr
 decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
-  if constexpr (same_as<decay_t<_Proj1>, identity> && same_as<decay_t<_Proj2>, identity> &&
+  if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
                 !is_member_pointer_v<decay_t<_Comp>>) {
     // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
     // optimizations that rely on the type of the comparator.
@@ -121,6 +108,6 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
lib/libcxx/include/__algorithm/max.h
@@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 const _Tp&
-max(const _Tp& __a, const _Tp& __b, _Compare __comp)
+max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
 {
     return __comp(__a, __b) ? __b : __a;
 }
@@ -37,9 +37,9 @@ template <class _Tp>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 const _Tp&
-max(const _Tp& __a, const _Tp& __b)
+max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
 {
-    return _VSTD::max(__a, __b, __less<_Tp>());
+    return _VSTD::max(__a, __b, __less<>());
 }
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 _Tp
 max(initializer_list<_Tp> __t)
 {
-    return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
+    return *_VSTD::max_element(__t.begin(), __t.end(), __less<>());
 }
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/max_element.h
@@ -24,7 +24,7 @@ template <class _Compare, class _ForwardIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
 __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
 {
-    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+    static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
         "std::max_element requires a ForwardIterator");
     if (__first != __last)
     {
@@ -48,8 +48,7 @@ template <class _ForwardIterator>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
 max_element(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::max_element(__first, __last,
-              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return _VSTD::max_element(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/merge.h
@@ -60,9 +60,7 @@ _OutputIterator
 merge(_InputIterator1 __first1, _InputIterator1 __last1,
       _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
 {
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
+    return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/min.h
@@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 const _Tp&
-min(const _Tp& __a, const _Tp& __b, _Compare __comp)
+min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
 {
     return __comp(__b, __a) ? __b : __a;
 }
@@ -37,9 +37,9 @@ template <class _Tp>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 const _Tp&
-min(const _Tp& __a, const _Tp& __b)
+min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
 {
-    return _VSTD::min(__a, __b, __less<_Tp>());
+    return _VSTD::min(__a, __b, __less<>());
 }
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 _Tp
 min(initializer_list<_Tp> __t)
 {
-    return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
+    return *_VSTD::min_element(__t.begin(), __t.end(), __less<>());
 }
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/min_element.h
@@ -22,6 +22,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Comp, class _Iter, class _Sent, class _Proj>
@@ -49,7 +52,7 @@ template <class _ForwardIterator, class _Compare>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
 min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
 {
-  static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+  static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
       "std::min_element requires a ForwardIterator");
   static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
               "The comparator has to be callable");
@@ -61,10 +64,11 @@ template <class _ForwardIterator>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
 min_element(_ForwardIterator __first, _ForwardIterator __last)
 {
-    return _VSTD::min_element(__first, __last,
-              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return _VSTD::min_element(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
lib/libcxx/include/__algorithm/min_max_result.h
@@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -47,7 +47,7 @@ struct min_max_result {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/minmax.h
@@ -27,7 +27,7 @@ template<class _Tp, class _Compare>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<const _Tp&, const _Tp&>
-minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
+minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
 {
     return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
                               pair<const _Tp&, const _Tp&>(__a, __b);
@@ -37,9 +37,9 @@ template<class _Tp>
 _LIBCPP_NODISCARD_EXT inline
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<const _Tp&, const _Tp&>
-minmax(const _Tp& __a, const _Tp& __b)
+minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
 {
-    return std::minmax(__a, __b, __less<_Tp>());
+    return std::minmax(__a, __b, __less<>());
 }
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<_Tp, _Tp>
 minmax(initializer_list<_Tp> __t)
 {
-    return std::minmax(__t, __less<_Tp>());
+    return std::minmax(__t, __less<>());
 }
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/minmax_element.h
@@ -12,9 +12,10 @@
 #include <__algorithm/comp.h>
 #include <__config>
 #include <__functional/identity.h>
+#include <__functional/invoke.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_callable.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -82,7 +83,7 @@ template <class _ForwardIterator, class _Compare>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<_ForwardIterator, _ForwardIterator>
 minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
-  static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+  static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
                 "std::minmax_element requires a ForwardIterator");
   static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
                 "The comparator has to be callable");
@@ -93,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com
 template <class _ForwardIterator>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
-    return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+    return std::minmax_element(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/mismatch.h
@@ -38,7 +38,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
   return std::mismatch(__first1, __last1, __first2, __equal_to());
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
lib/libcxx/include/__algorithm/move.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___ALGORITHM_MOVE_H
 
 #include <__algorithm/copy_move_common.h>
+#include <__algorithm/for_each_segment.h>
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/min.h>
 #include <__config>
@@ -45,36 +46,34 @@ struct __move_loop {
     return std::make_pair(std::move(__first), std::move(__result));
   }
 
-  template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+  template <class _InIter, class _OutIter>
+  struct _MoveSegment {
     using _Traits = __segmented_iterator_traits<_InIter>;
-    auto __sfirst = _Traits::__segment(__first);
-    auto __slast  = _Traits::__segment(__last);
-    if (__sfirst == __slast) {
-      auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
-      return std::make_pair(__last, std::move(__iters.second));
-    }
 
-    __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
-    ++__sfirst;
-    while (__sfirst != __slast) {
-      __result =
-          std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
-      ++__sfirst;
+    _OutIter& __result_;
+
+    _LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {}
+
+    _LIBCPP_HIDE_FROM_ABI void
+    operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
+      __result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
     }
-    __result =
-        std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+  };
+
+  template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+    std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
     return std::make_pair(__last, std::move(__result));
   }
 
   template <class _InIter,
             class _OutIter,
-            __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+            __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
                           int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) {
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits = __segmented_iterator_traits<_OutIter>;
     using _DiffT  = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
 
lib/libcxx/include/__algorithm/move_backward.h
@@ -76,11 +76,11 @@ struct __move_backward_loop {
 
   template <class _InIter,
             class _OutIter,
-            __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+            __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
                           int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-  operator()(_InIter __first, _InIter __last, _OutIter __result) {
+  operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits = __segmented_iterator_traits<_OutIter>;
     using _DiffT  = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
 
lib/libcxx/include/__algorithm/next_permutation.h
@@ -69,8 +69,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool
 next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
 {
-    return _VSTD::next_permutation(__first, __last,
-                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+    return _VSTD::next_permutation(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/nth_element.h
@@ -14,7 +14,6 @@
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/sort.h>
 #include <__config>
-#include <__debug>
 #include <__debug_utils/randomize_range.h>
 #include <__iterator/iterator_traits.h>
 #include <__utility/move.h>
@@ -249,8 +248,7 @@ void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Ra
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
-  std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename
-      iterator_traits<_RandomAccessIterator>::value_type>());
+  std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partial_sort.h
@@ -16,11 +16,11 @@
 #include <__algorithm/sift_down.h>
 #include <__algorithm/sort_heap.h>
 #include <__config>
-#include <__debug>
 #include <__debug_utils/randomize_range.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -87,8 +87,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 void
 partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
 {
-    _VSTD::partial_sort(__first, __middle, __last,
-                        __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+    _VSTD::partial_sort(__first, __middle, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partial_sort_copy.h
@@ -79,8 +79,7 @@ _RandomAccessIterator
 partial_sort_copy(_InputIterator __first, _InputIterator __last,
                   _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
 {
-    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
-                                   __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partition.h
@@ -14,7 +14,6 @@
 #include <__iterator/iterator_traits.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/pop_heap.h
@@ -17,20 +17,24 @@
 #include <__assert>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
     typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
-  _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");
 
   __comp_ref_type<_Compare> __comp_ref = __comp;
 
@@ -64,10 +68,11 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::pop_heap(std::move(__first), std::move(__last),
-      __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::pop_heap(std::move(__first), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_POP_HEAP_H
lib/libcxx/include/__algorithm/prev_permutation.h
@@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool
 prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
 {
-    return _VSTD::prev_permutation(__first, __last,
-                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+    return _VSTD::prev_permutation(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/pstl_any_all_none_of.h
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
+#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
+
+#include <__algorithm/pstl_find.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_any_of(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Predicate,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
+        return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last;
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+template <class>
+void __pstl_all_of(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Pred,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
+        return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
+          return !__g_pred(__value);
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+template <class>
+void __pstl_none_of(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Pred,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
+        return !std::any_of(__policy, __g_first, __g_last, __g_pred);
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
lib/libcxx/include/__algorithm/pstl_backend.h
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_BACKEND_H
+#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H
+
+#include <__algorithm/pstl_backends/cpu_backend.h>
+#include <__config>
+#include <execution>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+/*
+TODO: Documentation of how backends work
+
+A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
+
+  template <class _ExecutionPolicy, class _Iterator, class _Func>
+  void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  _Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
+  void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
+
+  template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
+  _OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
+
+  template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
+  _OutIterator __pstl_transform(_InIterator1 __first1,
+                                _InIterator1 __last1,
+                                _InIterator2 __first2,
+                                _OutIterator __result,
+                                _BinaryOperation __op);
+
+  template <class _ExecutionPolicy,
+            class _Iterator1,
+            class _Iterator2,
+            class _Tp,
+            class _BinaryOperation1,
+            class _BinaryOperation2>
+  _Tp __pstl_transform_reduce(_Backend,
+                              _Iterator1 __first1,
+                              _Iterator1 __last1,
+                              _Iterator2 __first2,
+                              _Iterator2 __last2,
+                              _Tp __init,
+                              _BinaryOperation1 __reduce,
+                              _BinaryOperation2 __transform);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+  _Tp __pstl_transform_reduce(_Backend,
+                              _Iterator __first,
+                              _Iterator __last,
+                              _Tp __init,
+                              _BinaryOperation __reduce,
+                              _UnaryOperation __transform);
+
+// TODO: Complete this list
+
+The following functions are optional but can be provided. If provided, they are used by the corresponding
+algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
+implemented, all the algorithms will eventually forward to the basis algorithms listed above:
+
+  template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
+  void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Tp>
+  _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Tp>
+  void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
+  void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Generator>
+  void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
+  void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
+
+  template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
+  _OutIterator __pstl_merge(_Backend,
+                            _Iterator1 __first1,
+                            _Iterator1 __last1,
+                            _Iterator2 __first2,
+                            _Iterator2 __last2,
+                            _OutIterator __result,
+                            _Comp __comp);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
+  _Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
+
+  temlate <class _ExecutionPolicy, class _Iterator>
+  __iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
+
+  template <class _ExecuitonPolicy, class _Iterator, class _Tp>
+  __iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+  __iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Tp>
+  void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
+  void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
+  void __pstl_replace_copy(_Backend,
+                           _Iterator __first,
+                           _Iterator __last,
+                           _OutIterator __result,
+                           const _Tp& __old_value,
+                           const _Tp& __new_value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
+  void __pstl_replace_copy_if(_Backend,
+                              _Iterator __first,
+                              _Iterator __last,
+                              _OutIterator __result,
+                              _Pred __pred,
+                              const _Tp& __new_value);
+
+  template <class _ExecutionPolicy, class _Iterator, class _Comp>
+  void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
+
+// TODO: Complete this list
+
+*/
+
+template <class _ExecutionPolicy>
+struct __select_backend;
+
+template <>
+struct __select_backend<std::execution::sequenced_policy> {
+  using type = __cpu_backend_tag;
+};
+
+#  if _LIBCPP_STD_VER >= 20
+template <>
+struct __select_backend<std::execution::unsequenced_policy> {
+  using type = __cpu_backend_tag;
+};
+#  endif
+
+#  if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) ||                          \
+      defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
+template <>
+struct __select_backend<std::execution::parallel_policy> {
+  using type = __cpu_backend_tag;
+};
+
+template <>
+struct __select_backend<std::execution::parallel_unsequenced_policy> {
+  using type = __cpu_backend_tag;
+};
+
+#  else
+
+// ...New vendors can add parallel backends here...
+
+#    error "Invalid choice of a PSTL parallel backend"
+#  endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H
lib/libcxx/include/__algorithm/pstl_copy.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
+#define _LIBCPP___ALGORITHM_PSTL_COPY_H
+
+#include <__algorithm/copy_n.h>
+#include <__algorithm/pstl_transform.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/remove_cvref.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// TODO: Use the std::copy/move shenanigans to forward to std::memmove
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardOutIterator,
+          enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
+  return std::transform(__policy, __first, __last, __result, __identity());
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardOutIterator,
+          class _Size,
+          enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
+  if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
+    return std::copy(__policy, __first, __first + __n, __result);
+  else
+    return std::copy_n(__first, __n, __result);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H
lib/libcxx/include/__algorithm/pstl_count.h
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_COUNT_H
+#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
+
+#include <__algorithm/count.h>
+#include <__algorithm/for_each.h>
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_for_each.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__atomic/atomic.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <__numeric/pstl_transform_reduce.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_count_if(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Predicate,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
+count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  using __diff_t = __iter_diff_t<_ForwardIterator>;
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
+        return std::transform_reduce(
+            __policy,
+            std::move(__g_first),
+            std::move(__g_last),
+            __diff_t(),
+            std::plus{},
+            [&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+template <class>
+void __pstl_count(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
+count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
+        return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) {
+          return __v == __g_value;
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      __value);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H
lib/libcxx/include/__algorithm/pstl_fill.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_FILL_H
+#define _LIBCPP___ALGORITHM_PSTL_FILL_H
+
+#include <__algorithm/fill_n.h>
+#include <__algorithm/pstl_for_each.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_fill(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
+        std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
+          __element = __g_value;
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      __value);
+}
+
+template <class>
+void __pstl_fill_n(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _SizeT,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
+      [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
+        if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
+          std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
+        else
+          std::fill_n(__g_first, __g_n, __g_value);
+      },
+      std::move(__first),
+      __n,
+      __value);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H
lib/libcxx/include/__algorithm/pstl_find.h
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_FIND_H
+#define _LIBCPP___ALGORITHM_PSTL_FIND_H
+
+#include <__algorithm/comp.h>
+#include <__algorithm/find.h>
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Predicate,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class>
+void __pstl_find_if_not();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Predicate,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
+        return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
+          return !__g_pred(__value);
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+template <class>
+void __pstl_find();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find),
+      [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
+        return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
+          return __element == __g_value;
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      __value);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H
lib/libcxx/include/__algorithm/pstl_for_each.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_FOR_EACH_H
+#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
+
+#include <__algorithm/for_each.h>
+#include <__algorithm/for_each_n.h>
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/void_t.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Function,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
+}
+
+template <class>
+void __pstl_for_each_n(); // declaration needed for the frontend dispatch below
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Size,
+          class _Function,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
+      [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {
+        if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
+          std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
+        } else {
+          std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
+        }
+      },
+      __first,
+      __size,
+      std::move(__func));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
lib/libcxx/include/__algorithm/pstl_frontend_dispatch.h
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_FRONTEND_DISPATCH
+#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
+
+#include <__config>
+#include <__type_traits/is_callable.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#  define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name)                                                                       \
+    [](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{},              \
+                                                           std::forward<decltype(__args)>(__args)...)) {               \
+      return std::name<_RawPolicy>(                                                                                    \
+          typename __select_backend<_RawPolicy>::type{}, std::forward<decltype(__args)>(__args)...);                   \
+    }
+
+template <class _SpecializedImpl, class _GenericImpl, class... _Args>
+_LIBCPP_HIDE_FROM_ABI decltype(auto)
+__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) {
+  if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) {
+    return __specialized_impl(std::forward<_Args>(__args)...);
+  } else {
+    return __generic_impl(std::forward<_Args>(__args)...);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
lib/libcxx/include/__algorithm/pstl_generate.h
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_GENERATE_H
+#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_for_each.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_generate();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Generator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate),
+      [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
+        std::for_each(
+            __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) {
+              __element = __g_gen();
+            });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__gen));
+}
+
+template <class>
+void __pstl_generate_n();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Size,
+          class _Generator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n),
+      [&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
+        std::for_each_n(__policy, std::move(__g_first), __g_n, [&](__iter_reference<_ForwardIterator> __element) {
+          __element = __g_gen();
+        });
+      },
+      std::move(__first),
+      __n,
+      std::move(__gen));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H
lib/libcxx/include/__algorithm/pstl_is_partitioned.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
+#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
+
+#include <__algorithm/pstl_any_all_none_of.h>
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_find.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_is_partitioned();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Predicate,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned),
+      [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
+        __g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred);
+        if (__g_first == __g_last)
+          return true;
+        ++__g_first;
+        return std::none_of(__policy, __g_first, __g_last, __g_pred);
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
lib/libcxx/include/__algorithm/pstl_merge.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
+#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardOutIterator,
+          class _Comp                                         = std::less<>,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+merge(_ExecutionPolicy&&,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2,
+      _ForwardOutIterator __result,
+      _Comp __comp = {}) {
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_merge<_RawPolicy>(
+      _Backend{},
+      std::move(__first1),
+      std::move(__last1),
+      std::move(__first2),
+      std::move(__last2),
+      std::move(__result),
+      std::move(__comp));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H
lib/libcxx/include/__algorithm/pstl_replace.h
@@ -0,0 +1,167 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_REPLACE_H
+#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_for_each.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__algorithm/pstl_transform.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_replace_if();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Pred,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+replace_if(_ExecutionPolicy&& __policy,
+           _ForwardIterator __first,
+           _ForwardIterator __last,
+           _Pred __pred,
+           const _Tp& __new_value) {
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if),
+      [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) {
+        std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
+          if (__g_pred(__element))
+            __element = __g_new_value;
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__pred),
+      __new_value);
+}
+
+template <class>
+void __pstl_replace();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+replace(_ExecutionPolicy&& __policy,
+        _ForwardIterator __first,
+        _ForwardIterator __last,
+        const _Tp& __old_value,
+        const _Tp& __new_value) {
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace),
+      [&__policy](
+          _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
+        std::replace_if(
+            __policy,
+            std::move(__g_first),
+            std::move(__g_last),
+            [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
+            __g_new_value);
+      },
+      std::move(__first),
+      std::move(__last),
+      __old_value,
+      __new_value);
+}
+
+template <class>
+void __pstl_replace_copy_if();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardOutIterator,
+          class _Pred,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
+    _ExecutionPolicy&& __policy,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _ForwardOutIterator __result,
+    _Pred __pred,
+    const _Tp& __new_value) {
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if),
+      [&__policy](_ForwardIterator __g_first,
+                  _ForwardIterator __g_last,
+                  _ForwardOutIterator __g_result,
+                  _Pred __g_pred,
+                  const _Tp& __g_new_value) {
+        std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
+          return __g_pred(__element) ? __g_new_value : __element;
+        });
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__result),
+      std::move(__pred),
+      __new_value);
+}
+
+template <class>
+void __pstl_replace_copy();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardOutIterator,
+          class _Tp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void replace_copy(
+    _ExecutionPolicy&& __policy,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _ForwardOutIterator __result,
+    const _Tp& __old_value,
+    const _Tp& __new_value) {
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy),
+      [&__policy](_ForwardIterator __g_first,
+                  _ForwardIterator __g_last,
+                  _ForwardOutIterator __g_result,
+                  const _Tp& __g_old_value,
+                  const _Tp& __g_new_value) {
+        return std::replace_copy_if(
+            __policy,
+            std::move(__g_first),
+            std::move(__g_last),
+            std::move(__g_result),
+            [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
+            __g_new_value);
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__result),
+      __old_value,
+      __new_value);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H
lib/libcxx/include/__algorithm/pstl_sort.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_SORT_H
+#define _LIBCPP___ALGORITHM_PSTL_SORT_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__algorithm/pstl_stable_sort.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_sort();
+
+template <class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _Comp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+  std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort),
+      [&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
+        std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__comp));
+}
+
+template <class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_SORT_H
lib/libcxx/include/__algorithm/pstl_stable_sort.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_STABLE_SORT_H
+#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _Comp                                         = less<>,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
lib/libcxx/include/__algorithm/pstl_transform.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_PSTL_TRANSFORM_H
+#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardOutIterator,
+          class _UnaryOperation,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _ForwardOutIterator __result,
+    _UnaryOperation __op) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+  _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_transform<_RawPolicy>(
+      _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardOutIterator,
+          class _BinaryOperation,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardOutIterator __result,
+    _BinaryOperation __op) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+  _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_transform<_RawPolicy>(
+      _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
lib/libcxx/include/__algorithm/push_heap.h
@@ -14,13 +14,17 @@
 #include <__algorithm/iterator_operations.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
@@ -68,10 +72,11 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::push_heap(std::move(__first), std::move(__last),
-      __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::push_heap(std::move(__first), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H
lib/libcxx/include/__algorithm/ranges_adjacent_find.h
@@ -24,17 +24,16 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __adjacent_find {
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
     if (__first == __last)
       return __first;
 
@@ -47,32 +46,33 @@ struct __fn {
     return __i;
   }
 
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
-            class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                                                       = identity,
             indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
     return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
   template <forward_range _Range,
             class _Proj = identity,
-            indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>,
-                                      projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
+            indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, projected<iterator_t<_Range>, _Proj>>
+                _Pred = ranges::equal_to>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
     return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
 };
 } // namespace __adjacent_find
 
 inline namespace __cpo {
-  inline constexpr auto adjacent_find = __adjacent_find::__fn{};
+inline constexpr auto adjacent_find = __adjacent_find::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
lib/libcxx/include/__algorithm/ranges_all_of.h
@@ -22,17 +22,15 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __all_of {
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (!std::invoke(__pred, std::invoke(__proj, *__first)))
         return false;
@@ -40,29 +38,32 @@ struct __fn {
     return true;
   }
 
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
     return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <input_range _Range, class _Proj = identity,
+  template <input_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
 };
 } // namespace __all_of
 
 inline namespace __cpo {
-  inline constexpr auto all_of = __all_of::__fn{};
+inline constexpr auto all_of = __all_of::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
lib/libcxx/include/__algorithm/ranges_any_of.h
@@ -22,17 +22,15 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __any_of {
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first)))
         return true;
@@ -40,29 +38,32 @@ struct __fn {
     return false;
   }
 
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
     return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <input_range _Range, class _Proj = identity,
+  template <input_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
 };
 } // namespace __any_of
 
 inline namespace __cpo {
-  inline constexpr auto any_of = __any_of::__fn{};
+inline constexpr auto any_of = __any_of::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
lib/libcxx/include/__algorithm/ranges_binary_search.h
@@ -24,40 +24,45 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __binary_search {
 struct __fn {
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Type,
+            class _Proj                                                             = identity,
             indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+    auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
     return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
   }
 
-  template <forward_range _Range, class _Type, class _Proj = identity,
+  template <forward_range _Range,
+            class _Type,
+            class _Proj                                                                          = identity,
             indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __first = ranges::begin(__r);
-    auto __last = ranges::end(__r);
-    auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
+    auto __last  = ranges::end(__r);
+    auto __ret   = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
     return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
   }
 };
 } // namespace __binary_search
 
 inline namespace __cpo {
-  inline constexpr auto binary_search = __binary_search::__fn{};
+inline constexpr auto binary_search = __binary_search::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
lib/libcxx/include/__algorithm/ranges_clamp.h
@@ -22,25 +22,20 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __clamp {
 struct __fn {
-
   template <class _Type,
-            class _Proj = identity,
+            class _Proj                                                      = identity,
             indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  const _Type& operator()(const _Type& __value,
-                          const _Type& __low,
-                          const _Type& __high,
-                          _Comp __comp = {},
-                          _Proj __proj = {}) const {
-    _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
-                   "Bad bounds passed to std::ranges::clamp");
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()(
+      const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const {
+    _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
+                                 "Bad bounds passed to std::ranges::clamp");
 
     if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low)))
       return __low;
@@ -49,17 +44,16 @@ struct __fn {
     else
       return __value;
   }
-
 };
 } // namespace __clamp
 
 inline namespace __cpo {
-  inline constexpr auto clamp = __clamp::__fn{};
+inline constexpr auto clamp = __clamp::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H
lib/libcxx/include/__algorithm/ranges_copy.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -36,19 +36,18 @@ using copy_result = in_out_result<_InIter, _OutIter>;
 
 namespace __copy {
 struct __fn {
-
   template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
     requires indirectly_copyable<_InIter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
   template <input_range _Range, weakly_incrementable _OutIter>
     requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __r, _OutIter __result) const {
     auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
@@ -56,12 +55,12 @@ struct __fn {
 } // namespace __copy
 
 inline namespace __cpo {
-  inline constexpr auto copy = __copy::__fn{};
+inline constexpr auto copy = __copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_COPY_H
lib/libcxx/include/__algorithm/ranges_copy_backward.h
@@ -23,30 +23,29 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
-template<class _Ip, class _Op>
+template <class _Ip, class _Op>
 using copy_backward_result = in_out_result<_Ip, _Op>;
 
 namespace __copy_backward {
 struct __fn {
-
   template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2>
     requires indirectly_copyable<_InIter1, _InIter2>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2>
+  operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
     auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
   template <bidirectional_range _Range, bidirectional_iterator _Iter>
     requires indirectly_copyable<iterator_t<_Range>, _Iter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
+  operator()(_Range&& __r, _Iter __result) const {
     auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
@@ -54,12 +53,12 @@ struct __fn {
 } // namespace __copy_backward
 
 inline namespace __cpo {
-  inline constexpr auto copy_backward = __copy_backward::__fn{};
+inline constexpr auto copy_backward = __copy_backward::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
lib/libcxx/include/__algorithm/ranges_copy_if.h
@@ -24,21 +24,19 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
-template<class _Ip, class _Op>
+template <class _Ip, class _Op>
 using copy_if_result = in_out_result<_Ip, _Op>;
 
 namespace __copy_if {
 struct __fn {
-
   template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI static constexpr
-  copy_if_result <_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
   __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first))) {
@@ -49,20 +47,23 @@ struct __fn {
     return {std::move(__first), std::move(__result)};
   }
 
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            weakly_incrementable _OutIter,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
     requires indirectly_copyable<_Iter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_if_result<_Iter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
   operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
     return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
   }
 
-  template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
+  template <input_range _Range,
+            weakly_incrementable _OutIter,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
     requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
   operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
     return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
   }
@@ -70,12 +71,12 @@ struct __fn {
 } // namespace __copy_if
 
 inline namespace __cpo {
-  inline constexpr auto copy_if = __copy_if::__fn{};
+inline constexpr auto copy_if = __copy_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_copy_n.h
@@ -27,7 +27,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -36,10 +36,9 @@ using copy_n_result = in_out_result<_Ip, _Op>;
 
 namespace __copy_n {
 struct __fn {
-
   template <class _InIter, class _DiffType, class _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
+  __go(_InIter __first, _DiffType __n, _OutIter __result) {
     while (__n != 0) {
       *__result = *__first;
       ++__first;
@@ -50,27 +49,27 @@ struct __fn {
   }
 
   template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
+  __go(_InIter __first, _DiffType __n, _OutIter __result) {
     auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result);
     return {__ret.first, __ret.second};
   }
 
   template <input_iterator _Ip, weakly_incrementable _Op>
     requires indirectly_copyable<_Ip, _Op>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
+  operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
     return __go(std::move(__first), __n, std::move(__result));
   }
 };
 } // namespace __copy_n
 
 inline namespace __cpo {
-  inline constexpr auto copy_n = __copy_n::__fn{};
+inline constexpr auto copy_n = __copy_n::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/ranges_count.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -34,16 +34,16 @@ namespace __count {
 struct __fn {
   template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
+  operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
     auto __pred = [&](auto&& __e) { return __e == __value; };
     return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
   template <input_range _Range, class _Type, class _Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
+  operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
     auto __pred = [&](auto&& __e) { return __e == __value; };
     return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
   }
@@ -51,12 +51,12 @@ struct __fn {
 } // namespace __count
 
 inline namespace __cpo {
-  inline constexpr auto count = __count::__fn{};
+inline constexpr auto count = __count::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H
lib/libcxx/include/__algorithm/ranges_count_if.h
@@ -25,15 +25,14 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 template <class _Iter, class _Sent, class _Proj, class _Pred>
-_LIBCPP_HIDE_FROM_ABI constexpr
-iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
-                                             _Pred& __pred, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
+__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
   iter_difference_t<_Iter> __counter(0);
   for (; __first != __last; ++__first) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
@@ -44,29 +43,32 @@ iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
 
 namespace __count_if {
 struct __fn {
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
+  operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
     return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <input_range _Range, class _Proj = identity,
+  template <input_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
+  operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
     return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
   }
 };
 } // namespace __count_if
 
 inline namespace __cpo {
-  inline constexpr auto count_if = __count_if::__fn{};
+inline constexpr auto count_if = __count_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
lib/libcxx/include/__algorithm/ranges_equal.h
@@ -9,6 +9,8 @@
 #ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H
 #define _LIBCPP___ALGORITHM_RANGES_EQUAL_H
 
+#include <__algorithm/equal.h>
+#include <__algorithm/unwrap_range.h>
 #include <__config>
 #include <__functional/identity.h>
 #include <__functional/invoke.h>
@@ -24,92 +26,79 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __equal {
 struct __fn {
-private:
-  template <class _Iter1, class _Sent1,
-            class _Iter2, class _Sent2,
-            class _Pred,
-            class _Proj1,
-            class _Proj2>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __equal_impl(_Iter1 __first1, _Sent1 __last1,
-                    _Iter2 __first2, _Sent2 __last2,
-                    _Pred& __pred,
-                    _Proj1& __proj1,
-                    _Proj2& __proj2) {
-    while (__first1 != __last1 && __first2 != __last2) {
-      if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
-        return false;
-      ++__first1;
-      ++__first2;
-    }
-    return __first1 == __last1 && __first2 == __last2;
-  }
-
-public:
-
-  template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Pred = ranges::equal_to,
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            input_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter1 __first1, _Sent1 __last1,
-                  _Iter2 __first2, _Sent2 __last2,
-                  _Pred __pred = {},
-                  _Proj1 __proj1 = {},
-                  _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
     if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
       if (__last1 - __first1 != __last2 - __first2)
         return false;
     }
-    return __equal_impl(std::move(__first1), std::move(__last1),
-                        std::move(__first2), std::move(__last2),
-                        __pred,
-                        __proj1,
-                        __proj2);
+    auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
+    auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
+    return std::__equal_impl(
+        std::move(__unwrapped1.first),
+        std::move(__unwrapped1.second),
+        std::move(__unwrapped2.first),
+        std::move(__unwrapped2.second),
+        __pred,
+        __proj1,
+        __proj2);
   }
 
   template <input_range _Range1,
             input_range _Range2,
-            class _Pred = ranges::equal_to,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range1&& __range1,
-                  _Range2&& __range2,
-                  _Pred __pred = {},
-                  _Proj1 __proj1 = {},
-                  _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
       if (ranges::distance(__range1) != ranges::distance(__range2))
         return false;
     }
-    return __equal_impl(ranges::begin(__range1), ranges::end(__range1),
-                        ranges::begin(__range2), ranges::end(__range2),
-                        __pred,
-                        __proj1,
-                        __proj2);
+    auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
+    auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
+    return std::__equal_impl(
+        std::move(__unwrapped1.first),
+        std::move(__unwrapped1.second),
+        std::move(__unwrapped2.first),
+        std::move(__unwrapped2.second),
+        __pred,
+        __proj1,
+        __proj2);
     return false;
   }
 };
 } // namespace __equal
 
 inline namespace __cpo {
-  inline constexpr auto equal = __equal::__fn{};
+inline constexpr auto equal = __equal::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H
lib/libcxx/include/__algorithm/ranges_equal_range.h
@@ -30,7 +30,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -38,28 +38,25 @@ namespace ranges {
 namespace __equal_range {
 
 struct __fn {
-  template <
-      forward_iterator _Iter,
-      sentinel_for<_Iter> _Sent,
-      class _Tp,
-      class _Proj                                                           = identity,
-      indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Tp,
+            class _Proj                                                           = identity,
+            indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
   _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
   operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    auto __ret = std::__equal_range<_RangeAlgPolicy>(
-        std::move(__first), std::move(__last), __value, __comp, __proj);
+    auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj);
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
-  template <
-      forward_range _Range,
-      class _Tp,
-      class _Proj                                                                        = identity,
-      indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+  template <forward_range _Range,
+            class _Tp,
+            class _Proj                                                                        = identity,
+            indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
   _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
   operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    auto __ret = std::__equal_range<_RangeAlgPolicy>(
-        ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
+    auto __ret =
+        std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 };
@@ -67,12 +64,12 @@ struct __fn {
 } // namespace __equal_range
 
 inline namespace __cpo {
-  inline constexpr auto equal_range = __equal_range::__fn{};
+inline constexpr auto equal_range = __equal_range::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
lib/libcxx/include/__algorithm/ranges_fill.h
@@ -20,7 +20,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -28,9 +28,8 @@ namespace ranges {
 namespace __fill {
 struct __fn {
   template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
-    if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
+    if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
       return ranges::fill_n(__first, __last - __first, __value);
     } else {
       for (; __first != __last; ++__first)
@@ -40,20 +39,19 @@ struct __fn {
   }
 
   template <class _Type, output_range<const _Type&> _Range>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
     return (*this)(ranges::begin(__range), ranges::end(__range), __value);
   }
 };
 } // namespace __fill
 
 inline namespace __cpo {
-  inline constexpr auto fill = __fill::__fn{};
+inline constexpr auto fill = __fill::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FILL_H
lib/libcxx/include/__algorithm/ranges_fill_n.h
@@ -17,7 +17,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -25,8 +25,8 @@ namespace ranges {
 namespace __fill_n {
 struct __fn {
   template <class _Type, output_iterator<const _Type&> _Iter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
     for (; __n != 0; --__n) {
       *__first = __value;
       ++__first;
@@ -37,12 +37,12 @@ struct __fn {
 } // namespace __fill_n
 
 inline namespace __cpo {
-  inline constexpr auto fill_n = __fill_n::__fn{};
+inline constexpr auto fill_n = __fill_n::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H
lib/libcxx/include/__algorithm/ranges_find.h
@@ -9,7 +9,9 @@
 #ifndef _LIBCPP___ALGORITHM_RANGES_FIND_H
 #define _LIBCPP___ALGORITHM_RANGES_FIND_H
 
+#include <__algorithm/find.h>
 #include <__algorithm/ranges_find_if.h>
+#include <__algorithm/unwrap_range.h>
 #include <__config>
 #include <__functional/identity.h>
 #include <__functional/invoke.h>
@@ -26,38 +28,48 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __find {
 struct __fn {
+  template <class _Iter, class _Sent, class _Tp, class _Proj>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Iter
+  __find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
+    if constexpr (forward_iterator<_Iter>) {
+      auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last));
+      return std::__rewrap_range<_Sent>(
+          std::move(__first), std::__find_impl(std::move(__first_un), std::move(__last_un), __value, __proj));
+    } else {
+      return std::__find_impl(std::move(__first), std::move(__last), __value, __proj);
+    }
+  }
+
   template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
-    auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
-    return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
+  operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
+    return __find_unwrap(std::move(__first), std::move(__last), __value, __proj);
   }
 
   template <input_range _Rp, class _Tp, class _Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
-    auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
-    return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
+  operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
+    return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj);
   }
 };
 } // namespace __find
 
 inline namespace __cpo {
-  inline constexpr auto find = __find::__fn{};
+inline constexpr auto find = __find::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FIND_H
lib/libcxx/include/__algorithm/ranges_find_end.h
@@ -27,25 +27,29 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __find_end {
 struct __fn {
-  template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Pred = ranges::equal_to,
+  template <forward_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            forward_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
-                              _Iter2 __first2, _Sent2 __last2,
-                              _Pred __pred = {},
-                              _Proj1 __proj1 = {},
-                              _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
     auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
         __first1,
         __last1,
@@ -61,16 +65,12 @@ struct __fn {
 
   template <forward_range _Range1,
             forward_range _Range2,
-            class _Pred = ranges::equal_to,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
-                                          _Range2&& __range2,
-                                          _Pred __pred = {},
-                                          _Proj1 __proj1 = {},
-                                          _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -87,12 +87,12 @@ struct __fn {
 } // namespace __find_end
 
 inline namespace __cpo {
-  inline constexpr auto find_end = __find_end::__fn{};
+inline constexpr auto find_end = __find_end::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H
lib/libcxx/include/__algorithm/ranges_find_first_of.h
@@ -24,21 +24,22 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __find_first_of {
 struct __fn {
-
   template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1,
-                              _Iter2 __first2, _Sent2 __last2,
-                              _Pred& __pred,
-                              _Proj1& __proj1,
-                              _Proj2& __proj2) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred& __pred,
+      _Proj1& __proj1,
+      _Proj2& __proj2) {
     for (; __first1 != __last1; ++__first1) {
       for (auto __j = __first2; __j != __last2; ++__j) {
         if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j)))
@@ -48,54 +49,53 @@ struct __fn {
     return __first1;
   }
 
-  template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Pred = ranges::equal_to,
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            forward_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter1 operator()(_Iter1 __first1, _Sent1 __last1,
-                    _Iter2 __first2, _Sent2 __last2,
-                    _Pred __pred = {},
-                    _Proj1 __proj1 = {},
-                    _Proj2 __proj2 = {}) const {
-    return __find_first_of_impl(std::move(__first1), std::move(__last1),
-                                std::move(__first2), std::move(__last2),
-                                __pred,
-                                __proj1,
-                                __proj2);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
+    return __find_first_of_impl(
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
   }
 
   template <input_range _Range1,
             forward_range _Range2,
-            class _Pred = ranges::equal_to,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range1> operator()(_Range1&& __range1,
-                                          _Range2&& __range2,
-                                          _Pred __pred = {},
-                                          _Proj1 __proj1 = {},
-                                          _Proj2 __proj2 = {}) const {
-    return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1),
-                                ranges::begin(__range2), ranges::end(__range2),
-                                __pred,
-                                __proj1,
-                                __proj2);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+    return __find_first_of_impl(
+        ranges::begin(__range1),
+        ranges::end(__range1),
+        ranges::begin(__range2),
+        ranges::end(__range2),
+        __pred,
+        __proj1,
+        __proj2);
   }
-
 };
 } // namespace __find_first_of
 
 inline namespace __cpo {
-  inline constexpr auto find_first_of = __find_first_of::__fn{};
+inline constexpr auto find_first_of = __find_first_of::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
lib/libcxx/include/__algorithm/ranges_find_if.h
@@ -24,15 +24,14 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
 template <class _Ip, class _Sp, class _Pred, class _Proj>
-_LIBCPP_HIDE_FROM_ABI static constexpr
-_Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
   for (; __first != __last; ++__first) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
       break;
@@ -42,30 +41,30 @@ _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
 
 namespace __find_if {
 struct __fn {
-
-  template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+  template <input_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
+  operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
     return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <input_range _Rp, class _Proj = identity,
-            indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+  template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
+  operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
     return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
   }
 };
 } // namespace __find_if
 
 inline namespace __cpo {
-  inline constexpr auto find_if = __find_if::__fn{};
+inline constexpr auto find_if = __find_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
lib/libcxx/include/__algorithm/ranges_find_if_not.h
@@ -26,25 +26,26 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __find_if_not {
 struct __fn {
-  template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+  template <input_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
+  operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
     auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
     return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj);
   }
 
-  template <input_range _Rp, class _Proj = identity,
-            indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+  template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
+  operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
     auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
     return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj);
   }
@@ -52,12 +53,12 @@ struct __fn {
 } // namespace __find_if_not
 
 inline namespace __cpo {
-  inline constexpr auto find_if_not = __find_if_not::__fn{};
+inline constexpr auto find_if_not = __find_if_not::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
lib/libcxx/include/__algorithm/ranges_for_each.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -37,42 +37,40 @@ namespace __for_each {
 struct __fn {
 private:
   template <class _Iter, class _Sent, class _Proj, class _Func>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func>
+  __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
     for (; __first != __last; ++__first)
       std::invoke(__func, std::invoke(__proj, *__first));
     return {std::move(__first), std::move(__func)};
   }
 
 public:
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
             class _Proj = identity,
             indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<_Iter, _Func>
+  operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const {
     return __for_each_impl(std::move(__first), std::move(__last), __func, __proj);
   }
 
   template <input_range _Range,
             class _Proj = identity,
             indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  for_each_result<borrowed_iterator_t<_Range>, _Func> operator()(_Range&& __range,
-                                                                 _Func __func,
-                                                                 _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func>
+  operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const {
     return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
   }
-
 };
 } // namespace __for_each
 
 inline namespace __cpo {
-  inline constexpr auto for_each = __for_each::__fn{};
+inline constexpr auto for_each = __for_each::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H
lib/libcxx/include/__algorithm/ranges_for_each_n.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,32 +35,25 @@ using for_each_n_result = in_fun_result<_Iter, _Func>;
 
 namespace __for_each_n {
 struct __fn {
-
-  template <input_iterator _Iter,
-            class _Proj = identity,
-            indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  for_each_n_result<_Iter, _Func> operator()(_Iter __first,
-                                             iter_difference_t<_Iter> __count,
-                                             _Func __func,
-                                             _Proj __proj = {}) const {
+  template <input_iterator _Iter, class _Proj = identity, indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr for_each_n_result<_Iter, _Func>
+  operator()(_Iter __first, iter_difference_t<_Iter> __count, _Func __func, _Proj __proj = {}) const {
     while (__count-- > 0) {
       std::invoke(__func, std::invoke(__proj, *__first));
       ++__first;
     }
     return {std::move(__first), std::move(__func)};
   }
-
 };
 } // namespace __for_each_n
 
 inline namespace __cpo {
-  inline constexpr auto for_each_n = __for_each_n::__fn{};
+inline constexpr auto for_each_n = __for_each_n::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H
lib/libcxx/include/__algorithm/ranges_generate.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -32,10 +32,8 @@ namespace ranges {
 namespace __generate {
 
 struct __fn {
-
   template <class _OutIter, class _Sent, class _Func>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) {
     for (; __first != __last; ++__first) {
       *__first = __gen();
     }
@@ -44,30 +42,27 @@ struct __fn {
   }
 
   template <input_or_output_iterator _OutIter, sentinel_for<_OutIter> _Sent, copy_constructible _Func>
-  requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const {
+    requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
+  _LIBCPP_HIDE_FROM_ABI constexpr _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const {
     return __generate_fn_impl(std::move(__first), std::move(__last), __gen);
   }
 
   template <class _Range, copy_constructible _Func>
-  requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const {
+    requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>>
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const {
     return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen);
   }
-
 };
 
 } // namespace __generate
 
 inline namespace __cpo {
-  inline constexpr auto generate = __generate::__fn{};
+inline constexpr auto generate = __generate::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H
lib/libcxx/include/__algorithm/ranges_generate_n.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -33,11 +33,10 @@ namespace ranges {
 namespace __generate_n {
 
 struct __fn {
-
   template <input_or_output_iterator _OutIter, copy_constructible _Func>
-  requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
+    requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
+  _LIBCPP_HIDE_FROM_ABI constexpr _OutIter
+  operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
     for (; __n > 0; --__n) {
       *__first = __gen();
       ++__first;
@@ -45,18 +44,17 @@ struct __fn {
 
     return __first;
   }
-
 };
 
 } // namespace __generate_n
 
 inline namespace __cpo {
-  inline constexpr auto generate_n = __generate_n::__fn{};
+inline constexpr auto generate_n = __generate_n::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
lib/libcxx/include/__algorithm/ranges_includes.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,14 +35,13 @@ namespace ranges {
 namespace __includes {
 
 struct __fn {
-  template <
-      input_iterator _Iter1,
-      sentinel_for<_Iter1> _Sent1,
-      input_iterator _Iter2,
-      sentinel_for<_Iter2> _Sent2,
-      class _Proj1                                                                           = identity,
-      class _Proj2                                                                           = identity,
-      indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            input_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Proj1                                                                           = identity,
+            class _Proj2                                                                           = identity,
+            indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
   _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
       _Iter1 __first1,
       _Sent1 __last1,
@@ -61,13 +60,12 @@ struct __fn {
         std::move(__proj2));
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      class _Proj1 = identity,
-      class _Proj2 = identity,
-      indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
-          _Comp = ranges::less>
+  template <input_range _Range1,
+            input_range _Range2,
+            class _Proj1 = identity,
+            class _Proj2 = identity,
+            indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
+                _Comp = ranges::less>
   _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
       _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     return std::__includes(
@@ -84,12 +82,12 @@ struct __fn {
 } // namespace __includes
 
 inline namespace __cpo {
-  inline constexpr auto includes = __includes::__fn{};
+inline constexpr auto includes = __includes::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H
lib/libcxx/include/__algorithm/ranges_inplace_merge.h
@@ -31,55 +31,49 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __inplace_merge {
 
-  struct __fn {
-    template <class _Iter, class _Sent, class _Comp, class _Proj>
-    _LIBCPP_HIDE_FROM_ABI static constexpr auto
-    __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
-      auto __last_iter = ranges::next(__middle, __last);
-      std::__inplace_merge<_RangeAlgPolicy>(
-          std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
-      return __last_iter;
-    }
+struct __fn {
+  template <class _Iter, class _Sent, class _Comp, class _Proj>
+  _LIBCPP_HIDE_FROM_ABI static constexpr auto
+  __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
+    auto __last_iter = ranges::next(__middle, __last);
+    std::__inplace_merge<_RangeAlgPolicy>(
+        std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
+    return __last_iter;
+  }
 
-    template <
-        bidirectional_iterator _Iter,
-        sentinel_for<_Iter> _Sent,
-        class _Comp = ranges::less,
-        class _Proj = identity>
-      requires sortable<_Iter, _Comp, _Proj>
-    _LIBCPP_HIDE_FROM_ABI _Iter
-    operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
-      return __inplace_merge_impl(
-          std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
-    }
+  template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+    requires sortable<_Iter, _Comp, _Proj>
+  _LIBCPP_HIDE_FROM_ABI _Iter
+  operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+    return __inplace_merge_impl(
+        std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
+  }
 
-    template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
-      requires sortable<
-          iterator_t<_Range>,
-          _Comp,
-          _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
-      operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
-      return __inplace_merge_impl(
-          ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
-    }
-  };
+  template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
+    requires sortable<iterator_t<_Range>, _Comp, _Proj>
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
+  operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
+    return __inplace_merge_impl(
+        ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
+  }
+};
 
 } // namespace __inplace_merge
 
 inline namespace __cpo {
-  inline constexpr auto inplace_merge = __inplace_merge::__fn{};
+inline constexpr auto inplace_merge = __inplace_merge::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
lib/libcxx/include/__algorithm/ranges_is_heap.h
@@ -26,7 +26,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -34,28 +34,30 @@ namespace ranges {
 namespace __is_heap {
 
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Comp>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
-    auto __last_iter = ranges::next(__first, __last);
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool
+  __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+    auto __last_iter        = ranges::next(__first, __last);
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
 
     auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
     return __result == __last;
   }
 
-  template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <random_access_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                               = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
-  template <random_access_range _Range, class _Proj = identity,
+  template <random_access_range _Range,
+            class _Proj                                                            = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
     return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
   }
 };
@@ -63,12 +65,12 @@ struct __fn {
 } // namespace __is_heap
 
 inline namespace __cpo {
-  inline constexpr auto is_heap = __is_heap::__fn{};
+inline constexpr auto is_heap = __is_heap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
lib/libcxx/include/__algorithm/ranges_is_heap_until.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,41 +35,42 @@ namespace ranges {
 namespace __is_heap_until {
 
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Comp>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
-    auto __last_iter = ranges::next(__first, __last);
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+    auto __last_iter        = ranges::next(__first, __last);
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
 
     return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
   }
 
-  template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <random_access_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                               = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
-  template <random_access_range _Range, class _Proj = identity,
+  template <random_access_range _Range,
+            class _Proj                                                            = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
     return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
   }
-
 };
 
 } // namespace __is_heap_until
 
 inline namespace __cpo {
-  inline constexpr auto is_heap_until = __is_heap_until::__fn{};
+inline constexpr auto is_heap_until = __is_heap_until::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
lib/libcxx/include/__algorithm/ranges_is_partitioned.h
@@ -23,17 +23,16 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __is_partitioned {
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool
+  __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (!std::invoke(__pred, std::invoke(__proj, *__first)))
         break;
@@ -51,31 +50,32 @@ struct __fn {
     return true;
   }
 
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
             class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
-    return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+    return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
   template <input_range _Range,
             class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
-    return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+    return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
 };
 } // namespace __is_partitioned
 
 inline namespace __cpo {
-  inline constexpr auto is_partitioned = __is_partitioned::__fn{};
+inline constexpr auto is_partitioned = __is_partitioned::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
lib/libcxx/include/__algorithm/ranges_is_permutation.h
@@ -25,65 +25,78 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __is_permutation {
 struct __fn {
-
-  template <class _Iter1, class _Sent1, class _Iter2, class _Sent2,
-            class _Proj1, class _Proj2, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
-                                  _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+  template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Pred>
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred& __pred,
+      _Proj1& __proj1,
+      _Proj2& __proj2) {
     return std::__is_permutation<_RangeAlgPolicy>(
-        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
-        __pred, __proj1, __proj2);
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
   }
 
-  template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Proj1 = identity,
-            class _Proj2 = identity,
-            indirect_equivalence_relation<projected<_Iter1, _Proj1>,
-                                          projected<_Iter2, _Proj2>> _Pred = ranges::equal_to>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
-                  _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+  template <
+      forward_iterator _Iter1,
+      sentinel_for<_Iter1> _Sent1,
+      forward_iterator _Iter2,
+      sentinel_for<_Iter2> _Sent2,
+      class _Proj1                                                                              = identity,
+      class _Proj2                                                                              = identity,
+      indirect_equivalence_relation<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
     return __is_permutation_func_impl(
-        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
-        __pred, __proj1, __proj2);
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
   }
 
   template <forward_range _Range1,
             forward_range _Range2,
-            class _Proj1 = identity,
-            class _Proj2 = identity,
-            indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range1&& __range1, _Range2&& __range2,
-                  _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+            class _Proj1                                                                = identity,
+            class _Proj2                                                                = identity,
+            indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>,
+                                          projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
       if (ranges::distance(__range1) != ranges::distance(__range2))
         return false;
     }
 
     return __is_permutation_func_impl(
-        ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2),
-        __pred, __proj1, __proj2);
+        ranges::begin(__range1),
+        ranges::end(__range1),
+        ranges::begin(__range2),
+        ranges::end(__range2),
+        __pred,
+        __proj1,
+        __proj2);
   }
 };
 } // namespace __is_permutation
 
 inline namespace __cpo {
-  inline constexpr auto is_permutation = __is_permutation::__fn{};
+inline constexpr auto is_permutation = __is_permutation::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_is_sorted.h
@@ -23,26 +23,27 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __is_sorted {
 struct __fn {
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
-            class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                               = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last;
   }
 
   template <forward_range _Range,
-            class _Proj = identity,
+            class _Proj                                                            = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __last = ranges::end(__range);
     return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last;
   }
@@ -50,12 +51,12 @@ struct __fn {
 } // namespace __is_sorted
 
 inline namespace __cpo {
-  inline constexpr auto is_sorted = __is_sorted::__fn{};
+inline constexpr auto is_sorted = __is_sorted::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H
lib/libcxx/include/__algorithm/ranges_is_sorted_until.h
@@ -24,15 +24,15 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
 template <class _Iter, class _Sent, class _Proj, class _Comp>
-_LIBCPP_HIDE_FROM_ABI constexpr
-_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Iter
+__is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
   if (__first == __last)
     return __first;
   auto __i = __first;
@@ -46,31 +46,32 @@ _Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj&
 
 namespace __is_sorted_until {
 struct __fn {
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
-            class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                               = identity,
             indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <forward_range _Range,
-            class _Proj = identity,
+            class _Proj                                                            = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
     return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
   }
 };
 } // namespace __is_sorted_until
 
 inline namespace __cpo {
-  inline constexpr auto is_sorted_until = __is_sorted_until::__fn{};
+inline constexpr auto is_sorted_until = __is_sorted_until::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H
lib/libcxx/include/__algorithm/ranges_iterator_concept.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -46,6 +46,6 @@ using __iterator_concept = decltype(__get_iterator_concept<_Iter>());
 } // namespace ranges
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H
lib/libcxx/include/__algorithm/ranges_lexicographical_compare.h
@@ -23,24 +23,24 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __lexicographical_compare {
 struct __fn {
-
   template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1,
-                                      _Iter2 __first2, _Sent2 __last2,
-                                      _Comp& __comp,
-                                      _Proj1& __proj1,
-                                      _Proj2& __proj2) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool __lexicographical_compare_impl(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Comp& __comp,
+      _Proj1& __proj1,
+      _Proj2& __proj2) {
     while (__first2 != __last2) {
-      if (__first1 == __last1
-       || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
+      if (__first1 == __last1 || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
         return true;
       if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1)))
         return false;
@@ -50,49 +50,52 @@ struct __fn {
     return false;
   }
 
-  template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Proj1 = identity,
-            class _Proj2 = identity,
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            input_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Proj1                                                                           = identity,
+            class _Proj2                                                                           = identity,
             indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter1 __first1, _Sent1 __last1,
-                  _Iter2 __first2, _Sent2 __last2,
-                  _Comp __comp = {},
-                  _Proj1 __proj1 = {},
-                  _Proj2 __proj2 = {}) const {
-    return __lexicographical_compare_impl(std::move(__first1), std::move(__last1),
-                                          std::move(__first2), std::move(__last2),
-                                          __comp,
-                                          __proj1,
-                                          __proj2);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Comp __comp   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
+    return __lexicographical_compare_impl(
+        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __comp, __proj1, __proj2);
   }
 
   template <input_range _Range1,
             input_range _Range2,
             class _Proj1 = identity,
             class _Proj2 = identity,
-            indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
-                                       projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
-    return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1),
-                                          ranges::begin(__range2), ranges::end(__range2),
-                                          __comp,
-                                          __proj1,
-                                          __proj2);
+            indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
+                _Comp = ranges::less>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+    return __lexicographical_compare_impl(
+        ranges::begin(__range1),
+        ranges::end(__range1),
+        ranges::begin(__range2),
+        ranges::end(__range2),
+        __comp,
+        __proj1,
+        __proj2);
   }
-
 };
 } // namespace __lexicographical_compare
 
 inline namespace __cpo {
-  inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
+inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
lib/libcxx/include/__algorithm/ranges_lower_bound.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,32 +35,34 @@ namespace ranges {
 
 namespace __lower_bound {
 struct __fn {
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Type,
+            class _Proj                                                             = identity,
             indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+    return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
   }
 
-  template <forward_range _Range, class _Type, class _Proj = identity,
+  template <forward_range _Range,
+            class _Type,
+            class _Proj                                                                          = identity,
             indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r,
-                                         const _Type& __value,
-                                         _Comp __comp = {},
-                                         _Proj __proj = {}) const {
-    return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+    return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
   }
 };
 } // namespace __lower_bound
 
 inline namespace __cpo {
-  inline constexpr auto lower_bound = __lower_bound::__fn{};
+inline constexpr auto lower_bound = __lower_bound::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H
lib/libcxx/include/__algorithm/ranges_make_heap.h
@@ -32,7 +32,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,8 +41,8 @@ namespace __make_heap {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -53,15 +53,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -69,12 +69,12 @@ struct __fn {
 } // namespace __make_heap
 
 inline namespace __cpo {
-  inline constexpr auto make_heap = __make_heap::__fn{};
+inline constexpr auto make_heap = __make_heap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H
lib/libcxx/include/__algorithm/ranges_max.h
@@ -20,6 +20,7 @@
 #include <__iterator/projected.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/is_trivially_copyable.h>
 #include <__utility/move.h>
 #include <initializer_list>
 
@@ -27,44 +28,50 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_PUSH_MACROS
-#include <__undef_macros>
+#  include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __max {
 struct __fn {
-  template <class _Tp, class _Proj = identity,
+  template <class _Tp,
+            class _Proj                                                    = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
+  operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a,
+             _LIBCPP_LIFETIMEBOUND const _Tp& __b,
+             _Comp __comp = {},
+             _Proj __proj = {}) const {
     return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a;
   }
 
-  template <copyable _Tp, class _Proj = identity,
+  template <copyable _Tp,
+            class _Proj                                                    = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
-    _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp
+  operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element");
 
     auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
     return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
   }
 
-  template <input_range _Rp, class _Proj = identity,
+  template <input_range _Rp,
+            class _Proj                                                         = identity,
             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
     requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp>
+  operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __first = ranges::begin(__r);
-    auto __last = ranges::end(__r);
+    auto __last  = ranges::end(__r);
 
-    _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element");
 
-    if constexpr (forward_range<_Rp>) {
+    if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
       auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
       return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
     } else {
@@ -80,7 +87,7 @@ struct __fn {
 } // namespace __max
 
 inline namespace __cpo {
-  inline constexpr auto max = __max::__fn{};
+inline constexpr auto max = __max::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
@@ -88,6 +95,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP_STD_VER > 17 &&
+#endif // _LIBCPP_STD_VER >= 20 &&
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MAX_H
lib/libcxx/include/__algorithm/ranges_max_element.h
@@ -24,25 +24,28 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __max_element {
 struct __fn {
-  template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+  template <forward_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj                                             = identity,
             indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
+  operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
     return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj);
   }
 
-  template <forward_range _Rp, class _Proj = identity,
+  template <forward_range _Rp,
+            class _Proj                                                         = identity,
             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
+  operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
     return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
   }
@@ -50,12 +53,12 @@ struct __fn {
 } // namespace __max_element
 
 inline namespace __cpo {
-  inline constexpr auto max_element = __max_element::__fn{};
+inline constexpr auto max_element = __max_element::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_merge.h
@@ -20,14 +20,14 @@
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
 #include <__ranges/dangling.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -38,25 +38,25 @@ using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
 
 namespace __merge {
 
-template <
-    class _InIter1,
-    class _Sent1,
-    class _InIter2,
-    class _Sent2,
-    class _OutIter,
-    class _Comp,
-    class _Proj1,
-    class _Proj2>
-_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>>
-__merge_impl(
-    _InIter1&& __first1,
-    _Sent1&& __last1,
-    _InIter2&& __first2,
-    _Sent2&& __last2,
-    _OutIter&& __result,
-    _Comp&& __comp,
-    _Proj1&& __proj1,
-    _Proj2&& __proj2) {
+template < class _InIter1,
+           class _Sent1,
+           class _InIter2,
+           class _Sent2,
+           class _OutIter,
+           class _Comp,
+           class _Proj1,
+           class _Proj2>
+_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>,
+                                             __remove_cvref_t<_InIter2>,
+                                             __remove_cvref_t<_OutIter>>
+__merge_impl(_InIter1&& __first1,
+             _Sent1&& __last1,
+             _InIter2&& __first2,
+             _Sent2&& __last2,
+             _OutIter&& __result,
+             _Comp&& __comp,
+             _Proj1&& __proj1,
+             _Proj2&& __proj2) {
   for (; __first1 != __last1 && __first2 != __last2; ++__result) {
     if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) {
       *__result = *__first2;
@@ -72,15 +72,14 @@ __merge_impl(
 }
 
 struct __fn {
-  template <
-      input_iterator _InIter1,
-      sentinel_for<_InIter1> _Sent1,
-      input_iterator _InIter2,
-      sentinel_for<_InIter2> _Sent2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()(
       _InIter1 __first1,
@@ -94,28 +93,20 @@ struct __fn {
     return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2);
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
-    requires mergeable<
-        iterator_t<_Range1>,
-        iterator_t<_Range2>,
-        _OutIter,
-        _Comp,
-        _Proj1,
-        _Proj2>
+  template <input_range _Range1,
+            input_range _Range2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr merge_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
-        operator()(
-            _Range1&& __range1,
-            _Range2&& __range2,
-            _OutIter __result,
-            _Comp __comp   = {},
-            _Proj1 __proj1 = {},
-            _Proj2 __proj2 = {}) const {
+  operator()(_Range1&& __range1,
+             _Range2&& __range2,
+             _OutIter __result,
+             _Comp __comp   = {},
+             _Proj1 __proj1 = {},
+             _Proj2 __proj2 = {}) const {
     return __merge::__merge_impl(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -131,12 +122,12 @@ struct __fn {
 } // namespace __merge
 
 inline namespace __cpo {
-  inline constexpr auto merge = __merge::__fn{};
+inline constexpr auto merge = __merge::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H
lib/libcxx/include/__algorithm/ranges_min.h
@@ -20,48 +20,53 @@
 #include <__iterator/projected.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/is_trivially_copyable.h>
 #include <initializer_list>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_PUSH_MACROS
-#include <__undef_macros>
+#  include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __min {
 struct __fn {
-  template <class _Tp, class _Proj = identity,
+  template <class _Tp,
+            class _Proj                                                    = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
+  operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a,
+             _LIBCPP_LIFETIMEBOUND const _Tp& __b,
+             _Comp __comp = {},
+             _Proj __proj = {}) const {
     return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a;
   }
 
-  template <copyable _Tp, class _Proj = identity,
+  template <copyable _Tp,
+            class _Proj                                                    = identity,
             indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
-    _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp
+  operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element");
     return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj);
   }
 
-  template <input_range _Rp, class _Proj = identity,
+  template <input_range _Rp,
+            class _Proj                                                         = identity,
             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
     requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp>
+  operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __first = ranges::begin(__r);
-    auto __last = ranges::end(__r);
-
-    _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
-
-    if constexpr (forward_range<_Rp>) {
+    auto __last  = ranges::end(__r);
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element");
+    if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
       return *ranges::__min_element_impl(__first, __last, __comp, __proj);
     } else {
       range_value_t<_Rp> __result = *__first;
@@ -76,7 +81,7 @@ struct __fn {
 } // namespace __min
 
 inline namespace __cpo {
-  inline constexpr auto min = __min::__fn{};
+inline constexpr auto min = __min::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
@@ -84,6 +89,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP_STD_VER > 17 &&
+#endif // _LIBCPP_STD_VER >= 20 &&
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MIN_H
lib/libcxx/include/__algorithm/ranges_min_element.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -32,8 +32,7 @@ namespace ranges {
 
 // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`.
 template <class _Ip, class _Sp, class _Proj, class _Comp>
-_LIBCPP_HIDE_FROM_ABI static constexpr
-_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
   if (__first == __last)
     return __first;
 
@@ -46,29 +45,32 @@ _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
 
 namespace __min_element {
 struct __fn {
-  template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+  template <forward_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj                                             = identity,
             indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
+  operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return ranges::__min_element_impl(__first, __last, __comp, __proj);
   }
 
-  template <forward_range _Rp, class _Proj = identity,
+  template <forward_range _Rp,
+            class _Proj                                                         = identity,
             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
+  operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
 } // namespace __min_element
 
 inline namespace __cpo {
-  inline constexpr auto min_element = __min_element::__fn{};
+inline constexpr auto min_element = __min_element::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_minmax.h
@@ -13,14 +13,18 @@
 #include <__algorithm/minmax_element.h>
 #include <__assert>
 #include <__concepts/copyable.h>
+#include <__concepts/same_as.h>
 #include <__config>
 #include <__functional/identity.h>
 #include <__functional/invoke.h>
 #include <__functional/ranges_operations.h>
 #include <__iterator/concepts.h>
+#include <__iterator/next.h>
 #include <__iterator/projected.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
@@ -30,10 +34,10 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_PUSH_MACROS
-#include <__undef_macros>
+#  include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -43,46 +47,67 @@ using minmax_result = min_max_result<_T1>;
 
 namespace __minmax {
 struct __fn {
-  template <class _Type, class _Proj = identity,
+  template <class _Type,
+            class _Proj                                                      = identity,
             indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
   _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<const _Type&>
-  operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+  operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a,
+             _LIBCPP_LIFETIMEBOUND const _Type& __b,
+             _Comp __comp = {},
+             _Proj __proj = {}) const {
     if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)))
       return {__b, __a};
     return {__a, __b};
   }
 
-  template <copyable _Type, class _Proj = identity,
+  template <copyable _Type,
+            class _Proj                                                      = identity,
             indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const {
-    _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element");
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type>
+  operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list has to contain at least one element");
     auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj);
-    return ranges::minmax_result<_Type> { *__iters.first, *__iters.second };
+    return ranges::minmax_result<_Type>{*__iters.first, *__iters.second};
   }
 
-  template <input_range _Range, class _Proj = identity,
+  template <input_range _Range,
+            class _Proj                                                            = identity,
             indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
     requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  ranges::minmax_result<range_value_t<_Range>> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
-    auto __first = ranges::begin(__r);
-    auto __last = ranges::end(__r);
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<range_value_t<_Range>>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+    auto __first  = ranges::begin(__r);
+    auto __last   = ranges::end(__r);
     using _ValueT = range_value_t<_Range>;
 
-    _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range has to contain at least one element");
 
     if constexpr (forward_range<_Range>) {
+      // Special-case the one element case. Avoid repeatedly initializing objects from the result of an iterator
+      // dereference when doing so might not be idempotent. The `if constexpr` avoids the extra branch in cases where
+      // it's not needed.
+      if constexpr (!same_as<remove_cvref_t<range_reference_t<_Range>>, _ValueT> ||
+                    is_rvalue_reference_v<range_reference_t<_Range>>) {
+        if (ranges::next(__first) == __last) {
+          // During initialization, members are allowed to refer to already initialized members
+          // (see http://eel.is/c++draft/dcl.init.aggr#6)
+          minmax_result<_ValueT> __result = {*__first, __result.min};
+          return __result;
+        }
+      }
       auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj);
       return {*__result.first, *__result.second};
     } else {
       // input_iterators can't be copied, so the implementation for input_iterators has to store
       // the values instead of a pointer to the correct values
       auto __less = [&](auto&& __a, auto&& __b) -> bool {
-        return std::invoke(__comp, std::invoke(__proj, std::forward<decltype(__a)>(__a)),
-                                   std::invoke(__proj, std::forward<decltype(__b)>(__b)));
+        return std::invoke(__comp,
+                           std::invoke(__proj, std::forward<decltype(__a)>(__a)),
+                           std::invoke(__proj, std::forward<decltype(__b)>(__b)));
       };
 
+      // During initialization, members are allowed to refer to already initialized members
+      // (see http://eel.is/c++draft/dcl.init.aggr#6)
       ranges::minmax_result<_ValueT> __result = {*__first, __result.min};
       if (__first == __last || ++__first == __last)
         return __result;
@@ -121,7 +146,7 @@ struct __fn {
 } // namespace __minmax
 
 inline namespace __cpo {
-  inline constexpr auto minmax = __minmax::__fn{};
+inline constexpr auto minmax = __minmax::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
@@ -129,6 +154,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
lib/libcxx/include/__algorithm/ranges_minmax_element.h
@@ -23,13 +23,12 @@
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,18 +39,20 @@ using minmax_element_result = min_max_result<_T1>;
 
 namespace __minmax_element {
 struct __fn {
-  template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+  template <forward_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj                                             = identity,
             indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip>
+  operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj);
     return {__ret.first, __ret.second};
   }
 
-  template <forward_range _Rp, class _Proj = identity,
+  template <forward_range _Rp,
+            class _Proj                                                         = identity,
             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  ranges::minmax_element_result<borrowed_iterator_t<_Rp>>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<borrowed_iterator_t<_Rp>>
   operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
     return {__ret.first, __ret.second};
@@ -60,13 +61,13 @@ struct __fn {
 } // namespace __minmax_element
 
 inline namespace __cpo {
-  inline constexpr auto minmax_element = __minmax_element::__fn{};
+inline constexpr auto minmax_element = __minmax_element::__fn{};
 } // namespace __cpo
 
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
lib/libcxx/include/__algorithm/ranges_mismatch.h
@@ -27,7 +27,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -36,12 +36,9 @@ using mismatch_result = in_in_result<_I1, _I2>;
 
 namespace __mismatch {
 struct __fn {
-  template <class _I1, class _S1, class _I2, class _S2,
-            class _Pred, class _Proj1, class _Proj2>
-  static _LIBCPP_HIDE_FROM_ABI constexpr
-  mismatch_result<_I1, _I2>
-  __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
-       _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+  template <class _I1, class _S1, class _I2, class _S2, class _Pred, class _Proj1, class _Proj2>
+  static _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2>
+  __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
     while (__first1 != __last1 && __first2 != __last2) {
       if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
         break;
@@ -51,34 +48,41 @@ struct __fn {
     return {std::move(__first1), std::move(__first2)};
   }
 
-  template <input_iterator _I1, sentinel_for<_I1> _S1,
-            input_iterator _I2, sentinel_for<_I2> _S2,
-            class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
+  template <input_iterator _I1,
+            sentinel_for<_I1> _S1,
+            input_iterator _I2,
+            sentinel_for<_I2> _S2,
+            class _Pred  = ranges::equal_to,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
-                                       _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()(
+      _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
+      const {
     return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2);
   }
 
-  template <input_range _R1, input_range _R2,
-            class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
+  template <input_range _R1,
+            input_range _R2,
+            class _Pred  = ranges::equal_to,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires indirectly_comparable<iterator_t<_R1>, iterator_t<_R2>, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  mismatch_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<borrowed_iterator_t<_R1>,
+                                                                        borrowed_iterator_t<_R2>>
   operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
-    return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2),
-                __pred, __proj1, __proj2);
+    return __go(
+        ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), __pred, __proj1, __proj2);
   }
 };
 } // namespace __mismatch
 
 inline namespace __cpo {
-  constexpr inline auto mismatch = __mismatch::__fn{};
+constexpr inline auto mismatch = __mismatch::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/ranges_move.h
@@ -23,7 +23,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -34,38 +34,36 @@ using move_result = in_out_result<_InIter, _OutIter>;
 
 namespace __move {
 struct __fn {
-
   template <class _InIter, class _Sent, class _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static move_result<_InIter, _OutIter>
+  __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
     auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
   template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
     requires indirectly_movable<_InIter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr move_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     return __move_impl(std::move(__first), std::move(__last), std::move(__result));
   }
 
   template <input_range _Range, weakly_incrementable _OutIter>
     requires indirectly_movable<iterator_t<_Range>, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  move_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr move_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result) const {
     return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
   }
-
 };
 } // namespace __move
 
 inline namespace __cpo {
-  inline constexpr auto move = __move::__fn{};
+inline constexpr auto move = __move::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H
lib/libcxx/include/__algorithm/ranges_move_backward.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -36,38 +36,36 @@ using move_backward_result = in_out_result<_InIter, _OutIter>;
 
 namespace __move_backward {
 struct __fn {
-
   template <class _InIter, class _Sent, class _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static move_backward_result<_InIter, _OutIter>
+  __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
     auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
   template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter>
     requires indirectly_movable<_InIter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result));
   }
 
   template <bidirectional_range _Range, bidirectional_iterator _Iter>
     requires indirectly_movable<iterator_t<_Range>, _Iter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  move_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __range, _Iter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter>
+  operator()(_Range&& __range, _Iter __result) const {
     return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
   }
-
 };
 } // namespace __move_backward
 
 inline namespace __cpo {
-  inline constexpr auto move_backward = __move_backward::__fn{};
+inline constexpr auto move_backward = __move_backward::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
lib/libcxx/include/__algorithm/ranges_next_permutation.h
@@ -28,7 +28,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -68,6 +68,6 @@ constexpr inline auto next_permutation = __next_permutation::__fn{};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_none_of.h
@@ -22,17 +22,16 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __none_of {
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static bool
+  __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first)))
         return false;
@@ -40,29 +39,32 @@ struct __fn {
     return true;
   }
 
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
     return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <input_range _Range, class _Proj = identity,
+  template <input_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
 };
 } // namespace __none_of
 
 inline namespace __cpo {
-  inline constexpr auto none_of = __none_of::__fn{};
+inline constexpr auto none_of = __none_of::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H
lib/libcxx/include/__algorithm/ranges_nth_element.h
@@ -31,7 +31,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,8 +40,8 @@ namespace __nth_element {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -52,16 +52,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {},
-                                         _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const {
     return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj);
   }
 };
@@ -69,12 +68,12 @@ struct __fn {
 } // namespace __nth_element
 
 inline namespace __cpo {
-  inline constexpr auto nth_element = __nth_element::__fn{};
+inline constexpr auto nth_element = __nth_element::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_partial_sort.h
@@ -33,7 +33,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -42,24 +42,23 @@ namespace __partial_sort {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
     return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp);
   }
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {},
-                                         _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
     return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj);
   }
 };
@@ -67,12 +66,12 @@ struct __fn {
 } // namespace __partial_sort
 
 inline namespace __cpo {
-  inline constexpr auto partial_sort = __partial_sort::__fn{};
+inline constexpr auto partial_sort = __partial_sort::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H
lib/libcxx/include/__algorithm/ranges_partial_sort_copy.h
@@ -30,7 +30,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -42,51 +42,68 @@ using partial_sort_copy_result = in_out_result<_InIter, _OutIter>;
 namespace __partial_sort_copy {
 
 struct __fn {
-
-  template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
-  requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> &&
-           indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  partial_sort_copy_result<_Iter1, _Iter2>
-  operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last,
-             _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            random_access_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> &&
+             indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>
+  _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<_Iter1, _Iter2> operator()(
+      _Iter1 __first,
+      _Sent1 __last,
+      _Iter2 __result_first,
+      _Sent2 __result_last,
+      _Comp __comp   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
     auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
-        std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last),
-        __comp, __proj1, __proj2
-    );
+        std::move(__first),
+        std::move(__last),
+        std::move(__result_first),
+        std::move(__result_last),
+        __comp,
+        __proj1,
+        __proj2);
     return {std::move(__result.first), std::move(__result.second)};
   }
 
-  template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less,
-            class _Proj1 = identity, class _Proj2 = identity>
-  requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> &&
-           sortable<iterator_t<_Range2>, _Comp, _Proj2> &&
-           indirect_strict_weak_order<_Comp, projected<iterator_t<_Range1>, _Proj1>,
-                                      projected<iterator_t<_Range2>, _Proj2>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
-  operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {},
-             _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+  template <input_range _Range1,
+            random_access_range _Range2,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> &&
+             sortable<iterator_t<_Range2>, _Comp, _Proj2> &&
+             indirect_strict_weak_order<_Comp,
+                                        projected<iterator_t<_Range1>, _Proj1>,
+                                        projected<iterator_t<_Range2>, _Proj2>>
+  _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
+  operator()(
+      _Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
-        ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range),
-        __comp, __proj1, __proj2
-    );
+        ranges::begin(__range),
+        ranges::end(__range),
+        ranges::begin(__result_range),
+        ranges::end(__result_range),
+        __comp,
+        __proj1,
+        __proj2);
     return {std::move(__result.first), std::move(__result.second)};
   }
-
 };
 
 } // namespace __partial_sort_copy
 
 inline namespace __cpo {
-  inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{};
+inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
lib/libcxx/include/__algorithm/ranges_partition.h
@@ -27,13 +27,12 @@
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,43 +40,44 @@ namespace ranges {
 namespace __partition {
 
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI static constexpr
-  subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
+  _LIBCPP_HIDE_FROM_ABI static constexpr subrange<__remove_cvref_t<_Iter>>
+  __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
     auto&& __projected_pred = std::__make_projected(__pred, __proj);
-    auto __result = std::__partition<_RangeAlgPolicy>(
+    auto __result           = std::__partition<_RangeAlgPolicy>(
         std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>());
 
     return {std::move(__result.first), std::move(__result.second)};
   }
 
-  template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <permutable _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
     return __partition_fn_impl(__first, __last, __pred, __proj);
   }
 
-  template <forward_range _Range, class _Proj = identity,
+  template <forward_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  requires permutable<iterator_t<_Range>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+    requires permutable<iterator_t<_Range>>
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
-
 };
 
 } // namespace __partition
 
 inline namespace __cpo {
-  inline constexpr auto partition = __partition::__fn{};
+inline constexpr auto partition = __partition::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H
lib/libcxx/include/__algorithm/ranges_partition_copy.h
@@ -19,14 +19,14 @@
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
 #include <__ranges/dangling.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -38,14 +38,18 @@ using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>;
 namespace __partition_copy {
 
 struct __fn {
-
   // TODO(ranges): delegate to the classic algorithm.
   template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static partition_copy_result<
-      __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2>
-  > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false,
-      _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>,
+                                                               __remove_cvref_t<_OutIter1>,
+                                                               __remove_cvref_t<_OutIter2> >
+  __partition_copy_fn_impl(
+      _InIter&& __first,
+      _Sent&& __last,
+      _OutIter1&& __out_true,
+      _OutIter2&& __out_false,
+      _Pred& __pred,
+      _Proj& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first))) {
         *__out_true = *__first;
@@ -60,39 +64,42 @@ struct __fn {
     return {std::move(__first), std::move(__out_true), std::move(__out_false)};
   }
 
-  template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
-            weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
-            class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
-  requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  partition_copy_result<_InIter, _OutIter1, _OutIter2>
-  operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false,
-             _Pred __pred, _Proj __proj = {}) const {
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
+            weakly_incrementable _OutIter1,
+            weakly_incrementable _OutIter2,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+    requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
+  _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()(
+      _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {})
+      const {
     return __partition_copy_fn_impl(
         std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj);
   }
 
-  template <input_range _Range, weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
-            class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
+  template <input_range _Range,
+            weakly_incrementable _OutIter1,
+            weakly_incrementable _OutIter2,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+    requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
+  _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
   operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const {
     return __partition_copy_fn_impl(
         ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj);
   }
-
 };
 
 } // namespace __partition_copy
 
 inline namespace __cpo {
-  inline constexpr auto partition_copy = __partition_copy::__fn{};
+inline constexpr auto partition_copy = __partition_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
lib/libcxx/include/__algorithm/ranges_partition_point.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,16 +35,15 @@ namespace ranges {
 namespace __partition_point {
 
 struct __fn {
-
   // TODO(ranges): delegate to the classic algorithm.
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) {
     auto __len = ranges::distance(__first, __last);
 
     while (__len != 0) {
       auto __half_len = std::__half_positive(__len);
-      auto __mid = ranges::next(__first, __half_len);
+      auto __mid      = ranges::next(__first, __half_len);
 
       if (std::invoke(__pred, std::invoke(__proj, *__mid))) {
         __first = ++__mid;
@@ -58,31 +57,32 @@ struct __fn {
     return __first;
   }
 
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
     return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
-  template <forward_range _Range, class _Proj = identity,
+  template <forward_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
-
 };
 
 } // namespace __partition_point
 
 inline namespace __cpo {
-  inline constexpr auto partition_point = __partition_point::__fn{};
+inline constexpr auto partition_point = __partition_point::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H
lib/libcxx/include/__algorithm/ranges_pop_heap.h
@@ -32,7 +32,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,10 +41,10 @@ namespace __pop_heap {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
-    auto __len = __last_iter - __first;
+    auto __len       = __last_iter - __first;
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
     std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len);
@@ -54,15 +54,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -70,12 +70,12 @@ struct __fn {
 } // namespace __pop_heap
 
 inline namespace __cpo {
-  inline constexpr auto pop_heap = __pop_heap::__fn{};
+inline constexpr auto pop_heap = __pop_heap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H
lib/libcxx/include/__algorithm/ranges_prev_permutation.h
@@ -28,7 +28,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,9 +40,7 @@ using prev_permutation_result = in_found_result<_InIter>;
 namespace __prev_permutation {
 
 struct __fn {
-
-  template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
-            class _Comp = ranges::less, class _Proj = identity>
+  template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter>
   operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
@@ -51,8 +49,7 @@ struct __fn {
     return {std::move(__result.first), std::move(__result.second)};
   }
 
-  template <bidirectional_range _Range,
-            class _Comp = ranges::less, class _Proj = identity>
+  template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
   operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
@@ -60,7 +57,6 @@ struct __fn {
         ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
     return {std::move(__result.first), std::move(__result.second)};
   }
-
 };
 
 } // namespace __prev_permutation
@@ -72,6 +68,6 @@ constexpr inline auto prev_permutation = __prev_permutation::__fn{};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_push_heap.h
@@ -32,7 +32,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,8 +41,8 @@ namespace __push_heap {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -53,15 +53,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -69,12 +69,12 @@ struct __fn {
 } // namespace __push_heap
 
 inline namespace __cpo {
-  inline constexpr auto push_heap = __push_heap::__fn{};
+inline constexpr auto push_heap = __push_heap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H
lib/libcxx/include/__algorithm/ranges_remove.h
@@ -25,27 +25,26 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __remove {
 struct __fn {
-
   template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
     auto __pred = [&](auto&& __other) { return __value == __other; };
     return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
   template <forward_range _Range, class _Type, class _Proj = identity>
-    requires permutable<iterator_t<_Range>>
-          && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
+    requires permutable<iterator_t<_Range>> &&
+             indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
     auto __pred = [&](auto&& __other) { return __value == __other; };
     return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
@@ -53,12 +52,12 @@ struct __fn {
 } // namespace __remove
 
 inline namespace __cpo {
-  inline constexpr auto remove = __remove::__fn{};
+inline constexpr auto remove = __remove::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H
lib/libcxx/include/__algorithm/ranges_remove_copy.h
@@ -26,7 +26,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -37,40 +37,40 @@ using remove_copy_result = in_out_result<_InIter, _OutIter>;
 
 namespace __remove_copy {
 
-  struct __fn {
-    template <input_iterator _InIter,
-              sentinel_for<_InIter> _Sent,
-              weakly_incrementable _OutIter,
-              class _Type,
-              class _Proj = identity>
-      requires indirectly_copyable<_InIter, _OutIter> &&
-               indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
-    _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
-    operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
-      auto __pred = [&](auto&& __val) { return __value == __val; };
-      return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
-    }
+struct __fn {
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
+            weakly_incrementable _OutIter,
+            class _Type,
+            class _Proj = identity>
+    requires indirectly_copyable<_InIter, _OutIter> &&
+             indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
+  _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
+    auto __pred = [&](auto&& __val) { return __value == __val; };
+    return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
+  }
 
-    template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
-      requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
-               indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
-    _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
-    operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
-      auto __pred = [&](auto&& __val) { return __value == __val; };
-      return ranges::__remove_copy_if_impl(
-          ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
-    }
-  };
+  template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
+    requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
+             indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
+  _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
+    auto __pred = [&](auto&& __val) { return __value == __val; };
+    return ranges::__remove_copy_if_impl(
+        ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
+  }
+};
 
 } // namespace __remove_copy
 
 inline namespace __cpo {
-  inline constexpr auto remove_copy = __remove_copy::__fn{};
+inline constexpr auto remove_copy = __remove_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
lib/libcxx/include/__algorithm/ranges_remove_copy_if.h
@@ -29,7 +29,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -52,39 +52,39 @@ __remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& _
 
 namespace __remove_copy_if {
 
-  struct __fn {
-    template <input_iterator _InIter,
-              sentinel_for<_InIter> _Sent,
-              weakly_incrementable _OutIter,
-              class _Proj = identity,
-              indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
-      requires indirectly_copyable<_InIter, _OutIter>
-    _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter>
-    operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
-      return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
-    }
+struct __fn {
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
+            weakly_incrementable _OutIter,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+    requires indirectly_copyable<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+    return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
+  }
 
-    template <input_range _Range,
-              weakly_incrementable _OutIter,
-              class _Proj = identity,
-              indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-      requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-    _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
-    operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
-      return ranges::__remove_copy_if_impl(
-          ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
-    }
-  };
+  template <input_range _Range,
+            weakly_incrementable _OutIter,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+    requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+    return ranges::__remove_copy_if_impl(
+        ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
+  }
+};
 
 } // namespace __remove_copy_if
 
 inline namespace __cpo {
-  inline constexpr auto remove_copy_if = __remove_copy_if::__fn{};
+inline constexpr auto remove_copy_if = __remove_copy_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_remove_if.h
@@ -27,15 +27,15 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
 template <class _Iter, class _Sent, class _Proj, class _Pred>
-_LIBCPP_HIDE_FROM_ABI constexpr
-subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+__remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
   auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj);
   if (__new_end == __last)
     return {__new_end, __new_end};
@@ -52,12 +52,12 @@ subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Pr
 
 namespace __remove_if {
 struct __fn {
-
-  template <permutable _Iter, sentinel_for<_Iter> _Sent,
+  template <permutable _Iter,
+            sentinel_for<_Iter> _Sent,
             class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
     return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
   }
 
@@ -65,21 +65,20 @@ struct __fn {
             class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
     requires permutable<iterator_t<_Range>>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
-
 };
 } // namespace __remove_if
 
 inline namespace __cpo {
-  inline constexpr auto remove_if = __remove_if::__fn{};
+inline constexpr auto remove_if = __remove_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H
lib/libcxx/include/__algorithm/ranges_replace.h
@@ -24,51 +24,40 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __replace {
 struct __fn {
-
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
-            class _Type1,
-            class _Type2,
-            class _Proj = identity>
-    requires indirectly_writable<_Iter, const _Type2&>
-          && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last,
-                   const _Type1& __old_value,
-                   const _Type2& __new_value,
-                   _Proj __proj = {}) const {
+  template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type1, class _Type2, class _Proj = identity>
+    requires indirectly_writable<_Iter, const _Type2&> &&
+             indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(
+      _Iter __first, _Sent __last, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
     auto __pred = [&](const auto& __val) { return __val == __old_value; };
     return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
   }
 
-  template <input_range _Range,
-            class _Type1,
-            class _Type2,
-            class _Proj = identity>
-    requires indirectly_writable<iterator_t<_Range>, const _Type2&>
-          && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
+  template <input_range _Range, class _Type1, class _Type2, class _Proj = identity>
+    requires indirectly_writable<iterator_t<_Range>, const _Type2&> &&
+             indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
   _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
   operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
     auto __pred = [&](auto&& __val) { return __val == __old_value; };
     return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
   }
-
 };
 } // namespace __replace
 
 inline namespace __cpo {
-  inline constexpr auto replace = __replace::__fn{};
+inline constexpr auto replace = __replace::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H
lib/libcxx/include/__algorithm/ranges_replace_copy.h
@@ -26,7 +26,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -37,55 +37,52 @@ using replace_copy_result = in_out_result<_InIter, _OutIter>;
 
 namespace __replace_copy {
 
-  struct __fn {
-    template <input_iterator _InIter,
-              sentinel_for<_InIter> _Sent,
-              class _OldType,
-              class _NewType,
-              output_iterator<const _NewType&> _OutIter,
-              class _Proj = identity>
-      requires indirectly_copyable<_InIter, _OutIter> &&
-               indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*>
-    _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter>
-    operator()(_InIter __first,
-               _Sent __last,
-               _OutIter __result,
-               const _OldType& __old_value,
-               const _NewType& __new_value,
-               _Proj __proj = {}) const {
-      auto __pred = [&](const auto& __value) { return __value == __old_value; };
-      return ranges::__replace_copy_if_impl(
-          std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
-    }
+struct __fn {
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
+            class _OldType,
+            class _NewType,
+            output_iterator<const _NewType&> _OutIter,
+            class _Proj = identity>
+    requires indirectly_copyable<_InIter, _OutIter> &&
+             indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*>
+  _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter>
+  operator()(_InIter __first,
+             _Sent __last,
+             _OutIter __result,
+             const _OldType& __old_value,
+             const _NewType& __new_value,
+             _Proj __proj = {}) const {
+    auto __pred = [&](const auto& __value) { return __value == __old_value; };
+    return ranges::__replace_copy_if_impl(
+        std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
+  }
 
-    template <input_range _Range,
-              class _OldType,
-              class _NewType,
-              output_iterator<const _NewType&> _OutIter,
-              class _Proj = identity>
-      requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
-               indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*>
-    _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter>
-    operator()(_Range&& __range,
-               _OutIter __result,
-               const _OldType& __old_value,
-               const _NewType& __new_value,
-               _Proj __proj = {}) const {
-      auto __pred = [&](const auto& __value) { return __value == __old_value; };
-      return ranges::__replace_copy_if_impl(
-          ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
-    }
-  };
+  template <input_range _Range,
+            class _OldType,
+            class _NewType,
+            output_iterator<const _NewType&> _OutIter,
+            class _Proj = identity>
+    requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
+             indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*>
+  _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(
+      _Range&& __range, _OutIter __result, const _OldType& __old_value, const _NewType& __new_value, _Proj __proj = {})
+      const {
+    auto __pred = [&](const auto& __value) { return __value == __old_value; };
+    return ranges::__replace_copy_if_impl(
+        ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
+  }
+};
 
 } // namespace __replace_copy
 
 inline namespace __cpo {
-  inline constexpr auto replace_copy = __replace_copy::__fn{};
+inline constexpr auto replace_copy = __replace_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
lib/libcxx/include/__algorithm/ranges_replace_copy_if.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -51,43 +51,43 @@ _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __repl
 
 namespace __replace_copy_if {
 
-  struct __fn {
-    template <input_iterator _InIter,
-              sentinel_for<_InIter> _Sent,
-              class _Type,
-              output_iterator<const _Type&> _OutIter,
-              class _Proj = identity,
-              indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
-      requires indirectly_copyable<_InIter, _OutIter>
-    _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()(
-        _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {})
-        const {
-      return ranges::__replace_copy_if_impl(
-          std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
-    }
-
-    template <input_range _Range,
-              class _Type,
-              output_iterator<const _Type&> _OutIter,
-              class _Proj = identity,
-              indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-      requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-    _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
-    operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
-      return ranges::__replace_copy_if_impl(
-          ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
-    }
-  };
+struct __fn {
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
+            class _Type,
+            output_iterator<const _Type&> _OutIter,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+    requires indirectly_copyable<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()(
+      _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {})
+      const {
+    return ranges::__replace_copy_if_impl(
+        std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
+  }
+
+  template <input_range _Range,
+            class _Type,
+            output_iterator<const _Type&> _OutIter,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+    requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
+    return ranges::__replace_copy_if_impl(
+        ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
+  }
+};
 
 } // namespace __replace_copy_if
 
 inline namespace __cpo {
-  inline constexpr auto replace_copy_if = __replace_copy_if::__fn{};
+inline constexpr auto replace_copy_if = __replace_copy_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_replace_if.h
@@ -23,15 +23,15 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
 template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred>
-_LIBCPP_HIDE_FROM_ABI constexpr
-_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Iter
+__replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
   for (; __first != __last; ++__first) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
       *__first = __new_value;
@@ -41,14 +41,14 @@ _Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type&
 
 namespace __replace_if {
 struct __fn {
-
-  template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+  template <input_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
             class _Type,
             class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
     requires indirectly_writable<_Iter, const _Type&>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
     return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
   }
 
@@ -61,17 +61,16 @@ struct __fn {
   operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
     return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
   }
-
 };
 } // namespace __replace_if
 
 inline namespace __cpo {
-  inline constexpr auto replace_if = __replace_if::__fn{};
+inline constexpr auto replace_if = __replace_if::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H
lib/libcxx/include/__algorithm/ranges_reverse.h
@@ -22,18 +22,16 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __reverse {
 struct __fn {
-
   template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
     requires permutable<_Iter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const {
     if constexpr (random_access_iterator<_Iter>) {
       if (__first == __last)
         return __first;
@@ -63,21 +61,19 @@ struct __fn {
 
   template <bidirectional_range _Range>
     requires permutable<iterator_t<_Range>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
-
 };
 } // namespace __reverse
 
 inline namespace __cpo {
-  inline constexpr auto reverse = __reverse::__fn{};
+inline constexpr auto reverse = __reverse::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H
lib/libcxx/include/__algorithm/ranges_reverse_copy.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -36,32 +36,30 @@ using reverse_copy_result = in_out_result<_InIter, _OutIter>;
 
 namespace __reverse_copy {
 struct __fn {
-
   template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
     requires indirectly_copyable<_InIter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result));
   }
 
   template <bidirectional_range _Range, weakly_incrementable _OutIter>
     requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result) const {
     auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result));
     return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)};
   }
-
 };
 } // namespace __reverse_copy
 
 inline namespace __cpo {
-  inline constexpr auto reverse_copy = __reverse_copy::__fn{};
+inline constexpr auto reverse_copy = __reverse_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
lib/libcxx/include/__algorithm/ranges_rotate.h
@@ -25,7 +25,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -33,39 +33,34 @@ namespace ranges {
 namespace __rotate {
 
 struct __fn {
-
   template <class _Iter, class _Sent>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) {
-    auto __ret = std::__rotate<_RangeAlgPolicy>(
-      std::move(__first), std::move(__middle), std::move(__last));
+  _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) {
+    auto __ret = std::__rotate<_RangeAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last));
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
   template <permutable _Iter, sentinel_for<_Iter> _Sent>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const {
     return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last));
   }
 
   template <forward_range _Range>
-  requires permutable<iterator_t<_Range>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const {
+    requires permutable<iterator_t<_Range>>
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, iterator_t<_Range> __middle) const {
     return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range));
   }
-
 };
 
 } // namespace __rotate
 
 inline namespace __cpo {
-  inline constexpr auto rotate = __rotate::__fn{};
+inline constexpr auto rotate = __rotate::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H
lib/libcxx/include/__algorithm/ranges_rotate_copy.h
@@ -23,7 +23,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -34,11 +34,9 @@ using rotate_copy_result = in_out_result<_InIter, _OutIter>;
 
 namespace __rotate_copy {
 struct __fn {
-
   template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
     requires indirectly_copyable<_InIter, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  rotate_copy_result<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<_InIter, _OutIter>
   operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const {
     auto __res1 = ranges::copy(__middle, __last, std::move(__result));
     auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out));
@@ -47,22 +45,20 @@ struct __fn {
 
   template <bidirectional_range _Range, weakly_incrementable _OutIter>
     requires indirectly_copyable<iterator_t<_Range>, _OutIter>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter>
   operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const {
     return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result));
   }
-
 };
 } // namespace __rotate_copy
 
 inline namespace __cpo {
-  inline constexpr auto rotate_copy = __rotate_copy::__fn{};
+inline constexpr auto rotate_copy = __rotate_copy::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H
lib/libcxx/include/__algorithm/ranges_sample.h
@@ -19,15 +19,15 @@
 #include <__random/uniform_random_bit_generator.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,40 +35,35 @@ namespace ranges {
 namespace __sample {
 
 struct __fn {
-
   template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Gen>
-  requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) &&
-           indirectly_copyable<_Iter, _OutIter> &&
-           uniform_random_bit_generator<remove_reference_t<_Gen>>
-  _LIBCPP_HIDE_FROM_ABI
-  _OutIter operator()(_Iter __first, _Sent __last,
-                      _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const {
+    requires(forward_iterator<_Iter> || random_access_iterator<_OutIter>) && indirectly_copyable<_Iter, _OutIter> &&
+            uniform_random_bit_generator<remove_reference_t<_Gen>>
+  _LIBCPP_HIDE_FROM_ABI _OutIter
+  operator()(_Iter __first, _Sent __last, _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const {
     _ClassicGenAdaptor<_Gen> __adapted_gen(__gen);
     return std::__sample<_RangeAlgPolicy>(
         std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen);
   }
 
   template <input_range _Range, weakly_incrementable _OutIter, class _Gen>
-  requires (forward_range<_Range> || random_access_iterator<_OutIter>) &&
-           indirectly_copyable<iterator_t<_Range>, _OutIter> &&
-           uniform_random_bit_generator<remove_reference_t<_Gen>>
-  _LIBCPP_HIDE_FROM_ABI
-  _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const {
-    return (*this)(ranges::begin(__range), ranges::end(__range),
-                   std::move(__out_first), __n, std::forward<_Gen>(__gen));
+    requires(forward_range<_Range> || random_access_iterator<_OutIter>) &&
+            indirectly_copyable<iterator_t<_Range>, _OutIter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
+  _LIBCPP_HIDE_FROM_ABI _OutIter
+  operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const {
+    return (*this)(
+        ranges::begin(__range), ranges::end(__range), std::move(__out_first), __n, std::forward<_Gen>(__gen));
   }
-
 };
 
 } // namespace __sample
 
 inline namespace __cpo {
-  inline constexpr auto sample = __sample::__fn{};
+inline constexpr auto sample = __sample::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H
lib/libcxx/include/__algorithm/ranges_search.h
@@ -28,7 +28,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -69,33 +69,33 @@ struct __fn {
     return {__ret.first, __ret.second};
   }
 
-  template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
-            forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
-            class _Pred = ranges::equal_to,
+  template <forward_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            forward_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
-                              _Iter2 __first2, _Sent2 __last2,
-                              _Pred __pred = {},
-                              _Proj1 __proj1 = {},
-                              _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
     return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
   }
 
   template <forward_range _Range1,
             forward_range _Range2,
-            class _Pred = ranges::equal_to,
+            class _Pred  = ranges::equal_to,
             class _Proj1 = identity,
             class _Proj2 = identity>
     requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
-                                          _Range2&& __range2,
-                                          _Pred __pred = {},
-                                          _Proj1 __proj1 = {},
-                                          _Proj2 __proj2 = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
     auto __first1 = ranges::begin(__range1);
     if constexpr (sized_range<_Range2>) {
       auto __size2 = ranges::size(__range2);
@@ -119,17 +119,16 @@ struct __fn {
         __proj1,
         __proj2);
   }
-
 };
 } // namespace __search
 
 inline namespace __cpo {
-  inline constexpr auto search = __search::__fn{};
+inline constexpr auto search = __search::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H
lib/libcxx/include/__algorithm/ranges_search_n.h
@@ -31,14 +31,13 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __search_n {
 struct __fn {
-
   template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj>
   _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl(
       _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
@@ -59,36 +58,31 @@ struct __fn {
       }
     }
 
-    auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last,
-                                                               __count,
-                                                               __value,
-                                                               __pred,
-                                                               __proj);
+    auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, __count, __value, __pred, __proj);
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
             class _Type,
             class _Pred = ranges::equal_to,
             class _Proj = identity>
     requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  subrange<_Iter> operator()(_Iter __first, _Sent __last,
-                             iter_difference_t<_Iter> __count,
-                             const _Type& __value,
-                             _Pred __pred = {},
-                             _Proj __proj = _Proj{}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first,
+             _Sent __last,
+             iter_difference_t<_Iter> __count,
+             const _Type& __value,
+             _Pred __pred = {},
+             _Proj __proj = _Proj{}) const {
     return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj);
   }
 
   template <forward_range _Range, class _Type, class _Pred = ranges::equal_to, class _Proj = identity>
     requires indirectly_comparable<iterator_t<_Range>, const _Type*, _Pred, _Proj>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_subrange_t<_Range> operator()(_Range&& __range,
-                                         range_difference_t<_Range> __count,
-                                         const _Type& __value,
-                                         _Pred __pred = {},
-                                         _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(
+      _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {})
+      const {
     auto __first = ranges::begin(__range);
     if (__count <= 0)
       return {__first, __first};
@@ -106,12 +100,12 @@ struct __fn {
 } // namespace __search_n
 
 inline namespace __cpo {
-  inline constexpr auto search_n = __search_n::__fn{};
+inline constexpr auto search_n = __search_n::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H
lib/libcxx/include/__algorithm/ranges_set_difference.h
@@ -30,7 +30,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -42,15 +42,14 @@ using set_difference_result = in_out_result<_InIter, _OutIter>;
 namespace __set_difference {
 
 struct __fn {
-  template <
-      input_iterator _InIter1,
-      sentinel_for<_InIter1> _Sent1,
-      input_iterator _InIter2,
-      sentinel_for<_InIter2> _Sent2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()(
       _InIter1 __first1,
@@ -66,22 +65,20 @@ struct __fn {
     return {std::move(__ret.first), std::move(__ret.second)};
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_range _Range1,
+            input_range _Range2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<borrowed_iterator_t<_Range1>, _OutIter>
-    operator()(
-        _Range1&& __range1,
-        _Range2&& __range2,
-        _OutIter __result,
-        _Comp __comp   = {},
-        _Proj1 __proj1 = {},
-        _Proj2 __proj2 = {}) const {
+  operator()(_Range1&& __range1,
+             _Range2&& __range2,
+             _OutIter __result,
+             _Comp __comp   = {},
+             _Proj1 __proj1 = {},
+             _Proj2 __proj2 = {}) const {
     auto __ret = std::__set_difference<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -96,11 +93,11 @@ struct __fn {
 } // namespace __set_difference
 
 inline namespace __cpo {
-  inline constexpr auto set_difference = __set_difference::__fn{};
+inline constexpr auto set_difference = __set_difference::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 #endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
lib/libcxx/include/__algorithm/ranges_set_intersection.h
@@ -28,7 +28,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,15 +40,14 @@ using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
 namespace __set_intersection {
 
 struct __fn {
-  template <
-      input_iterator _InIter1,
-      sentinel_for<_InIter1> _Sent1,
-      input_iterator _InIter2,
-      sentinel_for<_InIter2> _Sent2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()(
       _InIter1 __first1,
@@ -69,30 +68,22 @@ struct __fn {
     return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      weakly_incrementable _OutIter,
-      class _Comp  = less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
-    requires mergeable<
-        iterator_t<_Range1>,
-        iterator_t<_Range2>,
-        _OutIter,
-        _Comp,
-        _Proj1,
-        _Proj2>
-    _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
-                                                            borrowed_iterator_t<_Range2>,
-                                                            _OutIter>
-    operator()(
-        _Range1&& __range1,
-        _Range2&& __range2,
-        _OutIter __result,
-        _Comp __comp   = {},
-        _Proj1 __proj1 = {},
-        _Proj2 __proj2 = {}) const {
+  template <input_range _Range1,
+            input_range _Range2,
+            weakly_incrementable _OutIter,
+            class _Comp  = less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
+  _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
+                                                          borrowed_iterator_t<_Range2>,
+                                                          _OutIter>
+  operator()(_Range1&& __range1,
+             _Range2&& __range2,
+             _OutIter __result,
+             _Comp __comp   = {},
+             _Proj1 __proj1 = {},
+             _Proj2 __proj2 = {}) const {
     auto __ret = std::__set_intersection<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -107,11 +98,11 @@ struct __fn {
 } // namespace __set_intersection
 
 inline namespace __cpo {
-  inline constexpr auto set_intersection = __set_intersection::__fn{};
+inline constexpr auto set_intersection = __set_intersection::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 #endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H
lib/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
@@ -28,7 +28,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,15 +40,14 @@ using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _Ou
 namespace __set_symmetric_difference {
 
 struct __fn {
-  template <
-      input_iterator _InIter1,
-      sentinel_for<_InIter1> _Sent1,
-      input_iterator _InIter2,
-      sentinel_for<_InIter2> _Sent2,
-      weakly_incrementable _OutIter,
-      class _Comp  = ranges::less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
+            weakly_incrementable _OutIter,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()(
       _InIter1 __first1,
@@ -69,30 +68,22 @@ struct __fn {
     return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      weakly_incrementable _OutIter,
-      class _Comp  = ranges::less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
-    requires mergeable<
-        iterator_t<_Range1>,
-        iterator_t<_Range2>,
-        _OutIter,
-        _Comp,
-        _Proj1,
-        _Proj2>
+  template <input_range _Range1,
+            input_range _Range2,
+            weakly_incrementable _OutIter,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
                                                                   borrowed_iterator_t<_Range2>,
                                                                   _OutIter>
-    operator()(
-        _Range1&& __range1,
-        _Range2&& __range2,
-        _OutIter __result,
-        _Comp __comp   = {},
-        _Proj1 __proj1 = {},
-        _Proj2 __proj2 = {}) const {
+  operator()(_Range1&& __range1,
+             _Range2&& __range2,
+             _OutIter __result,
+             _Comp __comp   = {},
+             _Proj1 __proj1 = {},
+             _Proj2 __proj2 = {}) const {
     auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -107,11 +98,11 @@ struct __fn {
 } // namespace __set_symmetric_difference
 
 inline namespace __cpo {
-  inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{};
+inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 #endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
lib/libcxx/include/__algorithm/ranges_set_union.h
@@ -31,7 +31,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -43,15 +43,14 @@ using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
 namespace __set_union {
 
 struct __fn {
-  template <
-      input_iterator _InIter1,
-      sentinel_for<_InIter1> _Sent1,
-      input_iterator _InIter2,
-      sentinel_for<_InIter2> _Sent2,
-      weakly_incrementable _OutIter,
-      class _Comp  = ranges::less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
+            weakly_incrementable _OutIter,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
   _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()(
       _InIter1 __first1,
@@ -72,30 +71,20 @@ struct __fn {
     return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
   }
 
-  template <
-      input_range _Range1,
-      input_range _Range2,
-      weakly_incrementable _OutIter,
-      class _Comp  = ranges::less,
-      class _Proj1 = identity,
-      class _Proj2 = identity>
-    requires mergeable<
-        iterator_t<_Range1>,
-        iterator_t<_Range2>,
-        _OutIter,
-        _Comp,
-        _Proj1,
-        _Proj2>
-  _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>,
-                                                   borrowed_iterator_t<_Range2>,
-                                                   _OutIter>
-    operator()(
-        _Range1&& __range1,
-        _Range2&& __range2,
-        _OutIter __result,
-        _Comp __comp   = {},
-        _Proj1 __proj1 = {},
-        _Proj2 __proj2 = {}) const {
+  template <input_range _Range1,
+            input_range _Range2,
+            weakly_incrementable _OutIter,
+            class _Comp  = ranges::less,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
+  _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
+  operator()(_Range1&& __range1,
+             _Range2&& __range2,
+             _OutIter __result,
+             _Comp __comp   = {},
+             _Proj1 __proj1 = {},
+             _Proj2 __proj2 = {}) const {
     auto __ret = std::__set_union<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
@@ -110,12 +99,12 @@ struct __fn {
 } // namespace __set_union
 
 inline namespace __cpo {
-  inline constexpr auto set_union = __set_union::__fn{};
+inline constexpr auto set_union = __set_union::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
lib/libcxx/include/__algorithm/ranges_shuffle.h
@@ -23,15 +23,15 @@
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
 #include <__ranges/dangling.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -39,33 +39,29 @@ namespace ranges {
 namespace __shuffle {
 
 struct __fn {
-
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Gen>
-  requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
-  _LIBCPP_HIDE_FROM_ABI
-  _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const {
+    requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
+  _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const {
     _ClassicGenAdaptor<_Gen> __adapted_gen(__gen);
     return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen);
   }
 
-  template<random_access_range _Range, class _Gen>
-  requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
-  _LIBCPP_HIDE_FROM_ABI
-  borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
+  template <random_access_range _Range, class _Gen>
+    requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
     return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen));
   }
-
 };
 
 } // namespace __shuffle
 
 inline namespace __cpo {
-  inline constexpr auto shuffle = __shuffle::__fn{};
+inline constexpr auto shuffle = __shuffle::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
lib/libcxx/include/__algorithm/ranges_sort.h
@@ -31,7 +31,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,8 +40,8 @@ namespace __sort {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -52,15 +52,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -68,12 +68,12 @@ struct __fn {
 } // namespace __sort
 
 inline namespace __cpo {
-  inline constexpr auto sort = __sort::__fn{};
+inline constexpr auto sort = __sort::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SORT_H
lib/libcxx/include/__algorithm/ranges_sort_heap.h
@@ -32,7 +32,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,8 +41,8 @@ namespace __sort_heap {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr static
-  _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
+  __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -53,15 +53,15 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -69,12 +69,12 @@ struct __fn {
 } // namespace __sort_heap
 
 inline namespace __cpo {
-  inline constexpr auto sort_heap = __sort_heap::__fn{};
+inline constexpr auto sort_heap = __sort_heap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H
lib/libcxx/include/__algorithm/ranges_stable_partition.h
@@ -26,15 +26,15 @@
 #include <__ranges/concepts.h>
 #include <__ranges/dangling.h>
 #include <__ranges/subrange.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -42,47 +42,46 @@ namespace ranges {
 namespace __stable_partition {
 
 struct __fn {
-
   template <class _Iter, class _Sent, class _Proj, class _Pred>
-  _LIBCPP_HIDE_FROM_ABI static
-  subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl(
-      _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
+  _LIBCPP_HIDE_FROM_ABI static subrange<__remove_cvref_t<_Iter>>
+  __stable_partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_pred = std::__make_projected(__pred, __proj);
-    auto __result = std::__stable_partition<_RangeAlgPolicy>(
+    auto __result           = std::__stable_partition<_RangeAlgPolicy>(
         std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>());
 
     return {std::move(__result), std::move(__last_iter)};
   }
 
-  template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+  template <bidirectional_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj = identity,
             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
-  requires permutable<_Iter>
-  _LIBCPP_HIDE_FROM_ABI
-  subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+    requires permutable<_Iter>
+  _LIBCPP_HIDE_FROM_ABI subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
     return __stable_partition_fn_impl(__first, __last, __pred, __proj);
   }
 
-  template <bidirectional_range _Range, class _Proj = identity,
+  template <bidirectional_range _Range,
+            class _Proj = identity,
             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
-  requires permutable<iterator_t<_Range>>
-  _LIBCPP_HIDE_FROM_ABI
-  borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+    requires permutable<iterator_t<_Range>>
+  _LIBCPP_HIDE_FROM_ABI borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
     return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
   }
-
 };
 
 } // namespace __stable_partition
 
 inline namespace __cpo {
-  inline constexpr auto stable_partition = __stable_partition::__fn{};
+inline constexpr auto stable_partition = __stable_partition::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H
lib/libcxx/include/__algorithm/ranges_stable_sort.h
@@ -31,7 +31,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -40,8 +40,7 @@ namespace __stable_sort {
 
 struct __fn {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
-  _LIBCPP_HIDE_FROM_ABI
-  static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  _LIBCPP_HIDE_FROM_ABI static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
@@ -52,15 +51,14 @@ struct __fn {
 
   template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<_Iter, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI
-  _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
     return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
   }
 
   template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
     requires sortable<iterator_t<_Range>, _Comp, _Proj>
-  _LIBCPP_HIDE_FROM_ABI
-  borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
     return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
   }
 };
@@ -68,12 +66,12 @@ struct __fn {
 } // namespace __stable_sort
 
 inline namespace __cpo {
-  inline constexpr auto stable_sort = __stable_sort::__fn{};
+inline constexpr auto stable_sort = __stable_sort::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H
lib/libcxx/include/__algorithm/ranges_starts_with.h
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_RANGES_STARTS_WITH_H
+#define _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
+
+#include <__algorithm/in_in_result.h>
+#include <__algorithm/ranges_mismatch.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __starts_with {
+struct __fn {
+  template <input_iterator _Iter1,
+            sentinel_for<_Iter1> _Sent1,
+            input_iterator _Iter2,
+            sentinel_for<_Iter2> _Sent2,
+            class _Pred  = ranges::equal_to,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Iter1 __first1,
+      _Sent1 __last1,
+      _Iter2 __first2,
+      _Sent2 __last2,
+      _Pred __pred   = {},
+      _Proj1 __proj1 = {},
+      _Proj2 __proj2 = {}) const {
+    return __mismatch::__fn::__go(
+               std::move(__first1),
+               std::move(__last1),
+               std::move(__first2),
+               std::move(__last2),
+               __pred,
+               __proj1,
+               __proj2)
+               .in2 == __last2;
+  }
+
+  template <input_range _Range1,
+            input_range _Range2,
+            class _Pred  = ranges::equal_to,
+            class _Proj1 = identity,
+            class _Proj2 = identity>
+    requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
+      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+    return __mismatch::__fn::__go(
+               ranges::begin(__range1),
+               ranges::end(__range1),
+               ranges::begin(__range2),
+               ranges::end(__range2),
+               __pred,
+               __proj1,
+               __proj2)
+               .in2 == ranges::end(__range2);
+  }
+};
+} // namespace __starts_with
+inline namespace __cpo {
+inline constexpr auto starts_with = __starts_with::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
lib/libcxx/include/__algorithm/ranges_swap_ranges.h
@@ -24,7 +24,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,8 +35,7 @@ using swap_ranges_result = in_in_result<_I1, _I2>;
 
 namespace __swap_ranges {
 struct __fn {
-  template <input_iterator _I1, sentinel_for<_I1> _S1,
-            input_iterator _I2, sentinel_for<_I2> _S2>
+  template <input_iterator _I1, sentinel_for<_I1> _S1, input_iterator _I2, sentinel_for<_I2> _S2>
     requires indirectly_swappable<_I1, _I2>
   _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2>
   operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const {
@@ -47,22 +46,20 @@ struct __fn {
 
   template <input_range _R1, input_range _R2>
     requires indirectly_swappable<iterator_t<_R1>, iterator_t<_R2>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
+  _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
   operator()(_R1&& __r1, _R2&& __r2) const {
-    return operator()(ranges::begin(__r1), ranges::end(__r1),
-                      ranges::begin(__r2), ranges::end(__r2));
+    return operator()(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2));
   }
 };
 } // namespace __swap_ranges
 
 inline namespace __cpo {
-  inline constexpr auto swap_ranges = __swap_ranges::__fn{};
+inline constexpr auto swap_ranges = __swap_ranges::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H
lib/libcxx/include/__algorithm/ranges_transform.h
@@ -26,7 +26,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,15 +41,9 @@ using binary_transform_result = in_in_out_result<_I1, _I2, _O1>;
 namespace __transform {
 struct __fn {
 private:
-  template <class _InIter, class _Sent,
-            class _OutIter,
-            class _Func,
-            class _Proj>
-  _LIBCPP_HIDE_FROM_ABI static constexpr
-  unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last,
-                                                    _OutIter __result,
-                                                    _Func& __operation,
-                                                    _Proj& __projection) {
+  template <class _InIter, class _Sent, class _OutIter, class _Func, class _Proj>
+  _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter>
+  __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) {
     while (__first != __last) {
       *__result = std::invoke(__operation, std::invoke(__projection, *__first));
       ++__first;
@@ -59,76 +53,80 @@ private:
     return {std::move(__first), std::move(__result)};
   }
 
-  template <class _InIter1, class _Sent1,
-            class _InIter2, class _Sent2,
+  template <class _InIter1,
+            class _Sent1,
+            class _InIter2,
+            class _Sent2,
             class _OutIter,
             class _Func,
             class _Proj1,
             class _Proj2>
   _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter>
-  __binary(_InIter1 __first1, _Sent1 __last1,
-           _InIter2 __first2, _Sent2 __last2,
+  __binary(_InIter1 __first1,
+           _Sent1 __last1,
+           _InIter2 __first2,
+           _Sent2 __last2,
            _OutIter __result,
            _Func& __binary_operation,
            _Proj1& __projection1,
            _Proj2& __projection2) {
     while (__first1 != __last1 && __first2 != __last2) {
-      *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1),
-                                                  std::invoke(__projection2, *__first2));
+      *__result =
+          std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2));
       ++__first1;
       ++__first2;
       ++__result;
     }
     return {std::move(__first1), std::move(__first2), std::move(__result)};
   }
+
 public:
-  template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
+  template <input_iterator _InIter,
+            sentinel_for<_InIter> _Sent,
             weakly_incrementable _OutIter,
             copy_constructible _Func,
             class _Proj = identity>
     requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last,
-                                                       _OutIter __result,
-                                                       _Func __operation,
-                                                       _Proj __proj = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<_InIter, _OutIter>
+  operator()(_InIter __first, _Sent __last, _OutIter __result, _Func __operation, _Proj __proj = {}) const {
     return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj);
   }
 
-  template <input_range _Range,
-            weakly_incrementable _OutIter,
-            copy_constructible _Func,
-            class _Proj = identity>
+  template <input_range _Range, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj = identity>
     requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected<iterator_t<_Range>, _Proj>>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range,
-                                                                           _OutIter __result,
-                                                                           _Func __operation,
-                                                                           _Proj __projection = {}) const {
+  _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<borrowed_iterator_t<_Range>, _OutIter>
+  operator()(_Range&& __range, _OutIter __result, _Func __operation, _Proj __projection = {}) const {
     return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection);
   }
 
-  template <input_iterator _InIter1, sentinel_for<_InIter1> _Sent1,
-            input_iterator _InIter2, sentinel_for<_InIter2> _Sent2,
+  template <input_iterator _InIter1,
+            sentinel_for<_InIter1> _Sent1,
+            input_iterator _InIter2,
+            sentinel_for<_InIter2> _Sent2,
             weakly_incrementable _OutIter,
             copy_constructible _Func,
             class _Proj1 = identity,
             class _Proj2 = identity>
-    requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>,
-                                                                     projected<_InIter2, _Proj2>>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1,
-                                                                   _InIter2 __first2, _Sent2 __last2,
-                                                                   _OutIter __result,
-                                                                   _Func __binary_operation,
-                                                                   _Proj1 __projection1 = {},
-                                                                   _Proj2 __projection2 = {}) const {
-    return __binary(std::move(__first1), std::move(__last1),
-                    std::move(__first2), std::move(__last2),
-                    std::move(__result),
-                    __binary_operation,
-                    __projection1,
-                    __projection2);
+    requires indirectly_writable<_OutIter,
+                                 indirect_result_t<_Func&, projected<_InIter1, _Proj1>, projected<_InIter2, _Proj2>>>
+  _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(
+      _InIter1 __first1,
+      _Sent1 __last1,
+      _InIter2 __first2,
+      _Sent2 __last2,
+      _OutIter __result,
+      _Func __binary_operation,
+      _Proj1 __projection1 = {},
+      _Proj2 __projection2 = {}) const {
+    return __binary(
+        std::move(__first1),
+        std::move(__last1),
+        std::move(__first2),
+        std::move(__last2),
+        std::move(__result),
+        __binary_operation,
+        __projection1,
+        __projection2);
   }
 
   template <input_range _Range1,
@@ -137,34 +135,38 @@ public:
             copy_constructible _Func,
             class _Proj1 = identity,
             class _Proj2 = identity>
-    requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>,
-                                                                     projected<iterator_t<_Range2>, _Proj2>>>
-  _LIBCPP_HIDE_FROM_ABI constexpr
-  binary_transform_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
+    requires indirectly_writable<
+        _OutIter,
+        indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>>
+  _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<borrowed_iterator_t<_Range1>,
+                                                          borrowed_iterator_t<_Range2>,
+                                                          _OutIter>
   operator()(_Range1&& __range1,
              _Range2&& __range2,
              _OutIter __result,
              _Func __binary_operation,
              _Proj1 __projection1 = {},
              _Proj2 __projection2 = {}) const {
-    return __binary(ranges::begin(__range1), ranges::end(__range1),
-                    ranges::begin(__range2), ranges::end(__range2),
-                    std::move(__result),
-                    __binary_operation,
-                    __projection1,
-                    __projection2);
+    return __binary(
+        ranges::begin(__range1),
+        ranges::end(__range1),
+        ranges::begin(__range2),
+        ranges::end(__range2),
+        std::move(__result),
+        __binary_operation,
+        __projection1,
+        __projection2);
   }
-
 };
 } // namespace __transform
 
 inline namespace __cpo {
-  inline constexpr auto transform = __transform::__fn{};
+inline constexpr auto transform = __transform::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H
lib/libcxx/include/__algorithm/ranges_unique.h
@@ -32,48 +32,46 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __unique {
 
-  struct __fn {
-    template <
-        permutable _Iter,
-        sentinel_for<_Iter> _Sent,
-        class _Proj                                                  = identity,
-        indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
-    _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
-    operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
-      auto __ret = std::__unique<_RangeAlgPolicy>(
-          std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
-      return {std::move(__ret.first), std::move(__ret.second)};
-    }
+struct __fn {
+  template <permutable _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Proj                                                  = identity,
+            indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+    auto __ret =
+        std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
+    return {std::move(__ret.first), std::move(__ret.second)};
+  }
 
-    template <
-        forward_range _Range,
-        class _Proj                                                               = identity,
-        indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
-      requires permutable<iterator_t<_Range>>
-    _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
-    operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
-      auto __ret = std::__unique<_RangeAlgPolicy>(
-          ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
-      return {std::move(__ret.first), std::move(__ret.second)};
-    }
-  };
+  template <forward_range _Range,
+            class _Proj                                                               = identity,
+            indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
+    requires permutable<iterator_t<_Range>>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+    auto __ret = std::__unique<_RangeAlgPolicy>(
+        ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
+    return {std::move(__ret.first), std::move(__ret.second)};
+  }
+};
 
 } // namespace __unique
 
 inline namespace __cpo {
-  inline constexpr auto unique = __unique::__fn{};
+inline constexpr auto unique = __unique::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
lib/libcxx/include/__algorithm/ranges_unique_copy.h
@@ -21,7 +21,6 @@
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/projected.h>
-#include <__iterator/readable_traits.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
 #include <__ranges/dangling.h>
@@ -33,7 +32,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -87,9 +86,9 @@ struct __fn {
             class _Proj                                                               = identity,
             indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
     requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
-      (forward_iterator<iterator_t<_Range>> ||
-       (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
-       indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
+             (forward_iterator<iterator_t<_Range>> ||
+              (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
+              indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
   _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<borrowed_iterator_t<_Range>, _OutIter>
   operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __ret = std::__unique_copy<_RangeAlgPolicy>(
@@ -111,6 +110,6 @@ inline constexpr auto unique_copy = __unique_copy::__fn{};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
lib/libcxx/include/__algorithm/ranges_upper_bound.h
@@ -25,51 +25,50 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 namespace __upper_bound {
 struct __fn {
-  template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+  template <forward_iterator _Iter,
+            sentinel_for<_Iter> _Sent,
+            class _Type,
+            class _Proj                                                             = identity,
             indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
+  operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
       return !std::invoke(__comp, __rhs, __lhs);
     };
 
-    return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
+    return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
   }
 
-  template <forward_range _Range, class _Type, class _Proj = identity,
+  template <forward_range _Range,
+            class _Type,
+            class _Proj                                                                          = identity,
             indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
-  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
-  borrowed_iterator_t<_Range> operator()(_Range&& __r,
-                                         const _Type& __value,
-                                         _Comp __comp = {},
-                                         _Proj __proj = {}) const {
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
       return !std::invoke(__comp, __rhs, __lhs);
     };
 
-    return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r),
-                                                   ranges::end(__r),
-                                                   __value,
-                                                   __comp_lhs_rhs_swapped,
-                                                   __proj);
+    return std::__lower_bound<_RangeAlgPolicy>(
+        ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj);
   }
 };
 } // namespace __upper_bound
 
 inline namespace __cpo {
-  inline constexpr auto upper_bound = __upper_bound::__fn{};
+inline constexpr auto upper_bound = __upper_bound::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H
lib/libcxx/include/__algorithm/rotate.h
@@ -15,9 +15,9 @@
 #include <__algorithm/swap_ranges.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_trivially_move_assignable.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__algorithm/sample.h
@@ -16,8 +16,8 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__random/uniform_int_distribution.h>
+#include <__type_traits/common_type.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -77,7 +77,7 @@ _LIBCPP_INLINE_VISIBILITY
 _SampleIterator __sample(_PopulationIterator __first,
                          _PopulationSentinel __last, _SampleIterator __output_iter,
                          _Distance __n, _UniformRandomNumberGenerator& __g) {
-  _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number.");
 
   using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>;
   using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
@@ -88,22 +88,22 @@ _SampleIterator __sample(_PopulationIterator __first,
       __g, _PopIterCategory());
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _PopulationIterator, class _SampleIterator, class _Distance,
           class _UniformRandomNumberGenerator>
 inline _LIBCPP_INLINE_VISIBILITY
 _SampleIterator sample(_PopulationIterator __first,
                        _PopulationIterator __last, _SampleIterator __output_iter,
                        _Distance __n, _UniformRandomNumberGenerator&& __g) {
-  static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
-                __is_cpp17_random_access_iterator<_SampleIterator>::value,
+  static_assert(__has_forward_iterator_category<_PopulationIterator>::value ||
+                __has_random_access_iterator_category<_SampleIterator>::value,
                 "SampleIterator must meet the requirements of RandomAccessIterator");
 
   return std::__sample<_ClassicAlgPolicy>(
       std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/search.h
@@ -14,12 +14,13 @@
 #include <__algorithm/iterator_operations.h>
 #include <__config>
 #include <__functional/identity.h>
+#include <__functional/invoke.h>
 #include <__iterator/advance.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/is_callable.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -126,8 +127,8 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
                                    _Pred& __pred,
                                    _Proj1& __proj1,
                                    _Proj2& __proj2,
-                                   __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value
-                                              && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) {
+                                   __enable_if_t<__has_random_access_iterator_category<_Iter1>::value
+                                              && __has_random_access_iterator_category<_Iter2>::value>* = nullptr) {
 
   auto __size2 = __last2 - __first2;
   if (__size2 == 0)
@@ -158,10 +159,10 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
                                    _Pred& __pred,
                                    _Proj1& __proj1,
                                    _Proj2& __proj2,
-                                   __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
-                                              && __is_cpp17_forward_iterator<_Iter2>::value
-                                              && !(__is_cpp17_random_access_iterator<_Iter1>::value
-                                                && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) {
+                                   __enable_if_t<__has_forward_iterator_category<_Iter1>::value
+                                              && __has_forward_iterator_category<_Iter2>::value
+                                              && !(__has_random_access_iterator_category<_Iter1>::value
+                                                && __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
   return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1,
                                                        __first2, __last2,
                                                        __pred,
@@ -187,7 +188,7 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
   return std::search(__first1, __last1, __first2, __last2, __equal_to());
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _ForwardIterator, class _Searcher>
 _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
 search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) {
lib/libcxx/include/__algorithm/search_n.h
@@ -14,14 +14,15 @@
 #include <__algorithm/iterator_operations.h>
 #include <__config>
 #include <__functional/identity.h>
+#include <__functional/invoke.h>
 #include <__iterator/advance.h>
 #include <__iterator/concepts.h>
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/is_callable.h>
 #include <__utility/convert_to_integral.h>
 #include <__utility/pair.h>
-#include <type_traits>  // __convert_to_integral
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -129,7 +130,7 @@ pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last,
                                    const _Type& __value,
                                    _Pred& __pred,
                                    _Proj& __proj,
-                                   __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) {
+                                   __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
   return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last,
                                                                __count,
                                                                __value,
@@ -149,8 +150,8 @@ pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last,
                                      const _Type& __value,
                                      _Pred& __pred,
                                      _Proj& __proj,
-                                     __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
-                                               && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) {
+                                     __enable_if_t<__has_forward_iterator_category<_Iter1>::value
+                                               && !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) {
   return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last,
                                                          __count,
                                                          __value,
lib/libcxx/include/__algorithm/set_difference.h
@@ -17,9 +17,9 @@
 #include <__functional/identity.h>
 #include <__functional/invoke.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -66,14 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
     _InputIterator2 __first2,
     _InputIterator2 __last2,
     _OutputIterator __result) {
-  return std::__set_difference<_ClassicAlgPolicy>(
-      __first1,
-      __last1,
-      __first2,
-      __last2,
-      __result,
-      __less<typename iterator_traits<_InputIterator1>::value_type,
-             typename iterator_traits<_InputIterator2>::value_type>()).second;
+  return std::__set_difference<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __result, __less<>()).second;
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/set_intersection.h
@@ -89,8 +89,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_i
              std::move(__first2),
              std::move(__last2),
              std::move(__result),
-             __less<typename iterator_traits<_InputIterator1>::value_type,
-                    typename iterator_traits<_InputIterator2>::value_type>())
+             __less<>())
       .__out_;
 }
 
lib/libcxx/include/__algorithm/set_symmetric_difference.h
@@ -96,8 +96,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri
       std::move(__first2),
       std::move(__last2),
       std::move(__result),
-      __less<typename iterator_traits<_InputIterator1>::value_type,
-             typename iterator_traits<_InputIterator2>::value_type>());
+      __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/set_union.h
@@ -92,8 +92,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union(
       std::move(__first2),
       std::move(__last2),
       std::move(__result),
-      __less<typename iterator_traits<_InputIterator1>::value_type,
-             typename iterator_traits<_InputIterator2>::value_type>());
+      __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/shift_left.h
@@ -12,7 +12,6 @@
 #include <__algorithm/move.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -20,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY constexpr
@@ -33,7 +32,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last,
     }
 
     _ForwardIterator __m = __first;
-    if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
+    if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
         if (__n >= __last - __first) {
             return __first;
         }
@@ -49,7 +48,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last,
     return _VSTD::move(__m, __last, __first);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/shift_right.h
@@ -15,7 +15,6 @@
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__utility/swap.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -23,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY constexpr
@@ -35,14 +34,14 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last,
         return __first;
     }
 
-    if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
+    if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
         decltype(__n) __d = __last - __first;
         if (__n >= __d) {
             return __last;
         }
         _ForwardIterator __m = __first + (__d - __n);
         return _VSTD::move_backward(__first, __m, __last);
-    } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) {
+    } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
         _ForwardIterator __m = __last;
         for (; __n > 0; --__n) {
             if (__m == __first) {
@@ -95,7 +94,7 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last,
     }
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/shuffle.h
@@ -11,7 +11,6 @@
 
 #include <__algorithm/iterator_operations.h>
 #include <__config>
-#include <__debug>
 #include <__iterator/iterator_traits.h>
 #include <__random/uniform_int_distribution.h>
 #include <__utility/forward.h>
@@ -29,9 +28,9 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer {
+class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {
 public:
-  __libcpp_debug_randomizer() {
+  _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() {
     __state_ = __seed();
     __inc_ = __state_ + 0xda3e39cb94b95bdbULL;
     __inc_ = (__inc_ << 1) | 1;
@@ -65,11 +64,11 @@ private:
 
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
   || defined(_LIBCPP_BUILDING_LIBRARY)
-class _LIBCPP_TYPE_VIS __rs_default;
+class _LIBCPP_EXPORTED_FROM_ABI __rs_default;
 
-_LIBCPP_FUNC_VIS __rs_default __rs_get();
+_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
 
-class _LIBCPP_TYPE_VIS __rs_default
+class _LIBCPP_EXPORTED_FROM_ABI __rs_default
 {
     static unsigned __c_;
 
@@ -85,13 +84,13 @@ public:
 
     result_type operator()();
 
-    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
-    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;}
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;}
 
-    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
+    friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
 };
 
-_LIBCPP_FUNC_VIS __rs_default __rs_get();
+_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
 
 template <class _RandomAccessIterator>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
lib/libcxx/include/__algorithm/sift_down.h
@@ -19,6 +19,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
@@ -83,7 +86,7 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
                   typename iterator_traits<_RandomAccessIterator>::difference_type __len)
 {
     using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
-    _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2");
 
     _RandomAccessIterator __hole = __first;
     _RandomAccessIterator __child_i = __first;
@@ -111,4 +114,6 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H
lib/libcxx/include/__algorithm/sort.h
@@ -11,23 +11,27 @@
 
 #include <__algorithm/comp.h>
 #include <__algorithm/comp_ref_type.h>
+#include <__algorithm/iter_swap.h>
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/min_element.h>
 #include <__algorithm/partial_sort.h>
 #include <__algorithm/unwrap_iter.h>
+#include <__assert>
+#include <__bit/blsr.h>
+#include <__bit/countl.h>
+#include <__bit/countr.h>
 #include <__config>
-#include <__debug>
 #include <__debug_utils/randomize_range.h>
+#include <__debug_utils/strict_weak_ordering_check.h>
 #include <__functional/operations.h>
 #include <__functional/ranges_operations.h>
 #include <__iterator/iterator_traits.h>
-#include <__memory/destruct_n.h>
-#include <__memory/unique_ptr.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/disjunction.h>
 #include <__type_traits/is_arithmetic.h>
-#include <__type_traits/is_trivially_copy_assignable.h>
-#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_constant_evaluated.h>
 #include <__utility/move.h>
-#include <bit>
+#include <__utility/pair.h>
 #include <climits>
 #include <cstdint>
 
@@ -37,52 +41,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// Wraps an algorithm policy tag and a comparator in a single struct, used to pass the policy tag around without
-// changing the number of template arguments (to keep the ABI stable). This is only used for the "range" policy tag.
-//
-// To create an object of this type, use `_WrapAlgPolicy<T, C>::type` -- see the specialization below for the rationale.
-template <class _PolicyT, class _CompT, class = void>
-struct _WrapAlgPolicy {
-  using type = _WrapAlgPolicy;
-
-  using _AlgPolicy = _PolicyT;
-  using _Comp = _CompT;
-  _Comp& __comp;
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-  _WrapAlgPolicy(_Comp& __c) : __comp(__c) {}
-};
-
-// Specialization for the "classic" policy tag that avoids creating a struct and simply defines an alias for the
-// comparator. When unwrapping, a pristine comparator is always considered to have the "classic" tag attached. Passing
-// the pristine comparator where possible allows using template instantiations from the dylib.
-template <class _PolicyT, class _CompT>
-struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t<std::is_same<_PolicyT, _ClassicAlgPolicy>::value> > {
-  using type = _CompT;
-};
-
-// Unwraps a pristine functor (e.g. `std::less`) as if it were wrapped using `_WrapAlgPolicy`. The policy tag is always
-// set to "classic".
-template <class _CompT>
-struct _UnwrapAlgPolicy {
-  using _AlgPolicy = _ClassicAlgPolicy;
-  using _Comp = _CompT;
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
-  _Comp __get_comp(_Comp __comp) { return __comp; }
-};
-
-// Unwraps a `_WrapAlgPolicy` struct.
-template <class... _Ts>
-struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > {
-  using _Wrapped = _WrapAlgPolicy<_Ts...>;
-  using _AlgPolicy = typename _Wrapped::_AlgPolicy;
-  using _Comp = typename _Wrapped::_Comp;
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
-  _Comp __get_comp(_Wrapped& __w) { return __w.__comp; }
-};
-
 // stable, 2-3 compares, 0-2 swaps
 
 template <class _AlgPolicy, class _Compare, class _ForwardIterator>
@@ -126,78 +84,53 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIte
 
 template <class _AlgPolicy, class _Compare, class _ForwardIterator>
 _LIBCPP_HIDE_FROM_ABI
-unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
+void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
                  _Compare __c) {
-  using _Ops = _IterOps<_AlgPolicy>;
-
-  unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
+  using _Ops   = _IterOps<_AlgPolicy>;
+  std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
   if (__c(*__x4, *__x3)) {
     _Ops::iter_swap(__x3, __x4);
-    ++__r;
     if (__c(*__x3, *__x2)) {
       _Ops::iter_swap(__x2, __x3);
-      ++__r;
       if (__c(*__x2, *__x1)) {
         _Ops::iter_swap(__x1, __x2);
-        ++__r;
       }
     }
   }
-  return __r;
 }
 
 // stable, 4-10 compares, 0-9 swaps
 
-template <class _WrappedComp, class _ForwardIterator>
-_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
-                                _ForwardIterator __x4, _ForwardIterator __x5, _WrappedComp __wrapped_comp) {
-  using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
-  using _AlgPolicy = typename _Unwrap::_AlgPolicy;
+template <class _AlgPolicy, class _Comp, class _ForwardIterator>
+_LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+                                   _ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) {
   using _Ops = _IterOps<_AlgPolicy>;
 
-  using _Compare = typename _Unwrap::_Comp;
-  _Compare __c = _Unwrap::__get_comp(__wrapped_comp);
-
-  unsigned __r = std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c);
-  if (__c(*__x5, *__x4)) {
+  std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp);
+  if (__comp(*__x5, *__x4)) {
     _Ops::iter_swap(__x4, __x5);
-    ++__r;
-    if (__c(*__x4, *__x3)) {
+    if (__comp(*__x4, *__x3)) {
       _Ops::iter_swap(__x3, __x4);
-      ++__r;
-      if (__c(*__x3, *__x2)) {
+      if (__comp(*__x3, *__x2)) {
         _Ops::iter_swap(__x2, __x3);
-        ++__r;
-        if (__c(*__x2, *__x1)) {
+        if (__comp(*__x2, *__x1)) {
           _Ops::iter_swap(__x1, __x2);
-          ++__r;
         }
       }
     }
   }
-  return __r;
-}
-
-template <class _AlgPolicy, class _Compare, class _ForwardIterator>
-_LIBCPP_HIDE_FROM_ABI unsigned __sort5_wrap_policy(
-    _ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5,
-    _Compare __c) {
-  using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type;
-  _WrappedComp __wrapped_comp(__c);
-  return std::__sort5<_WrappedComp>(
-      std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __wrapped_comp);
 }
 
 // The comparator being simple is a prerequisite for using the branchless optimization.
 template <class _Tp>
 struct __is_simple_comparator : false_type {};
-template <class _Tp>
-struct __is_simple_comparator<__less<_Tp>&> : true_type {};
+template <>
+struct __is_simple_comparator<__less<>&> : true_type {};
 template <class _Tp>
 struct __is_simple_comparator<less<_Tp>&> : true_type {};
 template <class _Tp>
 struct __is_simple_comparator<greater<_Tp>&> : true_type {};
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <>
 struct __is_simple_comparator<ranges::less&> : true_type {};
 template <>
@@ -206,9 +139,16 @@ struct __is_simple_comparator<ranges::greater&> : true_type {};
 
 template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
 using __use_branchless_sort =
-    integral_constant<bool, __is_cpp17_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
+    integral_constant<bool, __libcpp_is_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
                                 is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>;
 
+namespace __detail {
+
+// Size in bits for the bitset in use.
+enum { __block_size = sizeof(uint64_t) * 8 };
+
+} // namespace __detail
+
 // Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary.
 template <class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
@@ -268,10 +208,15 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2,
   std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c);
 }
 
-template <class, class _Compare, class _RandomAccessIterator>
+template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
-__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
-                         _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
+__sort5_maybe_branchless(
+    _RandomAccessIterator __x1,
+    _RandomAccessIterator __x2,
+    _RandomAccessIterator __x3,
+    _RandomAccessIterator __x4,
+    _RandomAccessIterator __x5,
+    _Compare __c) {
   std::__cond_swap<_Compare>(__x1, __x2, __c);
   std::__cond_swap<_Compare>(__x4, __x5, __c);
   std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c);
@@ -284,7 +229,8 @@ template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
 __sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
                          _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
-  std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c);
+  std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>(
+      std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c);
 }
 
 // Assumes size > 0
@@ -300,34 +246,49 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir
   }
 }
 
+// Sort the iterator range [__first, __last) using the comparator __comp using
+// the insertion sort algorithm.
 template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
 _LIBCPP_HIDE_FROM_ABI
 void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
   using _Ops = _IterOps<_AlgPolicy>;
 
   typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-  if (__first != __last) {
-    _BidirectionalIterator __i = __first;
-    for (++__i; __i != __last; ++__i) {
-      _BidirectionalIterator __j = __i;
-      value_type __t(_Ops::__iter_move(__j));
-      for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
+  if (__first == __last)
+    return;
+  _BidirectionalIterator __i = __first;
+  for (++__i; __i != __last; ++__i) {
+    _BidirectionalIterator __j = __i;
+    --__j;
+    if (__comp(*__i, *__j)) {
+      value_type __t(_Ops::__iter_move(__i));
+      _BidirectionalIterator __k = __j;
+      __j                        = __i;
+      do {
         *__j = _Ops::__iter_move(__k);
+        __j  = __k;
+      } while (__j != __first && __comp(__t, *--__k));
       *__j = std::move(__t);
     }
   }
 }
 
+// Sort the iterator range [__first, __last) using the comparator __comp using
+// the insertion sort algorithm.  Insertion sort has two loops, outer and inner.
+// The implementation below has no bounds check (unguarded) for the inner loop.
+// Assumes that there is an element in the position (__first - 1) and that each
+// element in the input range is greater or equal to the element at __first - 1.
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
-_LIBCPP_HIDE_FROM_ABI
-void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+_LIBCPP_HIDE_FROM_ABI void
+__insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIterator __last, _Compare __comp) {
   using _Ops = _IterOps<_AlgPolicy>;
-
   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
   typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-  _RandomAccessIterator __j = __first + difference_type(2);
-  std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp);
-  for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
+  if (__first == __last)
+    return;
+  const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled
+  for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) {
+    _RandomAccessIterator __j = __i - difference_type(1);
     if (__comp(*__i, *__j)) {
       value_type __t(_Ops::__iter_move(__i));
       _RandomAccessIterator __k = __j;
@@ -335,23 +296,20 @@ void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __l
       do {
         *__j = _Ops::__iter_move(__k);
         __j = __k;
-      } while (__j != __first && __comp(__t, *--__k));
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __k != __leftmost,
+            "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above.
       *__j = std::move(__t);
     }
-    __j = __i;
   }
 }
 
-template <class _WrappedComp, class _RandomAccessIterator>
-_LIBCPP_HIDDEN bool __insertion_sort_incomplete(
-    _RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) {
-  using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
-  using _AlgPolicy = typename _Unwrap::_AlgPolicy;
+template <class _AlgPolicy, class _Comp, class _RandomAccessIterator>
+_LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
   using _Ops = _IterOps<_AlgPolicy>;
 
-  using _Compare = typename _Unwrap::_Comp;
-  _Compare __comp = _Unwrap::__get_comp(__wrapped_comp);
-
   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
   switch (__last - __first) {
   case 0:
@@ -359,24 +317,24 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete(
     return true;
   case 2:
     if (__comp(*--__last, *__first))
-      _IterOps<_AlgPolicy>::iter_swap(__first, __last);
+      _Ops::iter_swap(__first, __last);
     return true;
   case 3:
-    std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
+    std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp);
     return true;
   case 4:
-    std::__sort4_maybe_branchless<_AlgPolicy, _Compare>(
+    std::__sort4_maybe_branchless<_AlgPolicy, _Comp>(
         __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
     return true;
   case 5:
-    std::__sort5_maybe_branchless<_AlgPolicy, _Compare>(
+    std::__sort5_maybe_branchless<_AlgPolicy, _Comp>(
         __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3),
         --__last, __comp);
     return true;
   }
   typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
   _RandomAccessIterator __j = __first + difference_type(2);
-  std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp);
+  std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp);
   const unsigned __limit = 8;
   unsigned __count = 0;
   for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
@@ -397,48 +355,380 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete(
   return true;
 }
 
-template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
-_LIBCPP_HIDE_FROM_ABI
-void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
-                           typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) {
+template <class _AlgPolicy, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) {
   using _Ops = _IterOps<_AlgPolicy>;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  // Swap one pair on each iteration as long as both bitsets have at least one
+  // element for swapping.
+  while (__left_bitset != 0 && __right_bitset != 0) {
+    difference_type __tz_left  = __libcpp_ctz(__left_bitset);
+    __left_bitset              = __libcpp_blsr(__left_bitset);
+    difference_type __tz_right = __libcpp_ctz(__right_bitset);
+    __right_bitset             = __libcpp_blsr(__right_bitset);
+    _Ops::iter_swap(__first + __tz_left, __last - __tz_right);
+  }
+}
 
-  typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-  if (__first1 != __last1) {
-    __destruct_n __d(0);
-    unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
-    value_type* __last2 = __first2;
-    ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1));
-    __d.template __incr<value_type>();
-    for (++__last2; ++__first1 != __last1; ++__last2) {
-      value_type* __j2 = __last2;
-      value_type* __i2 = __j2;
-      if (__comp(*__first1, *--__i2)) {
-        ::new ((void*)__j2) value_type(std::move(*__i2));
-        __d.template __incr<value_type>();
-        for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
-          *__j2 = std::move(*__i2);
-        *__j2 = _Ops::__iter_move(__first1);
-      } else {
-        ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1));
-        __d.template __incr<value_type>();
+template <class _Compare,
+          class _RandomAccessIterator,
+          class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
+inline _LIBCPP_HIDE_FROM_ABI void
+__populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) {
+  // Possible vectorization. With a proper "-march" flag, the following loop
+  // will be compiled into a set of SIMD instructions.
+  _RandomAccessIterator __iter = __first;
+  for (int __j = 0; __j < __detail::__block_size;) {
+    bool __comp_result = !__comp(*__iter, __pivot);
+    __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
+    __j++;
+    ++__iter;
+  }
+}
+
+template <class _Compare,
+          class _RandomAccessIterator,
+          class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
+inline _LIBCPP_HIDE_FROM_ABI void
+__populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) {
+  // Possible vectorization. With a proper "-march" flag, the following loop
+  // will be compiled into a set of SIMD instructions.
+  _RandomAccessIterator __iter = __lm1;
+  for (int __j = 0; __j < __detail::__block_size;) {
+    bool __comp_result = __comp(*__iter, __pivot);
+    __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
+    __j++;
+    --__iter;
+  }
+}
+
+template <class _AlgPolicy,
+          class _Compare,
+          class _RandomAccessIterator,
+          class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
+inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks(
+    _RandomAccessIterator& __first,
+    _RandomAccessIterator& __lm1,
+    _Compare __comp,
+    _ValueType& __pivot,
+    uint64_t& __left_bitset,
+    uint64_t& __right_bitset) {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  difference_type __remaining_len = __lm1 - __first + 1;
+  difference_type __l_size;
+  difference_type __r_size;
+  if (__left_bitset == 0 && __right_bitset == 0) {
+    __l_size = __remaining_len / 2;
+    __r_size = __remaining_len - __l_size;
+  } else if (__left_bitset == 0) {
+    // We know at least one side is a full block.
+    __l_size = __remaining_len - __detail::__block_size;
+    __r_size = __detail::__block_size;
+  } else { // if (__right_bitset == 0)
+    __l_size = __detail::__block_size;
+    __r_size = __remaining_len - __detail::__block_size;
+  }
+  // Record the comparison outcomes for the elements currently on the left side.
+  if (__left_bitset == 0) {
+    _RandomAccessIterator __iter = __first;
+    for (int __j = 0; __j < __l_size; __j++) {
+      bool __comp_result = !__comp(*__iter, __pivot);
+      __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
+      ++__iter;
+    }
+  }
+  // Record the comparison outcomes for the elements currently on the right
+  // side.
+  if (__right_bitset == 0) {
+    _RandomAccessIterator __iter = __lm1;
+    for (int __j = 0; __j < __r_size; __j++) {
+      bool __comp_result = __comp(*__iter, __pivot);
+      __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
+      --__iter;
+    }
+  }
+  std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
+  __first += (__left_bitset == 0) ? __l_size : 0;
+  __lm1 -= (__right_bitset == 0) ? __r_size : 0;
+}
+
+template <class _AlgPolicy, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within(
+    _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) {
+  using _Ops = _IterOps<_AlgPolicy>;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  if (__left_bitset) {
+    // Swap within the left side.  Need to find set positions in the reverse
+    // order.
+    while (__left_bitset != 0) {
+      difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset);
+      __left_bitset &= (static_cast<uint64_t>(1) << __tz_left) - 1;
+      _RandomAccessIterator __it = __first + __tz_left;
+      if (__it != __lm1) {
+        _Ops::iter_swap(__it, __lm1);
       }
+      --__lm1;
+    }
+    __first = __lm1 + difference_type(1);
+  } else if (__right_bitset) {
+    // Swap within the right side.  Need to find set positions in the reverse
+    // order.
+    while (__right_bitset != 0) {
+      difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset);
+      __right_bitset &= (static_cast<uint64_t>(1) << __tz_right) - 1;
+      _RandomAccessIterator __it = __lm1 - __tz_right;
+      if (__it != __first) {
+        _Ops::iter_swap(__it, __first);
+      }
+      ++__first;
     }
-    __h.release();
   }
 }
 
-template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
-void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-                 typename iterator_traits<_RandomAccessIterator>::difference_type __depth) {
+// Partition [__first, __last) using the comparator __comp.  *__first has the
+// chosen pivot.  Elements that are equivalent are kept to the left of the
+// pivot.  Returns the iterator for the pivot and a bool value which is true if
+// the provided range is already sorted, false otherwise.  We assume that the
+// length of the range is at least three elements.
+//
+// __bitset_partition uses bitsets for storing outcomes of the comparisons
+// between the pivot and other elements.
+template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
+_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
+__bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
   using _Ops = _IterOps<_AlgPolicy>;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
+  const _RandomAccessIterator __begin = __first;            // used for bounds checking, those are not moved around
+  const _RandomAccessIterator __end = __last; (void)__end;  //
+
+  value_type __pivot(_Ops::__iter_move(__first));
+  // Find the first element greater than the pivot.
+  if (__comp(__pivot, *(__last - difference_type(1)))) {
+    // Not guarded since we know the last element is greater than the pivot.
+    do {
+      ++__first;
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __first != __end,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+    } while (!__comp(__pivot, *__first));
+  } else {
+    while (++__first < __last && !__comp(__pivot, *__first)) {
+    }
+  }
+  // Find the last element less than or equal to the pivot.
+  if (__first < __last) {
+    // It will be always guarded because __introsort will do the median-of-three
+    // before calling this.
+    do {
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __last != __begin,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      --__last;
+    } while (__comp(__pivot, *__last));
+  }
+  // If the first element greater than the pivot is at or after the
+  // last element less than or equal to the pivot, then we have covered the
+  // entire range without swapping elements.  This implies the range is already
+  // partitioned.
+  bool __already_partitioned = __first >= __last;
+  if (!__already_partitioned) {
+    _Ops::iter_swap(__first, __last);
+    ++__first;
+  }
 
+  // In [__first, __last) __last is not inclusive. From now on, it uses last
+  // minus one to be inclusive on both sides.
+  _RandomAccessIterator __lm1 = __last - difference_type(1);
+  uint64_t __left_bitset      = 0;
+  uint64_t __right_bitset     = 0;
+
+  // Reminder: length = __lm1 - __first + 1.
+  while (__lm1 - __first >= 2 * __detail::__block_size - 1) {
+    // Record the comparison outcomes for the elements currently on the left
+    // side.
+    if (__left_bitset == 0)
+      std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset);
+    // Record the comparison outcomes for the elements currently on the right
+    // side.
+    if (__right_bitset == 0)
+      std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset);
+    // Swap the elements recorded to be the candidates for swapping in the
+    // bitsets.
+    std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
+    // Only advance the iterator if all the elements that need to be moved to
+    // other side were moved.
+    __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
+    __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
+  }
+  // Now, we have a less-than a block worth of elements on at least one of the
+  // sides.
+  std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>(
+      __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset);
+  // At least one the bitsets would be empty.  For the non-empty one, we need to
+  // properly partition the elements that appear within that bitset.
+  std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset);
+
+  // Move the pivot to its correct position.
+  _RandomAccessIterator __pivot_pos = __first - difference_type(1);
+  if (__begin != __pivot_pos) {
+    *__begin = _Ops::__iter_move(__pivot_pos);
+  }
+  *__pivot_pos = std::move(__pivot);
+  return std::make_pair(__pivot_pos, __already_partitioned);
+}
+
+// Partition [__first, __last) using the comparator __comp.  *__first has the
+// chosen pivot.  Elements that are equivalent are kept to the right of the
+// pivot.  Returns the iterator for the pivot and a bool value which is true if
+// the provided range is already sorted, false otherwise.  We assume that the
+// length of the range is at least three elements.
+template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
+_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
+__partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  using _Ops = _IterOps<_AlgPolicy>;
   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-  typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-  const difference_type __limit =
-      is_trivially_copy_constructible<value_type>::value && is_trivially_copy_assignable<value_type>::value ? 30 : 6;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
+  _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
+  const _RandomAccessIterator __begin = __first;            // used for bounds checking, those are not moved around
+  const _RandomAccessIterator __end = __last; (void)__end;  //
+  value_type __pivot(_Ops::__iter_move(__first));
+  // Find the first element greater or equal to the pivot.  It will be always
+  // guarded because __introsort will do the median-of-three before calling
+  // this.
+  do {
+    ++__first;
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __first != __end,
+        "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+  } while (__comp(*__first, __pivot));
+
+  // Find the last element less than the pivot.
+  if (__begin == __first - difference_type(1)) {
+    while (__first < __last && !__comp(*--__last, __pivot))
+      ;
+  } else {
+    // Guarded.
+    do {
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __last != __begin,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      --__last;
+    } while (!__comp(*__last, __pivot));
+  }
+
+  // If the first element greater than or equal to the pivot is at or after the
+  // last element less than the pivot, then we have covered the entire range
+  // without swapping elements.  This implies the range is already partitioned.
+  bool __already_partitioned = __first >= __last;
+  // Go through the remaining elements.  Swap pairs of elements (one to the
+  // right of the pivot and the other to left of the pivot) that are not on the
+  // correct side of the pivot.
+  while (__first < __last) {
+    _Ops::iter_swap(__first, __last);
+    do {
+      ++__first;
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __first != __end,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+    } while (__comp(*__first, __pivot));
+    do {
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __last != __begin,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      --__last;
+    } while (!__comp(*__last, __pivot));
+  }
+  // Move the pivot to its correct position.
+  _RandomAccessIterator __pivot_pos = __first - difference_type(1);
+  if (__begin != __pivot_pos) {
+    *__begin = _Ops::__iter_move(__pivot_pos);
+  }
+  *__pivot_pos = std::move(__pivot);
+  return std::make_pair(__pivot_pos, __already_partitioned);
+}
+
+// Similar to the above function.  Elements equivalent to the pivot are put to
+// the left of the pivot.  Returns the iterator to the pivot element.
+template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
+_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
+__partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  using _Ops = _IterOps<_AlgPolicy>;
+  typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
+  // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748
+  _RandomAccessIterator __begin = __first;                  // used for bounds checking, those are not moved around
+  const _RandomAccessIterator __end = __last; (void)__end;  //
+  value_type __pivot(_Ops::__iter_move(__first));
+  if (__comp(__pivot, *(__last - difference_type(1)))) {
+    // Guarded.
+    do {
+      ++__first;
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __first != __end,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+    } while (!__comp(__pivot, *__first));
+  } else {
+    while (++__first < __last && !__comp(__pivot, *__first)) {
+    }
+  }
+
+  if (__first < __last) {
+    // It will be always guarded because __introsort will do the
+    // median-of-three before calling this.
+    do {
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __last != __begin,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      --__last;
+    } while (__comp(__pivot, *__last));
+  }
+  while (__first < __last) {
+    _Ops::iter_swap(__first, __last);
+    do {
+      ++__first;
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __first != __end,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+    } while (!__comp(__pivot, *__first));
+    do {
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __last != __begin,
+          "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+      --__last;
+    } while (__comp(__pivot, *__last));
+  }
+  _RandomAccessIterator __pivot_pos = __first - difference_type(1);
+  if (__begin != __pivot_pos) {
+    *__begin = _Ops::__iter_move(__pivot_pos);
+  }
+  *__pivot_pos = std::move(__pivot);
+  return __first;
+}
+
+// The main sorting function.  Implements introsort combined with other ideas:
+//  - option of using block quick sort for partitioning,
+//  - guarded and unguarded insertion sort for small lengths,
+//  - Tuckey's ninther technique for computing the pivot,
+//  - check on whether partition was not required.
+// The implementation is partly based on Orson Peters' pattern-defeating
+// quicksort, published at: <https://github.com/orlp/pdqsort>.
+template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, bool _UseBitSetPartition>
+void __introsort(_RandomAccessIterator __first,
+                 _RandomAccessIterator __last,
+                 _Compare __comp,
+                 typename iterator_traits<_RandomAccessIterator>::difference_type __depth,
+                 bool __leftmost = true) {
+  using _Ops = _IterOps<_AlgPolicy>;
+  typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+  using _Comp_ref = __comp_ref_type<_Compare>;
+  // Upper bound for using insertion sort for sorting.
+  _LIBCPP_CONSTEXPR difference_type __limit = 24;
+  // Lower bound for using Tuckey's ninther technique for median computation.
+  _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128;
   while (true) {
-  __restart:
     difference_type __len = __last - __first;
     switch (__len) {
     case 0:
@@ -446,7 +736,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
       return;
     case 2:
       if (__comp(*--__last, *__first))
-        _IterOps<_AlgPolicy>::iter_swap(__first, __last);
+        _Ops::iter_swap(__first, __last);
       return;
     case 3:
       std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
@@ -461,131 +751,62 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
           --__last, __comp);
       return;
     }
-    if (__len <= __limit) {
-      std::__insertion_sort_3<_AlgPolicy, _Compare>(__first, __last, __comp);
+    // Use insertion sort if the length of the range is below the specified limit.
+    if (__len < __limit) {
+      if (__leftmost) {
+        std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
+      } else {
+        std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp);
+      }
       return;
     }
-    // __len > 5
     if (__depth == 0) {
       // Fallback to heap sort as Introsort suggests.
       std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp);
       return;
     }
     --__depth;
-    _RandomAccessIterator __m = __first;
-    _RandomAccessIterator __lm1 = __last;
-    --__lm1;
-    unsigned __n_swaps;
     {
-      difference_type __delta;
-      if (__len >= 1000) {
-        __delta = __len / 2;
-        __m += __delta;
-        __delta /= 2;
-        __n_swaps = std::__sort5_wrap_policy<_AlgPolicy, _Compare>(
-            __first, __first + __delta, __m, __m + __delta, __lm1, __comp);
+      difference_type __half_len = __len / 2;
+      // Use Tuckey's ninther technique or median of 3 for pivot selection
+      // depending on the length of the range being sorted.
+      if (__len > __ninther_threshold) {
+        std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp);
+        std::__sort3<_AlgPolicy, _Compare>(
+            __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp);
+        std::__sort3<_AlgPolicy, _Compare>(
+            __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp);
+        std::__sort3<_AlgPolicy, _Compare>(
+            __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp);
+        _Ops::iter_swap(__first, __first + __half_len);
       } else {
-        __delta = __len / 2;
-        __m += __delta;
-        __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, __lm1, __comp);
-      }
-    }
-    // *__m is median
-    // partition [__first, __m) < *__m and *__m <= [__m, __last)
-    // (this inhibits tossing elements equivalent to __m around unnecessarily)
-    _RandomAccessIterator __i = __first;
-    _RandomAccessIterator __j = __lm1;
-    // j points beyond range to be tested, *__m is known to be <= *__lm1
-    // The search going up is known to be guarded but the search coming down isn't.
-    // Prime the downward search with a guard.
-    if (!__comp(*__i, *__m)) // if *__first == *__m
-    {
-      // *__first == *__m, *__first doesn't go in first part
-      // manually guard downward moving __j against __i
-      while (true) {
-        if (__i == --__j) {
-          // *__first == *__m, *__m <= all other elements
-          // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
-          ++__i; // __first + 1
-          __j = __last;
-          if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
-          {
-            while (true) {
-              if (__i == __j)
-                return; // [__first, __last) all equivalent elements
-              if (__comp(*__first, *__i)) {
-                _Ops::iter_swap(__i, __j);
-                ++__n_swaps;
-                ++__i;
-                break;
-              }
-              ++__i;
-            }
-          }
-          // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
-          if (__i == __j)
-            return;
-          while (true) {
-            while (!__comp(*__first, *__i))
-              ++__i;
-            while (__comp(*__first, *--__j))
-              ;
-            if (__i >= __j)
-              break;
-            _Ops::iter_swap(__i, __j);
-            ++__n_swaps;
-            ++__i;
-          }
-          // [__first, __i) == *__first and *__first < [__i, __last)
-          // The first part is sorted, sort the second part
-          // std::__sort<_Compare>(__i, __last, __comp);
-          __first = __i;
-          goto __restart;
-        }
-        if (__comp(*__j, *__m)) {
-          _Ops::iter_swap(__i, __j);
-          ++__n_swaps;
-          break; // found guard for downward moving __j, now use unguarded partition
-        }
-      }
-    }
-    // It is known that *__i < *__m
-    ++__i;
-    // j points beyond range to be tested, *__m is known to be <= *__lm1
-    // if not yet partitioned...
-    if (__i < __j) {
-      // known that *(__i - 1) < *__m
-      // known that __i <= __m
-      while (true) {
-        // __m still guards upward moving __i
-        while (__comp(*__i, *__m))
-          ++__i;
-        // It is now known that a guard exists for downward moving __j
-        while (!__comp(*--__j, *__m))
-          ;
-        if (__i > __j)
-          break;
-        _Ops::iter_swap(__i, __j);
-        ++__n_swaps;
-        // It is known that __m != __j
-        // If __m just moved, follow it
-        if (__m == __i)
-          __m = __j;
-        ++__i;
+        std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp);
       }
     }
-    // [__first, __i) < *__m and *__m <= [__i, __last)
-    if (__i != __m && __comp(*__m, *__i)) {
-      _Ops::iter_swap(__i, __m);
-      ++__n_swaps;
+    // The elements to the left of the current iterator range are already
+    // sorted.  If the current iterator range to be sorted is not the
+    // leftmost part of the entire iterator range and the pivot is same as
+    // the highest element in the range to the left, then we know that all
+    // the elements in the range [first, pivot] would be equal to the pivot,
+    // assuming the equal elements are put on the left side when
+    // partitioned.  This also means that we do not need to sort the left
+    // side of the partition.
+    if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) {
+      __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>(
+          __first, __last, _Comp_ref(__comp));
+      continue;
     }
+    // Use bitset partition only if asked for.
+    auto __ret =
+        _UseBitSetPartition
+            ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp)
+            : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp);
+    _RandomAccessIterator __i = __ret.first;
     // [__first, __i) < *__i and *__i <= [__i+1, __last)
     // If we were given a perfect partition, see if insertion sort is quick...
-    if (__n_swaps == 0) {
-      using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type;
-      _WrappedComp __wrapped_comp(__comp);
-      bool __fs = std::__insertion_sort_incomplete<_WrappedComp>(__first, __i, __wrapped_comp);
-      if (std::__insertion_sort_incomplete<_WrappedComp>(__i + difference_type(1), __last, __wrapped_comp)) {
+    if (__ret.second) {
+      bool __fs = std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__first, __i, __comp);
+      if (std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp)) {
         if (__fs)
           return;
         __last = __i;
@@ -597,14 +818,11 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
         }
       }
     }
-    // sort smaller range with recursive call and larger with tail recursion elimination
-    if (__i - __first < __last - __i) {
-      std::__introsort<_AlgPolicy, _Compare>(__first, __i, __comp, __depth);
-      __first = ++__i;
-    } else {
-      std::__introsort<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp, __depth);
-      __last = __i;
-    }
+    // Sort the left partiton recursively and the right partition with tail recursion elimination.
+    std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>(
+        __first, __i, __comp, __depth, __leftmost);
+    __leftmost = false;
+    __first    = ++__i;
   }
 }
 
@@ -627,77 +845,107 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
   return __log2;
 }
 
-template <class _WrappedComp, class _RandomAccessIterator>
-_LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) {
+template <class _Comp, class _RandomAccessIterator>
+void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp);
+
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
+#endif
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
+extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
+
+template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
   difference_type __depth_limit = 2 * std::__log2i(__last - __first);
 
-  using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
-  using _AlgPolicy = typename _Unwrap::_AlgPolicy;
-  using _Compare = typename _Unwrap::_Comp;
-  _Compare __comp = _Unwrap::__get_comp(__wrapped_comp);
-  std::__introsort<_AlgPolicy, _Compare>(__first, __last, __comp, __depth_limit);
+  // Only use bitset partitioning for arithmetic types.  We should also check
+  // that the default comparator is in use so that we are sure that there are no
+  // branches in the comparator.
+  std::__introsort<_AlgPolicy,
+                   _Comp&,
+                   _RandomAccessIterator,
+                   __use_branchless_sort<_Comp, _RandomAccessIterator>::value>(
+      __first, __last, __comp, __depth_limit);
 }
 
-template <class _Compare, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) {
-  __less<uintptr_t> __comp;
-  std::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
-}
+template <class _Type, class... _Options>
+using __is_any_of = _Or<is_same<_Type, _Options>...>;
 
-extern template _LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
+template <class _Type>
+using __sort_is_specialized_in_library = __is_any_of<
+    _Type,
+    char,
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-extern template _LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
+    wchar_t,
 #endif
-extern template _LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
-extern template _LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
+    signed char,
+    unsigned char,
+    short,
+    unsigned short,
+    int,
+    unsigned int,
+    long,
+    unsigned long,
+    long long,
+    unsigned long long,
+    float,
+    double,
+    long double>;
+
+template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
+  __less<_Type> __comp;
+  std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
+}
+
+template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<_Type>&) {
+  __less<_Type> __comp;
+  std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
+}
+
+#if _LIBCPP_STD_VER >= 14
+template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<>&) {
+  __less<_Type> __comp;
+  std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
+}
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges::less&) {
+  __less<_Type> __comp;
+  std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
+}
 #endif
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
-extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
 
 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
   std::__debug_randomize_range<_AlgPolicy>(__first, __last);
 
-  using _Comp_ref = __comp_ref_type<_Comp>;
   if (__libcpp_is_constant_evaluated()) {
-    std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp);
-
+    std::__partial_sort<_AlgPolicy>(
+        std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__last), __comp);
   } else {
-    using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Comp_ref>::type;
-    _Comp_ref __comp_ref(__comp);
-    _WrappedComp __wrapped_comp(__comp_ref);
-    std::__sort<_WrappedComp>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __wrapped_comp);
+    std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
   }
+  std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
 }
 
 template <class _RandomAccessIterator, class _Comp>
@@ -709,7 +957,7 @@ void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __c
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::sort(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/sort_heap.h
@@ -14,9 +14,11 @@
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/pop_heap.h>
 #include <__config>
+#include <__debug_utils/strict_weak_ordering_check.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -27,11 +29,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
+  _RandomAccessIterator __saved_last = __last;
   __comp_ref_type<_Compare> __comp_ref = __comp;
 
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
   for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
     std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n);
+  std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref);
 }
 
 template <class _RandomAccessIterator, class _Compare>
@@ -46,8 +50,7 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::sort_heap(std::move(__first), std::move(__last),
-      __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::sort_heap(std::move(__first), std::move(__last), __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/stable_partition.h
@@ -21,7 +21,6 @@
 #include <__utility/move.h>
 #include <__utility/pair.h>
 #include <new>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -123,7 +122,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardIterator
 __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                    forward_iterator_tag)
 {
-    const unsigned __alloc_limit = 3;  // might want to make this a function of trivial assignment
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+
+    const difference_type __alloc_limit = 3;  // might want to make this a function of trivial assignment
     // Either prove all true and return __first or point to first false
     while (true)
     {
@@ -135,8 +137,6 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
     }
     // We now have a reduced range [__first, __last)
     // *__first is known to be false
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
     difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
     pair<value_type*, ptrdiff_t> __p(0, 0);
     unique_ptr<value_type, __return_temporary_buffer> __h;
lib/libcxx/include/__algorithm/stable_sort.h
@@ -15,14 +15,15 @@
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/sort.h>
 #include <__config>
+#include <__debug_utils/strict_weak_ordering_check.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/destruct_n.h>
 #include <__memory/temporary_buffer.h>
 #include <__memory/unique_ptr.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
 #include <new>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -30,6 +31,37 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
+_LIBCPP_HIDE_FROM_ABI
+void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
+                           typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) {
+  using _Ops = _IterOps<_AlgPolicy>;
+
+  typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+  if (__first1 != __last1) {
+    __destruct_n __d(0);
+    unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
+    value_type* __last2 = __first2;
+    ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1));
+    __d.template __incr<value_type>();
+    for (++__last2; ++__first1 != __last1; ++__last2) {
+      value_type* __j2 = __last2;
+      value_type* __i2 = __j2;
+      if (__comp(*__first1, *--__i2)) {
+        ::new ((void*)__j2) value_type(std::move(*__i2));
+        __d.template __incr<value_type>();
+        for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
+          *__j2 = std::move(*__i2);
+        *__j2 = _Ops::__iter_move(__first1);
+      } else {
+        ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1));
+        __d.template __incr<value_type>();
+      }
+    }
+    __h.release();
+  }
+}
+
 template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2>
 _LIBCPP_HIDE_FROM_ABI void
 __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
@@ -228,6 +260,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
   }
 
   std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
+  std::__check_strict_weak_ordering_sorted(__first, __last, __comp);
 }
 
 template <class _RandomAccessIterator, class _Compare>
@@ -239,7 +272,7 @@ void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
 template <class _RandomAccessIterator>
 inline _LIBCPP_HIDE_FROM_ABI
 void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
-  std::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+  std::stable_sort(__first, __last, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/three_way_comp_ref_type.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
+#define _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
+
+#include <__compare/ordering.h>
+#include <__config>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Comp>
+struct __debug_three_way_comp {
+  _Comp& __comp_;
+  _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {}
+
+  template <class _Tp, class _Up>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) {
+    auto __r = __comp_(__x, __y);
+    if constexpr (__comparison_category<decltype(__comp_(__x, __y))>)
+      __do_compare_assert(__y, __x, __r);
+    return __r;
+  }
+
+  template <class _Tp, class _Up>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) {
+    auto __r = __comp_(__x, __y);
+    if constexpr (__comparison_category<decltype(__comp_(__x, __y))>)
+      __do_compare_assert(__y, __x, __r);
+    return __r;
+  }
+
+  template <class _LHS, class _RHS, class _Order>
+  _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) {
+    _Order __expected = __o;
+    if (__o == _Order::less)
+      __expected = _Order::greater;
+    if (__o == _Order::greater)
+      __expected = _Order::less;
+    _LIBCPP_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering");
+    (void)__l;
+    (void)__r;
+  }
+};
+
+// Pass the comparator by lvalue reference. Or in debug mode, using a
+// debugging wrapper that stores a reference.
+#  if _LIBCPP_ENABLE_DEBUG_MODE
+template <class _Comp>
+using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>;
+#  else
+template <class _Comp>
+using __three_way_comp_ref_type = _Comp&;
+#  endif
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
lib/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h
@@ -11,13 +11,13 @@
 
 #include <__config>
 #include <__functional/invoke.h>
-#include <type_traits>
+#include <__type_traits/remove_cvref.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
@@ -57,6 +57,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H
lib/libcxx/include/__algorithm/unwrap_iter.h
@@ -21,24 +21,27 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // TODO: Change the name of __unwrap_iter_impl to something more appropriate
 // The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter),
 // to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy.
-// In debug mode, we don't do this.
 //
 // Some algorithms (e.g. std::copy, but not std::sort) need to convert an
 // "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter.
 
 // Default case - we can't unwrap anything
-template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value>
+template <class _Iter, bool = __libcpp_is_contiguous_iterator<_Iter>::value>
 struct __unwrap_iter_impl {
   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter, _Iter __iter) { return __iter; }
   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; }
 };
 
-#ifndef _LIBCPP_ENABLE_DEBUG_MODE
+// TODO(hardening): make sure that the following unwrapping doesn't unexpectedly turn hardened iterators into raw
+// pointers.
 
 // It's a contiguous iterator, so we can use a raw pointer instead
 template <class _Iter>
@@ -54,8 +57,6 @@ struct __unwrap_iter_impl<_Iter, true> {
   }
 };
 
-#endif // !_LIBCPP_ENABLE_DEBUG_MODE
-
 template<class _Iter,
          class _Impl = __unwrap_iter_impl<_Iter>,
          __enable_if_t<is_copy_constructible<_Iter>::value, int> = 0>
@@ -64,6 +65,14 @@ decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXC
   return _Impl::__unwrap(__i);
 }
 
+// Allow input_iterators to be passed to __unwrap_iter (but not __rewrap_iter)
+#if _LIBCPP_STD_VER >= 20
+template <class _Iter, __enable_if_t<!is_copy_constructible<_Iter>::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI constexpr _Iter __unwrap_iter(_Iter __i) noexcept {
+  return __i;
+}
+#endif
+
 template <class _OrigIter, class _Iter, class _Impl = __unwrap_iter_impl<_OrigIter> >
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig_iter, _Iter __iter) _NOEXCEPT {
   return _Impl::__rewrap(std::move(__orig_iter), std::move(__iter));
@@ -71,4 +80,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_PUSH_MACROS
+
 #endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H
lib/libcxx/include/__algorithm/unwrap_range.h
@@ -28,7 +28,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
 // the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Iter, class _Sent>
 struct __unwrap_range_impl {
   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
@@ -43,7 +43,7 @@ struct __unwrap_range_impl {
   }
 
   _LIBCPP_HIDE_FROM_ABI static constexpr auto
-  __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter)
+  __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter)
     requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
   {
     return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
@@ -80,7 +80,7 @@ template <
 _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
   return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
 }
-#else  // _LIBCPP_STD_VER > 17
+#else  // _LIBCPP_STD_VER >= 20
 template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
   return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
@@ -90,7 +90,7 @@ template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declv
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
   return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__algorithm/upper_bound.h
@@ -25,6 +25,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp, class _Proj>
@@ -47,8 +50,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
 template <class _ForwardIterator, class _Tp, class _Compare>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
 upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
-  static_assert(is_copy_constructible<_ForwardIterator>::value,
-                "Iterator has to be copy constructible");
+  static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible");
   return std::__upper_bound<_ClassicAlgPolicy>(
       std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity());
 }
@@ -56,13 +58,11 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
 template <class _ForwardIterator, class _Tp>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
 upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
-  return std::upper_bound(
-      std::move(__first),
-      std::move(__last),
-      __value,
-      __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
+  return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>());
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H
lib/libcxx/include/__atomic/aliases.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ATOMIC_ALIASES_H
+#define _LIBCPP___ATOMIC_ALIASES_H
+
+#include <__atomic/atomic.h>
+#include <__atomic/atomic_lock_free.h>
+#include <__atomic/contention_t.h>
+#include <__atomic/is_always_lock_free.h>
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using atomic_bool   = atomic<bool>;
+using atomic_char   = atomic<char>;
+using atomic_schar  = atomic<signed char>;
+using atomic_uchar  = atomic<unsigned char>;
+using atomic_short  = atomic<short>;
+using atomic_ushort = atomic<unsigned short>;
+using atomic_int    = atomic<int>;
+using atomic_uint   = atomic<unsigned int>;
+using atomic_long   = atomic<long>;
+using atomic_ulong  = atomic<unsigned long>;
+using atomic_llong  = atomic<long long>;
+using atomic_ullong = atomic<unsigned long long>;
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+using atomic_char8_t = atomic<char8_t>;
+#endif
+using atomic_char16_t = atomic<char16_t>;
+using atomic_char32_t = atomic<char32_t>;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using atomic_wchar_t = atomic<wchar_t>;
+#endif
+
+using atomic_int_least8_t   = atomic<int_least8_t>;
+using atomic_uint_least8_t  = atomic<uint_least8_t>;
+using atomic_int_least16_t  = atomic<int_least16_t>;
+using atomic_uint_least16_t = atomic<uint_least16_t>;
+using atomic_int_least32_t  = atomic<int_least32_t>;
+using atomic_uint_least32_t = atomic<uint_least32_t>;
+using atomic_int_least64_t  = atomic<int_least64_t>;
+using atomic_uint_least64_t = atomic<uint_least64_t>;
+
+using atomic_int_fast8_t   = atomic<int_fast8_t>;
+using atomic_uint_fast8_t  = atomic<uint_fast8_t>;
+using atomic_int_fast16_t  = atomic<int_fast16_t>;
+using atomic_uint_fast16_t = atomic<uint_fast16_t>;
+using atomic_int_fast32_t  = atomic<int_fast32_t>;
+using atomic_uint_fast32_t = atomic<uint_fast32_t>;
+using atomic_int_fast64_t  = atomic<int_fast64_t>;
+using atomic_uint_fast64_t = atomic<uint_fast64_t>;
+
+using atomic_int8_t   = atomic< int8_t>;
+using atomic_uint8_t  = atomic<uint8_t>;
+using atomic_int16_t  = atomic< int16_t>;
+using atomic_uint16_t = atomic<uint16_t>;
+using atomic_int32_t  = atomic< int32_t>;
+using atomic_uint32_t = atomic<uint32_t>;
+using atomic_int64_t  = atomic< int64_t>;
+using atomic_uint64_t = atomic<uint64_t>;
+
+using atomic_intptr_t  = atomic<intptr_t>;
+using atomic_uintptr_t = atomic<uintptr_t>;
+using atomic_size_t    = atomic<size_t>;
+using atomic_ptrdiff_t = atomic<ptrdiff_t>;
+using atomic_intmax_t  = atomic<intmax_t>;
+using atomic_uintmax_t = atomic<uintmax_t>;
+
+// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
+
+#if _LIBCPP_STD_VER >= 17
+#  define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
+#else
+#  define _LIBCPP_CONTENTION_LOCK_FREE false
+#endif
+
+#if ATOMIC_LLONG_LOCK_FREE == 2
+using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>;
+using __libcpp_unsigned_lock_free =
+    __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>;
+#elif ATOMIC_INT_LOCK_FREE == 2
+using __libcpp_signed_lock_free   = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>;
+using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>;
+#elif ATOMIC_SHORT_LOCK_FREE == 2
+using __libcpp_signed_lock_free   = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>;
+using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>;
+#elif ATOMIC_CHAR_LOCK_FREE == 2
+using __libcpp_signed_lock_free   = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>;
+using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>;
+#else
+// No signed/unsigned lock-free types
+#  define _LIBCPP_NO_LOCK_FREE_TYPES
+#endif
+
+#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
+using atomic_signed_lock_free   = atomic<__libcpp_signed_lock_free>;
+using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ALIASES_H
lib/libcxx/include/__atomic/atomic.h
@@ -0,0 +1,664 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_H
+#define _LIBCPP___ATOMIC_ATOMIC_H
+
+#include <__atomic/atomic_base.h>
+#include <__atomic/check_memory_order.h>
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/memory_order.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_pointer.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct atomic
+    : public __atomic_base<_Tp>
+{
+  using __base          = __atomic_base<_Tp>;
+  using value_type      = _Tp;
+  using difference_type = value_type;
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI
+    atomic() = default;
+#else
+    _LIBCPP_HIDE_FROM_ABI
+    atomic() _NOEXCEPT = default;
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI
+    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator=(_Tp __d) volatile _NOEXCEPT
+        {__base::store(__d); return __d;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator=(_Tp __d) _NOEXCEPT
+        {__base::store(__d); return __d;}
+
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+};
+
+// atomic<T*>
+
+template <class _Tp>
+struct atomic<_Tp*>
+    : public __atomic_base<_Tp*>
+{
+    using __base          = __atomic_base<_Tp*>;
+    using value_type      = _Tp*;
+    using difference_type = ptrdiff_t;
+
+    _LIBCPP_HIDE_FROM_ABI
+    atomic() _NOEXCEPT = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
+        {__base::store(__d); return __d;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator=(_Tp* __d) _NOEXCEPT
+        {__base::store(__d); return __d;}
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+        // __atomic_fetch_add accepts function pointers, guard against them.
+        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
+        return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+        // __atomic_fetch_add accepts function pointers, guard against them.
+        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
+        return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+        // __atomic_fetch_add accepts function pointers, guard against them.
+        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
+        return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+        // __atomic_fetch_add accepts function pointers, guard against them.
+        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
+        return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
+
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+};
+
+// atomic_is_lock_free
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->is_lock_free();
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->is_lock_free();
+}
+
+// atomic_init
+
+template <class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
+void
+atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
+}
+
+template <class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
+void
+atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
+}
+
+// atomic_store
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void
+atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    __o->store(__d);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void
+atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    __o->store(__d);
+}
+
+// atomic_store_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void
+atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
+{
+    __o->store(__d, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void
+atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
+{
+    __o->store(__d, __m);
+}
+
+// atomic_load
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->load();
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->load();
+}
+
+// atomic_load_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
+{
+    return __o->load(__m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
+{
+    return __o->load(__m);
+}
+
+// atomic_exchange
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->exchange(__d);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->exchange(__d);
+}
+
+// atomic_exchange_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
+{
+    return __o->exchange(__d, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
+{
+    return __o->exchange(__d, __m);
+}
+
+// atomic_compare_exchange_weak
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d);
+}
+
+// atomic_compare_exchange_strong
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d);
+}
+
+// atomic_compare_exchange_weak_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
+                                      typename atomic<_Tp>::value_type __d,
+                                      memory_order __s, memory_order __f) _NOEXCEPT
+  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
+{
+    return __o->compare_exchange_weak(*__e, __d, __s, __f);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
+                                      memory_order __s, memory_order __f) _NOEXCEPT
+  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
+{
+    return __o->compare_exchange_weak(*__e, __d, __s, __f);
+}
+
+// atomic_compare_exchange_strong_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
+                                        typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
+                                        memory_order __s, memory_order __f) _NOEXCEPT
+  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
+{
+    return __o->compare_exchange_strong(*__e, __d, __s, __f);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool
+atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
+                                        typename atomic<_Tp>::value_type __d,
+                                        memory_order __s, memory_order __f) _NOEXCEPT
+  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
+{
+    return __o->compare_exchange_strong(*__e, __d, __s, __f);
+}
+
+// atomic_wait
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_wait(const volatile atomic<_Tp>* __o,
+                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
+{
+    return __o->wait(__v);
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_wait(const atomic<_Tp>* __o,
+                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
+{
+    return __o->wait(__v);
+}
+
+// atomic_wait_explicit
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
+                          typename atomic<_Tp>::value_type __v,
+                          memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
+{
+    return __o->wait(__v, __m);
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_wait_explicit(const atomic<_Tp>* __o,
+                          typename atomic<_Tp>::value_type __v,
+                          memory_order __m) _NOEXCEPT
+  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
+{
+    return __o->wait(__v, __m);
+}
+
+// atomic_notify_one
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    __o->notify_one();
+}
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
+{
+    __o->notify_one();
+}
+
+// atomic_notify_all
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    __o->notify_all();
+}
+template <class _Tp>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
+{
+    __o->notify_all();
+}
+
+// atomic_fetch_add
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp
+atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+// atomic_fetch_add_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+// atomic_fetch_sub
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+// atomic_fetch_sub_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+// atomic_fetch_and
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_and(__op);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_and(__op);
+}
+
+// atomic_fetch_and_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_and(__op, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_and(__op, __m);
+}
+
+// atomic_fetch_or
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_or(__op);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_or(__op);
+}
+
+// atomic_fetch_or_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_or(__op, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_or(__op, __m);
+}
+
+// atomic_fetch_xor
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_xor(__op);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
+{
+    return __o->fetch_xor(__op);
+}
+
+// atomic_fetch_xor_explicit
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_xor(__op, __m);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_xor(__op, __m);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_H
lib/libcxx/include/__atomic/atomic_base.h
@@ -0,0 +1,232 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_BASE_H
+#define _LIBCPP___ATOMIC_ATOMIC_BASE_H
+
+#include <__atomic/atomic_sync.h>
+#include <__atomic/check_memory_order.h>
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/is_always_lock_free.h>
+#include <__atomic/memory_order.h>
+#include <__availability>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_same.h>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
+struct __atomic_base  // false
+{
+    mutable __cxx_atomic_impl<_Tp> __a_;
+
+#if _LIBCPP_STD_VER >= 17
+  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI
+    bool is_lock_free() const volatile _NOEXCEPT
+        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
+    _LIBCPP_HIDE_FROM_ABI
+    bool is_lock_free() const _NOEXCEPT
+        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
+    _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
+      std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
+      std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
+        _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
+      return std::__cxx_atomic_load(std::addressof(__a_), __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
+        _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
+      return std::__cxx_atomic_load(std::addressof(__a_), __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI
+    operator _Tp() const volatile _NOEXCEPT {return load();}
+    _LIBCPP_HIDE_FROM_ABI
+    operator _Tp() const _NOEXCEPT          {return load();}
+    _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
+        volatile _NOEXCEPT {
+      std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
+    wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
+      std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
+      std::__cxx_atomic_notify_one(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
+      std::__cxx_atomic_notify_one(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
+      std::__cxx_atomic_notify_all(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
+      std::__cxx_atomic_notify_all(std::addressof(__a_));
+    }
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI constexpr
+    __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
+#else
+    _LIBCPP_HIDE_FROM_ABI
+    __atomic_base() _NOEXCEPT = default;
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
+
+    __atomic_base(const __atomic_base&) = delete;
+};
+
+#if _LIBCPP_STD_VER >= 17
+template <class _Tp, bool __b>
+_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
+#endif
+
+// atomic<Integral>
+
+template <class _Tp>
+struct __atomic_base<_Tp, true>
+    : public __atomic_base<_Tp, false>
+{
+    using __base = __atomic_base<_Tp, false>;
+
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    __atomic_base() _NOEXCEPT = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_BASE_H
lib/libcxx/include/__atomic/atomic_flag.h
@@ -0,0 +1,230 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_FLAG_H
+#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
+
+#include <__atomic/atomic_sync.h>
+#include <__atomic/contention_t.h>
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/memory_order.h>
+#include <__chrono/duration.h>
+#include <__config>
+#include <__threading_support>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct atomic_flag
+{
+    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
+
+    _LIBCPP_HIDE_FROM_ABI
+    bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
+        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
+    _LIBCPP_HIDE_FROM_ABI
+    bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
+        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
+
+    _LIBCPP_HIDE_FROM_ABI
+    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
+    _LIBCPP_HIDE_FROM_ABI
+    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
+    _LIBCPP_HIDE_FROM_ABI
+    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
+    _LIBCPP_HIDE_FROM_ABI
+    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
+
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
+        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
+        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void notify_one() volatile _NOEXCEPT
+        {__cxx_atomic_notify_one(&__a_);}
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void notify_one() _NOEXCEPT
+        {__cxx_atomic_notify_one(&__a_);}
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void notify_all() volatile _NOEXCEPT
+        {__cxx_atomic_notify_all(&__a_);}
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
+    void notify_all() _NOEXCEPT
+        {__cxx_atomic_notify_all(&__a_);}
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI constexpr
+    atomic_flag() _NOEXCEPT : __a_(false) {}
+#else
+    atomic_flag() _NOEXCEPT = default;
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
+
+    atomic_flag(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) volatile = delete;
+
+};
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test_and_set();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test_and_set();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test_and_set(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool
+atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test_and_set(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
+{
+    __o->clear();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
+{
+    __o->clear();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    __o->clear(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    __o->clear(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
+{
+    __o->wait(__v);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
+{
+    __o->wait(__v);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_wait_explicit(const volatile atomic_flag* __o,
+                          bool __v, memory_order __m) _NOEXCEPT
+{
+    __o->wait(__v, __m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_wait_explicit(const atomic_flag* __o,
+                          bool __v, memory_order __m) _NOEXCEPT
+{
+    __o->wait(__v, __m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
+{
+    __o->notify_one();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
+{
+    __o->notify_one();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
+{
+    __o->notify_all();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
+void
+atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
+{
+    __o->notify_all();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H
lib/libcxx/include/__atomic/atomic_init.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_INIT_H
+#define _LIBCPP___ATOMIC_ATOMIC_INIT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#define ATOMIC_FLAG_INIT {false}
+#define ATOMIC_VAR_INIT(__v) {__v}
+
+#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
+#  pragma clang deprecated(ATOMIC_VAR_INIT)
+# endif
+#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H
lib/libcxx/include/__atomic/atomic_lock_free.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_LOCK_FREE_H
+#define _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
+# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
+# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+# define ATOMIC_CHAR8_T_LOCK_FREE   __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
+# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
+# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
+# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
+# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
+# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
+# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
+# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
+# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
+#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
+# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
+# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+# define ATOMIC_CHAR8_T_LOCK_FREE   __GCC_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
+# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
+# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
+# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
+# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
+# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
+# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
+# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
+# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
+#endif
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
lib/libcxx/include/__atomic/atomic_sync.h
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_ATOMIC_SYNC_H
+#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H
+
+#include <__atomic/contention_t.h>
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/memory_order.h>
+#include <__availability>
+#include <__chrono/duration.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__thread/poll_with_backoff.h>
+#include <__threading_support>
+#include <__type_traits/decay.h>
+#include <cstring>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
+
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
+
+template <class _Atp, class _Fn>
+struct __libcpp_atomic_wait_backoff_impl {
+    _Atp* __a;
+    _Fn __test_fn;
+    _LIBCPP_AVAILABILITY_SYNC
+    _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const
+    {
+        if(__elapsed > chrono::microseconds(64))
+        {
+            auto const __monitor = std::__libcpp_atomic_monitor(__a);
+            if(__test_fn())
+                return true;
+            std::__libcpp_atomic_wait(__a, __monitor);
+        }
+        else if(__elapsed > chrono::microseconds(4))
+            __libcpp_thread_yield();
+        else
+            {} // poll
+        return false;
+    }
+};
+
+template <class _Atp, class _Fn>
+_LIBCPP_AVAILABILITY_SYNC
+_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
+{
+    __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn};
+    return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
+}
+
+#else // _LIBCPP_HAS_NO_THREADS
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
+template <class _Atp, class _Fn>
+_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
+{
+    return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
+}
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+template <typename _Tp> _LIBCPP_HIDE_FROM_ABI
+bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
+    return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
+}
+
+template <class _Atp, class _Tp>
+struct __cxx_atomic_wait_test_fn_impl {
+    _Atp* __a;
+    _Tp __val;
+    memory_order __order;
+    _LIBCPP_HIDE_FROM_ABI bool operator()() const
+    {
+        return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
+    }
+};
+
+template <class _Atp, class _Tp>
+_LIBCPP_AVAILABILITY_SYNC
+_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
+{
+    __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
+    return std::__cxx_atomic_wait(__a, __test_fn);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_H
lib/libcxx/include/__atomic/check_memory_order.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_CHECK_MEMORY_ORDER_H
+#define _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
+  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
+                           __m == memory_order_acquire || \
+                           __m == memory_order_acq_rel,   \
+                        "memory order argument to atomic operation is invalid")
+
+#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
+  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
+                           __m == memory_order_acq_rel,   \
+                        "memory order argument to atomic operation is invalid")
+
+#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
+  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
+                           __f == memory_order_acq_rel,   \
+                        "memory order argument to atomic operation is invalid")
+
+#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
lib/libcxx/include/__atomic/contention_t.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ATOMIC_CONTENTION_T_H
+#define _LIBCPP___ATOMIC_CONTENTION_T_H
+
+#include <__atomic/cxx_atomic_impl.h>
+#include <__config>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
+    using __cxx_contention_t = int32_t;
+#else
+    using __cxx_contention_t = int64_t;
+#endif // __linux__ || (_AIX && !__64BIT__)
+
+using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_CONTENTION_T_H
lib/libcxx/include/__atomic/cxx_atomic_impl.h
@@ -0,0 +1,831 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_CXX_ATOMIC_IMPL_H
+#define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
+
+#include <__atomic/is_always_lock_free.h>
+#include <__atomic/memory_order.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/remove_const.h>
+#include <cstddef>
+#include <cstring>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
+    defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
+
+// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
+// the default operator= in an object is not volatile, a byte-by-byte copy
+// is required.
+template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI
+typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
+__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
+  __a_value = __val;
+}
+template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI
+typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
+__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
+  volatile char* __to         = reinterpret_cast<volatile char*>(std::addressof(__a_value));
+  volatile char* __end = __to + sizeof(_Tp);
+  volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));
+  while (__to != __end)
+    *__to++ = *__from++;
+}
+
+#endif
+
+#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
+
+template <typename _Tp>
+struct __cxx_atomic_base_impl {
+
+  _LIBCPP_HIDE_FROM_ABI
+#ifndef _LIBCPP_CXX03_LANG
+    __cxx_atomic_base_impl() _NOEXCEPT = default;
+#else
+    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
+#endif // _LIBCPP_CXX03_LANG
+  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
+    : __a_value(value) {}
+  _Tp __a_value;
+};
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
+  // Avoid switch statement to make this a constexpr.
+  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
+         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
+          (__order == memory_order_release ? __ATOMIC_RELEASE:
+           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
+            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
+              __ATOMIC_CONSUME))));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
+  // Avoid switch statement to make this a constexpr.
+  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
+         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
+          (__order == memory_order_release ? __ATOMIC_RELAXED:
+           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
+            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
+              __ATOMIC_CONSUME))));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
+  __cxx_atomic_assign_volatile(__a->__a_value, __val);
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
+  __a->__a_value = __val;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline
+void __cxx_atomic_thread_fence(memory_order __order) {
+  __atomic_thread_fence(__to_gcc_order(__order));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline
+void __cxx_atomic_signal_fence(memory_order __order) {
+  __atomic_signal_fence(__to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
+                        memory_order __order) {
+  __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
+                        memory_order __order) {
+  __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
+                      memory_order __order) {
+  _Tp __ret;
+  __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
+  return __ret;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
+  _Tp __ret;
+  __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
+  return __ret;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                          _Tp __value, memory_order __order) {
+  _Tp __ret;
+  __atomic_exchange(
+      std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
+  return __ret;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
+                          memory_order __order) {
+  _Tp __ret;
+  __atomic_exchange(
+      std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
+  return __ret;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(
+    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
+    memory_order __success, memory_order __failure) {
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      false,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(
+    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
+    memory_order __failure) {
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      false,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(
+    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
+    memory_order __success, memory_order __failure) {
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      true,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(
+    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
+    memory_order __failure) {
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      true,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
+}
+
+template <typename _Tp>
+struct __skip_amt { enum {value = 1}; };
+
+template <typename _Tp>
+struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
+
+// FIXME: Haven't figured out what the spec says about using arrays with
+// atomic_fetch_add. Force a failure rather than creating bad behavior.
+template <typename _Tp>
+struct __skip_amt<_Tp[]> { };
+template <typename _Tp, int n>
+struct __skip_amt<_Tp[n]> { };
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                           _Td __delta, memory_order __order) {
+  return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
+                           memory_order __order) {
+  return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                           _Td __delta, memory_order __order) {
+  return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
+                           memory_order __order) {
+  return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order __order) {
+  return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order __order) {
+  return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                          _Tp __pattern, memory_order __order) {
+  return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
+                          memory_order __order) {
+  return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order __order) {
+  return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
+                           memory_order __order) {
+  return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
+}
+
+#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
+
+#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
+
+template <typename _Tp>
+struct __cxx_atomic_base_impl {
+
+  _LIBCPP_HIDE_FROM_ABI
+#ifndef _LIBCPP_CXX03_LANG
+    __cxx_atomic_base_impl() _NOEXCEPT = default;
+#else
+    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
+#endif // _LIBCPP_CXX03_LANG
+  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
+    : __a_value(__value) {}
+  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
+};
+
+#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
+
+_LIBCPP_HIDE_FROM_ABI inline
+void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
+    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline
+void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
+    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
+    __c11_atomic_init(std::addressof(__a->__a_value), __val);
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
+    __c11_atomic_init(std::addressof(__a->__a_value), __val);
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
+    __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
+    __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
+    using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
+    return __c11_atomic_load(
+        const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
+    using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
+    return __c11_atomic_load(
+        const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
+    return __c11_atomic_exchange(
+        std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
+    return __c11_atomic_exchange(
+        std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
+  // Avoid switch statement to make this a constexpr.
+  return __order == memory_order_release ? memory_order_relaxed:
+         (__order == memory_order_acq_rel ? memory_order_acquire:
+             __order);
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
+  return __c11_atomic_compare_exchange_strong(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
+  return __c11_atomic_compare_exchange_strong(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
+  return __c11_atomic_compare_exchange_weak(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
+  return __c11_atomic_compare_exchange_weak(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_and(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_and(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_or(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_or(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_xor(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
+  return __c11_atomic_fetch_xor(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
+}
+
+#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
+
+#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
+
+template<typename _Tp>
+struct __cxx_atomic_lock_impl {
+
+  _LIBCPP_HIDE_FROM_ABI
+  __cxx_atomic_lock_impl() _NOEXCEPT
+    : __a_value(), __a_lock(0) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit
+  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
+    : __a_value(value), __a_lock(0) {}
+
+  _Tp __a_value;
+  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
+
+  _LIBCPP_HIDE_FROM_ABI void __lock() const volatile {
+    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
+        /*spin*/;
+  }
+  _LIBCPP_HIDE_FROM_ABI void __lock() const {
+    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
+        /*spin*/;
+  }
+  _LIBCPP_HIDE_FROM_ABI void __unlock() const volatile {
+    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
+  }
+  _LIBCPP_HIDE_FROM_ABI void __unlock() const {
+    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
+  }
+  _LIBCPP_HIDE_FROM_ABI _Tp __read() const volatile {
+    __lock();
+    _Tp __old;
+    __cxx_atomic_assign_volatile(__old, __a_value);
+    __unlock();
+    return __old;
+  }
+  _LIBCPP_HIDE_FROM_ABI _Tp __read() const {
+    __lock();
+    _Tp __old = __a_value;
+    __unlock();
+    return __old;
+  }
+};
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
+  __cxx_atomic_assign_volatile(__a->__a_value, __val);
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
+  __a->__a_value = __val;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
+  __a->__lock();
+  __cxx_atomic_assign_volatile(__a->__a_value, __val);
+  __a->__unlock();
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
+  __a->__lock();
+  __a->__a_value = __val;
+  __a->__unlock();
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
+  return __a->__read();
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
+  return __a->__read();
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, __value);
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value = __value;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
+  _Tp __temp;
+  __a->__lock();
+  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
+  bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
+  if(__ret)
+    __cxx_atomic_assign_volatile(__a->__a_value, __value);
+  else
+    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
+  __a->__unlock();
+  return __ret;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
+                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
+  __a->__lock();
+  bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
+  if(__ret)
+    std::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
+  else
+    std::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
+  __a->__unlock();
+  return __ret;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
+  _Tp __temp;
+  __a->__lock();
+  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
+  bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
+  if(__ret)
+    __cxx_atomic_assign_volatile(__a->__a_value, __value);
+  else
+    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
+  __a->__unlock();
+  return __ret;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
+                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
+  __a->__lock();
+  bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
+  if(__ret)
+    std::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
+  else
+    std::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
+  __a->__unlock();
+  return __ret;
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                           _Td __delta, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
+                           _Td __delta, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value += __delta;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
+                           ptrdiff_t __delta, memory_order) {
+  __a->__lock();
+  _Tp* __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
+                           ptrdiff_t __delta, memory_order) {
+  __a->__lock();
+  _Tp* __old = __a->__a_value;
+  __a->__a_value += __delta;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                           _Td __delta, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp, typename _Td>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
+                           _Td __delta, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value -= __delta;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value &= __pattern;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                          _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
+                          _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value |= __pattern;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old;
+  __cxx_atomic_assign_volatile(__old, __a->__a_value);
+  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
+  __a->__unlock();
+  return __old;
+}
+template <typename _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
+                           _Tp __pattern, memory_order) {
+  __a->__lock();
+  _Tp __old = __a->__a_value;
+  __a->__a_value ^= __pattern;
+  __a->__unlock();
+  return __old;
+}
+
+template <typename _Tp,
+          typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
+                                                __cxx_atomic_base_impl<_Tp>,
+                                                __cxx_atomic_lock_impl<_Tp> >::type>
+#else
+template <typename _Tp,
+          typename _Base = __cxx_atomic_base_impl<_Tp> >
+#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
+struct __cxx_atomic_impl : public _Base {
+    static_assert(is_trivially_copyable<_Tp>::value,
+      "std::atomic<T> requires that 'T' be a trivially copyable type");
+
+  _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
+    : _Base(__value) {}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
lib/libcxx/include/__atomic/fence.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ATOMIC_FENCE_H
+#define _LIBCPP___ATOMIC_FENCE_H
+
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/memory_order.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_thread_fence(memory_order __m) _NOEXCEPT
+{
+    __cxx_atomic_thread_fence(__m);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void
+atomic_signal_fence(memory_order __m) _NOEXCEPT
+{
+    __cxx_atomic_signal_fence(__m);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_FENCE_H
lib/libcxx/include/__atomic/is_always_lock_free.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_IS_ALWAYS_LOCK_FREE_H
+#define _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __libcpp_is_always_lock_free {
+  // __atomic_always_lock_free is available in all Standard modes
+  static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H
lib/libcxx/include/__atomic/kill_dependency.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ATOMIC_KILL_DEPENDENCY_H
+#define _LIBCPP___ATOMIC_KILL_DEPENDENCY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+_Tp kill_dependency(_Tp __y) _NOEXCEPT
+{
+    return __y;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_KILL_DEPENDENCY_H
lib/libcxx/include/__atomic/memory_order.h
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ATOMIC_MEMORY_ORDER_H
+#define _LIBCPP___ATOMIC_MEMORY_ORDER_H
+
+#include <__config>
+#include <__type_traits/is_same.h>
+#include <__type_traits/underlying_type.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Figure out what the underlying type for `memory_order` would be if it were
+// declared as an unscoped enum (accounting for -fshort-enums). Use this result
+// to pin the underlying type in C++20.
+enum __legacy_memory_order {
+    __mo_relaxed,
+    __mo_consume,
+    __mo_acquire,
+    __mo_release,
+    __mo_acq_rel,
+    __mo_seq_cst
+};
+
+using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type;
+
+#if _LIBCPP_STD_VER >= 20
+
+enum class memory_order : __memory_order_underlying_t {
+  relaxed = __mo_relaxed,
+  consume = __mo_consume,
+  acquire = __mo_acquire,
+  release = __mo_release,
+  acq_rel = __mo_acq_rel,
+  seq_cst = __mo_seq_cst
+};
+
+static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
+  "unexpected underlying type for std::memory_order");
+
+inline constexpr auto memory_order_relaxed = memory_order::relaxed;
+inline constexpr auto memory_order_consume = memory_order::consume;
+inline constexpr auto memory_order_acquire = memory_order::acquire;
+inline constexpr auto memory_order_release = memory_order::release;
+inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
+inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
+
+#else
+
+enum memory_order {
+  memory_order_relaxed = __mo_relaxed,
+  memory_order_consume = __mo_consume,
+  memory_order_acquire = __mo_acquire,
+  memory_order_release = __mo_release,
+  memory_order_acq_rel = __mo_acq_rel,
+  memory_order_seq_cst = __mo_seq_cst,
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ATOMIC_MEMORY_ORDER_H
lib/libcxx/include/__bit/bit_cast.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _ToType, class _FromType>
   requires(sizeof(_ToType) == sizeof(_FromType) &&
@@ -29,7 +29,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _Fr
   return __builtin_bit_cast(_ToType, __from);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__bit/bit_ceil.h
@@ -24,18 +24,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
   if (__t < 2)
     return 1;
   const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));
-  _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
 
   if constexpr (sizeof(_Tp) >= sizeof(unsigned))
     return _Tp{1} << __n;
   else {
     const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
-    const unsigned __retVal = 1u << (__n + __extra);
-    return (_Tp)(__retVal >> __extra);
+    const unsigned __ret_val = 1u << (__n + __extra);
+    return (_Tp)(__ret_val >> __extra);
   }
 }
 
lib/libcxx/include/__bit/bit_floor.h
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
   return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
 }
 
lib/libcxx/include/__bit/bit_width.h
@@ -22,7 +22,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
   return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
 }
 
lib/libcxx/include/__bit/byteswap.h
@@ -13,7 +13,6 @@
 #include <__concepts/arithmetic.h>
 #include <__config>
 #include <cstdint>
-#include <cstdlib>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -21,10 +20,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 template <integral _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
 
   if constexpr (sizeof(_Tp) == 1) {
     return __val;
@@ -48,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
   }
 }
 
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__bit/countl.h
@@ -24,13 +24,13 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_clz(unsigned __x)           _NOEXCEPT { return __builtin_clz(__x); }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_clz(unsigned long __x)      _NOEXCEPT { return __builtin_clzl(__x); }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
 
 #  ifndef _LIBCPP_HAS_NO_INT128
@@ -86,12 +86,12 @@ int __countl_zero(_Tp __t) _NOEXCEPT
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
   return std::__countl_zero(__t);
 }
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
   return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
 }
 
lib/libcxx/include/__bit/countr.h
@@ -23,19 +23,19 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_ctz(unsigned __x)           _NOEXCEPT { return __builtin_ctz(__x); }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_ctz(unsigned long __x)      _NOEXCEPT { return __builtin_ctzl(__x); }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
 
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
   if (__t == 0)
     return numeric_limits<_Tp>::digits;
 
@@ -57,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
 }
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
   return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
 }
 
lib/libcxx/include/__bit/has_single_bit.h
@@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
   return __t != 0 && (((__t & (__t - 1)) == 0));
 }
 
lib/libcxx/include/__bit/popcount.h
@@ -35,7 +35,7 @@ int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popco
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
   if (sizeof(_Tp) <= sizeof(unsigned int))
     return std::__libcpp_popcount(static_cast<unsigned int>(__t));
   else if (sizeof(_Tp) <= sizeof(unsigned long))
lib/libcxx/include/__bit/rotate.h
@@ -34,7 +34,7 @@ _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
 #if _LIBCPP_STD_VER >= 20
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
   const unsigned int __dig = numeric_limits<_Tp>::digits;
   if ((__cnt % __dig) == 0)
     return __t;
@@ -42,7 +42,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
 }
 
 template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
   return std::__rotr(__t, __cnt);
 }
 
lib/libcxx/include/__charconv/chars_format.h
@@ -19,58 +19,45 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
-
-enum class _LIBCPP_ENUM_VIS chars_format
-{
-    scientific = 0x1,
-    fixed = 0x2,
-    hex = 0x4,
-    general = fixed | scientific
-};
-
-inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
-operator~(chars_format __x) {
-  return chars_format(~_VSTD::__to_underlying(__x));
+#if _LIBCPP_STD_VER >= 17
+
+enum class _LIBCPP_ENUM_VIS chars_format { scientific = 0x1, fixed = 0x2, hex = 0x4, general = fixed | scientific };
+
+inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator~(chars_format __x) {
+  return chars_format(~std::__to_underlying(__x));
 }
 
-inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
-operator&(chars_format __x, chars_format __y) {
-  return chars_format(_VSTD::__to_underlying(__x) &
-                      _VSTD::__to_underlying(__y));
+inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator&(chars_format __x, chars_format __y) {
+  return chars_format(std::__to_underlying(__x) & std::__to_underlying(__y));
 }
 
-inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
-operator|(chars_format __x, chars_format __y) {
-  return chars_format(_VSTD::__to_underlying(__x) |
-                      _VSTD::__to_underlying(__y));
+inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator|(chars_format __x, chars_format __y) {
+  return chars_format(std::__to_underlying(__x) | std::__to_underlying(__y));
 }
 
-inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
-operator^(chars_format __x, chars_format __y) {
-  return chars_format(_VSTD::__to_underlying(__x) ^
-                      _VSTD::__to_underlying(__y));
+inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator^(chars_format __x, chars_format __y) {
+  return chars_format(std::__to_underlying(__x) ^ std::__to_underlying(__y));
 }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
 operator&=(chars_format& __x, chars_format __y) {
   __x = __x & __y;
   return __x;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
 operator|=(chars_format& __x, chars_format __y) {
   __x = __x | __y;
   return __x;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
 operator^=(chars_format& __x, chars_format __y) {
   __x = __x ^ __y;
   return __x;
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__charconv/from_chars_integral.h
@@ -0,0 +1,239 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHARCONV_FROM_CHARS_INTEGRAL_H
+#define _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H
+
+#include <__algorithm/copy_n.h>
+#include <__charconv/from_chars_result.h>
+#include <__charconv/traits.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__system_error/errc.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_unsigned.h>
+#include <__type_traits/make_unsigned.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+
+from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
+
+template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) {
+  using __tl = numeric_limits<_Tp>;
+  decltype(std::__to_unsigned_like(__value)) __x;
+
+  bool __neg = (__first != __last && *__first == '-');
+  auto __r   = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
+  switch (__r.ec) {
+  case errc::invalid_argument:
+    return {__first, __r.ec};
+  case errc::result_out_of_range:
+    return __r;
+  default:
+    break;
+  }
+
+  if (__neg) {
+    if (__x <= std::__complement(std::__to_unsigned_like(__tl::min()))) {
+      __x = std::__complement(__x);
+      std::copy_n(std::addressof(__x), 1, std::addressof(__value));
+      return __r;
+    }
+  } else {
+    if (__x <= std::__to_unsigned_like(__tl::max())) {
+      __value = __x;
+      return __r;
+    }
+  }
+
+  return {__r.ptr, errc::result_out_of_range};
+}
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __in_pattern(_Tp __c) {
+  return '0' <= __c && __c <= '9';
+}
+
+struct _LIBCPP_HIDDEN __in_pattern_result {
+  bool __ok;
+  int __val;
+
+  explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
+};
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result __in_pattern(_Tp __c, int __base) {
+  if (__base <= 10)
+    return {'0' <= __c && __c < '0' + __base, __c - '0'};
+  else if (std::__in_pattern(__c))
+    return {true, __c - '0'};
+  else if ('a' <= __c && __c < 'a' + __base - 10)
+    return {true, __c - 'a' + 10};
+  else
+    return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
+}
+
+template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) {
+  auto __find_non_zero = [](_It __firstit, _It __lastit) {
+    for (; __firstit != __lastit; ++__firstit)
+      if (*__firstit != '0')
+        break;
+    return __firstit;
+  };
+
+  auto __p = __find_non_zero(__first, __last);
+  if (__p == __last || !std::__in_pattern(*__p, __args...)) {
+    if (__p == __first)
+      return {__first, errc::invalid_argument};
+    else {
+      __value = 0;
+      return {__p, {}};
+    }
+  }
+
+  auto __r = __f(__p, __last, __value, __args...);
+  if (__r.ec == errc::result_out_of_range) {
+    for (; __r.ptr != __last; ++__r.ptr) {
+      if (!std::__in_pattern(*__r.ptr, __args...))
+        break;
+    }
+  }
+
+  return __r;
+}
+
+template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) {
+  using __tx          = __itoa::__traits<_Tp>;
+  using __output_type = typename __tx::type;
+
+  return std::__subject_seq_combinator(
+      __first, __last, __value, [](const char* __f, const char* __l, _Tp& __val) -> from_chars_result {
+        __output_type __a, __b;
+        auto __p = __tx::__read(__f, __l, __a, __b);
+        if (__p == __l || !std::__in_pattern(*__p)) {
+          __output_type __m = numeric_limits<_Tp>::max();
+          if (__m >= __a && __m - __a >= __b) {
+            __val = __a + __b;
+            return {__p, {}};
+          }
+        }
+        return {__p, errc::result_out_of_range};
+      });
+}
+
+template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) {
+  using __t = decltype(std::__to_unsigned_like(__value));
+  return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
+}
+
+/*
+// Code used to generate __from_chars_log2f_lut.
+#include <cmath>
+#include <format>
+#include <iostream>
+
+int main() {
+  for (int i = 2; i <= 36; ++i)
+    std::cout << std::format("{},\n", log2f(i));
+}
+*/
+/// log2f table for bases [2, 36].
+inline constexpr float __from_chars_log2f_lut[35] = {
+    1,         1.5849625, 2,         2.321928, 2.5849626, 2.807355, 3,        3.169925,  3.321928,
+    3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4,        4.087463, 4.169925,  4.2479277,
+    4.321928,  4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044,  4.7548876, 4.807355,
+    4.857981,  4.9068904, 4.9541965, 5,        5.044394,  5.087463, 5.129283, 5.169925};
+
+template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) {
+  if (__base == 10)
+    return std::__from_chars_atoi(__first, __last, __value);
+
+  return std::__subject_seq_combinator(
+      __first,
+      __last,
+      __value,
+      [](const char* __p, const char* __lastp, _Tp& __val, int __b) -> from_chars_result {
+        using __tl = numeric_limits<_Tp>;
+        // __base is always between 2 and 36 inclusive.
+        auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2];
+        _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
+
+        for (int __i = 1; __p != __lastp; ++__i, ++__p) {
+          if (auto __c = __in_pattern(*__p, __b)) {
+            if (__i < __digits - 1)
+              __x = __x * __b + __c.__val;
+            else {
+              if (!__itoa::__mul_overflowed(__x, __b, __x))
+                ++__p;
+              __y = __c.__val;
+              break;
+            }
+          } else
+            break;
+        }
+
+        if (__p == __lastp || !__in_pattern(*__p, __b)) {
+          if (__tl::max() - __x >= __y) {
+            __val = __x + __y;
+            return {__p, {}};
+          }
+        }
+        return {__p, errc::result_out_of_range};
+      },
+      __base);
+}
+
+template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+__from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) {
+  using __t = decltype(std::__to_unsigned_like(__value));
+  return std::__sign_combinator(__first, __last, __value, __from_chars_integral<__t>, __base);
+}
+
+template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+from_chars(const char* __first, const char* __last, _Tp& __value) {
+  return std::__from_chars_atoi(__first, __last, __value);
+}
+
+template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
+from_chars(const char* __first, const char* __last, _Tp& __value, int __base) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
+  return std::__from_chars_integral(__first, __last, __value, __base);
+}
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H
lib/libcxx/include/__charconv/from_chars_result.h
@@ -11,7 +11,7 @@
 #define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H
 
 #include <__config>
-#include <__errc>
+#include <__system_error/errc.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -19,18 +19,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
-struct _LIBCPP_TYPE_VIS from_chars_result
-{
-    const char* ptr;
-    errc ec;
-#  if _LIBCPP_STD_VER > 17
-    _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
+struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result {
+  const char* ptr;
+  errc ec;
+#  if _LIBCPP_STD_VER >= 20
+  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
 #  endif
 };
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__charconv/tables.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 namespace __itoa {
 
@@ -62,32 +62,41 @@ inline constexpr char __base_16_lut[512] = {
     'f', 'd', 'f', 'e', 'f', 'f'};
 
 inline constexpr uint32_t __pow10_32[10] = {
-    UINT32_C(0),      UINT32_C(10),      UINT32_C(100),      UINT32_C(1000),      UINT32_C(10000),
-    UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)};
-
-inline constexpr uint64_t __pow10_64[20] = {UINT64_C(0),
-                                               UINT64_C(10),
-                                               UINT64_C(100),
-                                               UINT64_C(1000),
-                                               UINT64_C(10000),
-                                               UINT64_C(100000),
-                                               UINT64_C(1000000),
-                                               UINT64_C(10000000),
-                                               UINT64_C(100000000),
-                                               UINT64_C(1000000000),
-                                               UINT64_C(10000000000),
-                                               UINT64_C(100000000000),
-                                               UINT64_C(1000000000000),
-                                               UINT64_C(10000000000000),
-                                               UINT64_C(100000000000000),
-                                               UINT64_C(1000000000000000),
-                                               UINT64_C(10000000000000000),
-                                               UINT64_C(100000000000000000),
-                                               UINT64_C(1000000000000000000),
-                                               UINT64_C(10000000000000000000)};
+    UINT32_C(0),
+    UINT32_C(10),
+    UINT32_C(100),
+    UINT32_C(1000),
+    UINT32_C(10000),
+    UINT32_C(100000),
+    UINT32_C(1000000),
+    UINT32_C(10000000),
+    UINT32_C(100000000),
+    UINT32_C(1000000000)};
+
+inline constexpr uint64_t __pow10_64[20] = {
+    UINT64_C(0),
+    UINT64_C(10),
+    UINT64_C(100),
+    UINT64_C(1000),
+    UINT64_C(10000),
+    UINT64_C(100000),
+    UINT64_C(1000000),
+    UINT64_C(10000000),
+    UINT64_C(100000000),
+    UINT64_C(1000000000),
+    UINT64_C(10000000000),
+    UINT64_C(100000000000),
+    UINT64_C(1000000000000),
+    UINT64_C(10000000000000),
+    UINT64_C(100000000000000),
+    UINT64_C(1000000000000000),
+    UINT64_C(10000000000000000),
+    UINT64_C(100000000000000000),
+    UINT64_C(1000000000000000000),
+    UINT64_C(10000000000000000000)};
 
 #  ifndef _LIBCPP_HAS_NO_INT128
-inline constexpr int __pow10_128_offset = 0;
+inline constexpr int __pow10_128_offset      = 0;
 inline constexpr __uint128_t __pow10_128[40] = {
     UINT64_C(0),
     UINT64_C(10),
@@ -147,7 +156,7 @@ inline constexpr char __digits_base_10[200] = {
 
 } // namespace __itoa
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__charconv/to_chars.h
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHARCONV_TO_CHARS
+#define _LIBCPP___CHARCONV_TO_CHARS
+
+#include <__charconv/to_chars_floating_point.h>
+#include <__charconv/to_chars_integral.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CHARCONV_TO_CHARS
lib/libcxx/include/__charconv/to_chars_base_10.h
@@ -25,7 +25,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 namespace __itoa {
 
@@ -72,7 +72,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __fir
                            static_cast<uint32_t>(__value % 100000000));
 }
 
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept {
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
+__base_10_u32(char* __first, uint32_t __value) noexcept {
   if (__value < 1000000) {
     if (__value < 10000) {
       if (__value < 100) {
@@ -107,7 +108,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(c
   return __itoa::__append10(__first, __value);
 }
 
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept {
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
+__base_10_u64(char* __buffer, uint64_t __value) noexcept {
   if (__value <= UINT32_MAX)
     return __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value));
 
@@ -130,12 +132,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(c
 /// range that can be used. However the range is sufficient for
 /// \ref __base_10_u128.
 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept {
-  _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__exp >= __pow10_128_offset, "Index out of bounds");
   return __pow10_128[__exp - __pow10_128_offset];
 }
 
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept {
-  _LIBCPP_ASSERT(
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
+__base_10_u128(char* __buffer, __uint128_t __value) noexcept {
+  _LIBCPP_ASSERT_UNCATEGORIZED(
       __value > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
 
   // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be
@@ -159,8 +162,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(
     __value %= __itoa::__pow_10(29);
     __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
     __value %= __itoa::__pow_10(19);
-  }
-  else {
+  } else {
     // step 2
     // This version needs to determine the position of the leading non-zero digit.
     __buffer = __base_10_u64(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
@@ -176,7 +178,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(
 #  endif
 } // namespace __itoa
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__charconv/to_chars_floating_point.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHARCONV_TO_CHARS_FLOATING_POINT_H
+#define _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H
+
+#include <__availability>
+#include <__charconv/chars_format.h>
+#include <__charconv/to_chars_result.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, float __value);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, double __value);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, long double __value);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, float __value, chars_format __fmt);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, double __value, chars_format __fmt);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
+
+_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H
lib/libcxx/include/__charconv/to_chars_integral.h
@@ -0,0 +1,326 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHARCONV_TO_CHARS_INTEGRAL_H
+#define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
+
+#include <__algorithm/copy_n.h>
+#include <__bit/countl.h>
+#include <__charconv/tables.h>
+#include <__charconv/to_chars_base_10.h>
+#include <__charconv/to_chars_result.h>
+#include <__charconv/traits.h>
+#include <__config>
+#include <__system_error/errc.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/make_32_64_or_128_bit.h>
+#include <__type_traits/make_unsigned.h>
+#include <__utility/unreachable.h>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+
+to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
+  auto __x = std::__to_unsigned_like(__value);
+  if (__value < 0 && __first != __last) {
+    *__first++ = '-';
+    __x        = std::__complement(__x);
+  }
+
+  return std::__to_chars_itoa(__first, __last, __x, false_type());
+}
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
+  using __tx  = __itoa::__traits<_Tp>;
+  auto __diff = __last - __first;
+
+  if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
+    return {__tx::__convert(__first, __value), errc(0)};
+  else
+    return {__last, errc::value_too_large};
+}
+
+#  ifndef _LIBCPP_HAS_NO_INT128
+template <>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
+  // When the value fits in 64-bits use the 64-bit code path. This reduces
+  // the number of expensive calculations on 128-bit values.
+  //
+  // NOTE the 128-bit code path requires this optimization.
+  if (__value <= numeric_limits<uint64_t>::max())
+    return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
+
+  using __tx  = __itoa::__traits<__uint128_t>;
+  auto __diff = __last - __first;
+
+  if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
+    return {__tx::__convert(__first, __value), errc(0)};
+  else
+    return {__last, errc::value_too_large};
+}
+#  endif
+
+template <class _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) {
+  auto __x = std::__to_unsigned_like(__value);
+  if (__value < 0 && __first != __last) {
+    *__first++ = '-';
+    __x        = std::__complement(__x);
+  }
+
+  return std::__to_chars_integral(__first, __last, __x, __base, false_type());
+}
+
+namespace __itoa {
+
+template <unsigned _Base>
+struct _LIBCPP_HIDDEN __integral;
+
+template <>
+struct _LIBCPP_HIDDEN __integral<2> {
+  template <typename _Tp>
+  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+    // If value == 0 still need one digit. If the value != this has no
+    // effect since the code scans for the most significant bit set. (Note
+    // that __libcpp_clz doesn't work for 0.)
+    return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
+  }
+
+  template <typename _Tp>
+  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
+  __to_chars(char* __first, char* __last, _Tp __value) {
+    ptrdiff_t __cap = __last - __first;
+    int __n         = __width(__value);
+    if (__n > __cap)
+      return {__last, errc::value_too_large};
+
+    __last                   = __first + __n;
+    char* __p                = __last;
+    const unsigned __divisor = 16;
+    while (__value > __divisor) {
+      unsigned __c = __value % __divisor;
+      __value /= __divisor;
+      __p -= 4;
+      std::copy_n(&__base_2_lut[4 * __c], 4, __p);
+    }
+    do {
+      unsigned __c = __value % 2;
+      __value /= 2;
+      *--__p = "01"[__c];
+    } while (__value != 0);
+    return {__last, errc(0)};
+  }
+};
+
+template <>
+struct _LIBCPP_HIDDEN __integral<8> {
+  template <typename _Tp>
+  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+    // If value == 0 still need one digit. If the value != this has no
+    // effect since the code scans for the most significat bit set. (Note
+    // that __libcpp_clz doesn't work for 0.)
+    return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
+  }
+
+  template <typename _Tp>
+  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
+  __to_chars(char* __first, char* __last, _Tp __value) {
+    ptrdiff_t __cap = __last - __first;
+    int __n         = __width(__value);
+    if (__n > __cap)
+      return {__last, errc::value_too_large};
+
+    __last             = __first + __n;
+    char* __p          = __last;
+    unsigned __divisor = 64;
+    while (__value > __divisor) {
+      unsigned __c = __value % __divisor;
+      __value /= __divisor;
+      __p -= 2;
+      std::copy_n(&__base_8_lut[2 * __c], 2, __p);
+    }
+    do {
+      unsigned __c = __value % 8;
+      __value /= 8;
+      *--__p = "01234567"[__c];
+    } while (__value != 0);
+    return {__last, errc(0)};
+  }
+};
+
+template <>
+struct _LIBCPP_HIDDEN __integral<16> {
+  template <typename _Tp>
+  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+    // If value == 0 still need one digit. If the value != this has no
+    // effect since the code scans for the most significat bit set. (Note
+    // that __libcpp_clz doesn't work for 0.)
+    return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
+  }
+
+  template <typename _Tp>
+  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
+  __to_chars(char* __first, char* __last, _Tp __value) {
+    ptrdiff_t __cap = __last - __first;
+    int __n         = __width(__value);
+    if (__n > __cap)
+      return {__last, errc::value_too_large};
+
+    __last             = __first + __n;
+    char* __p          = __last;
+    unsigned __divisor = 256;
+    while (__value > __divisor) {
+      unsigned __c = __value % __divisor;
+      __value /= __divisor;
+      __p -= 2;
+      std::copy_n(&__base_16_lut[2 * __c], 2, __p);
+    }
+    if (__first != __last)
+      do {
+        unsigned __c = __value % 16;
+        __value /= 16;
+        *--__p = "0123456789abcdef"[__c];
+      } while (__value != 0);
+    return {__last, errc(0)};
+  }
+};
+
+} // namespace __itoa
+
+template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
+  return __itoa::__integral<_Base>::__width(__value);
+}
+
+template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
+  return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
+}
+
+template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value) {
+  return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
+}
+
+template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value) {
+  return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
+}
+
+template <typename _Tp>
+_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__value >= 0, "The function requires a non-negative value.");
+
+  unsigned __base_2 = __base * __base;
+  unsigned __base_3 = __base_2 * __base;
+  unsigned __base_4 = __base_2 * __base_2;
+
+  int __r = 0;
+  while (true) {
+    if (__value < __base)
+      return __r + 1;
+    if (__value < __base_2)
+      return __r + 2;
+    if (__value < __base_3)
+      return __r + 3;
+    if (__value < __base_4)
+      return __r + 4;
+
+    __value /= __base_4;
+    __r += 4;
+  }
+
+  __libcpp_unreachable();
+}
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) {
+  if (__base == 10) [[likely]]
+    return std::__to_chars_itoa(__first, __last, __value, false_type());
+
+  switch (__base) {
+  case 2:
+    return std::__to_chars_integral<2>(__first, __last, __value);
+  case 8:
+    return std::__to_chars_integral<8>(__first, __last, __value);
+  case 16:
+    return std::__to_chars_integral<16>(__first, __last, __value);
+  }
+
+  ptrdiff_t __cap = __last - __first;
+  int __n         = std::__to_chars_integral_width(__value, __base);
+  if (__n > __cap)
+    return {__last, errc::value_too_large};
+
+  __last    = __first + __n;
+  char* __p = __last;
+  do {
+    unsigned __c = __value % __base;
+    __value /= __base;
+    *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
+  } while (__value != 0);
+  return {__last, errc(0)};
+}
+
+template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, _Tp __value) {
+  using _Type = __make_32_64_or_128_bit_t<_Tp>;
+  static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
+  return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
+}
+
+template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+to_chars(char* __first, char* __last, _Tp __value, int __base) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
+
+  using _Type = __make_32_64_or_128_bit_t<_Tp>;
+  return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
+}
+
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
lib/libcxx/include/__charconv/to_chars_result.h
@@ -11,7 +11,7 @@
 #define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H
 
 #include <__config>
-#include <__errc>
+#include <__system_error/errc.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -19,18 +19,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
-struct _LIBCPP_TYPE_VIS to_chars_result
-{
-    char* ptr;
-    errc ec;
-#  if _LIBCPP_STD_VER > 17
-    _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
+struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result {
+  char* ptr;
+  errc ec;
+#  if _LIBCPP_STD_VER >= 20
+  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
 #  endif
 };
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__charconv/traits.h
@@ -0,0 +1,199 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHARCONV_TRAITS
+#define _LIBCPP___CHARCONV_TRAITS
+
+#include <__bit/countl.h>
+#include <__charconv/tables.h>
+#include <__charconv/to_chars_base_10.h>
+#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_unsigned.h>
+#include <cstdint>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+
+namespace __itoa {
+
+template <typename _Tp, typename = void>
+struct _LIBCPP_HIDDEN __traits_base;
+
+template <typename _Tp>
+struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> {
+  using type = uint32_t;
+
+  /// The width estimation using a log10 algorithm.
+  ///
+  /// The algorithm is based on
+  /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+  /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+  /// function requires its input to have at least one bit set the value of
+  /// zero is set to one. This means the first element of the lookup table is
+  /// zero.
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
+    auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
+    return __t - (__v < __itoa::__pow10_32[__t]) + 1;
+  }
+
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
+    return __itoa::__base_10_u32(__p, __v);
+  }
+
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() {
+    return __itoa::__pow10_32;
+  }
+};
+
+template <typename _Tp>
+struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
+  using type = uint64_t;
+
+  /// The width estimation using a log10 algorithm.
+  ///
+  /// The algorithm is based on
+  /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+  /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+  /// function requires its input to have at least one bit set the value of
+  /// zero is set to one. This means the first element of the lookup table is
+  /// zero.
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
+    auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
+    return __t - (__v < __itoa::__pow10_64[__t]) + 1;
+  }
+
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
+    return __itoa::__base_10_u64(__p, __v);
+  }
+
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() {
+    return __itoa::__pow10_64;
+  }
+};
+
+#  ifndef _LIBCPP_HAS_NO_INT128
+template <typename _Tp>
+struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
+  using type = __uint128_t;
+
+  /// The width estimation using a log10 algorithm.
+  ///
+  /// The algorithm is based on
+  /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+  /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+  /// function requires its input to have at least one bit set the value of
+  /// zero is set to one. This means the first element of the lookup table is
+  /// zero.
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
+    // There's always a bit set in the upper 64-bits.
+    auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
+    _LIBCPP_ASSERT_UNCATEGORIZED(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
+    // __t is adjusted since the lookup table misses the lower entries.
+    return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
+  }
+
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
+    return __itoa::__base_10_u128(__p, __v);
+  }
+
+  // TODO FMT This pow function should get an index.
+  // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() {
+    return __itoa::__pow10_128;
+  }
+};
+#  endif
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
+__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) {
+  auto __c = __a * __b;
+  __r      = __c;
+  return __c > numeric_limits<unsigned char>::max();
+}
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
+__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) {
+  auto __c = __a * __b;
+  __r      = __c;
+  return __c > numeric_limits<unsigned short>::max();
+}
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
+  static_assert(is_unsigned<_Tp>::value, "");
+  return __builtin_mul_overflow(__a, __b, &__r);
+}
+
+template <typename _Tp, typename _Up>
+inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
+  return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
+}
+
+template <typename _Tp>
+struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> {
+  static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
+  using __traits_base<_Tp>::__pow;
+  using typename __traits_base<_Tp>::type;
+
+  // precondition: at least one non-zero character available
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
+  __read(char const* __p, char const* __ep, type& __a, type& __b) {
+    type __cprod[digits];
+    int __j = digits - 1;
+    int __i = digits;
+    do {
+      if (*__p < '0' || *__p > '9')
+        break;
+      __cprod[--__i] = *__p++ - '0';
+    } while (__p != __ep && __i != 0);
+
+    __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, __cprod[__i]);
+    if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
+      --__p;
+    return __p;
+  }
+
+  template <typename _It1, typename _It2, class _Up>
+  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
+  __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) {
+    for (; __first1 < __last1; ++__first1, ++__first2)
+      __init = __init + *__first1 * *__first2;
+    return __init;
+  }
+};
+
+} // namespace __itoa
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp __complement(_Tp __x) {
+  static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
+  return _Tp(~__x + 1);
+}
+
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___CHARCONV_TRAITS
lib/libcxx/include/__chrono/calendar.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -26,12 +26,12 @@ namespace chrono
 {
 
 struct local_t {};
-template<class Duration>
-using local_time  = time_point<local_t, Duration>;
+template<class _Duration>
+using local_time  = time_point<local_t, _Duration>;
 using local_seconds = local_time<seconds>;
 using local_days    = local_time<days>;
 
-struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; };
+struct last_spec { explicit last_spec() = default; };
 inline constexpr last_spec last{};
 
 
@@ -39,6 +39,6 @@ inline constexpr last_spec last{};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_CALENDAR_H
lib/libcxx/include/__chrono/concepts.h
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___CHRONO_CONCEPTS_H
+#define _LIBCPP___CHRONO_CONCEPTS_H
+
+#include <__chrono/hh_mm_ss.h>
+#include <__chrono/time_point.h>
+#include <__config>
+#include <__type_traits/is_specialization.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+concept __is_hh_mm_ss = __is_specialization_v<_Tp, chrono::hh_mm_ss>;
+
+template <class _Tp>
+concept __is_time_point = __is_specialization_v<_Tp, chrono::time_point>;
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CHRONO_CONCEPTS_H
lib/libcxx/include/__chrono/convert_to_tm.h
@@ -10,8 +10,11 @@
 #ifndef _LIBCPP___CHRONO_CONVERT_TO_TM_H
 #define _LIBCPP___CHRONO_CONVERT_TO_TM_H
 
+#include <__chrono/calendar.h>
+#include <__chrono/concepts.h>
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
+#include <__chrono/file_clock.h>
 #include <__chrono/hh_mm_ss.h>
 #include <__chrono/month.h>
 #include <__chrono/month_weekday.h>
@@ -26,17 +29,23 @@
 #include <__chrono/year_month_weekday.h>
 #include <__concepts/same_as.h>
 #include <__config>
+#include <__format/format_error.h>
 #include <__memory/addressof.h>
+#include <__type_traits/is_convertible.h>
 #include <cstdint>
 #include <ctime>
+#include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // Conerts a chrono date and weekday to a given _Tm type.
 //
@@ -67,6 +76,24 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday _
   return __result;
 }
 
+template <class _Tm, class _Duration>
+_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const chrono::sys_time<_Duration> __tp) {
+  chrono::sys_days __days = chrono::floor<chrono::days>(__tp);
+  chrono::year_month_day __ymd{__days};
+
+  _Tm __result = std::__convert_to_tm<_Tm>(chrono::year_month_day{__ymd}, chrono::weekday{__days});
+
+  uint64_t __sec =
+      chrono::duration_cast<chrono::seconds>(__tp - chrono::time_point_cast<chrono::seconds>(__days)).count();
+  __sec %= 24 * 3600;
+  __result.tm_hour = __sec / 3600;
+  __sec %= 3600;
+  __result.tm_min = __sec / 60;
+  __result.tm_sec = __sec % 60;
+
+  return __result;
+}
+
 // Convert a chrono (calendar) time point, or dururation to the given _Tm type,
 // which must have the same properties as std::tm.
 template <class _Tm, class _ChronoT>
@@ -76,17 +103,37 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
   __result.tm_zone = "UTC";
 #  endif
 
-  if constexpr (chrono::__is_duration<_ChronoT>::value) {
+  if constexpr (__is_time_point<_ChronoT>) {
+    if constexpr (same_as<typename _ChronoT::clock, chrono::system_clock>)
+      return std::__convert_to_tm<_Tm>(__value);
+    else if constexpr (same_as<typename _ChronoT::clock, chrono::file_clock>)
+      return std::__convert_to_tm<_Tm>(_ChronoT::clock::to_sys(__value));
+    else if constexpr (same_as<typename _ChronoT::clock, chrono::local_t>)
+      return std::__convert_to_tm<_Tm>(chrono::sys_time<typename _ChronoT::duration>{__value.time_since_epoch()});
+    else
+      static_assert(sizeof(_ChronoT) == 0, "TODO: Add the missing clock specialization");
+  } else if constexpr (chrono::__is_duration<_ChronoT>::value) {
     // [time.format]/6
     //   ...  However, if a flag refers to a "time of day" (e.g. %H, %I, %p,
     //   etc.), then a specialization of duration is interpreted as the time of
     //   day elapsed since midnight.
-    uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count();
-    __sec %= 24 * 3600;
-    __result.tm_hour = __sec / 3600;
-    __sec %= 3600;
-    __result.tm_min = __sec / 60;
-    __result.tm_sec = __sec % 60;
+
+    // Not all values can be converted to hours, it may run into ratio
+    // conversion errors. In that case the conversion to seconds works.
+    if constexpr (is_convertible_v<_ChronoT, chrono::hours>) {
+      auto __hour      = chrono::floor<chrono::hours>(__value);
+      auto __sec       = chrono::duration_cast<chrono::seconds>(__value - __hour);
+      __result.tm_hour = __hour.count() % 24;
+      __result.tm_min  = __sec.count() / 60;
+      __result.tm_sec  = __sec.count() % 60;
+    } else {
+      uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count();
+      __sec %= 24 * 3600;
+      __result.tm_hour = __sec / 3600;
+      __sec %= 3600;
+      __result.tm_min = __sec / 60;
+      __result.tm_sec = __sec % 60;
+    }
   } else if constexpr (same_as<_ChronoT, chrono::day>)
     __result.tm_mday = static_cast<unsigned>(__value);
   else if constexpr (same_as<_ChronoT, chrono::month>)
@@ -114,14 +161,26 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
   } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> ||
                        same_as<_ChronoT, chrono::year_month_weekday_last>) {
     return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast<chrono::sys_days>(__value)}, __value.weekday());
+  } else if constexpr (__is_hh_mm_ss<_ChronoT>) {
+    __result.tm_sec = __value.seconds().count();
+    __result.tm_min = __value.minutes().count();
+    // In libc++ hours is stored as a long. The type in std::tm is an int. So
+    // the overflow can only occur when hour uses more bits than an int
+    // provides.
+    if constexpr (sizeof(std::chrono::hours::rep) > sizeof(__result.tm_hour))
+      if (__value.hours().count() > std::numeric_limits<decltype(__result.tm_hour)>::max())
+        std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow");
+    __result.tm_hour = __value.hours().count();
   } else
     static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
 
   return __result;
 }
 
-#endif //if _LIBCPP_STD_VER > 17
+#endif // if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H
lib/libcxx/include/__chrono/day.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -29,7 +29,7 @@ class day {
 private:
     unsigned char __d_;
 public:
-    _LIBCPP_HIDE_FROM_ABI day() = default;
+    day() = default;
     _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast<unsigned char>(__val)) {}
     _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++()    noexcept { ++__d_; return *this; }
     _LIBCPP_HIDE_FROM_ABI inline constexpr day  operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
@@ -79,6 +79,6 @@ day& day::operator-=(const days& __dd) noexcept
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_DAY_H
lib/libcxx/include/__chrono/duration.h
@@ -10,6 +10,8 @@
 #ifndef _LIBCPP___CHRONO_DURATION_H
 #define _LIBCPP___CHRONO_DURATION_H
 
+#include <__compare/ordering.h>
+#include <__compare/three_way_comparable.h>
 #include <__config>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
@@ -130,7 +132,7 @@ duration_cast(const duration<_Rep, _Period>& __fd)
 template <class _Rep>
 struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Rep>
 inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
 #endif
@@ -144,7 +146,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  _NOEXCEPT {return numeric_limits<_Rep>::lowest();}
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _ToDuration, class _Rep, class _Period>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
@@ -186,11 +188,11 @@ round(const duration<_Rep, _Period>& __d)
 {
     _ToDuration __lower = chrono::floor<_ToDuration>(__d);
     _ToDuration __upper = __lower + _ToDuration{1};
-    auto __lowerDiff = __d - __lower;
-    auto __upperDiff = __upper - __d;
-    if (__lowerDiff < __upperDiff)
+    auto __lower_diff   = __d - __lower;
+    auto __upper_diff   = __upper - __d;
+    if (__lower_diff < __upper_diff)
         return __lower;
-    if (__lowerDiff > __upperDiff)
+    if (__lower_diff > __upper_diff)
         return __upper;
     return __lower.count() & 1 ? __upper : __lower;
 }
@@ -242,11 +244,10 @@ private:
     rep __rep_;
 public:
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 #ifndef _LIBCPP_CXX03_LANG
-        duration() = default;
+        constexpr duration() = default;
 #else
-        duration() {}
+        _LIBCPP_HIDE_FROM_ABI duration() {}
 #endif
 
     template <class _Rep2>
@@ -307,7 +308,7 @@ typedef duration<long long,        milli> milliseconds;
 typedef duration<long long              > seconds;
 typedef duration<     long, ratio<  60> > minutes;
 typedef duration<     long, ratio<3600> > hours;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 typedef duration<     int, ratio_multiply<ratio<24>, hours::period>>         days;
 typedef duration<     int, ratio_multiply<ratio<7>,   days::period>>         weeks;
 typedef duration<     int, ratio_multiply<ratio<146097, 400>, days::period>> years;
@@ -343,6 +344,8 @@ operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
     return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 // Duration !=
 
 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
@@ -354,6 +357,8 @@ operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
     return !(__lhs == __rhs);
 }
 
+#endif // _LIBCPP_STD_VER <= 17
+
 // Duration <
 
 template <class _LhsDuration, class _RhsDuration>
@@ -417,6 +422,20 @@ operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
     return !(__lhs < __rhs);
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template<class _Rep1, class _Period1, class _Rep2, class _Period2>
+  requires three_way_comparable<common_type_t<_Rep1, _Rep2>>
+_LIBCPP_HIDE_FROM_ABI
+constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs,
+                           const duration<_Rep2, _Period2>& __rhs)
+{
+    using _Ct = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
+    return _Ct(__lhs).count() <=> _Ct(__rhs).count();
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
 // Duration +
 
 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
@@ -530,7 +549,7 @@ operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
 
 } // namespace chrono
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 // Suffixes for duration literals [time.duration.literals]
 inline namespace literals
 {
@@ -609,7 +628,7 @@ namespace chrono { // hoist the literals into namespace std::chrono
    using namespace literals::chrono_literals;
 } // namespace chrono
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__chrono/file_clock.h
@@ -27,7 +27,7 @@ struct _FilesystemClock;
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 #endif // !_LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -44,7 +44,7 @@ using file_time = time_point<file_clock, _Duration>;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #ifndef _LIBCPP_CXX03_LANG
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -63,9 +63,9 @@ struct _FilesystemClock {
   _LIBCPP_EXPORTED_FROM_ABI
   static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
 
-  _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept;
+  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   template <class _Duration>
   _LIBCPP_HIDE_FROM_ABI
   static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
@@ -77,7 +77,7 @@ struct _FilesystemClock {
   static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
     return chrono::file_time<_Duration>(__t.time_since_epoch());
   }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 };
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 #endif // !_LIBCPP_CXX03_LANG
lib/libcxx/include/__chrono/formatter.h
@@ -11,9 +11,11 @@
 #define _LIBCPP___CHRONO_FORMATTER_H
 
 #include <__chrono/calendar.h>
+#include <__chrono/concepts.h>
 #include <__chrono/convert_to_tm.h>
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
+#include <__chrono/file_clock.h>
 #include <__chrono/hh_mm_ss.h>
 #include <__chrono/month.h>
 #include <__chrono/month_weekday.h>
@@ -21,6 +23,7 @@
 #include <__chrono/ostream.h>
 #include <__chrono/parser_std_format_spec.h>
 #include <__chrono/statically_widen.h>
+#include <__chrono/system_clock.h>
 #include <__chrono/time_point.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
@@ -35,13 +38,12 @@
 #include <__format/format_functions.h>
 #include <__format/format_parse_context.h>
 #include <__format/formatter.h>
-#include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__format/write_escaped.h>
 #include <__memory/addressof.h>
 #include <cmath>
 #include <ctime>
 #include <sstream>
-#include <string>
 #include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -50,7 +52,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#if _LIBCPP_STD_VER >= 20
 
 namespace __formatter {
 
@@ -75,13 +77,15 @@ namespace __formatter {
 // For tiny ratios it's not possible to convert a duration to a hh_mm_ss. This
 // fails compile-time due to the limited precision of the ratio (64-bit is too
 // small). Therefore a duration uses its own conversion.
-template <class _CharT, class _Tp>
-  requires(chrono::__is_duration<_Tp>::value)
-_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) {
+template <class _CharT, class _Rep, class _Period>
+_LIBCPP_HIDE_FROM_ABI void
+__format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_stringstream<_CharT>& __sstr) {
   __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
 
+  using __duration = chrono::duration<_Rep, _Period>;
+
   auto __fraction = __value - chrono::duration_cast<chrono::seconds>(__value);
-  if constexpr (chrono::treat_as_floating_point_v<typename _Tp::rep>)
+  if constexpr (chrono::treat_as_floating_point_v<_Rep>)
     // When the floating-point value has digits itself they are ignored based
     // on the wording in [tab:time.format.spec]
     //   If the precision of the input cannot be exactly represented with
@@ -96,19 +100,44 @@ _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_string
     // https://godbolt.org/z/6dsbnW8ba
     std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
                    _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
-                   __fraction.count(),
-                   chrono::hh_mm_ss<_Tp>::fractional_width);
+                   chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
+                   chrono::hh_mm_ss<__duration>::fractional_width);
+  else
+    std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
+                   _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
+                   chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
+                   chrono::hh_mm_ss<__duration>::fractional_width);
+}
+
+template <class _CharT, __is_time_point _Tp>
+_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) {
+  __formatter::__format_sub_seconds(__value.time_since_epoch(), __sstr);
+}
+
+template <class _CharT, class _Duration>
+_LIBCPP_HIDE_FROM_ABI void
+__format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstream<_CharT>& __sstr) {
+  __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
+  if constexpr (chrono::treat_as_floating_point_v<typename _Duration::rep>)
+    std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
+                   _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
+                   __value.subseconds().count(),
+                   __value.fractional_width);
   else
     std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
                    _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
-                   __fraction.count(),
-                   chrono::hh_mm_ss<_Tp>::fractional_width);
+                   __value.subseconds().count(),
+                   __value.fractional_width);
 }
 
 template <class _Tp>
 consteval bool __use_fraction() {
-  if constexpr (chrono::__is_duration<_Tp>::value)
+  if constexpr (__is_time_point<_Tp>)
+    return chrono::hh_mm_ss<typename _Tp::duration>::fractional_width;
+  else if constexpr (chrono::__is_duration<_Tp>::value)
     return chrono::hh_mm_ss<_Tp>::fractional_width;
+  else if constexpr (__is_hh_mm_ss<_Tp>)
+    return _Tp::fractional_width;
   else
     return false;
 }
@@ -169,7 +198,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
         if (__year < 1000 || __year > 9999)
           __formatter::__format_century(__year, __sstr);
         else
-          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
       } break;
 
       case _CharT('j'):
@@ -180,7 +209,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
           // an intemediate step.
           __sstr << chrono::duration_cast<chrono::days>(chrono::duration_cast<chrono::seconds>(__value)).count();
         else
-          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
         break;
 
       case _CharT('q'):
@@ -208,7 +237,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
 
       case _CharT('S'):
       case _CharT('T'):
-        __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+        __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
         if constexpr (__use_fraction<_Tp>())
           __formatter::__format_sub_seconds(__value, __sstr);
         break;
@@ -240,20 +269,19 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
         //
         // TODO FMT evaluate the comment above.
 
-#  if defined(__GLIBC__) || defined(_AIX)
+#  if defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
       case _CharT('y'):
         // Glibc fails for negative values, AIX for positive values too.
         __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100);
         break;
-#  endif // defined(__GLIBC__) || defined(_AIX)
+#  endif // defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
 
-      case _CharT('Y'): {
-        int __year = __t.tm_year + 1900;
-        if (__year < 1000)
-          __formatter::__format_year(__year, __sstr);
-        else
-          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
-      } break;
+      case _CharT('Y'):
+        // Depending on the platform's libc the range of supported years is
+        // limited. Intead of of testing all conditions use the internal
+        // implementation unconditionally.
+        __formatter::__format_year(__t.tm_year + 1900, __sstr);
+        break;
 
       case _CharT('F'): {
         int __year = __t.tm_year + 1900;
@@ -261,9 +289,14 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
           __formatter::__format_year(__year, __sstr);
           __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
         } else
-          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
       } break;
 
+      case _CharT('Z'):
+        // TODO FMT Add proper timezone support.
+        __sstr << _LIBCPP_STATICALLY_WIDEN(_CharT, "UTC");
+        break;
+
       case _CharT('O'):
         if constexpr (__use_fraction<_Tp>()) {
           // Handle OS using the normal representation for the non-fractional
@@ -271,7 +304,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
           // fractional part should be formatted.
           if (*(__it + 1) == 'S') {
             ++__it;
-            __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+            __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
             __formatter::__format_sub_seconds(__value, __sstr);
             break;
           }
@@ -281,7 +314,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
         ++__it;
         [[fallthrough]];
       default:
-        __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+        __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
         break;
       }
     } else {
@@ -292,7 +325,9 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
-  if constexpr (same_as<_Tp, chrono::day>)
+  if constexpr (__is_time_point<_Tp>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::day>)
     return true;
   else if constexpr (same_as<_Tp, chrono::month>)
     return __value.ok();
@@ -322,13 +357,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
     return __value.weekday().ok();
   else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
     return __value.weekday().ok();
+  else if constexpr (__is_hh_mm_ss<_Tp>)
+    return true;
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
-  if constexpr (same_as<_Tp, chrono::day>)
+  if constexpr (__is_time_point<_Tp>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::day>)
     return true;
   else if constexpr (same_as<_Tp, chrono::month>)
     return __value.ok();
@@ -358,13 +397,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
     return __value.weekday().ok();
   else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
     return __value.weekday().ok();
+  else if constexpr (__is_hh_mm_ss<_Tp>)
+    return true;
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
-  if constexpr (same_as<_Tp, chrono::day>)
+  if constexpr (__is_time_point<_Tp>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::day>)
     return true;
   else if constexpr (same_as<_Tp, chrono::month>)
     return __value.ok();
@@ -394,13 +437,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
     return __value.ok();
   else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
     return __value.ok();
+  else if constexpr (__is_hh_mm_ss<_Tp>)
+    return true;
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
-  if constexpr (same_as<_Tp, chrono::day>)
+  if constexpr (__is_time_point<_Tp>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::day>)
     return true;
   else if constexpr (same_as<_Tp, chrono::month>)
     return __value.ok();
@@ -430,16 +477,18 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
     return __value.month().ok();
   else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
     return __value.month().ok();
+  else if constexpr (__is_hh_mm_ss<_Tp>)
+    return true;
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
 
-template <class _CharT, class _Tp>
+template <class _CharT, class _Tp, class _FormatContext>
 _LIBCPP_HIDE_FROM_ABI auto
 __format_chrono(const _Tp& __value,
-                auto& __ctx,
+                _FormatContext& __ctx,
                 __format_spec::__parsed_specifications<_CharT> __specs,
-                basic_string_view<_CharT> __chrono_specs) -> decltype(__ctx.out()) {
+                basic_string_view<_CharT> __chrono_specs) {
   basic_stringstream<_CharT> __sstr;
   // [time.format]/2
   // 2.1 - the "C" locale if the L option is not present in chrono-format-spec, otherwise
@@ -464,42 +513,63 @@ __format_chrono(const _Tp& __value,
     } else {
       // Test __weekday_name_ before __weekday_ to give a better error.
       if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value))
-        std::__throw_format_error("formatting a weekday name needs a valid weekday");
+        std::__throw_format_error("Formatting a weekday name needs a valid weekday");
 
       if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value))
-        std::__throw_format_error("formatting a weekday needs a valid weekday");
+        std::__throw_format_error("Formatting a weekday needs a valid weekday");
 
       if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value))
-        std::__throw_format_error("formatting a day of year needs a valid date");
+        std::__throw_format_error("Formatting a day of year needs a valid date");
 
       if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value))
-        std::__throw_format_error("formatting a week of year needs a valid date");
+        std::__throw_format_error("Formatting a week of year needs a valid date");
 
       if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value))
-        std::__throw_format_error("formatting a month name from an invalid month number");
+        std::__throw_format_error("Formatting a month name from an invalid month number");
+
+      if constexpr (__is_hh_mm_ss<_Tp>) {
+        // Note this is a pedantic intepretation of the Standard. A hh_mm_ss
+        // is no longer a time_of_day and can store an arbitrary number of
+        // hours. A number of hours in a 12 or 24 hour clock can't represent
+        // 24 hours or more. The functions std::chrono::make12 and
+        // std::chrono::make24 reaffirm this view point.
+        //
+        // Interestingly this will be the only output stream function that
+        // throws.
+        //
+        // TODO FMT The wording probably needs to be adapted to
+        // - The displayed hours is hh_mm_ss.hours() % 24
+        // - It should probably allow %j in the same fashion as duration.
+        // - The stream formatter should change its output when hours >= 24
+        //   - Write it as not valid,
+        //   - or write the number of days.
+        if (__specs.__chrono_.__hour_ && __value.hours().count() > 23)
+          std::__throw_format_error("Formatting a hour needs a valid value");
+
+        if (__value.is_negative())
+          __sstr << _CharT('-');
+      }
 
       __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs);
     }
   }
 
-  // TODO FMT Use the stringstream's view after P0408R7 has been implemented.
-  basic_string<_CharT> __str = __sstr.str();
-  return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
+  return __formatter::__write_string(__sstr.view(), __ctx.out(), __specs);
 }
 
 } // namespace __formatter
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_chrono {
+struct _LIBCPP_TEMPLATE_VIS __formatter_chrono {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(
-      basic_format_parse_context<_CharT>& __parse_ctx, __format_spec::__fields __fields, __format_spec::__flags __flags)
-      -> decltype(__parse_ctx.begin()) {
-    return __parser_.__parse(__parse_ctx, __fields, __flags);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
+  __parse(_ParseContext& __ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) {
+    return __parser_.__parse(__ctx, __fields, __flags);
   }
 
-  template <class _Tp>
-  _LIBCPP_HIDE_FROM_ABI auto format(const _Tp& __value, auto& __ctx) const -> decltype(__ctx.out()) const {
+  template <class _Tp, class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __value, _FormatContext& __ctx) const {
     return __formatter::__format_chrono(
         __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_);
   }
@@ -507,13 +577,47 @@ public:
   __format_spec::__parser_chrono<_CharT> __parser_;
 };
 
+template <class _Duration, __fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::sys_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
+  }
+};
+
+template <class _Duration, __fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::file_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
+  }
+};
+
+template <class _Duration, __fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::local_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    // The flags are not __clock since there is no associated time-zone.
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date_time);
+  }
+};
+
 template <class _Rep, class _Period, __fmt_char_type _CharT>
 struct formatter<chrono::duration<_Rep, _Period>, _CharT> : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
     // [time.format]/1
     // Giving a precision specification in the chrono-format-spec is valid only
     // for std::chrono::duration types where the representation type Rep is a
@@ -523,193 +627,203 @@ public:
     //
     // Note this doesn't refer to chrono::treat_as_floating_point_v<_Rep>.
     if constexpr (std::floating_point<_Rep>)
-      return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration);
+      return _Base::__parse(__ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration);
     else
-      return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration);
+      return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::day, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::day, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_indexed, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_indexed, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_last, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_last, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day_last, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day_last, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday_last, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday_last, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day_last, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day_last, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
   }
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday_last, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday_last, _CharT>
     : public __formatter_chrono<_CharT> {
 public:
   using _Base = __formatter_chrono<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
   }
 };
 
-#endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+template <class _Duration, __fmt_char_type _CharT>
+struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time);
+  }
+};
+#endif // if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__chrono/hh_mm_ss.h
@@ -13,14 +13,14 @@
 #include <__chrono/duration.h>
 #include <__chrono/time_point.h>
 #include <__config>
+#include <__type_traits/common_type.h>
 #include <ratio>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -85,6 +85,7 @@ private:
     chrono::seconds __s_;
     precision       __f_;
 };
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss);
 
 _LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
 _LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
@@ -107,6 +108,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noe
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_HH_MM_SS_H
lib/libcxx/include/__chrono/literals.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -44,6 +44,6 @@ namespace chrono { // hoist the literals into namespace std::chrono
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_LITERALS_H
lib/libcxx/include/__chrono/month.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -29,11 +29,11 @@ class month {
 private:
     unsigned char __m_;
 public:
-    _LIBCPP_HIDE_FROM_ABI month() = default;
+    month() = default;
     _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast<unsigned char>(__val)) {}
-    _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++()    noexcept { ++__m_; return *this; }
+    _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++()    noexcept { *this += months{1}; return *this; }
     _LIBCPP_HIDE_FROM_ABI inline constexpr month  operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
-    _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--()    noexcept { --__m_; return *this; }
+    _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--()    noexcept { *this -= months{1}; return *this; }
     _LIBCPP_HIDE_FROM_ABI inline constexpr month  operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
     _LIBCPP_HIDE_FROM_ABI        constexpr month& operator+=(const months& __m1) noexcept;
     _LIBCPP_HIDE_FROM_ABI        constexpr month& operator-=(const months& __m1) noexcept;
@@ -98,6 +98,6 @@ inline constexpr month December{12};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_MONTH_H
lib/libcxx/include/__chrono/month_weekday.h
@@ -18,7 +18,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,10 +41,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
 { return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
 { return month_weekday{__lhs, __rhs}; }
@@ -77,11 +73,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
 { return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
 { return month_weekday_last{__lhs, __rhs}; }
@@ -101,6 +92,6 @@ month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H
lib/libcxx/include/__chrono/monthday.h
@@ -20,7 +20,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -32,7 +32,7 @@ private:
    chrono::month __m_;
    chrono::day   __d_;
 public:
-    _LIBCPP_HIDE_FROM_ABI month_day() = default;
+    month_day() = default;
     _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
         : __m_{__mval}, __d_{__dval} {}
     _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
@@ -124,6 +124,6 @@ month_day_last operator/(last_spec, int __rhs) noexcept
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_MONTHDAY_H
lib/libcxx/include/__chrono/ostream.h
@@ -10,12 +10,16 @@
 #ifndef _LIBCPP___CHRONO_OSTREAM_H
 #define _LIBCPP___CHRONO_OSTREAM_H
 
+#include <__chrono/calendar.h>
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
+#include <__chrono/file_clock.h>
+#include <__chrono/hh_mm_ss.h>
 #include <__chrono/month.h>
 #include <__chrono/month_weekday.h>
 #include <__chrono/monthday.h>
 #include <__chrono/statically_widen.h>
+#include <__chrono/system_clock.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
 #include <__chrono/year_month.h>
@@ -33,10 +37,28 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#if _LIBCPP_STD_VER >= 20
 
 namespace chrono {
 
+template <class _CharT, class _Traits, class _Duration>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration> __tp) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
+}
+
+template <class _CharT, class _Traits, class _Duration>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
+}
+
+template <class _CharT, class _Traits, class _Duration>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) {
+  return __os << sys_time<_Duration>{__tp.time_since_epoch()};
+}
+
 // Depending on the type the return is a const _CharT* or a basic_string<_CharT>
 template <class _CharT, class _Period>
 _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
@@ -92,7 +114,7 @@ _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
 }
 
 template <class _CharT, class _Traits, class _Rep, class _Period>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {
   basic_ostringstream<_CharT, _Traits> __s;
   __s.flags(__os.flags());
@@ -103,21 +125,19 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>&
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
-operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
-  return __os
-      << (__d.ok()
-              ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
-              // Note this error differs from the wording of the Standard. The
-              // Standard wording doesn't work well on AIX or Windows. There
-              // the formatted day seems to be either modulo 100 or completely
-              // omitted. Judging by the wording this is valid.
-              // TODO FMT Write a paper of file an LWG issue.
-              : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast<unsigned>(__d)));
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
+  return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
+                           // Note this error differs from the wording of the Standard. The
+                           // Standard wording doesn't work well on AIX or Windows. There
+                           // the formatted day seems to be either modulo 100 or completely
+                           // omitted. Judging by the wording this is valid.
+                           // TODO FMT Write a paper of file an LWG issue.
+                           : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"),
+                                         static_cast<unsigned>(__d)));
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
   return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)
                            : std::format(__os.getloc(),
@@ -126,14 +146,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {
   return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)
                            : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
   return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)
                             : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used.
@@ -142,7 +162,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
   auto __i = __wdi.index();
   return __os << (__i >= 1 && __i <= 5
@@ -154,13 +174,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
   // TODO FMT The Standard allows 30th of February to be printed.
   // It would be nice to show an error message instead.
@@ -168,47 +188,47 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
   return __os << std::format(
              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
   return __os << std::format(
              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
   return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
                              : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
   return __os << std::format(
              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
   return __os << std::format(
              __os.getloc(),
@@ -219,7 +239,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymw
 }
 
 template <class _CharT, class _Traits>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
   return __os << std::format(
              __os.getloc(),
@@ -229,9 +249,15 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last&
              __ymwdl.weekday_last());
 }
 
+template <class _CharT, class _Traits, class _Duration>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);
+}
+
 } // namespace chrono
 
-#endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#endif // if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__chrono/parser_std_format_spec.h
@@ -24,7 +24,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format_spec {
 
@@ -137,17 +137,19 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) {
 
 template <class _CharT>
 class _LIBCPP_TEMPLATE_VIS __parser_chrono {
+  using _ConstIterator = typename basic_format_parse_context<_CharT>::const_iterator;
+
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields, __flags __flags)
-      -> decltype(__parse_ctx.begin()) {
-    const _CharT* __begin = __parser_.__parse(__parse_ctx, __fields);
-    const _CharT* __end   = __parse_ctx.end();
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
+  __parse(_ParseContext& __ctx, __fields __fields, __flags __flags) {
+    _ConstIterator __begin = __parser_.__parse(__ctx, __fields);
+    _ConstIterator __end   = __ctx.end();
     if (__begin == __end)
       return __begin;
 
-    const _CharT* __last = __parse_chrono_specs(__begin, __end, __flags);
-    __chrono_specs_      = basic_string_view<_CharT>{__begin, __last};
+    _ConstIterator __last = __parse_chrono_specs(__begin, __end, __flags);
+    __chrono_specs_       = basic_string_view<_CharT>{__begin, __last};
 
     return __last;
   }
@@ -156,19 +158,20 @@ public:
   basic_string_view<_CharT> __chrono_specs_;
 
 private:
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-  __parse_chrono_specs(const _CharT* __begin, const _CharT* __end, __flags __flags) {
-    _LIBCPP_ASSERT(__begin != __end,
-                   "When called with an empty input the function will cause "
-                   "undefined behavior by evaluating data not in the input");
+  _LIBCPP_HIDE_FROM_ABI constexpr _ConstIterator
+  __parse_chrono_specs(_ConstIterator __begin, _ConstIterator __end, __flags __flags) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __begin != __end,
+        "When called with an empty input the function will cause "
+        "undefined behavior by evaluating data not in the input");
 
     if (*__begin != _CharT('%') && *__begin != _CharT('}'))
-      std::__throw_format_error("Expected '%' or '}' in the chrono format-string");
+      std::__throw_format_error("The format specifier expects a '%' or a '}'");
 
     do {
       switch (*__begin) {
       case _CharT('{'):
-        std::__throw_format_error("The chrono-specs contains a '{'");
+        std::__throw_format_error("The chrono specifiers contain a '{'");
 
       case _CharT('}'):
         return __begin;
@@ -190,10 +193,10 @@ private:
   /// \pre *__begin == '%'
   /// \post __begin points at the end parsed conversion-spec
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  __parse_conversion_spec(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
+  __parse_conversion_spec(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
     ++__begin;
     if (__begin == __end)
-      std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec");
+      std::__throw_format_error("End of input while parsing a conversion specifier");
 
     switch (*__begin) {
     case _CharT('n'):
@@ -212,6 +215,7 @@ private:
     case _CharT('p'): // TODO FMT does the formater require an hour or a time?
     case _CharT('H'):
     case _CharT('I'):
+      __parser_.__hour_ = true;
       __validate_hour(__flags);
       break;
 
@@ -219,6 +223,7 @@ private:
     case _CharT('R'):
     case _CharT('T'):
     case _CharT('X'):
+      __parser_.__hour_ = true;
       __format_spec::__validate_time(__flags);
       break;
 
@@ -304,13 +309,14 @@ private:
   /// \pre *__begin == 'E'
   /// \post __begin is incremented by one.
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  __parse_modifier_E(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
+  __parse_modifier_E(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
     ++__begin;
     if (__begin == __end)
       std::__throw_format_error("End of input while parsing the modifier E");
 
     switch (*__begin) {
     case _CharT('X'):
+      __parser_.__hour_ = true;
       __format_spec::__validate_time(__flags);
       break;
 
@@ -343,7 +349,7 @@ private:
   /// \pre *__begin == 'O'
   /// \post __begin is incremented by one.
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  __parse_modifier_O(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
+  __parse_modifier_O(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
     ++__begin;
     if (__begin == __end)
       std::__throw_format_error("End of input while parsing the modifier O");
@@ -359,6 +365,7 @@ private:
 
     case _CharT('I'):
     case _CharT('H'):
+      __parser_.__hour_ = true;
       __format_spec::__validate_hour(__flags);
       break;
 
@@ -403,7 +410,7 @@ private:
 
 } // namespace __format_spec
 
-#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__chrono/statically_widen.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <__fmt_char_type _CharT>
@@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s
     return __wstr;
 }
 #    define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str)
-#  else  // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
 // Without this indirection the unit test test/libcxx/modules_include.sh.cpp
 // fails for the CI build "No wide characters". This seems like a bug.
@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s
 #    define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str)
 #  endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-#endif   //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__chrono/steady_clock.h
@@ -24,7 +24,7 @@ namespace chrono
 {
 
 #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
-class _LIBCPP_TYPE_VIS steady_clock
+class _LIBCPP_EXPORTED_FROM_ABI steady_clock
 {
 public:
     typedef nanoseconds                                   duration;
lib/libcxx/include/__chrono/system_clock.h
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace chrono
 {
 
-class _LIBCPP_TYPE_VIS system_clock
+class _LIBCPP_EXPORTED_FROM_ABI system_clock
 {
 public:
     typedef microseconds                     duration;
@@ -38,7 +38,7 @@ public:
     static time_point from_time_t(time_t __t) _NOEXCEPT;
 };
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Duration>
 using sys_time    = time_point<system_clock, _Duration>;
lib/libcxx/include/__chrono/time_point.h
@@ -11,6 +11,8 @@
 #define _LIBCPP___CHRONO_TIME_POINT_H
 
 #include <__chrono/duration.h>
+#include <__compare/ordering.h>
+#include <__compare/three_way_comparable.h>
 #include <__config>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
@@ -90,7 +92,7 @@ time_point_cast(const time_point<_Clock, _Duration>& __t)
     return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _ToDuration, class _Clock, class _Duration>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
@@ -138,7 +140,7 @@ abs(duration<_Rep, _Period> __d)
 {
     return __d >= __d.zero() ? +__d : -__d;
 }
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 // time_point ==
 
@@ -150,6 +152,8 @@ operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
     return __lhs.time_since_epoch() == __rhs.time_since_epoch();
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 // time_point !=
 
 template <class _Clock, class _Duration1, class _Duration2>
@@ -160,6 +164,8 @@ operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
     return !(__lhs == __rhs);
 }
 
+#endif // _LIBCPP_STD_VER <= 17
+
 // time_point <
 
 template <class _Clock, class _Duration1, class _Duration2>
@@ -200,6 +206,16 @@ operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
     return !(__lhs < __rhs);
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2>
+_LIBCPP_HIDE_FROM_ABI constexpr auto
+operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
+    return __lhs.time_since_epoch() <=> __rhs.time_since_epoch();
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
 // time_point operator+(time_point x, duration y);
 
 template <class _Clock, class _Duration1, class _Rep2, class _Period2>
lib/libcxx/include/__chrono/weekday.h
@@ -20,7 +20,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -35,7 +35,7 @@ private:
     unsigned char __wd_;
     _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept;
 public:
-  _LIBCPP_HIDE_FROM_ABI weekday() = default;
+  weekday() = default;
   _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
   _LIBCPP_HIDE_FROM_ABI inline constexpr          weekday(const sys_days& __sysd) noexcept
           : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {}
@@ -69,10 +69,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
 { return __lhs.c_encoding() == __rhs.c_encoding(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
 { return __lhs.c_encoding() < __rhs.c_encoding(); }
@@ -126,7 +122,7 @@ private:
     chrono::weekday __wd_;
     unsigned char   __idx_;
 public:
-    _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default;
+    weekday_indexed() = default;
     _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
         : __wd_{__wdval}, __idx_(__idxval) {}
     _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; }
@@ -138,11 +134,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
 { return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
 class weekday_last {
 private:
     chrono::weekday __wd_;
@@ -157,10 +148,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
 { return __lhs.weekday() == __rhs.weekday(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
 
@@ -180,6 +167,6 @@ inline constexpr weekday   Saturday{6};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_WEEKDAY_H
lib/libcxx/include/__chrono/year.h
@@ -22,7 +22,7 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -33,7 +33,7 @@ class year {
 private:
     short __y_;
 public:
-    _LIBCPP_HIDE_FROM_ABI year() = default;
+    year() = default;
     _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast<short>(__val)) {}
 
     _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++()    noexcept { ++__y_; return *this; }
@@ -95,7 +95,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_POP_MACROS
 
lib/libcxx/include/__chrono/year_month.h
@@ -20,7 +20,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -31,7 +31,7 @@ class year_month {
     chrono::year  __y_;
     chrono::month __m_;
 public:
-    _LIBCPP_HIDE_FROM_ABI year_month() = default;
+    year_month() = default;
     _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
         : __y_{__yval}, __m_{__mval} {}
     _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year  year()  const noexcept { return __y_; }
@@ -96,6 +96,6 @@ year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_YEAR_MONTH_H
lib/libcxx/include/__chrono/year_month_day.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -42,7 +42,7 @@ private:
     chrono::month __m_;
     chrono::day   __d_;
 public:
-     _LIBCPP_HIDE_FROM_ABI year_month_day() = default;
+     year_month_day() = default;
      _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(
             const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
             : __y_{__yval}, __m_{__mval}, __d_{__dval} {}
@@ -302,6 +302,6 @@ bool year_month_day::ok() const noexcept
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H
lib/libcxx/include/__chrono/year_month_weekday.h
@@ -27,7 +27,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -39,7 +39,7 @@ class year_month_weekday {
     chrono::month           __m_;
     chrono::weekday_indexed __wdi_;
 public:
-    _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default;
+    year_month_weekday() = default;
     _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
                                const chrono::weekday_indexed& __wdival) noexcept
         : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {}
@@ -98,10 +98,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
 { return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
@@ -191,11 +187,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
 bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
 _LIBCPP_HIDE_FROM_ABI inline constexpr
 year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
 { return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
@@ -250,6 +241,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekd
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
lib/libcxx/include/__compare/common_comparison_category.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __comp_detail {
 
@@ -65,14 +65,14 @@ _LIBCPP_HIDE_FROM_ABI
 constexpr auto __get_comp_type() {
   using _CCC = _ClassifyCompCategory;
   constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
-  constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds);
-  if constexpr (_Cat == _None)
+  constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds);
+  if constexpr (__cat == _None)
     return void();
-  else if constexpr (_Cat == _PartialOrd)
+  else if constexpr (__cat == _PartialOrd)
     return partial_ordering::equivalent;
-  else if constexpr (_Cat == _WeakOrd)
+  else if constexpr (__cat == _WeakOrd)
     return weak_ordering::equivalent;
-  else if constexpr (_Cat == _StrongOrd)
+  else if constexpr (__cat == _StrongOrd)
     return strong_ordering::equivalent;
   else
     static_assert(_False, "unhandled case");
@@ -88,7 +88,7 @@ struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
 template<class... _Ts>
 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/compare_partial_order_fallback.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __compare_partial_order_fallback {
@@ -67,7 +67,7 @@ inline namespace __cpo {
     inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/compare_strong_order_fallback.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __compare_strong_order_fallback {
@@ -64,7 +64,7 @@ inline namespace __cpo {
     inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/compare_three_way.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 struct _LIBCPP_TEMPLATE_VIS compare_three_way
 {
@@ -34,7 +34,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way
     using is_transparent = void;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/compare_three_way_result.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<class, class, class>
 struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { };
@@ -37,7 +37,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_resul
 template<class _Tp, class _Up = _Tp>
 using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/compare_weak_order_fallback.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __compare_weak_order_fallback {
@@ -64,7 +64,7 @@ inline namespace __cpo {
     inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/is_eq.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
 _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
@@ -27,7 +27,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexce
 _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
 _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/ordering.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // exposition only
 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
@@ -40,7 +40,7 @@ template<class _Tp, class... _Args>
 inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
 
 struct _CmpUnspecifiedParam {
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL
+  _LIBCPP_HIDE_FROM_ABI constexpr
   _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
 
   template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
@@ -319,7 +319,7 @@ inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater)
 template <class _Tp>
 concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/partial_order.h
@@ -24,7 +24,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __partial_order {
@@ -67,7 +67,7 @@ inline namespace __cpo {
     inline constexpr auto partial_order = __partial_order::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/strong_order.h
@@ -30,7 +30,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __strong_order {
@@ -130,7 +130,7 @@ inline namespace __cpo {
     inline constexpr auto strong_order = __strong_order::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/synth_three_way.h
@@ -21,30 +21,36 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [expos.only.func]
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
-  []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u)
-    requires requires {
-      { __t < __u } -> __boolean_testable;
-      { __u < __t } -> __boolean_testable;
-    }
-  {
-    if constexpr (three_way_comparable_with<_Tp, _Up>) {
-      return __t <=> __u;
-    } else {
-      if (__t < __u) return weak_ordering::less;
-      if (__u < __t) return weak_ordering::greater;
-      return weak_ordering::equivalent;
-    }
-  };
+// TODO MODULES restore the lamba to match the Standard.
+// See https://github.com/llvm/llvm-project/issues/57222
+//_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
+//  []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u)
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up& __u)
+  requires requires {
+    { __t < __u } -> __boolean_testable;
+    { __u < __t } -> __boolean_testable;
+  }
+{
+  if constexpr (three_way_comparable_with<_Tp, _Up>) {
+    return __t <=> __u;
+  } else {
+    if (__t < __u)
+      return weak_ordering::less;
+    if (__u < __t)
+      return weak_ordering::greater;
+    return weak_ordering::equivalent;
+  }
+}
 
 template <class _Tp, class _Up = _Tp>
 using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>()));
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/three_way_comparable.h
@@ -25,7 +25,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<class _Tp, class _Cat>
 concept __compares_as =
@@ -52,7 +52,7 @@ concept three_way_comparable_with =
     { __u <=> __t } -> __compares_as<_Cat>;
   };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__compare/weak_order.h
@@ -24,7 +24,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [cmp.alg]
 namespace __weak_order {
@@ -95,7 +95,7 @@ inline namespace __cpo {
     inline constexpr auto weak_order = __weak_order::__fn{};
 } // namespace __cpo
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/arithmetic.h
@@ -22,20 +22,20 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concepts.arithmetic], arithmetic concepts
 
-template<class _Tp>
+template <class _Tp>
 concept integral = is_integral_v<_Tp>;
 
-template<class _Tp>
+template <class _Tp>
 concept signed_integral = integral<_Tp> && is_signed_v<_Tp>;
 
-template<class _Tp>
+template <class _Tp>
 concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;
 
-template<class _Tp>
+template <class _Tp>
 concept floating_point = is_floating_point_v<_Tp>;
 
 // Concept helpers for the internal type traits for the fundamental types.
@@ -45,7 +45,7 @@ concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value;
 template <class _Tp>
 concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/assignable.h
@@ -22,19 +22,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.assignable]
 
-template<class _Lhs, class _Rhs>
+template <class _Lhs, class _Rhs>
 concept assignable_from =
-  is_lvalue_reference_v<_Lhs> &&
-  common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> &&
-  requires (_Lhs __lhs, _Rhs&& __rhs) {
-    { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
-  };
+    is_lvalue_reference_v<_Lhs> &&
+    common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> &&
+    requires(_Lhs __lhs, _Rhs&& __rhs) {
+      { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
+    };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/boolean_testable.h
@@ -19,19 +19,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concepts.booleantestable]
 
-template<class _Tp>
+template <class _Tp>
 concept __boolean_testable_impl = convertible_to<_Tp, bool>;
 
-template<class _Tp>
+template <class _Tp>
 concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) {
   { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/class_or_enum.h
@@ -21,19 +21,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // Whether a type is a class type or enumeration type according to the Core wording.
 
-template<class _Tp>
+template <class _Tp>
 concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
 
 // Work around Clang bug https://llvm.org/PR52970
 // TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14).
-template<class _Tp>
+template <class _Tp>
 concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/common_reference_with.h
@@ -20,17 +20,16 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.commonref]
 
-template<class _Tp, class _Up>
+template <class _Tp, class _Up>
 concept common_reference_with =
-  same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> &&
-  convertible_to<_Tp, common_reference_t<_Tp, _Up>> &&
-  convertible_to<_Up, common_reference_t<_Tp, _Up>>;
+    same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> &&
+    convertible_to<_Tp, common_reference_t<_Tp, _Up>> && convertible_to<_Up, common_reference_t<_Tp, _Up>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/common_with.h
@@ -23,27 +23,29 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.common]
 
-template<class _Tp, class _Up>
+// clang-format off
+template <class _Tp, class _Up>
 concept common_with =
-  same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
-  requires {
-    static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
-    static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
-  } &&
-  common_reference_with<
-    add_lvalue_reference_t<const _Tp>,
-    add_lvalue_reference_t<const _Up>> &&
-  common_reference_with<
-    add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
-    common_reference_t<
-      add_lvalue_reference_t<const _Tp>,
-      add_lvalue_reference_t<const _Up>>>;
-
-#endif // _LIBCPP_STD_VER > 17
+    same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
+    requires {
+        static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
+        static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
+    } &&
+    common_reference_with<
+        add_lvalue_reference_t<const _Tp>,
+        add_lvalue_reference_t<const _Up>> &&
+    common_reference_with<
+        add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
+        common_reference_t<
+            add_lvalue_reference_t<const _Tp>,
+            add_lvalue_reference_t<const _Up>>>;
+// clang-format on
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/constructible.h
@@ -20,36 +20,35 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.constructible]
-template<class _Tp, class... _Args>
-concept constructible_from =
-    destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
+template <class _Tp, class... _Args>
+concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
 
 // [concept.default.init]
 
-template<class _Tp>
+template <class _Tp>
 concept __default_initializable = requires { ::new _Tp; };
 
-template<class _Tp>
-concept default_initializable = constructible_from<_Tp> &&
-    requires { _Tp{}; } && __default_initializable<_Tp>;
+template <class _Tp>
+concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>;
 
 // [concept.moveconstructible]
-template<class _Tp>
-concept move_constructible =
-  constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
+template <class _Tp>
+concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
 
 // [concept.copyconstructible]
-template<class _Tp>
+// clang-format off
+template <class _Tp>
 concept copy_constructible =
-  move_constructible<_Tp> &&
-  constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
-  constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
-  constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
+    move_constructible<_Tp> &&
+    constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
+    constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
+    constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
+// clang-format on
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/convertible_to.h
@@ -19,18 +19,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.convertible]
 
-template<class _From, class _To>
-concept convertible_to =
-  is_convertible_v<_From, _To> &&
-  requires {
-    static_cast<_To>(std::declval<_From>());
-  };
+template <class _From, class _To>
+concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast<_To>(std::declval<_From>()); };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/copyable.h
@@ -20,19 +20,21 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concepts.object]
 
-template<class _Tp>
+// clang-format off
+template <class _Tp>
 concept copyable =
-  copy_constructible<_Tp> &&
-  movable<_Tp> &&
-  assignable_from<_Tp&, _Tp&> &&
-  assignable_from<_Tp&, const _Tp&> &&
-  assignable_from<_Tp&, const _Tp>;
-
-#endif // _LIBCPP_STD_VER > 17
+    copy_constructible<_Tp> &&
+    movable<_Tp> &&
+    assignable_from<_Tp&, _Tp&> &&
+    assignable_from<_Tp&, const _Tp&> &&
+    assignable_from<_Tp&, const _Tp>;
+// clang-format on
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/derived_from.h
@@ -19,16 +19,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.derived]
 
-template<class _Dp, class _Bp>
-concept derived_from =
-  is_base_of_v<_Bp, _Dp> &&
-  is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
+template <class _Dp, class _Bp>
+concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/destructible.h
@@ -18,14 +18,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.destructible]
 
-template<class _Tp>
+template <class _Tp>
 concept destructible = is_nothrow_destructible_v<_Tp>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/different_from.h
@@ -19,12 +19,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
-template<class _Tp, class _Up>
+template <class _Tp, class _Up>
 concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/equality_comparable.h
@@ -21,33 +21,35 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.equalitycomparable]
 
-template<class _Tp, class _Up>
+template <class _Tp, class _Up>
 concept __weakly_equality_comparable_with =
-  requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
-    { __t == __u } -> __boolean_testable;
-    { __t != __u } -> __boolean_testable;
-    { __u == __t } -> __boolean_testable;
-    { __u != __t } -> __boolean_testable;
-  };
-
-template<class _Tp>
+    requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
+      { __t == __u } -> __boolean_testable;
+      { __t != __u } -> __boolean_testable;
+      { __u == __t } -> __boolean_testable;
+      { __u != __t } -> __boolean_testable;
+    };
+
+template <class _Tp>
 concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
 
-template<class _Tp, class _Up>
+// clang-format off
+template <class _Tp, class _Up>
 concept equality_comparable_with =
-  equality_comparable<_Tp> && equality_comparable<_Up> &&
-  common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
-  equality_comparable<
-    common_reference_t<
-      __make_const_lvalue_ref<_Tp>,
-      __make_const_lvalue_ref<_Up>>> &&
-  __weakly_equality_comparable_with<_Tp, _Up>;
-
-#endif // _LIBCPP_STD_VER > 17
+    equality_comparable<_Tp> && equality_comparable<_Up> &&
+    common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
+    equality_comparable<
+        common_reference_t<
+            __make_const_lvalue_ref<_Tp>,
+            __make_const_lvalue_ref<_Up>>> &&
+    __weakly_equality_comparable_with<_Tp, _Up>;
+// clang-format on
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/invocable.h
@@ -19,21 +19,21 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.invocable]
 
-template<class _Fn, class... _Args>
+template <class _Fn, class... _Args>
 concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
   _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving
 };
 
 // [concept.regular.invocable]
 
-template<class _Fn, class... _Args>
+template <class _Fn, class... _Args>
 concept regular_invocable = invocable<_Fn, _Args...>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/movable.h
@@ -21,18 +21,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concepts.object]
 
-template<class _Tp>
-concept movable =
-  is_object_v<_Tp> &&
-  move_constructible<_Tp> &&
-  assignable_from<_Tp&, _Tp> &&
-  swappable<_Tp>;
+template <class _Tp>
+concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/predicate.h
@@ -20,15 +20,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.predicate]
 
-template<class _Fn, class... _Args>
-concept predicate =
-  regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
+template <class _Fn, class... _Args>
+concept predicate = regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/regular.h
@@ -19,14 +19,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.object]
 
-template<class _Tp>
+template <class _Tp>
 concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/relation.h
@@ -18,26 +18,25 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.relation]
 
-template<class _Rp, class _Tp, class _Up>
+template <class _Rp, class _Tp, class _Up>
 concept relation =
-  predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> &&
-  predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>;
+    predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>;
 
 // [concept.equiv]
 
-template<class _Rp, class _Tp, class _Up>
+template <class _Rp, class _Tp, class _Up>
 concept equivalence_relation = relation<_Rp, _Tp, _Up>;
 
 // [concept.strictweakorder]
 
-template<class _Rp, class _Tp, class _Up>
+template <class _Rp, class _Tp, class _Up>
 concept strict_weak_order = relation<_Rp, _Tp, _Up>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/same_as.h
@@ -18,17 +18,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.same]
 
-template<class _Tp, class _Up>
+template <class _Tp, class _Up>
 concept __same_as_impl = _IsSame<_Tp, _Up>::value;
 
-template<class _Tp, class _Up>
+template <class _Tp, class _Up>
 concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/semiregular.h
@@ -19,14 +19,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.object]
 
-template<class _Tp>
+template <class _Tp>
 concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__concepts/swappable.h
@@ -28,94 +28,96 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.swappable]
 
 namespace ranges {
 namespace __swap {
 
-  template<class _Tp>
-  void swap(_Tp&, _Tp&) = delete;
+template <class _Tp>
+void swap(_Tp&, _Tp&) = delete;
 
-  template<class _Tp, class _Up>
-  concept __unqualified_swappable_with =
+// clang-format off
+template <class _Tp, class _Up>
+concept __unqualified_swappable_with =
     (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) &&
     requires(_Tp&& __t, _Up&& __u) {
-      swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
+        swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
     };
+// clang-format on
 
-  struct __fn;
+struct __fn;
 
-  template<class _Tp, class _Up, size_t _Size>
-  concept __swappable_arrays =
-    !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> &&
+// clang-format off
+template <class _Tp, class _Up, size_t _Size>
+concept __swappable_arrays =
+    !__unqualified_swappable_with<_Tp (&)[_Size], _Up (&)[_Size]> &&
     extent_v<_Tp> == extent_v<_Up> &&
-    requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) {
-      __swap(__t[0], __u[0]);
+    requires(_Tp (&__t)[_Size], _Up (&__u)[_Size], const __fn& __swap) {
+        __swap(__t[0], __u[0]);
     };
-
-  template<class _Tp>
-  concept __exchangeable =
-    !__unqualified_swappable_with<_Tp&, _Tp&> &&
-    move_constructible<_Tp> &&
-    assignable_from<_Tp&, _Tp>;
-
-  struct __fn {
-    // 2.1   `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and...
-    // *The name `swap` is used here unqualified.
-    template<class _Tp, class _Up>
-      requires __unqualified_swappable_with<_Tp, _Up>
-    constexpr void operator()(_Tp&& __t, _Up&& __u) const
-      noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
-    {
-      swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
-    }
-
-    // 2.2   Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and...
-    template<class _Tp, class _Up, size_t _Size>
-      requires __swappable_arrays<_Tp, _Up, _Size>
-    constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const
-      noexcept(noexcept((*this)(*__t, *__u)))
-    {
-      // TODO(cjdb): replace with `ranges::swap_ranges`.
-      for (size_t __i = 0; __i < _Size; ++__i) {
-        (*this)(__t[__i], __u[__i]);
-      }
+// clang-format on
+
+template <class _Tp>
+concept __exchangeable =
+    !__unqualified_swappable_with<_Tp&, _Tp&> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp>;
+
+struct __fn {
+  // 2.1   `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and...
+  // *The name `swap` is used here unqualified.
+  template <class _Tp, class _Up>
+    requires __unqualified_swappable_with<_Tp, _Up>
+  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp&& __t, _Up&& __u) const
+      noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) {
+    swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
+  }
+
+  // 2.2   Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and...
+  template <class _Tp, class _Up, size_t _Size>
+    requires __swappable_arrays<_Tp, _Up, _Size>
+  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp (&__t)[_Size], _Up (&__u)[_Size]) const
+      noexcept(noexcept((*this)(*__t, *__u))) {
+    // TODO(cjdb): replace with `ranges::swap_ranges`.
+    for (size_t __i = 0; __i < _Size; ++__i) {
+      (*this)(__t[__i], __u[__i]);
     }
-
-    // 2.3   Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models...
-    template<__exchangeable _Tp>
-    constexpr void operator()(_Tp& __x, _Tp& __y) const
-      noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>)
-    {
-      __y = _VSTD::exchange(__x, _VSTD::move(__y));
-    }
-  };
+  }
+
+  // 2.3   Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models...
+  template <__exchangeable _Tp>
+  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp& __x, _Tp& __y) const
+      noexcept(is_nothrow_move_constructible_v<_Tp>&& is_nothrow_move_assignable_v<_Tp>) {
+    __y = _VSTD::exchange(__x, _VSTD::move(__y));
+  }
+};
 } // namespace __swap
 
 inline namespace __cpo {
-  inline constexpr auto swap = __swap::__fn{};
+inline constexpr auto swap = __swap::__fn{};
 } // namespace __cpo
 } // namespace ranges
 
-template<class _Tp>
+template <class _Tp>
 concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };
 
-template<class _Tp, class _Up>
-concept swappable_with =
-  common_reference_with<_Tp, _Up> &&
-  requires(_Tp&& __t, _Up&& __u) {
-    ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
-    ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));
-    ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
-    ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
-  };
+template <class _Tp, class _Up>
+concept swappable_with = common_reference_with<_Tp, _Up> && requires(_Tp&& __t, _Up&& __u) {
+  ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
+  ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));
+  ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
+  ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
+};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___CONCEPTS_SWAPPABLE_H
lib/libcxx/include/__concepts/totally_ordered.h
@@ -21,37 +21,38 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [concept.totallyordered]
 
-template<class _Tp, class _Up>
-concept __partially_ordered_with =
-  requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
-    { __t <  __u } -> __boolean_testable;
-    { __t >  __u } -> __boolean_testable;
-    { __t <= __u } -> __boolean_testable;
-    { __t >= __u } -> __boolean_testable;
-    { __u <  __t } -> __boolean_testable;
-    { __u >  __t } -> __boolean_testable;
-    { __u <= __t } -> __boolean_testable;
-    { __u >= __t } -> __boolean_testable;
-  };
-
-template<class _Tp>
+template <class _Tp, class _Up>
+concept __partially_ordered_with = requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
+  { __t < __u } -> __boolean_testable;
+  { __t > __u } -> __boolean_testable;
+  { __t <= __u } -> __boolean_testable;
+  { __t >= __u } -> __boolean_testable;
+  { __u < __t } -> __boolean_testable;
+  { __u > __t } -> __boolean_testable;
+  { __u <= __t } -> __boolean_testable;
+  { __u >= __t } -> __boolean_testable;
+};
+
+template <class _Tp>
 concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>;
 
-template<class _Tp, class _Up>
+// clang-format off
+template <class _Tp, class _Up>
 concept totally_ordered_with =
-  totally_ordered<_Tp> && totally_ordered<_Up> &&
-  equality_comparable_with<_Tp, _Up> &&
-  totally_ordered<
-    common_reference_t<
-      __make_const_lvalue_ref<_Tp>,
-      __make_const_lvalue_ref<_Up>>> &&
-  __partially_ordered_with<_Tp, _Up>;
-
-#endif // _LIBCPP_STD_VER > 17
+    totally_ordered<_Tp> && totally_ordered<_Up> &&
+    equality_comparable_with<_Tp, _Up> &&
+    totally_ordered<
+        common_reference_t<
+            __make_const_lvalue_ref<_Tp>,
+            __make_const_lvalue_ref<_Up>>> &&
+    __partially_ordered_with<_Tp, _Up>;
+// clang-format on
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__condition_variable/condition_variable.h
@@ -0,0 +1,245 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___CONDITION_VARIABLE_CONDITION_VARIABLE_H
+#define _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H
+
+#include <__chrono/steady_clock.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
+#include <__config>
+#include <__mutex/mutex.h>
+#include <__mutex/unique_lock.h>
+#include <__system_error/system_error.h>
+#include <__threading_support>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_floating_point.h>
+#include <__utility/move.h>
+#include <limits>
+#include <ratio>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+// enum class cv_status
+_LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
+
+class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
+  __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
+
+#  ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
+  ~condition_variable() = default;
+#  else
+  ~condition_variable();
+#  endif
+
+  condition_variable(const condition_variable&)            = delete;
+  condition_variable& operator=(const condition_variable&) = delete;
+
+  void notify_one() _NOEXCEPT;
+  void notify_all() _NOEXCEPT;
+
+  void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
+  template <class _Predicate>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(unique_lock<mutex>& __lk, _Predicate __pred);
+
+  template <class _Clock, class _Duration>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
+  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t);
+
+  template <class _Clock, class _Duration, class _Predicate>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
+  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred);
+
+  template <class _Rep, class _Period>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
+  wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d);
+
+  template <class _Rep, class _Period, class _Predicate>
+  bool _LIBCPP_HIDE_FROM_ABI
+  wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
+
+  typedef __libcpp_condvar_t* native_handle_type;
+  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
+
+private:
+  void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
+#  if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+  _LIBCPP_HIDE_FROM_ABI void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
+#  endif
+  template <class _Clock>
+  _LIBCPP_HIDE_FROM_ABI void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
+};
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+template <class _Rep, class _Period>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds>
+__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
+  using namespace chrono;
+  using __ratio       = ratio_divide<_Period, nano>;
+  using __ns_rep      = nanoseconds::rep;
+  _Rep __result_float = __d.count() * __ratio::num / __ratio::den;
+
+  _Rep __result_max = numeric_limits<__ns_rep>::max();
+  if (__result_float >= __result_max) {
+    return nanoseconds::max();
+  }
+
+  _Rep __result_min = numeric_limits<__ns_rep>::min();
+  if (__result_float <= __result_min) {
+    return nanoseconds::min();
+  }
+
+  return nanoseconds(static_cast<__ns_rep>(__result_float));
+}
+
+template <class _Rep, class _Period>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds>
+__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
+  using namespace chrono;
+  if (__d.count() == 0) {
+    return nanoseconds(0);
+  }
+
+  using __ratio         = ratio_divide<_Period, nano>;
+  using __ns_rep        = nanoseconds::rep;
+  __ns_rep __result_max = numeric_limits<__ns_rep>::max();
+  if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
+    return nanoseconds::max();
+  }
+
+  __ns_rep __result_min = numeric_limits<__ns_rep>::min();
+  if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
+    return nanoseconds::min();
+  }
+
+  __ns_rep __result = __d.count() * __ratio::num / __ratio::den;
+  if (__result == 0) {
+    return nanoseconds(1);
+  }
+
+  return nanoseconds(__result);
+}
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+template <class _Predicate>
+void condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) {
+  while (!__pred())
+    wait(__lk);
+}
+
+template <class _Clock, class _Duration>
+cv_status condition_variable::wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
+  using namespace chrono;
+  using __clock_tp_ns = time_point<_Clock, nanoseconds>;
+
+  typename _Clock::time_point __now = _Clock::now();
+  if (__t <= __now)
+    return cv_status::timeout;
+
+  __clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
+
+  __do_timed_wait(__lk, __t_ns);
+  return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
+}
+
+template <class _Clock, class _Duration, class _Predicate>
+bool condition_variable::wait_until(
+    unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
+  while (!__pred()) {
+    if (wait_until(__lk, __t) == cv_status::timeout)
+      return __pred();
+  }
+  return true;
+}
+
+template <class _Rep, class _Period>
+cv_status condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
+  using namespace chrono;
+  if (__d <= __d.zero())
+    return cv_status::timeout;
+  using __ns_rep                   = nanoseconds::rep;
+  steady_clock::time_point __c_now = steady_clock::now();
+
+#  if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+  using __clock_tp_ns     = time_point<steady_clock, nanoseconds>;
+  __ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
+#  else
+  using __clock_tp_ns     = time_point<system_clock, nanoseconds>;
+  __ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
+#  endif
+
+  __ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
+
+  if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
+    __do_timed_wait(__lk, __clock_tp_ns::max());
+  } else {
+    __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
+  }
+
+  return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
+}
+
+template <class _Rep, class _Period, class _Predicate>
+inline bool
+condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred) {
+  return wait_until(__lk, chrono::steady_clock::now() + __d, std::move(__pred));
+}
+
+#  if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+inline void condition_variable::__do_timed_wait(
+    unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT {
+  using namespace chrono;
+  if (!__lk.owns_lock())
+    __throw_system_error(EPERM, "condition_variable::timed wait: mutex not locked");
+  nanoseconds __d = __tp.time_since_epoch();
+  timespec __ts;
+  seconds __s                 = duration_cast<seconds>(__d);
+  using __ts_sec              = decltype(__ts.tv_sec);
+  const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
+  if (__s.count() < __ts_sec_max) {
+    __ts.tv_sec  = static_cast<__ts_sec>(__s.count());
+    __ts.tv_nsec = (__d - __s).count();
+  } else {
+    __ts.tv_sec  = __ts_sec_max;
+    __ts.tv_nsec = giga::num - 1;
+  }
+  int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
+  if (__ec != 0 && __ec != ETIMEDOUT)
+    __throw_system_error(__ec, "condition_variable timed_wait failed");
+}
+#  endif // _LIBCPP_HAS_COND_CLOCKWAIT
+
+template <class _Clock>
+inline void condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
+                                                chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT {
+  wait_for(__lk, __tp - _Clock::now());
+}
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H
lib/libcxx/include/__coroutine/coroutine_handle.h
@@ -21,7 +21,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -33,7 +33,6 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
 public:
     // [coroutine.handle.con], construct/reset
-    _LIBCPP_HIDE_FROM_ABI
     constexpr coroutine_handle() noexcept = default;
 
     _LIBCPP_HIDE_FROM_ABI
@@ -64,7 +63,7 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI
     bool done() const {
-        _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines");
         return __builtin_coro_done(__handle_);
     }
 
@@ -74,19 +73,19 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI
     void resume() const {
-        _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
-        _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done");
         __builtin_coro_resume(__handle_);
     }
 
     _LIBCPP_HIDE_FROM_ABI
     void destroy() const {
-        _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines");
         __builtin_coro_destroy(__handle_);
     }
 
 private:
-    bool __is_suspended() const {
+    _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
         // FIXME actually implement a check for if the coro is suspended.
         return __handle_ != nullptr;
     }
@@ -108,7 +107,6 @@ template <class _Promise>
 struct _LIBCPP_TEMPLATE_VIS coroutine_handle {
 public:
     // [coroutine.handle.con], construct/reset
-    _LIBCPP_HIDE_FROM_ABI
     constexpr coroutine_handle() noexcept = default;
 
     _LIBCPP_HIDE_FROM_ABI
@@ -154,7 +152,7 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI
     bool done() const {
-        _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines");
         return __builtin_coro_done(__handle_);
     }
 
@@ -164,14 +162,14 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI
     void resume() const {
-        _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
-        _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done");
         __builtin_coro_resume(__handle_);
     }
 
     _LIBCPP_HIDE_FROM_ABI
     void destroy() const {
-        _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines");
         __builtin_coro_destroy(__handle_);
     }
 
@@ -182,7 +180,7 @@ public:
     }
 
 private:
-    bool __is_suspended() const {
+    _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
         // FIXME actually implement a check for if the coro is suspended.
         return __handle_ != nullptr;
     }
@@ -198,6 +196,6 @@ struct hash<coroutine_handle<_Tp>> {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // __LIBCPP_STD_VER > 17
+#endif // __LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
lib/libcxx/include/__coroutine/coroutine_traits.h
@@ -16,7 +16,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -48,6 +48,6 @@ struct coroutine_traits
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // __LIBCPP_STD_VER > 17
+#endif // __LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H
lib/libcxx/include/__coroutine/noop_coroutine_handle.h
@@ -16,7 +16,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -107,6 +107,6 @@ noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle()
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // __LIBCPP_STD_VER > 17
+#endif // __LIBCPP_STD_VER >= 20
 
 #endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H
lib/libcxx/include/__coroutine/trivial_awaitables.h
@@ -16,7 +16,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -41,6 +41,6 @@ struct suspend_always {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // __LIBCPP_STD_VER > 17
+#endif // __LIBCPP_STD_VER >= 20
 
 #endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H
lib/libcxx/include/__debug_utils/strict_weak_ordering_check.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
+#define _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
+
+#include <__config>
+
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/is_sorted.h>
+#include <__assert>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_constant_evaluated.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _RandomAccessIterator, class _Comp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
+__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
+#ifdef _LIBCPP_DEBUG_STRICT_WEAK_ORDERING_CHECK
+  using __diff_t  = __iter_diff_t<_RandomAccessIterator>;
+  using _Comp_ref = __comp_ref_type<_Comp>;
+  if (!__libcpp_is_constant_evaluated()) {
+    // Check if the range is actually sorted.
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        (std::is_sorted<_RandomAccessIterator, _Comp_ref>(__first, __last, _Comp_ref(__comp))),
+        "The range is not sorted after the sort, your comparator is not a valid strict-weak ordering");
+    // Limit the number of elements we need to check.
+    __diff_t __size = __last - __first > __diff_t(100) ? __diff_t(100) : __last - __first;
+    __diff_t __p    = 0;
+    while (__p < __size) {
+      __diff_t __q = __p + __diff_t(1);
+      // Find first element that is greater than *(__first+__p).
+      while (__q < __size && !__comp(*(__first + __p), *(__first + __q))) {
+        ++__q;
+      }
+      // Check that the elements from __p to __q are equal between each other.
+      for (__diff_t __b = __p; __b < __q; ++__b) {
+        for (__diff_t __a = __p; __a <= __b; ++__a) {
+          _LIBCPP_ASSERT_UNCATEGORIZED(
+              !__comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering");
+          _LIBCPP_ASSERT_UNCATEGORIZED(
+              !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering");
+        }
+      }
+      // Check that elements between __p and __q are less than between __q and __size.
+      for (__diff_t __a = __p; __a < __q; ++__a) {
+        for (__diff_t __b = __q; __b < __size; ++__b) {
+          _LIBCPP_ASSERT_UNCATEGORIZED(
+              __comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering");
+          _LIBCPP_ASSERT_UNCATEGORIZED(
+              !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering");
+        }
+      }
+      // Skip these equal elements.
+      __p = __q;
+    }
+  }
+#else
+  (void)__first;
+  (void)__last;
+  (void)__comp;
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
lib/libcxx/include/__exception/exception.h
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___EXCEPTION_EXCEPTION_H
+#define _LIBCPP___EXCEPTION_EXCEPTION_H
+
+#include <__config>
+
+// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
+// which we use in order to be ABI-compatible with other STLs on Windows.
+#if defined(_LIBCPP_ABI_VCRUNTIME)
+#  include <vcruntime_exception.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
+// The std::exception class was already included above, but we're explicit about this condition here for clarity.
+
+#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
+// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
+// when _HAS_EXCEPTIONS == 0.
+//
+// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
+// (after all those are simply types like any other), we define an ABI-compatible version
+// of the VCRuntime std::exception and std::bad_exception types in that mode.
+
+struct __std_exception_data {
+  char const* _What;
+  bool _DoFree;
+};
+
+class exception { // base of all library exceptions
+public:
+  exception() _NOEXCEPT : __data_() {}
+
+  explicit exception(char const* __message) _NOEXCEPT : __data_() {
+    __data_._What   = __message;
+    __data_._DoFree = true;
+  }
+
+  exception(exception const&) _NOEXCEPT {}
+
+  exception& operator=(exception const&) _NOEXCEPT { return *this; }
+
+  virtual ~exception() _NOEXCEPT {}
+
+  virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
+
+private:
+  __std_exception_data __data_;
+};
+
+class bad_exception : public exception {
+public:
+  bad_exception() _NOEXCEPT : exception("bad exception") {}
+};
+
+#else  // !defined(_LIBCPP_ABI_VCRUNTIME)
+// On all other platforms, we define our own std::exception and std::bad_exception types
+// regardless of whether exceptions are turned on as a language feature.
+
+class _LIBCPP_EXPORTED_FROM_ABI exception {
+public:
+  _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {}
+  _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default;
+
+  virtual ~exception() _NOEXCEPT;
+  virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
+public:
+  _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {}
+  ~bad_exception() _NOEXCEPT override;
+  const char* what() const _NOEXCEPT override;
+};
+#endif // !_LIBCPP_ABI_VCRUNTIME
+
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_EXCEPTION_H
lib/libcxx/include/__exception/exception_ptr.h
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___EXCEPTION_EXCEPTION_PTR_H
+#define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
+
+#include <__config>
+#include <__exception/operations.h>
+#include <__memory/addressof.h>
+#include <cstddef>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+#ifndef _LIBCPP_ABI_MICROSOFT
+
+class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
+  void* __ptr_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
+  _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
+
+  exception_ptr(const exception_ptr&) _NOEXCEPT;
+  exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+  ~exception_ptr() _NOEXCEPT;
+
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
+
+  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+    return __x.__ptr_ == __y.__ptr_;
+  }
+
+  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+    return !(__x == __y);
+  }
+
+  friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
+  friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
+};
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  try {
+    throw __e;
+  } catch (...) {
+    return current_exception();
+  }
+#  else
+  ((void)__e);
+  std::abort();
+#  endif
+}
+
+#else // _LIBCPP_ABI_MICROSOFT
+
+class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
+  void* __ptr1_;
+  void* __ptr2_;
+  _LIBCPP_DIAGNOSTIC_POP
+
+public:
+  exception_ptr() _NOEXCEPT;
+  exception_ptr(nullptr_t) _NOEXCEPT;
+  exception_ptr(const exception_ptr& __other) _NOEXCEPT;
+  exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
+  exception_ptr& operator=(nullptr_t) _NOEXCEPT;
+  ~exception_ptr() _NOEXCEPT;
+  explicit operator bool() const _NOEXCEPT;
+};
+
+_LIBCPP_EXPORTED_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+_LIBCPP_EXPORTED_FROM_ABI void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
+
+_LIBCPP_EXPORTED_FROM_ABI exception_ptr __copy_exception_ptr(void* __except, const void* __ptr);
+_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
+
+// This is a built-in template function which automagically extracts the required
+// information.
+template <class _E>
+void* __GetExceptionInfo(_E);
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
+  return __copy_exception_ptr(std::addressof(__e), __GetExceptionInfo(__e));
+}
+
+#endif // _LIBCPP_ABI_MICROSOFT
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
lib/libcxx/include/__exception/nested_exception.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
+#define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
+
+#include <__config>
+#include <__exception/exception_ptr.h>
+#include <__memory/addressof.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_polymorphic.h>
+#include <__utility/forward.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+class _LIBCPP_EXPORTED_FROM_ABI nested_exception {
+  exception_ptr __ptr_;
+
+public:
+  nested_exception() _NOEXCEPT;
+  //     nested_exception(const nested_exception&) noexcept = default;
+  //     nested_exception& operator=(const nested_exception&) noexcept = default;
+  virtual ~nested_exception() _NOEXCEPT;
+
+  // access functions
+  _LIBCPP_NORETURN void rethrow_nested() const;
+  _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
+};
+
+template <class _Tp>
+struct __nested : public _Tp, public nested_exception {
+  _LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}
+};
+
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+template <class _Tp, class _Up, bool>
+struct __throw_with_nested;
+
+template <class _Tp, class _Up>
+struct __throw_with_nested<_Tp, _Up, true> {
+  _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) {
+    throw __nested<_Up>(std::forward<_Tp>(__t));
+  }
+};
+
+template <class _Tp, class _Up>
+struct __throw_with_nested<_Tp, _Up, false> {
+  _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); }
+};
+#endif
+
+template <class _Tp>
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  using _Up = __decay_t<_Tp>;
+  static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
+  __throw_with_nested<_Tp,
+                      _Up,
+                      is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
+                          !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));
+#else
+  ((void)__t);
+  // FIXME: Make this abort
+#endif
+}
+
+template <class _From, class _To>
+struct __can_dynamic_cast
+    : _BoolConstant< is_polymorphic<_From>::value &&
+                     (!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {};
+
+template <class _Ep>
+inline _LIBCPP_HIDE_FROM_ABI void
+rethrow_if_nested(const _Ep& __e, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {
+  const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e));
+  if (__nep)
+    __nep->rethrow_nested();
+}
+
+template <class _Ep>
+inline _LIBCPP_HIDE_FROM_ABI void
+rethrow_if_nested(const _Ep&, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {}
+
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
lib/libcxx/include/__exception/operations.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___EXCEPTION_OPERATIONS_H
+#define _LIBCPP___EXCEPTION_OPERATIONS_H
+
+#include <__availability>
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) ||                             \
+    defined(_LIBCPP_BUILDING_LIBRARY)
+using unexpected_handler = void (*)();
+_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void unexpected();
+#endif
+
+using terminate_handler = void (*)();
+_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
+
+_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
+
+class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
+
+_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_OPERATIONS_H
lib/libcxx/include/__exception/terminate.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___EXCEPTION_TERMINATE_H
+#define _LIBCPP___EXCEPTION_TERMINATE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT;
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_TERMINATE_H
lib/libcxx/include/__expected/bad_expected_access.h
@@ -10,14 +10,16 @@
 #define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
 
 #include <__config>
+#include <__exception/exception.h>
 #include <__utility/move.h>
 
-#include <exception>
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 #if _LIBCPP_STD_VER >= 23
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -33,14 +35,14 @@ protected:
   _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&)                 = default;
   _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default;
   _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&)      = default;
-  ~bad_expected_access() override                                                  = default;
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override                    = default;
 
 public:
   // The way this has been designed (by using a class template below) means that we'll already
   // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch
   // of work to do. So it is not worth hiding the <void> specialization in the dylib, given that
   // it adds deployment target restrictions.
-  const char* what() const noexcept override { return "bad access to std::expected"; }
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; }
 };
 
 template <class _Err>
@@ -61,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 23
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
lib/libcxx/include/__expected/expected.h
@@ -14,10 +14,12 @@
 #include <__expected/bad_expected_access.h>
 #include <__expected/unexpect.h>
 #include <__expected/unexpected.h>
+#include <__functional/invoke.h>
 #include <__memory/addressof.h>
 #include <__memory/construct_at.h>
 #include <__type_traits/conjunction.h>
 #include <__type_traits/disjunction.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_assignable.h>
 #include <__type_traits/is_constructible.h>
 #include <__type_traits/is_convertible.h>
@@ -44,36 +46,48 @@
 #include <__type_traits/negation.h>
 #include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_cvref.h>
+#include <__utility/as_const.h>
 #include <__utility/exception_guard.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
-#include <cstdlib> // for std::abort
+#include <__verbose_abort>
 #include <initializer_list>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 #if _LIBCPP_STD_VER >= 23
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-namespace __expected {
+template <class _Tp, class _Err>
+class expected;
+
+template <class _Tp>
+struct __is_std_expected : false_type {};
+
+template <class _Tp, class _Err>
+struct __is_std_expected<expected<_Tp, _Err>> : true_type {};
+
+struct __expected_construct_in_place_from_invoke_tag {};
+struct __expected_construct_unexpected_from_invoke_tag {};
 
 template <class _Err, class _Arg>
 _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
-#  ifndef _LIBCPP_NO_EXCEPTIONS
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
 #  else
   (void)__arg;
-  std::abort();
+  _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
 #  endif
 }
 
-} // namespace __expected
-
 template <class _Tp, class _Err>
 class expected {
   static_assert(
@@ -166,6 +180,15 @@ private:
             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
 
+  template <class _Func, class... _Args>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
+      std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
+      : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {}
+
+  template <class _Func, class... _Args>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
+      std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
+      : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
 
 public:
   template <class _Up, class _OtherErr>
@@ -503,32 +526,32 @@ public:
 
   // [expected.object.obs], observers
   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
     return std::addressof(__union_.__val_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
     return std::addressof(__union_.__val_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
     return __union_.__val_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
     return __union_.__val_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
     return std::move(__union_.__val_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
     return std::move(__union_.__val_);
   }
 
@@ -537,50 +560,56 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
+    static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+      std::__throw_bad_expected_access<_Err>(std::as_const(error()));
     }
     return __union_.__val_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
+    static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+      std::__throw_bad_expected_access<_Err>(std::as_const(error()));
     }
     return __union_.__val_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
+    static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
+                  "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+      std::__throw_bad_expected_access<_Err>(std::move(error()));
     }
     return std::move(__union_.__val_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
+    static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
+                  "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+      std::__throw_bad_expected_access<_Err>(std::move(error()));
     }
     return std::move(__union_.__val_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return __union_.__unex_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return __union_.__unex_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return std::move(__union_.__unex_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return std::move(__union_.__unex_);
   }
 
@@ -598,6 +627,245 @@ public:
     return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
   }
 
+  template <class _Up = _Err>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
+    static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
+    static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
+    if (has_value())
+      return std::forward<_Up>(__error);
+    return error();
+  }
+
+  template <class _Up = _Err>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
+    static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
+    static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
+    if (has_value())
+      return std::forward<_Up>(__error);
+    return std::move(error());
+  }
+
+  // [expected.void.monadic], monadic
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
+    using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Up::error_type, _Err>,
+                  "The result of f(value()) must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f), value());
+    }
+    return _Up(unexpect, error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
+    using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Up::error_type, _Err>,
+                  "The result of f(value()) must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f), value());
+    }
+    return _Up(unexpect, error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
+    using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
+    static_assert(
+        __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Up::error_type, _Err>,
+                  "The result of f(std::move(value())) must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f), std::move(value()));
+    }
+    return _Up(unexpect, std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
+    using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
+    static_assert(
+        __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Up::error_type, _Err>,
+                  "The result of f(std::move(value())) must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f), std::move(value()));
+    }
+    return _Up(unexpect, std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, _Tp&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
+    static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(error()) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp(in_place, value());
+    }
+    return std::invoke(std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, const _Tp&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
+    static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(error()) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp(in_place, value());
+    }
+    return std::invoke(std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, _Tp&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
+    static_assert(
+        __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(std::move(error())) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp(in_place, std::move(value()));
+    }
+    return std::invoke(std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, const _Tp&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
+    static_assert(
+        __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(std::move(error())) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp(in_place, std::move(value()));
+    }
+    return std::invoke(std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
+    using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, error());
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
+    } else {
+      std::invoke(std::forward<_Func>(__f), value());
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
+    using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, error());
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
+    } else {
+      std::invoke(std::forward<_Func>(__f), value());
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
+    using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, std::move(error()));
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(
+          __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
+    } else {
+      std::invoke(std::forward<_Func>(__f), std::move(value()));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
+    using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, std::move(error()));
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(
+          __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
+    } else {
+      std::invoke(std::forward<_Func>(__f), std::move(value()));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, _Tp&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(error()) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>(in_place, value());
+    }
+    return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, const _Tp&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(error()) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>(in_place, value());
+    }
+    return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, _Tp&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>(in_place, std::move(value()));
+    }
+    return expected<_Tp, _Gp>(
+        __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Tp, const _Tp&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>(in_place, std::move(value()));
+    }
+    return expected<_Tp, _Gp>(
+        __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
+  }
+
   // [expected.object.eq], equality operators
   template <class _T2, class _E2>
     requires(!is_void_v<_T2>)
@@ -625,24 +893,66 @@ public:
 
 private:
   struct __empty_t {};
-  // use named union because [[no_unique_address]] cannot be applied to an unnamed union
-  _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
+
+  template <class _ValueType, class _ErrorType>
+  union __union_t {
+    _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {}
+
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
+    = default;
+
+    // the expected's destructor handles this
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
+
+    _ValueType __val_;
+    _ErrorType __unex_;
+  };
+
+  // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
+  // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
+  // it's not clear that it's implementable, given that the function is allowed to clobber
+  // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
+  template <class _ValueType, class _ErrorType>
+    requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>)
+  union __union_t<_ValueType, _ErrorType> {
     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
 
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
-      requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
+      requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
     = default;
 
     // the expected's destructor handles this
     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
-      requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
+      requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>)
     {}
 
     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
-    _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
-    _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
-  } __union_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
+  };
 
+  _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_;
   bool __has_val_;
 };
 
@@ -762,6 +1072,19 @@ public:
     std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
   }
 
+private:
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f)
+      : __has_val_(true) {
+    std::invoke(std::forward<_Func>(__f));
+  }
+
+  template <class _Func, class... _Args>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
+      __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
+      : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
+
+public:
   // [expected.void.dtor], destructor
 
   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
@@ -894,41 +1217,270 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
 
   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
-    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+      std::__throw_bad_expected_access<_Err>(__union_.__unex_);
     }
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
     if (!__has_val_) {
-      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+      std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
     }
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return __union_.__unex_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return __union_.__unex_;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return std::move(__union_.__unex_);
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
-    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
     return std::move(__union_.__unex_);
   }
 
+  template <class _Up = _Err>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
+    static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
+    static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
+    if (has_value()) {
+      return std::forward<_Up>(__error);
+    }
+    return error();
+  }
+
+  template <class _Up = _Err>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
+    static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
+    static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
+    if (has_value()) {
+      return std::forward<_Up>(__error);
+    }
+    return std::move(error());
+  }
+
+  // [expected.void.monadic], monadic
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
+    using _Up = remove_cvref_t<invoke_result_t<_Func>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
+    static_assert(
+        is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f));
+    }
+    return _Up(unexpect, error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
+    using _Up = remove_cvref_t<invoke_result_t<_Func>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
+    static_assert(
+        is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f));
+    }
+    return _Up(unexpect, error());
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
+    using _Up = remove_cvref_t<invoke_result_t<_Func>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
+    static_assert(
+        is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f));
+    }
+    return _Up(unexpect, std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
+    using _Up = remove_cvref_t<invoke_result_t<_Func>>;
+    static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
+    static_assert(
+        is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
+    if (has_value()) {
+      return std::invoke(std::forward<_Func>(__f));
+    }
+    return _Up(unexpect, std::move(error()));
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
+    static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(error()) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp();
+    }
+    return std::invoke(std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
+    static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(error()) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp();
+    }
+    return std::invoke(std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
+    static_assert(__is_std_expected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(std::move(error())) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp();
+    }
+    return std::invoke(std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
+    using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
+    static_assert(__is_std_expected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a specialization of std::expected");
+    static_assert(is_same_v<typename _Gp::value_type, _Tp>,
+                  "The result of f(std::move(error())) must have the same value_type as this expected");
+    if (has_value()) {
+      return _Gp();
+    }
+    return std::invoke(std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
+    using _Up = remove_cv_t<invoke_result_t<_Func>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, error());
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
+    } else {
+      std::invoke(std::forward<_Func>(__f));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
+    using _Up = remove_cv_t<invoke_result_t<_Func>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, error());
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
+    } else {
+      std::invoke(std::forward<_Func>(__f));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
+    using _Up = remove_cv_t<invoke_result_t<_Func>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, std::move(error()));
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
+    } else {
+      std::invoke(std::forward<_Func>(__f));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+    requires is_constructible_v<_Err, const _Err&&>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
+    using _Up = remove_cv_t<invoke_result_t<_Func>>;
+    if (!has_value()) {
+      return expected<_Up, _Err>(unexpect, std::move(error()));
+    }
+    if constexpr (!is_void_v<_Up>) {
+      return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
+    } else {
+      std::invoke(std::forward<_Func>(__f));
+      return expected<_Up, _Err>();
+    }
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(error()) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>();
+    }
+    return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(error()) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>();
+    }
+    return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>();
+    }
+    return expected<_Tp, _Gp>(
+        __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
+  }
+
+  template <class _Func>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
+    using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
+    static_assert(__valid_std_unexpected<_Gp>::value,
+                  "The result of f(std::move(error())) must be a valid template argument for unexpected");
+    if (has_value()) {
+      return expected<_Tp, _Gp>();
+    }
+    return expected<_Tp, _Gp>(
+        __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
+  }
+
   // [expected.void.eq], equality operators
   template <class _T2, class _E2>
     requires is_void_v<_T2>
@@ -947,23 +1499,55 @@ public:
 
 private:
   struct __empty_t {};
-  // use named union because [[no_unique_address]] cannot be applied to an unnamed union
-  _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
+
+  template <class _ErrorType>
+  union __union_t {
     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
 
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
-      requires(is_trivially_destructible_v<_Err>)
+      requires(is_trivially_destructible_v<_ErrorType>)
     = default;
 
     // the expected's destructor handles this
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
+
+    __empty_t __empty_;
+    _ErrorType __unex_;
+  };
+
+  // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
+  // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
+  // it's not clear that it's implementable, given that the function is allowed to clobber
+  // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
+  template <class _ErrorType>
+    requires is_trivially_move_constructible_v<_ErrorType>
+  union __union_t<_ErrorType> {
+    _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
+
+    template <class _Func, class... _Args>
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
+        __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
+        : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
+
     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
-      requires(!is_trivially_destructible_v<_Err>)
+      requires(is_trivially_destructible_v<_ErrorType>)
+    = default;
+
+    // the expected's destructor handles this
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(!is_trivially_destructible_v<_ErrorType>)
     {}
 
     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
-    _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
-  } __union_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
+  };
 
+  _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_;
   bool __has_val_;
 };
 
@@ -971,4 +1555,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 23
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___EXPECTED_EXPECTED_H
lib/libcxx/include/__expected/unexpect.h
@@ -20,7 +20,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct unexpect_t {
-  _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default;
+  explicit unexpect_t() = default;
 };
 
 inline constexpr unexpect_t unexpect{};
lib/libcxx/include/__expected/unexpected.h
@@ -31,6 +31,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 #if _LIBCPP_STD_VER >= 23
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -119,4 +122,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 23
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___EXPECTED_UNEXPECTED_H
lib/libcxx/include/__filesystem/copy_options.h
@@ -21,8 +21,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
 enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
   none = 0,
   skip_existing = 1,
@@ -75,8 +73,6 @@ inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) {
   return __lhs = __lhs ^ __rhs;
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/directory_entry.h
@@ -12,8 +12,8 @@
 
 #include <__availability>
 #include <__chrono/time_point.h>
+#include <__compare/ordering.h>
 #include <__config>
-#include <__errc>
 #include <__filesystem/file_status.h>
 #include <__filesystem/file_time_type.h>
 #include <__filesystem/file_type.h>
@@ -21,11 +21,12 @@
 #include <__filesystem/operations.h>
 #include <__filesystem/path.h>
 #include <__filesystem/perms.h>
+#include <__system_error/errc.h>
+#include <__system_error/error_code.h>
+#include <__utility/move.h>
 #include <__utility/unreachable.h>
 #include <cstdint>
-#include <cstdlib>
 #include <iosfwd>
-#include <system_error>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -34,21 +35,20 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-#ifndef _LIBCPP_CXX03_LANG
+#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
 
 class directory_entry {
   typedef _VSTD_FS::path _Path;
 
 public:
   // constructors and destructors
-  directory_entry() noexcept = default;
-  directory_entry(directory_entry const&) = default;
-  directory_entry(directory_entry&&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default;
+  _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default;
 
   _LIBCPP_INLINE_VISIBILITY
   explicit directory_entry(_Path const& __p) : __p_(__p) {
@@ -61,10 +61,10 @@ public:
     __refresh(&__ec);
   }
 
-  ~directory_entry() {}
+  _LIBCPP_HIDE_FROM_ABI ~directory_entry() {}
 
-  directory_entry& operator=(directory_entry const&) = default;
-  directory_entry& operator=(directory_entry&&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default;
+  _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default;
 
   _LIBCPP_INLINE_VISIBILITY
   void assign(_Path const& __p) {
@@ -321,8 +321,7 @@ private:
     __data_ = __dt;
   }
 
-  _LIBCPP_FUNC_VIS
-  error_code __do_refresh() noexcept;
+  _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept;
 
   _LIBCPP_INLINE_VISIBILITY
   static bool __is_dne_error(error_code const& __ec) {
@@ -510,17 +509,17 @@ public:
 private:
   friend class directory_iterator;
   friend class recursive_directory_iterator;
-  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
-  __dir_element_proxy(__dir_element_proxy&& __o)
+  _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
+  _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o)
       : __elem_(_VSTD::move(__o.__elem_)) {}
   directory_entry __elem_;
 };
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
-#endif // _LIBCPP_CXX03_LANG
+#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_POP_MACROS
 
lib/libcxx/include/__filesystem/directory_iterator.h
@@ -16,22 +16,24 @@
 #include <__filesystem/directory_entry.h>
 #include <__filesystem/directory_options.h>
 #include <__filesystem/path.h>
+#include <__iterator/default_sentinel.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/shared_ptr.h>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/enable_view.h>
+#include <__system_error/error_code.h>
+#include <__utility/move.h>
 #include <cstddef>
-#include <system_error>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_CXX03_LANG
+#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
 
 class _LIBCPP_HIDDEN __dir_stream;
 class directory_iterator {
@@ -81,7 +83,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI
   const directory_entry& operator*() const {
-    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "The end iterator cannot be dereferenced");
     return __dereference();
   }
 
@@ -101,21 +103,23 @@ public:
   _LIBCPP_HIDE_FROM_ABI
   directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
 
+#  if _LIBCPP_STD_VER >= 20
+
+  _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); }
+
+#  endif
+
 private:
   inline _LIBCPP_HIDE_FROM_ABI friend bool
   operator==(const directory_iterator& __lhs,
              const directory_iterator& __rhs) noexcept;
 
   // construct the dir_stream
-  _LIBCPP_FUNC_VIS
-  directory_iterator(const path&, error_code*,
-                     directory_options = directory_options::none);
+  _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none);
 
-  _LIBCPP_FUNC_VIS
-  directory_iterator& __increment(error_code* __ec = nullptr);
+  _LIBCPP_EXPORTED_FROM_ABI directory_iterator& __increment(error_code* __ec = nullptr);
 
-  _LIBCPP_FUNC_VIS
-  const directory_entry& __dereference() const;
+  _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
 
 private:
   shared_ptr<__dir_stream> __imp_;
@@ -144,22 +148,22 @@ end(directory_iterator) noexcept {
   return directory_iterator();
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <>
-_LIBCPP_AVAILABILITY_FILESYSTEM
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true;
 
 template <>
-_LIBCPP_AVAILABILITY_FILESYSTEM
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#endif // _LIBCPP_CXX03_LANG
+#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
lib/libcxx/include/__filesystem/directory_options.h
@@ -21,8 +21,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
 enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
   none = 0,
   follow_directory_symlink = 1,
@@ -73,8 +71,6 @@ inline directory_options& operator^=(directory_options& __lhs,
   return __lhs = __lhs ^ __rhs;
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/file_status.h
@@ -23,9 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
-class _LIBCPP_TYPE_VIS file_status {
+class _LIBCPP_EXPORTED_FROM_ABI file_status {
 public:
   // constructors
   _LIBCPP_INLINE_VISIBILITY
@@ -35,14 +33,14 @@ public:
       : __ft_(__ft),
         __prms_(__prms) {}
 
-  file_status(const file_status&) noexcept = default;
-  file_status(file_status&&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI file_status(const file_status&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default;
 
   _LIBCPP_INLINE_VISIBILITY
   ~file_status() {}
 
-  file_status& operator=(const file_status&) noexcept = default;
-  file_status& operator=(file_status&&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI file_status& operator=(const file_status&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default;
 
   // observers
   _LIBCPP_INLINE_VISIBILITY
@@ -58,13 +56,19 @@ public:
   _LIBCPP_INLINE_VISIBILITY
   void permissions(perms __p) noexcept { __prms_ = __p; }
 
+#  if _LIBCPP_STD_VER >= 20
+
+  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const file_status& __lhs, const file_status& __rhs) noexcept {
+    return __lhs.type() == __rhs.type() && __lhs.permissions() == __rhs.permissions();
+  }
+
+#  endif
+
 private:
   file_type __ft_;
   perms __prms_;
 };
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/filesystem_error.h
@@ -14,11 +14,13 @@
 #include <__config>
 #include <__filesystem/path.h>
 #include <__memory/shared_ptr.h>
+#include <__system_error/error_code.h>
+#include <__system_error/system_error.h>
 #include <__utility/forward.h>
+#include <__verbose_abort>
 #include <iosfwd>
 #include <new>
-#include <system_error>
-#include <type_traits>
+#include <string>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -28,50 +30,38 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
+class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error {
 public:
-  _LIBCPP_INLINE_VISIBILITY
-  filesystem_error(const string& __what, error_code __ec)
-      : system_error(__ec, __what),
-        __storage_(make_shared<_Storage>(path(), path())) {
+  _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, error_code __ec)
+      : system_error(__ec, __what), __storage_(make_shared<_Storage>(path(), path())) {
     __create_what(0);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  filesystem_error(const string& __what, const path& __p1, error_code __ec)
-      : system_error(__ec, __what),
-        __storage_(make_shared<_Storage>(__p1, path())) {
+  _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, error_code __ec)
+      : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, path())) {
     __create_what(1);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  filesystem_error(const string& __what, const path& __p1, const path& __p2,
-                   error_code __ec)
-      : system_error(__ec, __what),
-        __storage_(make_shared<_Storage>(__p1, __p2)) {
+  _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, const path& __p2, error_code __ec)
+      : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, __p2)) {
     __create_what(2);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  const path& path1() const noexcept { return __storage_->__p1_; }
+  _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
 
-  _LIBCPP_INLINE_VISIBILITY
-  const path& path2() const noexcept { return __storage_->__p2_; }
+  _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
 
-  filesystem_error(const filesystem_error&) = default;
+  _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
   ~filesystem_error() override; // key function
 
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL
-  const char* what() const noexcept override {
-    return __storage_->__what_.c_str();
-  }
+  const char* what() const noexcept override { return __storage_->__what_.c_str(); }
 
   void __create_what(int __num_paths);
 
 private:
   struct _LIBCPP_HIDDEN _Storage {
-    _LIBCPP_INLINE_VISIBILITY
-    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
+    _LIBCPP_HIDE_FROM_ABI _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
 
     path __p1_;
     path __p2_;
@@ -80,22 +70,19 @@ private:
   shared_ptr<_Storage> __storage_;
 };
 
-// TODO(ldionne): We need to pop the pragma and push it again after
-//                filesystem_error to work around PR41078.
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
 template <class... _Args>
-_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_NO_EXCEPTIONS
-void __throw_filesystem_error(_Args&&... __args) {
+_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
+__throw_filesystem_error(_Args&&... __args) {
   throw filesystem_error(_VSTD::forward<_Args>(__args)...);
 }
-#else
-void __throw_filesystem_error(_Args&&...) {
-  _VSTD::abort();
+#  else
+template <class... _Args>
+_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
+__throw_filesystem_error(_Args&&...) {
+  _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode");
 }
-#endif
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+#  endif
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
lib/libcxx/include/__filesystem/operations.h
@@ -21,46 +21,46 @@
 #include <__filesystem/perm_options.h>
 #include <__filesystem/perms.h>
 #include <__filesystem/space_info.h>
+#include <__system_error/error_code.h>
 #include <cstdint>
-#include <system_error>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_CXX03_LANG
+#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
-_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr);
-_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr);
-_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr);
-_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr);
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
+
+_LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __create_directories(const path&, error_code* = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, error_code* = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, const path& __attributes, error_code* = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI path __current_path(error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __current_path(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI file_status __status(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI uintmax_t __file_size(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI file_status __symlink_status(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI file_time_type __last_write_time(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI path __read_symlink(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI uintmax_t __remove_all(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __remove(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __rename(const path& __from, const path& __to, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __resize_file(const path&, uintmax_t __size, error_code* = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI path __temp_directory_path(error_code* __ec = nullptr);
 
 inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
 inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
@@ -118,7 +118,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code&
 inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
 inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
 inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); }
-_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec = nullptr);
 inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
 inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
 inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
@@ -140,7 +140,7 @@ inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { r
 inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); }
 inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); }
 inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); }
-_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr);
 inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); }
 inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); }
 inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); }
@@ -180,7 +180,7 @@ inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) {
 inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); }
 inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); }
 inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); }
-_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr);
 inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); }
 inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); }
 inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); }
@@ -192,10 +192,10 @@ inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return
 inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
 inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
-#endif // _LIBCPP_CXX03_LANG
+#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 #endif // _LIBCPP___FILESYSTEM_OPERATIONS_H
lib/libcxx/include/__filesystem/path.h
@@ -14,12 +14,18 @@
 #include <__algorithm/replace_copy.h>
 #include <__availability>
 #include <__config>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__fwd/hash.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_pointer.h>
 #include <cstddef>
 #include <string>
 #include <string_view>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 # include <iomanip> // for quoted
@@ -34,7 +40,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
 
 template <class _Tp>
 struct __can_convert_char {
@@ -139,7 +145,7 @@ struct __is_pathable_string<
   }
 };
 
-template <class _Source, class _DS = typename decay<_Source>::type,
+template <class _Source, class _DS = __decay_t<_Source>,
           class _UnqualPtrType =
               __remove_const_t<__remove_pointer_t<_DS> >,
           bool _IsCharPtr = is_pointer<_DS>::value&&
@@ -168,7 +174,7 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
   static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
 };
 
-template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value,
+template <class _Iter, bool _IsIt = __has_input_iterator_category<_Iter>::value,
           class = void>
 struct __is_pathable_iter : false_type {};
 
@@ -217,10 +223,8 @@ typedef char __path_value;
 #endif
 
 #if defined(_LIBCPP_WIN32API)
-_LIBCPP_FUNC_VIS
-size_t __wide_to_char(const wstring&, char*, size_t);
-_LIBCPP_FUNC_VIS
-size_t __char_to_wide(const string&, wchar_t*, size_t);
+_LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t);
+_LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t);
 #endif
 
 template <class _ECharT>
@@ -303,7 +307,7 @@ struct _PathCVT<__path_value> {
 
   template <class _Iter>
   _LIBCPP_HIDE_FROM_ABI
-  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
+  static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type
   __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
     for (; __b != __e; ++__b)
       __dest.push_back(*__b);
@@ -311,7 +315,7 @@ struct _PathCVT<__path_value> {
 
   template <class _Iter>
   _LIBCPP_HIDE_FROM_ABI
-  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
+  static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type
   __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
     __dest.append(__b, __e);
   }
@@ -348,7 +352,7 @@ struct _PathCVT<char> {
 
   template <class _Iter>
   _LIBCPP_HIDE_FROM_ABI
-  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
+  static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type
   __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
     basic_string<char> __tmp(__b, __e);
     __append_string(__dest, __tmp);
@@ -356,7 +360,7 @@ struct _PathCVT<char> {
 
   template <class _Iter>
   _LIBCPP_HIDE_FROM_ABI
-  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
+  static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type
   __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
     basic_string<char> __tmp(__b, __e);
     __append_string(__dest, __tmp);
@@ -439,7 +443,7 @@ struct _PathExport<char8_t> {
 #endif /* !_LIBCPP_HAS_NO_CHAR8_T */
 #endif /* _LIBCPP_WIN32API */
 
-class _LIBCPP_TYPE_VIS path {
+class _LIBCPP_EXPORTED_FROM_ABI path {
   template <class _SourceOrIter, class _Tp = path&>
   using _EnableIfPathable =
       typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
@@ -1029,7 +1033,7 @@ public:
   }
 
   // iterators
-  class _LIBCPP_TYPE_VIS iterator;
+  class _LIBCPP_EXPORTED_FROM_ABI iterator;
   typedef iterator const_iterator;
 
   iterator begin() const;
@@ -1079,13 +1083,23 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept {
   __lhs.swap(__rhs);
 }
 
-_LIBCPP_FUNC_VIS
-size_t hash_value(const path& __p) noexcept;
+_LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept;
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <>
+struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash<_VSTD_FS::path> : __unary_function<_VSTD_FS::path, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(_VSTD_FS::path const& __p) const noexcept {
+    return _VSTD_FS::hash_value(__p);
+  }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
 #endif // _LIBCPP_CXX03_LANG
 
 #endif // _LIBCPP___FILESYSTEM_PATH_H
lib/libcxx/include/__filesystem/path_iterator.h
@@ -27,9 +27,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
-class _LIBCPP_TYPE_VIS path::iterator {
+class _LIBCPP_EXPORTED_FROM_ABI path::iterator {
 public:
   enum _ParserState : unsigned char {
     _Singular,
@@ -56,10 +54,10 @@ public:
       : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
         __state_(_Singular) {}
 
-  iterator(const iterator&) = default;
-  ~iterator() = default;
+  _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default;
+  _LIBCPP_HIDE_FROM_ABI ~iterator() = default;
 
-  iterator& operator=(const iterator&) = default;
+  _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default;
 
   _LIBCPP_INLINE_VISIBILITY
   reference operator*() const { return __stashed_elem_; }
@@ -69,10 +67,10 @@ public:
 
   _LIBCPP_INLINE_VISIBILITY
   iterator& operator++() {
-    _LIBCPP_ASSERT(__state_ != _Singular,
-                   "attempting to increment a singular iterator");
-    _LIBCPP_ASSERT(__state_ != _AtEnd,
-                   "attempting to increment the end iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular,
+                                 "attempting to increment a singular iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd,
+                                 "attempting to increment the end iterator");
     return __increment();
   }
 
@@ -85,10 +83,10 @@ public:
 
   _LIBCPP_INLINE_VISIBILITY
   iterator& operator--() {
-    _LIBCPP_ASSERT(__state_ != _Singular,
-                   "attempting to decrement a singular iterator");
-    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
-                   "attempting to decrement the begin iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular,
+                                 "attempting to decrement a singular iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__entry_.data() != __path_ptr_->native().data(),
+                                 "attempting to decrement the begin iterator");
     return __decrement();
   }
 
@@ -114,19 +112,19 @@ private:
   _ParserState __state_;
 };
 
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
                                                  const path::iterator& __rhs) {
   return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
          __lhs.__entry_.data() == __rhs.__entry_.data();
 }
 
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
                                                  const path::iterator& __rhs) {
   return !(__lhs == __rhs);
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/perm_options.h
@@ -21,8 +21,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
 enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
   replace = 1,
   add = 2,
@@ -68,8 +66,6 @@ inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) {
   return __lhs = __lhs ^ __rhs;
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/perms.h
@@ -21,8 +21,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
 // On Windows, these permission bits map to one single readonly flag per
 // file, and the executable bit is always returned as set. When setting
 // permissions, as long as the write bit is set for either owner, group or
@@ -86,8 +84,6 @@ inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __r
 _LIBCPP_INLINE_VISIBILITY
 inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/recursive_directory_iterator.h
@@ -15,22 +15,24 @@
 #include <__filesystem/directory_entry.h>
 #include <__filesystem/directory_options.h>
 #include <__filesystem/path.h>
+#include <__iterator/default_sentinel.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/shared_ptr.h>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/enable_view.h>
+#include <__system_error/error_code.h>
+#include <__utility/move.h>
 #include <cstddef>
-#include <system_error>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_CXX03_LANG
+#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
 
 class recursive_directory_iterator {
 public:
@@ -59,10 +61,10 @@ public:
   recursive_directory_iterator(const path& __p, error_code& __ec)
       : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
 
-  recursive_directory_iterator(const recursive_directory_iterator&) = default;
-  recursive_directory_iterator(recursive_directory_iterator&&) = default;
+  _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default;
+  _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default;
 
-  recursive_directory_iterator&
+  _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator&
   operator=(const recursive_directory_iterator&) = default;
 
   _LIBCPP_INLINE_VISIBILITY
@@ -76,7 +78,7 @@ public:
     return *this;
   }
 
-  ~recursive_directory_iterator() = default;
+  _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default;
 
   _LIBCPP_INLINE_VISIBILITY
   const directory_entry& operator*() const { return __dereference(); }
@@ -84,7 +86,7 @@ public:
   _LIBCPP_INLINE_VISIBILITY
   const directory_entry* operator->() const { return &__dereference(); }
 
-  recursive_directory_iterator& operator++() { return __increment(); }
+  _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); }
 
   _LIBCPP_INLINE_VISIBILITY
   __dir_element_proxy operator++(int) {
@@ -98,8 +100,8 @@ public:
     return __increment(&__ec);
   }
 
-  _LIBCPP_FUNC_VIS directory_options options() const;
-  _LIBCPP_FUNC_VIS int depth() const;
+  _LIBCPP_EXPORTED_FROM_ABI directory_options options() const;
+  _LIBCPP_EXPORTED_FROM_ABI int depth() const;
 
   _LIBCPP_INLINE_VISIBILITY
   void pop() { __pop(); }
@@ -113,25 +115,21 @@ public:
   _LIBCPP_INLINE_VISIBILITY
   void disable_recursion_pending() { __rec_ = false; }
 
-private:
-  _LIBCPP_FUNC_VIS
-  recursive_directory_iterator(const path& __p, directory_options __opt,
-                               error_code* __ec);
-
-  _LIBCPP_FUNC_VIS
-  const directory_entry& __dereference() const;
+#  if _LIBCPP_STD_VER >= 20
 
-  _LIBCPP_FUNC_VIS
-  bool __try_recursion(error_code* __ec);
-
-  _LIBCPP_FUNC_VIS
-  void __advance(error_code* __ec = nullptr);
+  _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept {
+    return *this == recursive_directory_iterator();
+  }
 
-  _LIBCPP_FUNC_VIS
-  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
+#  endif
 
-  _LIBCPP_FUNC_VIS
-  void __pop(error_code* __ec = nullptr);
+private:
+  _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec);
+  _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
+  _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec);
+  _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr);
+  _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr);
+  _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr);
 
   inline _LIBCPP_INLINE_VISIBILITY friend bool
   operator==(const recursive_directory_iterator&,
@@ -164,22 +162,22 @@ end(recursive_directory_iterator) noexcept {
   return recursive_directory_iterator();
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <>
-_LIBCPP_AVAILABILITY_FILESYSTEM
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true;
 
 template <>
-_LIBCPP_AVAILABILITY_FILESYSTEM
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
 inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#endif // _LIBCPP_CXX03_LANG
+#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 #endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H
lib/libcxx/include/__filesystem/space_info.h
@@ -22,20 +22,16 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-
-struct _LIBCPP_TYPE_VIS space_info {
+struct _LIBCPP_EXPORTED_FROM_ABI space_info {
   uintmax_t capacity;
   uintmax_t free;
   uintmax_t available;
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const space_info&, const space_info&) = default;
 #  endif
 };
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
 #endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/u8path.h
@@ -15,7 +15,6 @@
 #include <__config>
 #include <__filesystem/path.h>
 #include <string>
-#include <type_traits>
 
 // Only required on Windows for __widen_from_utf8, and included conservatively
 // because it requires support for localization.
@@ -31,7 +30,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
 
 template <class _InputIt>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
@@ -99,7 +98,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
 #endif
 }
 
-_LIBCPP_AVAILABILITY_FILESYSTEM_POP
+_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
lib/libcxx/include/__format/buffer.h
@@ -27,11 +27,18 @@
 #include <__iterator/incrementable_traits.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
+#include <__memory/allocate_at_least.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/construct_at.h>
+#include <__memory/ranges_construct_at.h>
+#include <__memory/uninitialized_algorithms.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/conditional.h>
+#include <__utility/exception_guard.h>
 #include <__utility/move.h>
 #include <cstddef>
 #include <string_view>
-#include <type_traits>
-#include <vector>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -42,7 +49,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format {
 
@@ -100,7 +107,7 @@ public:
     size_t __n = __str.size();
 
     __flush_on_overflow(__n);
-    if (__n <= __capacity_) {
+    if (__n < __capacity_) { //  push_back requires the buffer to have room for at least one character (so use <).
       _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_]));
       __size_ += __n;
       return;
@@ -108,7 +115,7 @@ public:
 
     // The output doesn't fit in the internal buffer.
     // Copy the data in "__capacity_" sized chunks.
-    _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
     const _InCharT* __first = __str.data();
     do {
       size_t __chunk = _VSTD::min(__n, __capacity_);
@@ -125,11 +132,11 @@ public:
   /// Like @ref __copy it may need to do type conversion.
   template <__fmt_char_type _InCharT, class _UnaryOperation>
   _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
-    _LIBCPP_ASSERT(__first <= __last, "not a valid range");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range");
 
     size_t __n = static_cast<size_t>(__last - __first);
     __flush_on_overflow(__n);
-    if (__n <= __capacity_) {
+    if (__n < __capacity_) { //  push_back requires the buffer to have room for at least one character (so use <).
       _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation));
       __size_ += __n;
       return;
@@ -137,7 +144,7 @@ public:
 
     // The output doesn't fit in the internal buffer.
     // Transform the data in "__capacity_" sized chunks.
-    _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
     do {
       size_t __chunk = _VSTD::min(__n, __capacity_);
       _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation);
@@ -151,7 +158,7 @@ public:
   /// A \c fill_n wrapper.
   _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
     __flush_on_overflow(__n);
-    if (__n <= __capacity_) {
+    if (__n < __capacity_) { //  push_back requires the buffer to have room for at least one character (so use <).
       _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value);
       __size_ += __n;
       return;
@@ -159,7 +166,7 @@ public:
 
     // The output doesn't fit in the internal buffer.
     // Fill the buffer in "__capacity_" sized chunks.
-    _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
     do {
       size_t __chunk = _VSTD::min(__n, __capacity_);
       _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value);
@@ -246,9 +253,9 @@ class _LIBCPP_TEMPLATE_VIS __direct_storage {};
 template <class _OutIt, class _CharT>
 concept __enable_direct_output = __fmt_char_type<_CharT> &&
     (same_as<_OutIt, _CharT*>
-#ifndef _LIBCPP_ENABLE_DEBUG_MODE
+     // TODO(hardening): the following check might not apply to hardened iterators and might need to be wrapped in an
+     // `#ifdef`.
      || same_as<_OutIt, __wrap_iter<_CharT*>>
-#endif
     );
 
 /// Write policy for directly writing to the underlying output.
@@ -510,13 +517,19 @@ public:
 // context and the format arguments need to be retargeted to the new context.
 // This retargeting is done by a basic_format_context specialized for the
 // __iterator of this container.
+//
+// This class uses its own buffer management, since using vector
+// would lead to a circular include with formatter for vector<bool>.
 template <__fmt_char_type _CharT>
 class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
+  using _Alloc = allocator<_CharT>;
+
 public:
   using value_type = _CharT;
 
   struct __iterator {
     using difference_type = ptrdiff_t;
+    using value_type      = _CharT;
 
     _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
         : __buffer_(std::addressof(__buffer)) {}
@@ -535,36 +548,101 @@ public:
     __retarget_buffer* __buffer_;
   };
 
-  _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); }
+  __retarget_buffer(const __retarget_buffer&)            = delete;
+  __retarget_buffer& operator=(const __retarget_buffer&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) {
+    // When the initial size is very small a lot of resizes happen
+    // when elements added. So use a hard-coded minimum size.
+    //
+    // Note a size < 2 will not work
+    // - 0 there is no buffer, while push_back requires 1 empty element.
+    // - 1 multiplied by the grow factor is 1 and thus the buffer never
+    //   grows.
+    auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT)));
+    __ptr_        = __result.ptr;
+    __capacity_   = __result.count;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() {
+    ranges::destroy_n(__ptr_, __size_);
+    allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
+  }
 
   _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; }
 
-  _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); }
+  _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
+    std::construct_at(__ptr_ + __size_, __c);
+    ++__size_;
+
+    if (__size_ == __capacity_)
+      __grow_buffer();
+  }
 
   template <__fmt_char_type _InCharT>
   _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
-    __buffer_.insert(__buffer_.end(), __str.begin(), __str.end());
+    size_t __n = __str.size();
+    if (__size_ + __n >= __capacity_)
+      // Push_back requires the buffer to have room for at least one character.
+      __grow_buffer(__size_ + __n + 1);
+
+    std::uninitialized_copy_n(__str.data(), __n, __ptr_ + __size_);
+    __size_ += __n;
   }
 
   template <__fmt_char_type _InCharT, class _UnaryOperation>
   _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
-    _LIBCPP_ASSERT(__first <= __last, "not a valid range");
-    std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation));
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range");
+
+    size_t __n = static_cast<size_t>(__last - __first);
+    if (__size_ + __n >= __capacity_)
+      // Push_back requires the buffer to have room for at least one character.
+      __grow_buffer(__size_ + __n + 1);
+
+    std::uninitialized_default_construct_n(__ptr_ + __size_, __n);
+    std::transform(__first, __last, __ptr_ + __size_, std::move(__operation));
+    __size_ += __n;
   }
 
-  _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); }
+  _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
+    if (__size_ + __n >= __capacity_)
+      // Push_back requires the buffer to have room for at least one character.
+      __grow_buffer(__size_ + __n + 1);
+
+    std::uninitialized_fill_n(__ptr_ + __size_, __n, __value);
+    __size_ += __n;
+  }
 
-  _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; }
+  _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, __size_}; }
 
 private:
-  // Use vector instead of string to avoid adding zeros after every append
-  // operation. The buffer is exposed as a string_view and not as a c-string.
-  vector<_CharT> __buffer_;
+  _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); }
+
+  _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__capacity > __capacity_, "the buffer must grow");
+    auto __result = std::__allocate_at_least(__alloc_, __capacity);
+    auto __guard  = std::__make_exception_guard([&] {
+      allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count);
+    });
+    // This shouldn't throw, but just to be safe. Note that at -O1 this
+    // guard is optimized away so there is no runtime overhead.
+    std::uninitialized_move_n(__ptr_, __size_, __result.ptr);
+    __guard.__complete();
+    ranges::destroy_n(__ptr_, __size_);
+    allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
+
+    __ptr_      = __result.ptr;
+    __capacity_ = __result.count;
+  }
+  _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
+  _CharT* __ptr_;
+  size_t __capacity_;
+  size_t __size_{0};
 };
 
 } // namespace __format
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/concepts.h
@@ -16,9 +16,9 @@
 #include <__format/format_fwd.h>
 #include <__format/format_parse_context.h>
 #include <__type_traits/is_specialization.h>
+#include <__type_traits/remove_const.h>
 #include <__utility/pair.h>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,7 +26,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 /// The character type specializations of \ref formatter.
 template <class _CharT>
@@ -44,19 +44,23 @@ concept __fmt_char_type =
 template <class _CharT>
 using __fmt_iter_for = _CharT*;
 
+template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>>
+concept __formattable_with =
+    semiregular<_Formatter> &&
+    requires(_Formatter& __f,
+             const _Formatter& __cf,
+             _Tp&& __t,
+             _Context __fc,
+             basic_format_parse_context<typename _Context::char_type> __pc) {
+      { __f.parse(__pc) } -> same_as<typename decltype(__pc)::iterator>;
+      { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>;
+    };
+
 template <class _Tp, class _CharT>
 concept __formattable =
-    (semiregular<formatter<remove_cvref_t<_Tp>, _CharT>>) &&
-    requires(formatter<remove_cvref_t<_Tp>, _CharT> __f,
-             const formatter<remove_cvref_t<_Tp>, _CharT> __cf,
-             _Tp __t,
-             basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc,
-             basic_format_parse_context<_CharT> __pc) {
-      { __f.parse(__pc) } -> same_as<typename basic_format_parse_context<_CharT>::iterator>;
-      { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>;
-    };
+    __formattable_with<remove_reference_t<_Tp>, basic_format_context<__fmt_iter_for<_CharT>, _CharT>>;
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
 template <class _Tp, class _CharT>
 concept formattable = __formattable<_Tp, _CharT>;
 
@@ -69,8 +73,8 @@ template <class _Tp>
 concept __fmt_pair_like =
     __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
 
-#  endif //_LIBCPP_STD_VER > 20
-#endif //_LIBCPP_STD_VER > 17
+#  endif //_LIBCPP_STD_VER >= 23
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/container_adaptor.h
@@ -14,17 +14,19 @@
 #  pragma GCC system_header
 #endif
 
-#include <__availability>
 #include <__config>
 #include <__format/concepts.h>
 #include <__format/formatter.h>
 #include <__format/range_default_formatter.h>
+#include <__ranges/ref_view.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/maybe_const.h>
 #include <queue>
 #include <stack>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 // [container.adaptors.format] only specifies the library should provide the
 // formatter specializations, not which header should provide them.
@@ -33,10 +35,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // adaptor headers. To use the format functions users already include <format>.
 
 template <class _Adaptor, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
+struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor {
 private:
-  using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
-  formatter<typename _Adaptor::container_type, _CharT> __underlying_;
+  using __maybe_const_container = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>;
+  using __maybe_const_adaptor   = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>;
+  formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_;
 
 public:
   template <class _ParseContext>
@@ -52,18 +55,18 @@ public:
 };
 
 template <class _CharT, class _Tp, formattable<_CharT> _Container>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<queue<_Tp, _Container>, _CharT>
     : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
 
 template <class _CharT, class _Tp, class _Container, class _Compare>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
     : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
 
 template <class _CharT, class _Tp, formattable<_CharT> _Container>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<stack<_Tp, _Container>, _CharT>
     : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
 
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/enable_insertable.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format {
 
@@ -28,7 +28,7 @@ inline constexpr bool __enable_insertable = false;
 
 } // namespace __format
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/escaped_output_table.h
@@ -72,7 +72,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 namespace __escaped_output_table {
 
@@ -1031,7 +1031,7 @@ inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0;
 
 } // namespace __escaped_output_table
 
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -73,7 +73,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __extended_grapheme_custer_property_boundary {
 
@@ -1654,7 +1654,7 @@ inline constexpr uint32_t __entries[1496] = {
 
 } // namespace __extended_grapheme_custer_property_boundary
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_arg.h
@@ -13,15 +13,17 @@
 #include <__assert>
 #include <__concepts/arithmetic.h>
 #include <__config>
-#include <__format/format_error.h>
+#include <__format/concepts.h>
 #include <__format/format_fwd.h>
 #include <__format/format_parse_context.h>
 #include <__functional/invoke.h>
 #include <__memory/addressof.h>
+#include <__type_traits/conditional.h>
 #include <__utility/forward.h>
+#include <__utility/move.h>
 #include <__utility/unreachable.h>
 #include <__variant/monostate.h>
-#include <string>
+#include <cstdint>
 #include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -30,7 +32,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format {
 /// The type stored in @ref basic_format_arg.
@@ -81,7 +83,7 @@ constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= _
 
 _LIBCPP_HIDE_FROM_ABI
 constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
-  _LIBCPP_ASSERT(__id <= __packed_types_max, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__id <= __packed_types_max, "");
 
   if (__id > 0)
     __types >>= __id * __packed_arg_t_bits;
@@ -94,7 +96,7 @@ constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
 // This function is not user obervable, so it can directly use the non-standard
 // types of the "variant". See __arg_t for more details.
 template <class _Visitor, class _Context>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
+_LIBCPP_HIDE_FROM_ABI decltype(auto)
 __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
   switch (__arg.__type_) {
   case __format::__arg_t::__none:
@@ -155,18 +157,14 @@ public:
   /// Contains the implementation for basic_format_arg::handle.
   struct __handle {
     template <class _Tp>
-    _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept
+    _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp& __v) noexcept
         : __ptr_(_VSTD::addressof(__v)),
           __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
-            using _Dp = remove_cvref_t<_Tp>;
-            using _Formatter = typename _Context::template formatter_type<_Dp>;
-            constexpr bool __const_formattable =
-                requires { _Formatter().format(std::declval<const _Dp&>(), std::declval<_Context&>()); };
-            using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>;
+            using _Dp = remove_const_t<_Tp>;
+            using _Qp = conditional_t<__formattable_with<const _Dp, _Context>, const _Dp, _Dp>;
+            static_assert(__formattable_with<_Qp, _Context>, "Mandated by [format.arg]/10");
 
-            static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18");
-
-            _Formatter __f;
+            typename _Context::template formatter_type<_Dp> __f;
             __parse_ctx.advance_to(__f.parse(__parse_ctx));
             __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx));
           }) {}
@@ -218,13 +216,11 @@ public:
   _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
       : __string_view_(__value) {}
   _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
-  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept
-      // TODO FMT Investigate why it doesn't work without the forward.
-      : __handle_(std::forward<__handle>(__value)) {}
+  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle&& __value) noexcept : __handle_(std::move(__value)) {}
 };
 
 template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg {
+class _LIBCPP_TEMPLATE_VIS basic_format_arg {
 public:
   class _LIBCPP_TEMPLATE_VIS handle;
 
@@ -276,7 +272,7 @@ private:
 // This function is user facing, so it must wrap the non-standard types of
 // the "variant" in a handle to stay conforming. See __arg_t for more details.
 template <class _Visitor, class _Context>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
+_LIBCPP_HIDE_FROM_ABI decltype(auto)
 visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
   switch (__arg.__type_) {
 #  ifndef _LIBCPP_HAS_NO_INT128
@@ -295,7 +291,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
   }
 }
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_arg_store.h
@@ -19,15 +19,15 @@
 #include <__config>
 #include <__format/concepts.h>
 #include <__format/format_arg.h>
-#include <__utility/forward.h>
-#include <cstring>
+#include <__type_traits/conditional.h>
+#include <__type_traits/extent.h>
+#include <__type_traits/remove_const.h>
 #include <string>
 #include <string_view>
-#include <type_traits>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format {
 
@@ -142,21 +142,31 @@ consteval __arg_t __determine_arg_t() {
 //
 // Note this version can't be constrained avoiding ambiguous overloads.
 // That means it can be instantiated by disabled formatters. To solve this, a
-// constrained version for not formattable formatters is added. That overload
-// is marked as deleted to fail creating a storage type for disabled formatters.
+// constrained version for not formattable formatters is added.
 template <class _Context, class _Tp>
 consteval __arg_t __determine_arg_t() {
   return __arg_t::__handle;
 }
 
+// The overload for not formattable types allows triggering the static
+// assertion below.
 template <class _Context, class _Tp>
   requires(!__formattable<_Tp, typename _Context::char_type>)
-consteval __arg_t __determine_arg_t() = delete;
+consteval __arg_t __determine_arg_t() {
+  return __arg_t::__none;
+}
 
+// Pseudo constuctor for basic_format_arg
+//
+// Modeled after template<class T> explicit basic_format_arg(T& v) noexcept;
+// [format.arg]/4-6
 template <class _Context, class _Tp>
-_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept {
-  constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>();
-  static_assert(__arg != __arg_t::__none);
+_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __value) noexcept {
+  using _Dp               = remove_const_t<_Tp>;
+  constexpr __arg_t __arg = __determine_arg_t<_Context, _Dp>();
+  static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
+
+  static_assert(__formattable_with<_Tp, _Context>);
 
   // Not all types can be used to directly initialize the
   // __basic_format_arg_value.  First handle all types needing adjustment, the
@@ -175,9 +185,9 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val
     return basic_format_arg<_Context>{__arg, static_cast<unsigned long long>(__value)};
   else if constexpr (__arg == __arg_t::__string_view)
     // Using std::size on a character array will add the NUL-terminator to the size.
-    if constexpr (is_array_v<remove_cvref_t<_Tp>>)
+    if constexpr (is_array_v<_Dp>)
       return basic_format_arg<_Context>{
-          __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<remove_cvref_t<_Tp>> - 1}};
+          __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<_Dp> - 1}};
     else
       // When the _Traits or _Allocator are different an implicit conversion will
       // fail.
@@ -186,8 +196,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val
   else if constexpr (__arg == __arg_t::__ptr)
     return basic_format_arg<_Context>{__arg, static_cast<const void*>(__value)};
   else if constexpr (__arg == __arg_t::__handle)
-    return basic_format_arg<_Context>{
-        __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}};
+    return basic_format_arg<_Context>{__arg, typename __basic_format_arg_value<_Context>::__handle{__value}};
   else
     return basic_format_arg<_Context>{__arg, __value};
 }
@@ -218,7 +227,7 @@ _LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>*
 template <class _Context, size_t N>
 struct __packed_format_arg_store {
   __basic_format_arg_value<_Context> __values_[N];
-  uint64_t __types_;
+  uint64_t __types_ = 0;
 };
 
 template <class _Context, size_t N>
@@ -247,7 +256,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
   _Storage __storage;
 };
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_args.h
@@ -24,12 +24,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args {
+class _LIBCPP_TEMPLATE_VIS basic_format_args {
 public:
-  _LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default;
+  basic_format_args() noexcept = default;
 
   template <class... _Args>
   _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept
@@ -71,9 +71,11 @@ private:
     const basic_format_arg<_Context>* __args_;
   };
 };
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args);
 
-#endif //_LIBCPP_STD_VER > 17
+template <class _Context, class... _Args>
+basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_Context>;
+
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_context.h
@@ -37,11 +37,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _OutIt, class _CharT>
 requires output_iterator<_OutIt, const _CharT&>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
+class _LIBCPP_TEMPLATE_VIS basic_format_context;
 
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 /**
@@ -80,7 +80,6 @@ requires output_iterator<_OutIt, const _CharT&>
 class
     // clang-format off
     _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_AVAILABILITY_FORMAT
     _LIBCPP_PREFERRED_NAME(format_context)
     _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context))
     // clang-format on
@@ -121,9 +120,9 @@ private:
   // TODO FMT Validate whether lazy creation is the best solution.
   optional<_VSTD::locale> __loc_;
 
-  template <class __OutIt, class __CharT>
-  friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT>
-  __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>,
+  template <class _OtherOutIt, class _OtherCharT>
+  friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT>
+  __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>,
                           optional<_VSTD::locale>&&);
 
   // Note: the Standard doesn't specify the required constructors.
@@ -134,9 +133,9 @@ private:
       : __out_it_(_VSTD::move(__out_it)), __args_(__args),
         __loc_(_VSTD::move(__loc)) {}
 #else
-  template <class __OutIt, class __CharT>
-  friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT>
-      __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>);
+  template <class _OtherOutIt, class _OtherCharT>
+  friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT>
+      __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>);
 
   _LIBCPP_HIDE_FROM_ABI
   explicit basic_format_context(_OutIt __out_it,
@@ -162,7 +161,7 @@ private:
 // Here the width of an element in input is determined dynamically.
 // Note when the top-level element has no width the retargeting is not needed.
 template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
+class _LIBCPP_TEMPLATE_VIS
     basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
 public:
   using iterator  = typename __format::__retarget_buffer<_CharT>::__iterator;
@@ -216,7 +215,7 @@ private:
 };
 
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_error.h
@@ -11,7 +11,7 @@
 #define _LIBCPP___FORMAT_FORMAT_ERROR_H
 
 #include <__config>
-#include <cstdlib>
+#include <__verbose_abort>
 #include <stdexcept>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -20,35 +20,31 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
-class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
+class _LIBCPP_EXPORTED_FROM_ABI format_error : public runtime_error {
 public:
   _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s)
       : runtime_error(__s) {}
   _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s)
       : runtime_error(__s) {}
-  // TODO FMT Remove when format is no longer experimental.
-  // Avoids linker errors when building the Clang-cl Windows DLL which doesn't
-  // support the experimental library.
-#  ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR
-  ~format_error() noexcept override;
-#  else
-  ~format_error() noexcept  override {}
-#  endif
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
+  ~format_error() noexcept override = default;
 };
+_LIBCPP_DIAGNOSTIC_POP
 
 _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void
 __throw_format_error(const char* __s) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   throw format_error(__s);
 #else
-  (void)__s;
-  _VSTD::abort();
+  _LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s);
 #endif
 }
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_functions.h
@@ -10,16 +10,10 @@
 #ifndef _LIBCPP___FORMAT_FORMAT_FUNCTIONS
 #define _LIBCPP___FORMAT_FORMAT_FUNCTIONS
 
-// TODO FMT This is added to fix Apple back-deployment.
-#include <version>
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-
 #include <__algorithm/clamp.h>
-#include <__availability>
 #include <__concepts/convertible_to.h>
 #include <__concepts/same_as.h>
 #include <__config>
-#include <__debug>
 #include <__format/buffer.h>
 #include <__format/format_arg.h>
 #include <__format/format_arg_store.h>
@@ -38,7 +32,9 @@
 #include <__format/formatter_string.h>
 #include <__format/parser_std_format_spec.h>
 #include <__iterator/back_insert_iterator.h>
+#include <__iterator/concepts.h>
 #include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h> // iter_value_t
 #include <__variant/monostate.h>
 #include <array>
 #include <string>
@@ -54,7 +50,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // TODO FMT Evaluate which templates should be external templates. This
 // improves the efficiency of the header. However since the header is still
@@ -67,16 +63,17 @@ using wformat_args = basic_format_args<wformat_context>;
 #endif
 
 template <class _Context = format_context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
   return _VSTD::__format_arg_store<_Context, _Args...>(__args...);
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&&... __args) {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
+make_wformat_args(_Args&&... __args) {
   return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...);
 }
-#endif
+#  endif
 
 namespace __format {
 
@@ -87,14 +84,16 @@ namespace __format {
 template <class _CharT>
 class _LIBCPP_TEMPLATE_VIS __compile_time_handle {
 public:
-  _LIBCPP_HIDE_FROM_ABI
-  constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); }
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr void __parse(_ParseContext& __ctx) const {
+    __parse_(__ctx);
+  }
 
   template <class _Tp>
   _LIBCPP_HIDE_FROM_ABI constexpr void __enable() {
-    __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) {
+    __parse_ = [](basic_format_parse_context<_CharT>& __ctx) {
       formatter<_Tp, _CharT> __f;
-      __parse_ctx.advance_to(__f.parse(__parse_ctx));
+      __ctx.advance_to(__f.parse(__ctx));
     };
   }
 
@@ -128,13 +127,13 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
     if (__id >= __size_)
-      std::__throw_format_error("Argument index out of bounds");
+      std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
     return __args_[__id];
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
     if (__id >= __size_)
-      std::__throw_format_error("Argument index out of bounds");
+      std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
     return __handles_[__id];
   }
 
@@ -147,41 +146,44 @@ private:
   size_t __size_;
 };
 
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __compile_time_validate_integral(__arg_t __type) {
-  switch (__type) {
-  case __arg_t::__int:
-  case __arg_t::__long_long:
-  case __arg_t::__i128:
-  case __arg_t::__unsigned:
-  case __arg_t::__unsigned_long_long:
-  case __arg_t::__u128:
-    return;
-
-  default:
-    std::__throw_format_error("Argument isn't an integral type");
-  }
-}
-
+// [format.string.std]/8
+// If { arg-idopt } is used in a width or precision, the value of the
+// corresponding formatting argument is used in its place. If the
+// corresponding formatting argument is not of standard signed or unsigned
+// integer type, or its value is negative for precision or non-positive for
+// width, an exception of type format_error is thrown.
+//
 // _HasPrecision does the formatter have a precision?
 template <class _CharT, class _Tp, bool _HasPrecision = false>
-_LIBCPP_HIDE_FROM_ABI constexpr void
-__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx,
-                                 __compile_time_basic_format_context<_CharT>& __ctx) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument(
+    basic_format_parse_context<_CharT>& __parse_ctx, __compile_time_basic_format_context<_CharT>& __ctx) {
+  auto __validate_type = [](__arg_t __type) {
+    // LWG3720 originally allowed "signed or unsigned integer types", however
+    // the final version explicitly changed it to "*standard* signed or unsigned
+    // integer types". It's trivial to use 128-bit integrals in libc++'s
+    // implementation, but other implementations may not implement it.
+    // (Using a width or precision, that does not fit in 64-bits, sounds very
+    // unlikely in real world code.)
+    switch (__type) {
+    case __arg_t::__int:
+    case __arg_t::__long_long:
+    case __arg_t::__unsigned:
+    case __arg_t::__unsigned_long_long:
+      return;
+
+    default:
+      std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
+    }
+  };
+
   formatter<_Tp, _CharT> __formatter;
   __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
-  // [format.string.std]/7
-  // ... If the corresponding formatting argument is not of integral type, or
-  // its value is negative for precision or non-positive for width, an
-  // exception of type format_error is thrown.
-  //
-  // Validate whether the arguments are integrals.
   if (__formatter.__parser_.__width_as_arg_)
-    __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_));
+    __validate_type(__ctx.arg(__formatter.__parser_.__width_));
 
   if constexpr (_HasPrecision)
     if (__formatter.__parser_.__precision_as_arg_)
-      __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_));
+      __validate_type(__ctx.arg(__formatter.__parser_.__precision_));
 }
 
 // This function is not user facing, so it can directly use the non-standard types of the "variant".
@@ -236,30 +238,31 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
   std::__throw_format_error("Invalid argument");
 }
 
-template <class _CharT, class _ParseCtx, class _Ctx>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
+template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx>
+_LIBCPP_HIDE_FROM_ABI constexpr _Iterator
+__handle_replacement_field(_Iterator __begin, _Iterator __end,
                            _ParseCtx& __parse_ctx, _Ctx& __ctx) {
+  using _CharT = iter_value_t<_Iterator>;
   __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
 
-  bool __parse = *__r.__ptr == _CharT(':');
-  switch (*__r.__ptr) {
+  bool __parse = *__r.__last == _CharT(':');
+  switch (*__r.__last) {
   case _CharT(':'):
     // The arg-id has a format-specifier, advance the input to the format-spec.
-    __parse_ctx.advance_to(__r.__ptr + 1);
+    __parse_ctx.advance_to(__r.__last + 1);
     break;
   case _CharT('}'):
     // The arg-id has no format-specifier.
-    __parse_ctx.advance_to(__r.__ptr);
+    __parse_ctx.advance_to(__r.__last);
     break;
   default:
-    std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'");
+    std::__throw_format_error("The argument index should end with a ':' or a '}'");
   }
 
   if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
     __arg_t __type = __ctx.arg(__r.__value);
     if (__type == __arg_t::__none)
-      std::__throw_format_error("Argument index out of bounds");
+      std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
     else if (__type == __arg_t::__handle)
       __ctx.__handle(__r.__value).__parse(__parse_ctx);
     else if (__parse)
@@ -268,7 +271,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
     _VSTD::__visit_format_arg(
         [&](auto __arg) {
           if constexpr (same_as<decltype(__arg), monostate>)
-            std::__throw_format_error("Argument index out of bounds");
+            std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
           else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
             __arg.format(__parse_ctx, __ctx);
           else {
@@ -293,8 +296,8 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
   using _CharT = typename _ParseCtx::char_type;
   static_assert(same_as<typename _Ctx::char_type, _CharT>);
 
-  const _CharT* __begin = __parse_ctx.begin();
-  const _CharT* __end = __parse_ctx.end();
+  auto __begin = __parse_ctx.begin();
+  auto __end = __parse_ctx.end();
   typename _Ctx::iterator __out_it = __ctx.out();
   while (__begin != __end) {
     switch (*__begin) {
@@ -341,7 +344,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string {
                            _Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
   }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept {
+  _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept {
     return __str_;
   }
 
@@ -353,20 +356,6 @@ private:
   static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
       __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
 
-  // TODO FMT remove this work-around when the AIX ICE has been resolved.
-#    if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400
-  template <class _Tp>
-  static constexpr __format::__compile_time_handle<_CharT> __get_handle() {
-    __format::__compile_time_handle<_CharT> __handle;
-    if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
-      __handle.template __enable<_Tp>();
-
-    return __handle;
-  }
-
-  static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{
-      __get_handle<_Args>()...};
-#    else
   static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] {
     using _Tp = remove_cvref_t<_Args>;
     __format::__compile_time_handle<_CharT> __handle;
@@ -375,7 +364,6 @@ private:
 
     return __handle;
   }()...};
-#    endif
 };
 
 template <class... _Args>
@@ -406,21 +394,21 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
 // https://reviews.llvm.org/D110499#inline-1180704
 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
 template <output_iterator<const char&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
   return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
 }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
   return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
 }
 #endif
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
                            _VSTD::make_format_args(__args...));
@@ -428,42 +416,48 @@ format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
                            _VSTD::make_wformat_args(__args...));
 }
 #endif
 
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
+// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
+// fires too eagerly, see http://llvm.org/PR61563.
+template <class = void>
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
 vformat(string_view __fmt, format_args __args) {
   string __res;
   _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
   return __res;
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
+// fires too eagerly, see http://llvm.org/PR61563.
+template <class = void>
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(wstring_view __fmt, wformat_args __args) {
   wstring __res;
   _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
   return __res;
 }
-#endif
+#  endif
 
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt,
-                                                                                      _Args&&... __args) {
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
+format(format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...));
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
 format(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...));
 }
-#endif
+#  endif
 
 template <class _Context, class _OutIt, class _CharT>
 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
@@ -476,14 +470,14 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
 }
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...));
 }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt,
             _Args&&... __args) {
   return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...));
@@ -499,20 +493,20 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
 }
 
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
 }
-#endif
+#  endif
 
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#  ifndef _LIBCPP_HAS_NO_LOCALIZATION
 
 template <class _OutIt, class _CharT, class _FormatOutIt>
 requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
@@ -533,7 +527,7 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
 }
 
 template <output_iterator<const char&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
     _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
   return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
                              __args);
@@ -541,7 +535,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
     _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
   return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
                              __args);
@@ -549,7 +543,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
 #endif
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
                            _VSTD::make_format_args(__args...));
@@ -557,14 +551,17 @@ format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&.
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
                            _VSTD::make_wformat_args(__args...));
 }
 #endif
 
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
+// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
+// fires too eagerly, see http://llvm.org/PR61563.
+template <class = void>
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
 vformat(locale __loc, string_view __fmt, format_args __args) {
   string __res;
   _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
@@ -572,32 +569,34 @@ vformat(locale __loc, string_view __fmt, format_args __args) {
   return __res;
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
+// fires too eagerly, see http://llvm.org/PR61563.
+template <class = void>
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
   wstring __res;
   _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
                     __args);
   return __res;
 }
-#endif
+#    endif
 
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
-                                                                                      format_string<_Args...> __fmt,
-                                                                                      _Args&&... __args) {
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
+format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
                         _VSTD::make_format_args(__args...));
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
 format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
                         _VSTD::make_wformat_args(__args...));
 }
-#endif
+#    endif
 
 template <class _Context, class _OutIt, class _CharT>
 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
@@ -611,7 +610,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
 }
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt,
             _Args&&... __args) {
   return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
@@ -620,7 +619,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt,
             _Args&&... __args) {
   return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
@@ -638,26 +637,23 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_
 }
 
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
 }
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
 }
-#endif
-
-#endif // _LIBCPP_HAS_NO_LOCALIZATION
+#    endif
 
+#  endif // _LIBCPP_HAS_NO_LOCALIZATION
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-
 #endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS
lib/libcxx/include/__format/format_fwd.h
@@ -20,19 +20,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg;
+class _LIBCPP_TEMPLATE_VIS basic_format_arg;
 
 template <class _OutIt, class _CharT>
   requires output_iterator<_OutIt, const _CharT&>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
+class _LIBCPP_TEMPLATE_VIS basic_format_context;
 
 template <class _Tp, class _CharT = char>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter;
+struct _LIBCPP_TEMPLATE_VIS formatter;
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_parse_context.h
@@ -12,6 +12,7 @@
 
 #include <__config>
 #include <__format/format_error.h>
+#include <__type_traits/is_constant_evaluated.h>
 #include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -20,10 +21,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
+class _LIBCPP_TEMPLATE_VIS basic_format_parse_context {
 public:
   using char_type = _CharT;
   using const_iterator = typename basic_string_view<_CharT>::const_iterator;
@@ -58,6 +59,18 @@ public:
 
     if (__indexing_ == __unknown)
       __indexing_ = __automatic;
+
+    // Throws an exception to make the expression a non core constant
+    // expression as required by:
+    // [format.parse.ctx]/8
+    //   Remarks: Let cur-arg-id be the value of next_arg_id_ prior to this
+    //   call. Call expressions where cur-arg-id >= num_args_ is true are not
+    //   core constant expressions (7.7 [expr.const]).
+    // Note: the Throws clause [format.parse.ctx]/9 doesn't specify the
+    // behavior when id >= num_args_.
+    if (is_constant_evaluated() && __next_arg_id_ >= __num_args_)
+      std::__throw_format_error("Argument index outside the valid range");
+
     return __next_arg_id_++;
   }
   _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
@@ -93,7 +106,7 @@ using format_parse_context = basic_format_parse_context<char>;
 using wformat_parse_context = basic_format_parse_context<wchar_t>;
 #endif
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_string.h
@@ -13,6 +13,8 @@
 #include <__assert>
 #include <__config>
 #include <__format/format_error.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h> // iter_value_t
 #include <cstddef>
 #include <cstdint>
 
@@ -22,22 +24,22 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format {
 
-template <class _CharT>
+template <contiguous_iterator _Iterator>
 struct _LIBCPP_TEMPLATE_VIS __parse_number_result {
-  const _CharT* __ptr;
+  _Iterator __last;
   uint32_t __value;
 };
 
-template <class _CharT>
-__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>;
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end);
 
 /**
  * The maximum value of a numeric argument.
@@ -53,27 +55,28 @@ __parse_number(const _CharT* __begin, const _CharT* __end);
 inline constexpr uint32_t __number_max = INT32_MAX;
 
 namespace __detail {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_zero(_Iterator __begin, _Iterator, auto& __parse_ctx) {
   __parse_ctx.check_arg_id(0);
   return {++__begin, 0}; // can never be larger than the maximum.
 }
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) {
   size_t __value = __parse_ctx.next_arg_id();
-  _LIBCPP_ASSERT(__value <= __number_max,
-                 "Compilers don't support this number of arguments");
+  _LIBCPP_ASSERT_UNCATEGORIZED(
+      __value <= __number_max,
+      "Compilers don't support this number of arguments");
 
   return {__begin, uint32_t(__value)};
 }
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
-  __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_manual(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+  __parse_number_result<_Iterator> __r = __format::__parse_number(__begin, __end);
   __parse_ctx.check_arg_id(__r.__value);
   return __r;
 }
@@ -86,9 +89,10 @@ __parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
  * The number is used for the 31-bit values @em width and @em precision. This
  * allows a maximum value of 2147483647.
  */
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end_input) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end_input) {
+  using _CharT = iter_value_t<_Iterator>;
   static_assert(__format::__number_max == INT32_MAX,
                 "The algorithm is implemented based on this value.");
   /*
@@ -98,7 +102,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
    * - Does the value exceed width of an uint32_t? (Switching to uint64_t would
    *   have the same issue, but with a higher maximum.)
    */
-  const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
+  _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
   uint32_t __value = *__begin - _CharT('0');
   while (++__begin != __end) {
     if (*__begin < _CharT('0') || *__begin > _CharT('9'))
@@ -120,7 +124,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
     if (__v > __number_max ||
         (__begin != __end_input && *__begin >= _CharT('0') &&
          *__begin <= _CharT('9')))
-      std::__throw_format_error("The numeric value of the format-spec is too large");
+      std::__throw_format_error("The numeric value of the format specifier is too large");
 
     __value = __v;
   }
@@ -134,9 +138,10 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
  * The parser will return a pointer beyond the last consumed character. This
  * should be the closing '}' of the arg-id.
  */
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+  using _CharT = iter_value_t<_Iterator>;
   switch (*__begin) {
   case _CharT('0'):
     return __detail::__parse_zero(__begin, __end, __parse_ctx);
@@ -149,14 +154,14 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
     return __detail::__parse_automatic(__begin, __end, __parse_ctx);
   }
   if (*__begin < _CharT('0') || *__begin > _CharT('9'))
-    std::__throw_format_error("The arg-id of the format-spec starts with an invalid character");
+    std::__throw_format_error("The argument index starts with an invalid character");
 
   return __detail::__parse_manual(__begin, __end, __parse_ctx);
 }
 
 } // namespace __format
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/format_to_n_result.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _OutIt>
 struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
@@ -28,7 +28,7 @@ struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result);
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 /// The default formatter template.
 ///
@@ -32,13 +32,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 /// - is_copy_assignable<F>, and
 /// - is_move_assignable<F>.
 template <class _Tp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
+struct _LIBCPP_TEMPLATE_VIS formatter {
   formatter() = delete;
   formatter(const formatter&) = delete;
   formatter& operator=(const formatter&) = delete;
 };
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
@@ -46,8 +46,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
     __formatter.set_debug_format();
 }
 
-#  endif // _LIBCPP_STD_VER > 20
-#endif   // _LIBCPP_STD_VER > 17
+#  endif // _LIBCPP_STD_VER >= 23
+#endif   // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_bool.h
@@ -11,17 +11,15 @@
 #define _LIBCPP___FORMAT_FORMATTER_BOOL_H
 
 #include <__algorithm/copy.h>
+#include <__assert>
 #include <__availability>
 #include <__config>
-#include <__debug>
 #include <__format/concepts.h>
-#include <__format/format_error.h>
 #include <__format/format_parse_context.h>
 #include <__format/formatter.h>
 #include <__format/formatter_integral.h>
 #include <__format/parser_std_format_spec.h>
 #include <__utility/unreachable.h>
-#include <string_view>
 
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #  include <locale>
@@ -33,19 +31,20 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<bool, _CharT> {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
-    __format_spec::__process_parsed_bool(__parser_);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
+    __format_spec::__process_parsed_bool(__parser_, "a bool");
     return __result;
   }
 
-  _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(bool __value, _FormatContext& __ctx) const {
     switch (__parser_.__type_) {
     case __format_spec::__type::__default:
     case __format_spec::__type::__string:
@@ -63,7 +62,7 @@ public:
           static_cast<unsigned>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx));
 
     default:
-      _LIBCPP_ASSERT(false, "The parse function should have validated the type");
+      _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type");
       __libcpp_unreachable();
     }
   }
@@ -71,7 +70,7 @@ public:
   __format_spec::__parser<_CharT> __parser_;
 };
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_char.h
@@ -19,6 +19,7 @@
 #include <__format/formatter_integral.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__format/write_escaped.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/is_signed.h>
 
@@ -28,23 +29,24 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char {
+struct _LIBCPP_TEMPLATE_VIS __formatter_char {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
-    __format_spec::__process_parsed_char(__parser_);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
+    __format_spec::__process_parsed_char(__parser_, "a character");
     return __result;
   }
 
-  _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT __value, _FormatContext& __ctx) const {
     if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char)
       return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
     if (__parser_.__type_ == __format_spec::__type::__debug)
       return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
 #  endif
@@ -60,13 +62,14 @@ public:
       return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
   }
 
-  _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out())
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(char __value, _FormatContext& __ctx) const
     requires(same_as<_CharT, wchar_t>)
   {
     return format(static_cast<wchar_t>(__value), __ctx);
   }
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
   _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
 #  endif
 
@@ -74,19 +77,19 @@ public:
 };
 
 template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char> : public __formatter_char<char> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {};
 
 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
 
 template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
+struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
 };
 
 #  endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_floating_point.h
@@ -16,6 +16,9 @@
 #include <__algorithm/min.h>
 #include <__algorithm/rotate.h>
 #include <__algorithm/transform.h>
+#include <__charconv/chars_format.h>
+#include <__charconv/to_chars_floating_point.h>
+#include <__charconv/to_chars_result.h>
 #include <__concepts/arithmetic.h>
 #include <__concepts/same_as.h>
 #include <__config>
@@ -25,10 +28,14 @@
 #include <__format/formatter_integral.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__iterator/concepts.h>
 #include <__memory/allocator.h>
+#include <__system_error/errc.h>
+#include <__type_traits/conditional.h>
 #include <__utility/move.h>
 #include <__utility/unreachable.h>
-#include <charconv>
+#include <cmath>
+#include <cstddef>
 
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #  include <locale>
@@ -43,28 +50,28 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __formatter {
 
 template <floating_point _Tp>
 _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) {
   to_chars_result __r = _VSTD::to_chars(__first, __last, __value);
-  _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
   return __r.ptr;
 }
 
 template <floating_point _Tp>
 _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) {
   to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt);
-  _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
   return __r.ptr;
 }
 
 template <floating_point _Tp>
 _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) {
   to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision);
-  _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
   return __r.ptr;
 }
 
@@ -246,10 +253,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe
     __result.__radix_point = __result.__last;
 
   // clang-format off
-  _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
-                 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
-                 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
-                 "Post-condition failure.");
+  _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
+                               (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
+                               (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
+                               "Post-condition failure.");
   // clang-format on
 
   return __result;
@@ -299,10 +306,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons
   }
 
   // clang-format off
-  _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
-                 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
-                 (__result.__exponent != __result.__last && *__result.__exponent == 'p'),
-                 "Post-condition failure.");
+  _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
+                               (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
+                               (__result.__exponent != __result.__last && *__result.__exponent == 'p'),
+                               "Post-condition failure.");
   // clang-format on
 
   return __result;
@@ -329,7 +336,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const
       __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision);
 
   char* __first = __integral + 1;
-  _LIBCPP_ASSERT(__first != __result.__last, "No exponent present");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first != __result.__last, "No exponent present");
   if (*__first == '.') {
     __result.__radix_point = __first;
     __result.__exponent    = __formatter::__find_exponent(__first + 1, __result.__last);
@@ -339,10 +346,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const
   }
 
   // clang-format off
-  _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
-                 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
-                 (__result.__exponent != __result.__last && *__result.__exponent == 'e'),
-                 "Post-condition failure.");
+  _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
+                               (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
+                               (__result.__exponent != __result.__last && *__result.__exponent == 'e'),
+                               "Post-condition failure.");
   // clang-format on
   return __result;
 }
@@ -372,10 +379,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<
   __result.__exponent = __result.__last;
 
   // clang-format off
-  _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
-                 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
-                 (__result.__exponent == __result.__last),
-                 "Post-condition failure.");
+  _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
+                               (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
+                               (__result.__exponent == __result.__last),
+                               "Post-condition failure.");
   // clang-format on
   return __result;
 }
@@ -409,10 +416,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
   }
 
   // clang-format off
-  _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
-                 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
-                 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
-                 "Post-condition failure.");
+  _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
+                               (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
+                               (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
+                               "Post-condition failure.");
   // clang-format on
 
   return __result;
@@ -484,7 +491,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(
     return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first);
 
   default:
-    _LIBCPP_ASSERT(false, "The parser should have validated the type");
+    _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parser should have validated the type");
     __libcpp_unreachable();
   }
 }
@@ -522,7 +529,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
   if (__size < __specs.__width_) {
     if (__zero_padding) {
       __specs.__alignment_ = __format_spec::__alignment::__right;
-      __specs.__fill_      = _CharT('0');
+      __specs.__fill_.__data[0] = _CharT('0');
     }
 
     __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
@@ -602,10 +609,40 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite(
   return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs);
 }
 
-template <floating_point _Tp, class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto
-__format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
-    -> decltype(__ctx.out()) {
+/// Writes additional zero's for the precision before the exponent.
+/// This is used when the precision requested in the format string is larger
+/// than the maximum precision of the floating-point type. These precision
+/// digits are always 0.
+///
+/// \param __exponent           The location of the exponent character.
+/// \param __num_trailing_zeros The number of 0's to write before the exponent
+///                             character.
+template <class _CharT, class _ParserCharT>
+_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
+    const _CharT* __first,
+    const _CharT* __last,
+    output_iterator<const _CharT&> auto __out_it,
+    __format_spec::__parsed_specifications<_ParserCharT> __specs,
+    size_t __size,
+    const _CharT* __exponent,
+    size_t __num_trailing_zeros) -> decltype(__out_it) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__num_trailing_zeros > 0,
+                               "The overload not writing trailing zeros should have been used");
+
+  __padding_size_result __padding =
+      __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
+  __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+  __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it));
+  __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
+  __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it));
+  return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
+
+template <floating_point _Tp, class _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
   bool __negative = _VSTD::signbit(__value);
 
   if (!_VSTD::isfinite(__value)) [[unlikely]]
@@ -707,7 +744,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
     // After the sign is written, zero padding is the same a right alignment
     // with '0'.
     __specs.__alignment_ = __format_spec::__alignment::__right;
-    __specs.__fill_      = _CharT('0');
+    __specs.__fill_.__data[0] = _CharT('0');
   }
 
   if (__num_trailing_zeros)
@@ -722,15 +759,15 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
 template <__fmt_char_type _CharT>
 struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point);
-    __format_spec::__process_parsed_floating_point(__parser_);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_floating_point);
+    __format_spec::__process_parsed_floating_point(__parser_, "a floating-point");
     return __result;
   }
 
-  template <floating_point _Tp>
-  _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <floating_point _Tp, class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const {
     return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
   }
 
@@ -738,16 +775,16 @@ public:
 };
 
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<float, _CharT>
     : public __formatter_floating_point<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT>
     : public __formatter_floating_point<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT>
     : public __formatter_floating_point<_CharT> {};
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_integer.h
@@ -19,8 +19,8 @@
 #include <__format/formatter_integral.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__type_traits/is_void.h>
 #include <__type_traits/make_32_64_or_128_bit.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -28,28 +28,28 @@
 
     _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
     template <__fmt_char_type _CharT>
-    struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer {
+    struct _LIBCPP_TEMPLATE_VIS __formatter_integer {
 
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
-    __format_spec::__process_parsed_integer(__parser_);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
+    __format_spec::__process_parsed_integer(__parser_, "an integer");
     return __result;
   }
 
-  template <integral _Tp>
-  _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <integral _Tp, class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const {
     __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
 
     if (__specs.__std_.__type_ == __format_spec::__type::__char)
       return __formatter::__format_char(__value, __ctx.out(), __specs);
 
     using _Type = __make_32_64_or_128_bit_t<_Tp>;
-    static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format");
+    static_assert(!is_void<_Type>::value, "unsupported integral type used in __formatter_integer::__format");
 
     // Reduce the number of instantiation of the integer formatter
     return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs);
@@ -60,47 +60,47 @@ public:
 
 // Signed integral types.
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<signed char, _CharT>
     : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __formatter_integer<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<short, _CharT> : public __formatter_integer<_CharT> {
 };
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<int, _CharT> : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<long, _CharT> : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<long long, _CharT>
     : public __formatter_integer<_CharT> {};
 #  ifndef _LIBCPP_HAS_NO_INT128
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT>
     : public __formatter_integer<_CharT> {};
 #  endif
 
 // Unsigned integral types.
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned char, _CharT>
     : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned short, _CharT>
     : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned, _CharT>
     : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long, _CharT>
     : public __formatter_integer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long long, _CharT>
     : public __formatter_integer<_CharT> {};
 #  ifndef _LIBCPP_HAS_NO_INT128
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT>
     : public __formatter_integer<_CharT> {};
 #  endif
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_integral.h
@@ -10,6 +10,9 @@
 #ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
 #define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
 
+#include <__charconv/to_chars_integral.h>
+#include <__charconv/to_chars_result.h>
+#include <__charconv/traits.h>
 #include <__concepts/arithmetic.h>
 #include <__concepts/same_as.h>
 #include <__config>
@@ -17,11 +20,13 @@
 #include <__format/format_error.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__system_error/errc.h>
+#include <__type_traits/make_unsigned.h>
 #include <__utility/unreachable.h>
 #include <array>
-#include <charconv>
 #include <limits>
 #include <string>
+#include <string_view>
 
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #  include <locale>
@@ -36,7 +41,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __formatter {
 
@@ -80,9 +85,9 @@ _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, _
  * regardless whether the @c std::numpunct's type is @c char or @c wchar_t.
  */
 _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) {
-  _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0],
-                 "The slow grouping formatting is used while there will be no "
-                 "separators written");
+  _LIBCPP_ASSERT_UNCATEGORIZED(!__grouping.empty() && __size > __grouping[0],
+                               "The slow grouping formatting is used while there will be no "
+                               "separators written");
   string __r;
   auto __end = __grouping.end() - 1;
   auto __ptr = __grouping.begin();
@@ -149,7 +154,7 @@ _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value
   // TODO FMT Evaluate code overhead due to not calling the internal function
   // directly. (Should be zero overhead.)
   to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base);
-  _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
   return __r.ptr;
 }
 
@@ -198,16 +203,82 @@ consteval size_t __buffer_size() noexcept
        + 1;                          // Reserve space for the sign.
 }
 
-template <unsigned_integral _Tp, class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto __format_integer(
+template <class _OutIt, class _CharT>
+_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
+                                                              const char* __last, string&& __grouping, _CharT __sep,
+                                                              __format_spec::__parsed_specifications<_CharT> __specs) {
+  int __size = (__first - __begin) +    // [sign][prefix]
+               (__last - __first) +     // data
+               (__grouping.size() - 1); // number of separator characters
+
+  __padding_size_result __padding = {0, 0};
+  if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
+    // Write [sign][prefix].
+    __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
+
+    if (__specs.__width_ > __size) {
+      // Write zero padding.
+      __padding.__before_ = __specs.__width_ - __size;
+      __out_it            = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0'));
+    }
+  } else {
+    if (__specs.__width_ > __size) {
+      // Determine padding and write padding.
+      __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
+
+      __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+    }
+    // Write [sign][prefix].
+    __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
+  }
+
+  auto __r = __grouping.rbegin();
+  auto __e = __grouping.rend() - 1;
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r != __e, "The slow grouping formatting is used while "
+                                           "there will be no separators written.");
+  // The output is divided in small groups of numbers to write:
+  // - A group before the first separator.
+  // - A separator and a group, repeated for the number of separators.
+  // - A group after the last separator.
+  // This loop achieves that process by testing the termination condition
+  // midway in the loop.
+  //
+  // TODO FMT This loop evaluates the loop invariant `__parser.__type !=
+  // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
+  // happens in the __write call.) Benchmark whether making two loops and
+  // hoisting the invariant is worth the effort.
+  while (true) {
+    if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) {
+      __last = __first + *__r;
+      __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper);
+      __first = __last;
+    } else {
+      __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it));
+      __first += *__r;
+    }
+
+    if (__r == __e)
+      break;
+
+    ++__r;
+    *__out_it++ = __sep;
+  }
+
+  return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
+
+
+template <unsigned_integral _Tp, class _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer(
     _Tp __value,
-    auto& __ctx,
+    _FormatContext& __ctx,
     __format_spec::__parsed_specifications<_CharT> __specs,
     bool __negative,
     char* __begin,
     char* __end,
     const char* __prefix,
-    int __base) -> decltype(__ctx.out()) {
+    int __base) {
   char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_);
   if (__specs.__std_.__alternate_form_ && __prefix)
     while (*__prefix)
@@ -246,7 +317,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
     // - Write data right aligned with '0' as fill character.
     __out_it             = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
     __specs.__alignment_ = __format_spec::__alignment::__right;
-    __specs.__fill_      = _CharT('0');
+    __specs.__fill_.__data[0] = _CharT('0');
     int32_t __size       = __first - __begin;
 
     __specs.__width_ -= _VSTD::min(__size, __specs.__width_);
@@ -258,10 +329,12 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
   return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper);
 }
 
-template <unsigned_integral _Tp, class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto __format_integer(
-    _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false)
-    -> decltype(__ctx.out()) {
+template <unsigned_integral _Tp, class _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__format_integer(_Tp __value,
+                 _FormatContext& __ctx,
+                 __format_spec::__parsed_specifications<_CharT> __specs,
+                 bool __negative = false) {
   switch (__specs.__std_.__type_) {
   case __format_spec::__type::__binary_lower_case: {
     array<char, __formatter::__buffer_size<decltype(__value), 2>()> __array;
@@ -292,15 +365,14 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
     return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16);
   }
   default:
-    _LIBCPP_ASSERT(false, "The parse function should have validated the type");
+    _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type");
     __libcpp_unreachable();
   }
 }
 
-template <signed_integral _Tp, class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto
-__format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
-    -> decltype(__ctx.out()) {
+template <signed_integral _Tp, class _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__format_integer(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
   // Depending on the std-format-spec string the sign and the value
   // might not be outputted together:
   // - alternate form may insert a prefix string.
@@ -336,10 +408,9 @@ struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
 };
 #  endif
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto
-__format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
-    -> decltype(__ctx.out()) {
+template <class _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__format_bool(bool __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
   if (__specs.__std_.__locale_specific_form_) {
     const auto& __np           = std::use_facet<numpunct<_CharT>>(__ctx.locale());
@@ -354,7 +425,7 @@ __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<
 
 } // namespace __formatter
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_output.h
@@ -13,22 +13,21 @@
 #include <__algorithm/ranges_copy.h>
 #include <__algorithm/ranges_fill_n.h>
 #include <__algorithm/ranges_transform.h>
-#include <__chrono/statically_widen.h>
+#include <__bit/countl.h>
 #include <__concepts/same_as.h>
 #include <__config>
 #include <__format/buffer.h>
 #include <__format/concepts.h>
-#include <__format/escaped_output_table.h>
 #include <__format/formatter.h>
 #include <__format/parser_std_format_spec.h>
 #include <__format/unicode.h>
 #include <__iterator/back_insert_iterator.h>
-#include <__type_traits/make_unsigned.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h> // iter_value_t
+#include <__memory/addressof.h>
 #include <__utility/move.h>
 #include <__utility/unreachable.h>
-#include <charconv>
 #include <cstddef>
-#include <string>
 #include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -37,7 +36,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __formatter {
 
@@ -59,15 +58,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) {
   return __c;
 }
 
-struct _LIBCPP_TYPE_VIS __padding_size_result {
+struct _LIBCPP_EXPORTED_FROM_ABI __padding_size_result {
   size_t __before_;
   size_t __after_;
 };
 
 _LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
 __padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) {
-  _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required");
-  _LIBCPP_ASSERT(
+  _LIBCPP_ASSERT_UNCATEGORIZED(__width > __size, "don't call this function when no padding is required");
+  _LIBCPP_ASSERT_UNCATEGORIZED(
       __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding");
 
   size_t __fill = __width - __size;
@@ -161,69 +160,45 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
   }
 }
 
-template <class _OutIt, class _CharT>
-_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
-                                                              const char* __last, string&& __grouping, _CharT __sep,
-                                                              __format_spec::__parsed_specifications<_CharT> __specs) {
-  int __size = (__first - __begin) +    // [sign][prefix]
-               (__last - __first) +     // data
-               (__grouping.size() - 1); // number of separator characters
-
-  __padding_size_result __padding = {0, 0};
-  if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
-    // Write [sign][prefix].
-    __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
-
-    if (__specs.__width_ > __size) {
-      // Write zero padding.
-      __padding.__before_ = __specs.__width_ - __size;
-      __out_it            = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0'));
-    }
-  } else {
-    if (__specs.__width_ > __size) {
-      // Determine padding and write padding.
-      __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
-
-      __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
-    }
-    // Write [sign][prefix].
-    __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
-  }
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
+  requires(same_as<_CharT, char>)
+_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
+  std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
+  if (__bytes == 0)
+    return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+
+  for (size_t __i = 0; __i < __n; ++__i)
+    __out_it = __formatter::__copy(
+        std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
+  return __out_it;
+}
 
-  auto __r = __grouping.rbegin();
-  auto __e = __grouping.rend() - 1;
-  _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while "
-                             "there will be no separators written.");
-  // The output is divided in small groups of numbers to write:
-  // - A group before the first separator.
-  // - A separator and a group, repeated for the number of separators.
-  // - A group after the last separator.
-  // This loop achieves that process by testing the termination condition
-  // midway in the loop.
-  //
-  // TODO FMT This loop evaluates the loop invariant `__parser.__type !=
-  // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
-  // happens in the __write call.) Benchmark whether making two loops and
-  // hoisting the invariant is worth the effort.
-  while (true) {
-    if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) {
-      __last = __first + *__r;
-      __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper);
-      __first = __last;
-    } else {
-      __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it));
-      __first += *__r;
-    }
-
-    if (__r == __e)
-      break;
-
-    ++__r;
-    *__out_it++ = __sep;
-  }
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
+  requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
+_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
+  if (!__unicode::__is_high_surrogate(__value.__data[0]))
+    return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+
+  for (size_t __i = 0; __i < __n; ++__i)
+    __out_it = __formatter::__copy(
+        std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
+  return __out_it;
+}
 
-  return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
+  requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
+_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
+  return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
 }
+#    endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  else    // _LIBCPP_HAS_NO_UNICODE
+template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
+_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
+  return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
+}
+#  endif   // _LIBCPP_HAS_NO_UNICODE
 
 /// Writes the input to the output with the required padding.
 ///
@@ -261,27 +236,27 @@ __write(basic_string_view<_CharT> __str,
   return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
 }
 
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
 _LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
-        const _CharT* __last,
-        output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+        _Iterator __last,
+        output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
         __format_spec::__parsed_specifications<_ParserCharT> __specs,
         ptrdiff_t __size) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
   return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size);
 }
 
 /// \overload
 ///
 /// Calls the function above where \a __size = \a __last - \a __first.
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
 _LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
-        const _CharT* __last,
-        output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+        _Iterator __last,
+        output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
         __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
   return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first);
 }
 
@@ -290,7 +265,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
                                                output_iterator<const _CharT&> auto __out_it,
                                                __format_spec::__parsed_specifications<_ParserCharT> __specs,
                                                _UnaryOperation __op) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
 
   ptrdiff_t __size = __last - __first;
   if (__size >= __specs.__width_)
@@ -302,35 +277,6 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
   return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
 }
 
-/// Writes additional zero's for the precision before the exponent.
-/// This is used when the precision requested in the format string is larger
-/// than the maximum precision of the floating-point type. These precision
-/// digits are always 0.
-///
-/// \param __exponent           The location of the exponent character.
-/// \param __num_trailing_zeros The number of 0's to write before the exponent
-///                             character.
-template <class _CharT, class _ParserCharT>
-_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
-    const _CharT* __first,
-    const _CharT* __last,
-    output_iterator<const _CharT&> auto __out_it,
-    __format_spec::__parsed_specifications<_ParserCharT> __specs,
-    size_t __size,
-    const _CharT* __exponent,
-    size_t __num_trailing_zeros) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
-  _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
-
-  __padding_size_result __padding =
-      __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
-  __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
-  __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it));
-  __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
-  __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it));
-  return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
-}
-
 /// Writes a string using format's width estimation algorithm.
 ///
 /// \pre !__specs.__has_precision()
@@ -342,7 +288,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision(
     basic_string_view<_CharT> __str,
     output_iterator<const _CharT&> auto __out_it,
     __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string");
+  _LIBCPP_ASSERT_UNCATEGORIZED(!__specs.__has_precision(), "use __write_string");
 
   // No padding -> copy the string
   if (!__specs.__has_width())
@@ -359,211 +305,15 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision(
 
 template <class _CharT>
 _LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) {
-  __format_spec::__column_width_result<_CharT> __result =
+  __format_spec::__column_width_result __result =
       __format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down);
   __str = basic_string_view<_CharT>{__str.begin(), __result.__last_};
   return __result.__width_;
 }
 
-/// Writes a string using format's width estimation algorithm.
-///
-/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
-/// input is ASCII.
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto __write_string(
-    basic_string_view<_CharT> __str,
-    output_iterator<const _CharT&> auto __out_it,
-    __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
-  if (!__specs.__has_precision())
-    return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs);
-
-  int __size = __formatter::__truncate(__str, __specs.__precision_);
-
-  return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
-}
-
-#  if _LIBCPP_STD_VER > 20
-
-struct __nul_terminator {};
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) {
-  return *__cstr == _CharT('\0');
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI void
-__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) {
-  back_insert_iterator __out_it{__str};
-  std::ranges::copy(__prefix, __nul_terminator{}, __out_it);
-
-  char __buffer[8];
-  to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16);
-  _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
-  std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it);
-
-  __str += _CharT('}');
-}
-
-// [format.string.escaped]/2.2.1.2
-// ...
-// then the sequence \u{hex-digit-sequence} is appended to E, where
-// hex-digit-sequence is the shortest hexadecimal representation of C using
-// lower-case hexadecimal digits.
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) {
-  __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
-}
-
-// [format.string.escaped]/2.2.3
-// Otherwise (X is a sequence of ill-formed code units), each code unit U is
-// appended to E in order as the sequence \x{hex-digit-sequence}, where
-// hex-digit-sequence is the shortest hexadecimal representation of U using
-// lower-case hexadecimal digits.
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) {
-  __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
-}
-
-template <class _CharT>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) {
-#    ifdef _LIBCPP_HAS_NO_UNICODE
-  // For ASCII assume everything above 127 is printable.
-  if (__value > 127)
-    return false;
-#    endif
-
-  if (!__escaped_output_table::__needs_escape(__value))
-    return false;
-
-  __formatter::__write_well_formed_escaped_code_unit(__str, __value);
-  return true;
-}
-
-template <class _CharT>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) {
-  return static_cast<make_unsigned_t<_CharT>>(__value);
-}
-
-enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote };
-
-// [format.string.escaped]/2
-template <class _CharT>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
-__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) {
-  // 2.2.1.1 - Mapped character in [tab:format.escape.sequences]
-  switch (__value) {
-  case _CharT('\t'):
-    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t");
-    return true;
-  case _CharT('\n'):
-    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n");
-    return true;
-  case _CharT('\r'):
-    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r");
-    return true;
-  case _CharT('\''):
-    if (__mark == __escape_quotation_mark::__apostrophe)
-      __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')");
-    else
-      __str += __value;
-    return true;
-  case _CharT('"'):
-    if (__mark == __escape_quotation_mark::__double_quote)
-      __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")");
-    else
-      __str += __value;
-    return true;
-  case _CharT('\\'):
-    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)");
-    return true;
-
-  // 2.2.1.2 - Space
-  case _CharT(' '):
-    __str += __value;
-    return true;
-  }
-
-  // 2.2.2
-  //   Otherwise, if X is a shift sequence, the effect on E and further
-  //   decoding of S is unspecified.
-  // For now shift sequences are ignored and treated as Unicode. Other parts
-  // of the format library do the same. It's unknown how ostream treats them.
-  // TODO FMT determine what to do with shift sequences.
-
-  // 2.2.1.2.1 and 2.2.1.2.2 - Escape
-  return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value));
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI void
-__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) {
-  __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()};
-
-  while (!__view.__at_end()) {
-    const _CharT* __first                               = __view.__position();
-    typename __unicode::__consume_p2286_result __result = __view.__consume_p2286();
-    if (__result.__ill_formed_size == 0) {
-      if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark))
-        // 2.2.1.3 - Add the character
-        ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str));
-
-    } else {
-      // 2.2.3 sequence of ill-formed code units
-      // The number of code-units in __result.__value depends on the character type being used.
-      if constexpr (sizeof(_CharT) == 1) {
-        _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4,
-                       "illegal number of invalid code units.");
-        if (__result.__ill_formed_size == 1) // ill-formed, one code unit
-          __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff);
-        else { // out of valid range, four code units
-               // The code point was properly encoded, decode the value.
-          __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0);
-          __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80);
-          __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80);
-          __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80);
-        }
-      } else if constexpr (sizeof(_CharT) == 2) {
-        _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit");
-        __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff);
-      } else {
-        static_assert(sizeof(_CharT) == 4, "unsupported character width");
-        _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point");
-        __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value);
-      }
-    }
-  }
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto
-__format_escaped_char(_CharT __value,
-                      output_iterator<const _CharT&> auto __out_it,
-                      __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
-  basic_string<_CharT> __str;
-  __str += _CharT('\'');
-  __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe);
-  __str += _CharT('\'');
-  return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size());
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI auto
-__format_escaped_string(basic_string_view<_CharT> __values,
-                        output_iterator<const _CharT&> auto __out_it,
-                        __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
-  basic_string<_CharT> __str;
-  __str += _CharT('"');
-  __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote);
-  __str += _CharT('"');
-  return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs);
-}
-
-#  endif // _LIBCPP_STD_VER > 20
-
 } // namespace __formatter
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_pointer.h
@@ -27,24 +27,27 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <__fmt_char_type _CharT>
 struct _LIBCPP_TEMPLATE_VIS __formatter_pointer {
 public:
-  constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; }
-
-  _LIBCPP_HIDE_FROM_ABI constexpr auto
-  parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer);
-    __format_spec::__process_display_type_pointer(__parser_.__type_);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_pointer);
+    __format_spec::__process_display_type_pointer(__parser_.__type_, "a pointer");
     return __result;
   }
 
-  _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const void* __ptr, _FormatContext& __ctx) const {
     __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
     __specs.__std_.__alternate_form_                       = true;
-    __specs.__std_.__type_                                 = __format_spec::__type::__hexadecimal_lower_case;
+    __specs.__std_.__type_ =
+        __specs.__std_.__type_ == __format_spec::__type::__pointer_upper_case
+            ? __format_spec::__type::__hexadecimal_upper_case
+            : __format_spec::__type::__hexadecimal_lower_case;
+
     return __formatter::__format_integer(reinterpret_cast<uintptr_t>(__ptr), __ctx, __specs);
   }
 
@@ -57,16 +60,16 @@ public:
 // - template<> struct formatter<void*, charT>;
 // - template<> struct formatter<const void*, charT>;
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<nullptr_t, _CharT>
     : public __formatter_pointer<_CharT> {};
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
 };
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT>
     : public __formatter_pointer<_CharT> {};
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_string.h
@@ -17,7 +17,7 @@
 #include <__format/formatter.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
-#include <__utility/move.h>
+#include <__format/write_escaped.h>
 #include <string>
 #include <string_view>
 
@@ -27,20 +27,22 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <__fmt_char_type _CharT>
 struct _LIBCPP_TEMPLATE_VIS __formatter_string {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string);
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_string);
     __format_spec::__process_display_type_string(__parser_.__type_);
     return __result;
   }
 
-  _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) {
-#  if _LIBCPP_STD_VER > 20
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(basic_string_view<_CharT> __str, _FormatContext& __ctx) const {
+#  if _LIBCPP_STD_VER >= 23
     if (__parser_.__type_ == __format_spec::__type::__debug)
       return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
 #  endif
@@ -48,7 +50,7 @@ public:
     return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
   }
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
   _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
 #  endif
 
@@ -57,16 +59,17 @@ public:
 
 // Formatter const char*.
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT>
     : public __formatter_string<_CharT> {
   using _Base = __formatter_string<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
-    _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have "
-                          "prevented an invalid pointer.");
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__str, "The basic_format_arg constructor should have "
+                                 "prevented an invalid pointer.");
 
     __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
     if (_Base::__parser_.__type_ == __format_spec::__type::__debug)
       return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
 #  endif
@@ -95,45 +98,38 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*,
 
 // Formatter char*.
 template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT>
     : public formatter<const _CharT*, _CharT> {
   using _Base = formatter<const _CharT*, _CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT* __str, _FormatContext& __ctx) const {
     return _Base::format(__str, __ctx);
   }
 };
 
 // Formatter char[].
 template <__fmt_char_type _CharT, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT>
     : public __formatter_string<_CharT> {
   using _Base = __formatter_string<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
-    return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
-  }
-};
-
-// Formatter const char[].
-template <__fmt_char_type _CharT, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT>
-    : public __formatter_string<_CharT> {
-  using _Base = __formatter_string<_CharT>;
-
-  _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(const _CharT (&__str)[_Size], _FormatContext& __ctx) const {
     return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
   }
 };
 
 // Formatter std::string.
 template <__fmt_char_type _CharT, class _Traits, class _Allocator>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
     : public __formatter_string<_CharT> {
   using _Base = __formatter_string<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const
-      -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(const basic_string<_CharT, _Traits, _Allocator>& __str, _FormatContext& __ctx) const {
     // Drop _Traits and _Allocator to have one std::basic_string formatter.
     return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
   }
@@ -141,18 +137,19 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_
 
 // Formatter std::string_view.
 template <__fmt_char_type _CharT, class _Traits>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT>
     : public __formatter_string<_CharT> {
   using _Base = __formatter_string<_CharT>;
 
-  _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const
-      -> decltype(__ctx.out()) {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(basic_string_view<_CharT, _Traits> __str, _FormatContext& __ctx) const {
     // Drop _Traits to have one std::basic_string_view formatter.
     return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
   }
 };
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/formatter_tuple.h
@@ -11,18 +11,16 @@
 #define _LIBCPP___FORMAT_FORMATTER_TUPLE_H
 
 #include <__algorithm/ranges_copy.h>
-#include <__availability>
 #include <__chrono/statically_widen.h>
 #include <__config>
+#include <__format/buffer.h>
 #include <__format/concepts.h>
-#include <__format/format_args.h>
 #include <__format/format_context.h>
 #include <__format/format_error.h>
 #include <__format/format_parse_context.h>
 #include <__format/formatter.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
-#include <__iterator/back_insert_iterator.h>
 #include <__type_traits/remove_cvref.h>
 #include <__utility/integer_sequence.h>
 #include <__utility/pair.h>
@@ -35,49 +33,52 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
-  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+struct _LIBCPP_TEMPLATE_VIS __formatter_tuple {
+  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
     __separator_ = __separator;
   }
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
     __opening_bracket_ = __opening_bracket;
     __closing_bracket_ = __closing_bracket;
   }
 
   template <class _ParseContext>
-  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
-    const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple);
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_tuple);
 
-    // [format.tuple]/7
-    //   ... For each element e in underlying_, if e.set_debug_format()
-    //   is a valid expression, calls e.set_debug_format().
-    // TODO FMT this can be removed when P2733 is accepted.
-    std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
-      std::__set_debug_format(std::get<_Index>(__underlying_));
-    });
-
-    const _CharT* __end = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
-
-    if (*__begin == _CharT('m')) {
+    auto __end = __ctx.end();
+    // Note 'n' is part of the type here
+    if (__parser_.__clear_brackets_)
+      set_brackets({}, {});
+    else if (__begin != __end && *__begin == _CharT('m')) {
       if constexpr (sizeof...(_Args) == 2) {
         set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
         set_brackets({}, {});
         ++__begin;
       } else
-        std::__throw_format_error("The format specifier m requires a pair or a two-element tuple");
-    } else if (*__begin == _CharT('n')) {
-      set_brackets({}, {});
-      ++__begin;
+        std::__throw_format_error("Type m requires a pair or a tuple with two elements");
     }
 
     if (__begin != __end && *__begin != _CharT('}'))
-      std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+      std::__throw_format_error("The format specifier should consume the input or end with a '}'");
+
+    __ctx.advance_to(__begin);
+
+    // [format.tuple]/7
+    //   ... For each element e in underlying_, if e.set_debug_format()
+    //   is a valid expression, calls e.set_debug_format().
+    std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
+      auto& __formatter = std::get<_Index>(__underlying_);
+      __formatter.parse(__ctx);
+      // Unlike the range_formatter we don't guard against evil parsers. Since
+      // this format-spec never has a format-spec for the underlying type
+      // adding the test would give additional overhead.
+      std::__set_debug_format(__formatter);
+    });
 
     return __begin;
   }
@@ -91,26 +92,25 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
     if (!__specs.__has_width())
       return __format_tuple(__tuple, __ctx);
 
-    basic_string<_CharT> __str;
-
-    // Since the output is written to a different iterator a new context is
-    // created. Since the underlying formatter uses the default formatting it
-    // doesn't need a locale or the formatting arguments. So creating a new
-    // context works.
-    //
-    // This solution works for this formatter, but it will not work for the
-    // range_formatter. In that patch a generic solution is work in progress.
-    // Once that is finished it can be used here. (The range_formatter will use
-    // these features so it's easier to add it there and then port it.)
-    //
-    // TODO FMT Use formatting wrapping used in the range_formatter.
-    basic_format_context __c = std::__format_context_create(
-        back_insert_iterator{__str},
-        basic_format_args<basic_format_context<back_insert_iterator<basic_string<_CharT>>, _CharT>>{});
+    // The size of the buffer needed is:
+    // - open bracket characters
+    // - close bracket character
+    // - n elements where every element may have a different size
+    // - (n -1) separators
+    // The size of the element is hard to predict, knowing the type helps but
+    // it depends on the format-spec. As an initial estimate we guess 6
+    // characters.
+    // Typically both brackets are 1 character and the separator is 2
+    // characters. Which means there will be
+    //   (n - 1) * 2 + 1 + 1 = n * 2 character
+    // So estimate 8 times the range size as buffer.
+    __format::__retarget_buffer<_CharT> __buffer{8 * tuple_size_v<_Tuple>};
+    basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
+        __buffer.__make_output_iterator(), __ctx};
 
     __format_tuple(__tuple, __c);
 
-    return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs);
+    return __formatter::__write_string_no_precision(basic_string_view{__buffer.__view()}, __ctx.out(), __specs);
   }
 
   template <class _FormatContext>
@@ -120,35 +120,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
     std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
       if constexpr (_Index)
         __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out);
-
-        // During review Victor suggested to make the exposition only
-        // __underlying_ member a local variable. Currently the Standard
-        // requires nested debug-enabled formatter specializations not to
-        // output escaped output. P2733 fixes that bug, once accepted the
-        // code below can be used.
-        // (Note when a paper allows parsing a tuple-underlying-spec the
-        // exposition only member needs to be a class member. Earlier
-        // revisions of P2286 proposed that, but this was not pursued,
-        // due to time constrains and complexity of the matter.)
-        // TODO FMT This can be updated after P2733 is accepted.
-#  if 0
-      // P2286 uses an exposition only member in the formatter
-      //   tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
-      // This was used in earlier versions of the paper since
-      // __underlying_.parse(...) was called. This is no longer the case
-      // so we can reduce the scope of the formatter.
-      //
-      // It does require the underlying's parse effect to be moved here too.
-      using _Arg = tuple_element<_Index, decltype(__tuple)>;
-      formatter<remove_cvref_t<_Args>, _CharT> __underlying;
-
-      // [format.tuple]/7
-      //   ... For each element e in underlying_, if e.set_debug_format()
-      //   is a valid expression, calls e.set_debug_format().
-      std::__set_debug_format(__underlying);
-#  else
       __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx));
-#  endif
     });
 
     return std::ranges::copy(__closing_bracket_, __ctx.out()).out;
@@ -164,14 +136,14 @@ private:
 };
 
 template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<pair<_Args...>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<pair<_Args...>, _CharT>
     : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {};
 
 template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<tuple<_Args...>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT>
     : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
 
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/parser_std_format_spec.h
@@ -16,23 +16,28 @@
 /// This header has some support for the chrono-format-spec since it doesn't
 /// affect the std-format-spec.
 
-#include <__algorithm/find_if.h>
+#include <__algorithm/copy_n.h>
 #include <__algorithm/min.h>
 #include <__assert>
 #include <__concepts/arithmetic.h>
 #include <__concepts/same_as.h>
 #include <__config>
-#include <__debug>
 #include <__format/format_arg.h>
 #include <__format/format_error.h>
 #include <__format/format_parse_context.h>
 #include <__format/format_string.h>
 #include <__format/unicode.h>
+#include <__format/width_estimation_table.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h> // iter_value_t
+#include <__memory/addressof.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_trivially_copyable.h>
 #include <__variant/monostate.h>
-#include <bit>
 #include <cstdint>
+#include <string>
 #include <string_view>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -43,24 +48,36 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __format_spec {
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void
+__throw_invalid_option_format_error(const char* __id, const char* __option) {
+  std::__throw_format_error(
+      (string("The format specifier for ") + __id + " does not allow the " + __option + " option").c_str());
+}
+
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) {
+  std::__throw_format_error(
+      (string("The type option contains an invalid value for ") + __id + " formatting argument").c_str());
+}
+
+template <contiguous_iterator _Iterator, class _ParseContext>
+_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) {
+  using _CharT = iter_value_t<_Iterator>;
   // This function is a wrapper to call the real parser. But it does the
   // validation for the pre-conditions and post-conditions.
   if (__begin == __end)
-    std::__throw_format_error("End of input while parsing format-spec arg-id");
+    std::__throw_format_error("End of input while parsing an argument index");
 
-  __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
+  __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __ctx);
 
-  if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
-    std::__throw_format_error("Invalid arg-id");
+  if (__r.__last == __end || *__r.__last != _CharT('}'))
+    std::__throw_format_error("The argument index is invalid");
 
-  ++__r.__ptr;
+  ++__r.__last;
   return __r;
 }
 
@@ -78,22 +95,33 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
   return _VSTD::__visit_format_arg(
       [](auto __arg) -> uint32_t {
         using _Type = decltype(__arg);
-        if constexpr (integral<_Type>) {
+        if constexpr (same_as<_Type, monostate>)
+          std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
+
+        // [format.string.std]/8
+        // If { arg-idopt } is used in a width or precision, the value of the
+        // corresponding formatting argument is used in its place. If the
+        // corresponding formatting argument is not of standard signed or unsigned
+        // integer type, or its value is negative for precision or non-positive for
+        // width, an exception of type format_error is thrown.
+        //
+        // When an integral is used in a format function, it is stored as one of
+        // the types checked below. Other integral types are promoted. For example,
+        // a signed char is stored as an int.
+        if constexpr (same_as<_Type, int> || same_as<_Type, unsigned int> || //
+                      same_as<_Type, long long> || same_as<_Type, unsigned long long>) {
           if constexpr (signed_integral<_Type>) {
             if (__arg < 0)
-              std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value");
+              std::__throw_format_error("An argument index may not have a negative value");
           }
 
           using _CT = common_type_t<_Type, decltype(__format::__number_max)>;
-          if (static_cast<_CT>(__arg) >
-              static_cast<_CT>(__format::__number_max))
-            std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value");
+          if (static_cast<_CT>(__arg) > static_cast<_CT>(__format::__number_max))
+            std::__throw_format_error("The value of the argument index exceeds its maximum value");
 
           return __arg;
-        } else if constexpr (same_as<_Type, monostate>)
-          std::__throw_format_error("Argument index out of bounds");
-        else
-          std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type");
+        } else
+          std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
       },
       __format_arg);
 }
@@ -104,42 +132,48 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
 /// explicitly.
 // TODO FMT Use an ABI tag for this struct.
 struct __fields {
-  uint8_t __sign_ : 1 {false};
-  uint8_t __alternate_form_ : 1 {false};
-  uint8_t __zero_padding_ : 1 {false};
-  uint8_t __precision_ : 1 {false};
-  uint8_t __locale_specific_form_ : 1 {false};
-  uint8_t __type_ : 1 {false};
+  uint16_t __sign_                 : 1 {false};
+  uint16_t __alternate_form_       : 1 {false};
+  uint16_t __zero_padding_         : 1 {false};
+  uint16_t __precision_            : 1 {false};
+  uint16_t __locale_specific_form_ : 1 {false};
+  uint16_t __type_                 : 1 {false};
   // Determines the valid values for fill.
   //
   // Originally the fill could be any character except { and }. Range-based
   // formatters use the colon to mark the beginning of the
   // underlying-format-spec. To avoid parsing ambiguities these formatter
   // specializations prohibit the use of the colon as a fill character.
-  uint8_t __allow_colon_in_fill_ : 1 {false};
+  uint16_t __use_range_fill_ : 1 {false};
+  uint16_t __clear_brackets_ : 1 {false};
+  uint16_t __consume_all_    : 1 {false};
 };
 
 // By not placing this constant in the formatter class it's not duplicated for
 // char and wchar_t.
+inline constexpr __fields __fields_bool{.__locale_specific_form_ = true, .__type_ = true, .__consume_all_ = true};
 inline constexpr __fields __fields_integral{
     .__sign_                 = true,
     .__alternate_form_       = true,
     .__zero_padding_         = true,
     .__locale_specific_form_ = true,
-    .__type_                 = true};
+    .__type_                 = true,
+    .__consume_all_          = true};
 inline constexpr __fields __fields_floating_point{
     .__sign_                 = true,
     .__alternate_form_       = true,
     .__zero_padding_         = true,
     .__precision_            = true,
     .__locale_specific_form_ = true,
-    .__type_                 = true};
-inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
-inline constexpr __fields __fields_pointer{.__type_ = true};
-
-#  if _LIBCPP_STD_VER > 20
-inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true};
-inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true};
+    .__type_                 = true,
+    .__consume_all_          = true};
+inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true, .__consume_all_ = true};
+inline constexpr __fields __fields_pointer{.__zero_padding_ = true, .__type_ = true, .__consume_all_ = true};
+
+#  if _LIBCPP_STD_VER >= 23
+inline constexpr __fields __fields_tuple{.__use_range_fill_ = true, .__clear_brackets_ = true};
+inline constexpr __fields __fields_range{.__use_range_fill_ = true, .__clear_brackets_ = true};
+inline constexpr __fields __fields_fill_align_width{};
 #  endif
 
 enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
@@ -164,7 +198,7 @@ enum class _LIBCPP_ENUM_VIS __sign : uint8_t {
 };
 
 enum class _LIBCPP_ENUM_VIS __type : uint8_t {
-  __default,
+  __default = 0,
   __string,
   __binary_lower_case,
   __binary_upper_case,
@@ -172,7 +206,8 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t {
   __decimal,
   __hexadecimal_lower_case,
   __hexadecimal_upper_case,
-  __pointer,
+  __pointer_lower_case,
+  __pointer_upper_case,
   __char,
   __hexfloat_lower_case,
   __hexfloat_upper_case,
@@ -185,6 +220,25 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t {
   __debug
 };
 
+_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __create_type_mask(__type __t) {
+  uint32_t __shift = static_cast<uint32_t>(__t);
+  if (__shift == 0)
+    return 1;
+
+  if (__shift > 31)
+    std::__throw_format_error("The type does not fit in the mask");
+
+  return 1 << __shift;
+}
+
+inline constexpr uint32_t __type_mask_integer =
+    __create_type_mask(__type::__binary_lower_case) |      //
+    __create_type_mask(__type::__binary_upper_case) |      //
+    __create_type_mask(__type::__decimal) |                //
+    __create_type_mask(__type::__octal) |                  //
+    __create_type_mask(__type::__hexadecimal_lower_case) | //
+    __create_type_mask(__type::__hexadecimal_upper_case);
+
 struct __std {
   __alignment __alignment_ : 3;
   __sign __sign_ : 2;
@@ -196,6 +250,7 @@ struct __std {
 struct __chrono {
   __alignment __alignment_ : 3;
   bool __locale_specific_form_ : 1;
+  bool __hour_                 : 1;
   bool __weekday_name_ : 1;
   bool __weekday_              : 1;
   bool __day_of_year_          : 1;
@@ -203,6 +258,25 @@ struct __chrono {
   bool __month_name_ : 1;
 };
 
+// The fill UCS scalar value.
+//
+// This is always an array, with 1, 2, or 4 elements.
+// The size of the data structure is always 32-bits.
+template <class _CharT>
+struct __code_point;
+
+template <>
+struct __code_point<char> {
+  char __data[4] = {' '};
+};
+
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+struct __code_point<wchar_t> {
+  wchar_t __data[4 / sizeof(wchar_t)] = {L' '};
+};
+#  endif
+
 /// Contains the parsed formatting specifications.
 ///
 /// This contains information for both the std-format-spec and the
@@ -238,7 +312,7 @@ struct __parsed_specifications {
   /// replaced with the value of that arg-id.
   int32_t __precision_;
 
-  _CharT __fill_;
+  __code_point<_CharT> __fill_;
 
   _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; }
 
@@ -265,48 +339,161 @@ static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>);
 template <class _CharT>
 class _LIBCPP_TEMPLATE_VIS __parser {
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields)
-      -> decltype(__parse_ctx.begin()) {
-
-    const _CharT* __begin = __parse_ctx.begin();
-    const _CharT* __end = __parse_ctx.end();
+  // Parses the format specification.
+  //
+  // Depending on whether the parsing is done compile-time or run-time
+  // the method slightly differs.
+  // - Only parses a field when it is in the __fields. Accepting all
+  //   fields and then validating the valid ones has a performance impact.
+  //   This is faster but gives slighly worse error messages.
+  // - At compile-time when a field is not accepted the parser will still
+  //   parse it and give an error when it's present. This gives a more
+  //   accurate error.
+  // The idea is that most times the format instead of the vformat
+  // functions are used. In that case the error will be detected during
+  // compilation and there is no need to pay for the run-time overhead.
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator __parse(_ParseContext& __ctx, __fields __fields) {
+    auto __begin = __ctx.begin();
+    auto __end   = __ctx.end();
     if (__begin == __end)
       return __begin;
 
-    if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end)
+    if (__parse_fill_align(__begin, __end, __fields.__use_range_fill_) && __begin == __end)
       return __begin;
 
-    if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end)
-      return __begin;
+    if (__fields.__sign_) {
+      if (__parse_sign(__begin) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_sign(__begin)) {
+      std::__throw_format_error("The format specification does not allow the sign option");
+    }
 
-    if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end)
-      return __begin;
+    if (__fields.__alternate_form_) {
+      if (__parse_alternate_form(__begin) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_alternate_form(__begin)) {
+      std::__throw_format_error("The format specifier does not allow the alternate form option");
+    }
 
-    if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end)
-      return __begin;
+    if (__fields.__zero_padding_) {
+      if (__parse_zero_padding(__begin) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_zero_padding(__begin)) {
+      std::__throw_format_error("The format specifier does not allow the zero-padding option");
+    }
 
-    if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end)
+    if (__parse_width(__begin, __end, __ctx) && __begin == __end)
       return __begin;
 
-    if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end)
-      return __begin;
+    if (__fields.__precision_) {
+      if (__parse_precision(__begin, __end, __ctx) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_precision(__begin, __end, __ctx)) {
+      std::__throw_format_error("The format specifier does not allow the precision option");
+    }
 
-    if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end)
-      return __begin;
+    if (__fields.__locale_specific_form_) {
+      if (__parse_locale_specific_form(__begin) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_locale_specific_form(__begin)) {
+      std::__throw_format_error("The format specifier does not allow the locale-specific form option");
+    }
+
+    if (__fields.__clear_brackets_) {
+      if (__parse_clear_brackets(__begin) && __begin == __end)
+        return __begin;
+    } else if (std::is_constant_evaluated() && __parse_clear_brackets(__begin)) {
+      std::__throw_format_error("The format specifier does not allow the n option");
+    }
 
-    if (__fields.__type_) {
+    if (__fields.__type_)
       __parse_type(__begin);
 
-      // When __type_ is false the calling parser is expected to do additional
-      // parsing. In that case that parser should do the end of format string
-      // validation.
-      if (__begin != __end && *__begin != _CharT('}'))
-        std::__throw_format_error("The format-spec should consume the input or end with a '}'");
-    }
+    if (!__fields.__consume_all_)
+      return __begin;
+
+    if (__begin != __end && *__begin != _CharT('}'))
+      std::__throw_format_error("The format specifier should consume the input or end with a '}'");
 
     return __begin;
   }
 
+  // Validates the selected the parsed data.
+  //
+  // The valid fields in the parser may depend on the display type
+  // selected. But the type is the last optional field, so by the time
+  // it's known an option can't be used, it already has been parsed.
+  // This does the validation again.
+  //
+  // For example an integral may have a sign, zero-padding, or alternate
+  // form when the type option is not 'c'. So the generic approach is:
+  //
+  // typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
+  // if (__parser.__type_ == __format_spec::__type::__char) {
+  //   __parser.__validate((__format_spec::__fields_bool, "an integer");
+  //   ... // more char adjustments
+  // } else {
+  //   ... // validate an integral type.
+  // }
+  //
+  // For some types all valid options need a second validation run, like
+  // boolean types.
+  //
+  // Depending on whether the validation is done at compile-time or
+  // run-time the error differs
+  // - run-time the exception is thrown and contains the type of field
+  //   being validated.
+  // - at compile-time the line with `std::__throw_format_error` is shown
+  //   in the output. In that case it's important for the error to be on one
+  //   line.
+  // Note future versions of C++ may allow better compile-time error
+  // reporting.
+  _LIBCPP_HIDE_FROM_ABI constexpr void
+  __validate(__fields __fields, const char* __id, uint32_t __type_mask = -1) const {
+    if (!__fields.__sign_ && __sign_ != __sign::__default) {
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier does not allow the sign option");
+      else
+        __format_spec::__throw_invalid_option_format_error(__id, "sign");
+    }
+
+    if (!__fields.__alternate_form_ && __alternate_form_) {
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier does not allow the alternate form option");
+      else
+        __format_spec::__throw_invalid_option_format_error(__id, "alternate form");
+    }
+
+    if (!__fields.__zero_padding_ && __alignment_ == __alignment::__zero_padding) {
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier does not allow the zero-padding option");
+      else
+        __format_spec::__throw_invalid_option_format_error(__id, "zero-padding");
+    }
+
+    if (!__fields.__precision_ && __precision_ != -1) { // Works both when the precision has a value or an arg-id.
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier does not allow the precision option");
+      else
+        __format_spec::__throw_invalid_option_format_error(__id, "precision");
+    }
+
+    if (!__fields.__locale_specific_form_ && __locale_specific_form_) {
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier does not allow the locale-specific form option");
+      else
+        __format_spec::__throw_invalid_option_format_error(__id, "locale-specific form");
+    }
+
+    if ((__create_type_mask(__type_) & __type_mask) == 0) {
+      if (std::is_constant_evaluated())
+        std::__throw_format_error("The format specifier uses an invalid value for the type option");
+      else
+        __format_spec::__throw_invalid_type_format_error(__id);
+    }
+  }
+
   /// \returns the `__parsed_specifications` with the resolved dynamic sizes..
   _LIBCPP_HIDE_FROM_ABI
   __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const {
@@ -326,6 +513,7 @@ public:
         .__chrono_ =
             __chrono{.__alignment_            = __alignment_,
                      .__locale_specific_form_ = __locale_specific_form_,
+                     .__hour_                 = __hour_,
                      .__weekday_name_         = __weekday_name_,
                      .__weekday_              = __weekday_,
                      .__day_of_year_          = __day_of_year_,
@@ -340,11 +528,13 @@ public:
   __sign __sign_ : 2 {__sign::__default};
   bool __alternate_form_ : 1 {false};
   bool __locale_specific_form_ : 1 {false};
-  bool __reserved_0_ : 1 {false};
+  bool __clear_brackets_       : 1 {false};
   __type __type_{__type::__default};
 
   // These flags are only used for formatting chrono. Since the struct has
   // padding space left it's added to this structure.
+  bool __hour_ : 1 {false};
+
   bool __weekday_name_ : 1 {false};
   bool __weekday_      : 1 {false};
 
@@ -353,8 +543,8 @@ public:
 
   bool __month_name_ : 1 {false};
 
-  uint8_t __reserved_1_ : 3 {0};
-  uint8_t __reserved_2_ : 6 {0};
+  uint8_t __reserved_0_ : 2 {0};
+  uint8_t __reserved_1_ : 6 {0};
   // These two flags are only used internally and not part of the
   // __parsed_specifications. Therefore put them at the end.
   bool __width_as_arg_ : 1 {false};
@@ -366,11 +556,7 @@ public:
   /// The requested precision, either the value or the arg-id.
   int32_t __precision_{-1};
 
-  // LWG 3576 will probably change this to always accept a Unicode code point
-  // To avoid changing the size with that change align the field so when it
-  // becomes 32-bit its alignment will remain the same. That also means the
-  // size will remain the same. (D2572 addresses the solution for LWG 3576.)
-  _CharT __fill_{_CharT(' ')};
+  __code_point<_CharT> __fill_{};
 
 private:
   _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) {
@@ -390,19 +576,90 @@ private:
     return false;
   }
 
+  _LIBCPP_HIDE_FROM_ABI constexpr void __validate_fill_character(_CharT __fill, bool __use_range_fill) {
+    // The forbidden fill characters all code points formed from a single code unit, thus the
+    // check can be omitted when more code units are used.
+    if (__use_range_fill && (__fill == _CharT('{') || __fill == _CharT('}') || __fill == _CharT(':')))
+      std::__throw_format_error("The fill option contains an invalid value");
+    else if (__fill == _CharT('{') || __fill == _CharT('}'))
+      std::__throw_format_error("The fill option contains an invalid value");
+  }
+
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+  // range-fill and tuple-fill are identical
+  template <contiguous_iterator _Iterator>
+    requires same_as<_CharT, char>
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+          || (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
+#    endif
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
+                                 "when called with an empty input the function will cause "
+                                 "undefined behavior by evaluating data not in the input");
+    __unicode::__code_point_view<_CharT> __view{__begin, __end};
+    __unicode::__consume_result __consumed = __view.__consume();
+    if (__consumed.__status != __unicode::__consume_result::__ok)
+      std::__throw_format_error("The format specifier contains malformed Unicode characters");
+
+    if (__view.__position() < __end && __parse_alignment(*__view.__position())) {
+      ptrdiff_t __code_units = __view.__position() - __begin;
+      if (__code_units == 1)
+        // The forbidden fill characters all are code points encoded
+        // in one code unit, thus the check can be omitted when more
+        // code units are used.
+        __validate_fill_character(*__begin, __use_range_fill);
+
+      std::copy_n(__begin, __code_units, std::addressof(__fill_.__data[0]));
+      __begin += __code_units + 1;
+      return true;
+    }
+
+    if (!__parse_alignment(*__begin))
+      return false;
+
+    ++__begin;
+    return true;
+  }
+
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+  template <contiguous_iterator _Iterator>
+    requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
+                                 "when called with an empty input the function will cause "
+                                 "undefined behavior by evaluating data not in the input");
+    if (__begin + 1 != __end && __parse_alignment(*(__begin + 1))) {
+      if (!__unicode::__is_scalar_value(*__begin))
+        std::__throw_format_error("The fill option contains an invalid value");
+
+      __validate_fill_character(*__begin, __use_range_fill);
+
+      __fill_.__data[0] = *__begin;
+      __begin += 2;
+      return true;
+    }
+
+    if (!__parse_alignment(*__begin))
+      return false;
+
+    ++__begin;
+    return true;
+  }
+
+#    endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+#  else // _LIBCPP_HAS_NO_UNICODE
   // range-fill and tuple-fill are identical
-  _LIBCPP_HIDE_FROM_ABI constexpr bool
-  __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) {
-    _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
-                                     "undefined behavior by evaluating data not in the input");
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
+                                 "when called with an empty input the function will cause "
+                                 "undefined behavior by evaluating data not in the input");
     if (__begin + 1 != __end) {
       if (__parse_alignment(*(__begin + 1))) {
-        if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':')))
-          std::__throw_format_error("The format-spec range-fill field contains an invalid character");
-        else if (*__begin == _CharT('{') || *__begin == _CharT('}'))
-          std::__throw_format_error("The format-spec fill field contains an invalid character");
+        __validate_fill_character(*__begin, __use_range_fill);
 
-        __fill_ = *__begin;
+        __fill_.__data[0] = *__begin;
         __begin += 2;
         return true;
       }
@@ -415,7 +672,10 @@ private:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) {
+#  endif // _LIBCPP_HAS_NO_UNICODE
+
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) {
     switch (*__begin) {
     case _CharT('-'):
       __sign_ = __sign::__minus;
@@ -433,7 +693,8 @@ private:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(_Iterator& __begin) {
     if (*__begin != _CharT('#'))
       return false;
 
@@ -442,7 +703,8 @@ private:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(_Iterator& __begin) {
     if (*__begin != _CharT('0'))
       return false;
 
@@ -452,15 +714,16 @@ private:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __ctx) {
     if (*__begin == _CharT('0'))
-      std::__throw_format_error("A format-spec width field shouldn't have a leading zero");
+      std::__throw_format_error("The width option should not have a leading zero");
 
     if (*__begin == _CharT('{')) {
-      __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
+      __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __ctx);
       __width_as_arg_ = true;
       __width_ = __r.__value;
-      __begin = __r.__ptr;
+      __begin = __r.__last;
       return true;
     }
 
@@ -469,40 +732,41 @@ private:
 
     __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
     __width_ = __r.__value;
-    _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, "
-                                  "due to validations in this function");
-    __begin = __r.__ptr;
+    _LIBCPP_ASSERT_UNCATEGORIZED(__width_ != 0, "A zero value isn't allowed and should be impossible, "
+                                                "due to validations in this function");
+    __begin = __r.__last;
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end,
-                                                         auto& __parse_ctx) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(_Iterator& __begin, _Iterator __end, auto& __ctx) {
     if (*__begin != _CharT('.'))
       return false;
 
     ++__begin;
     if (__begin == __end)
-      std::__throw_format_error("End of input while parsing format-spec precision");
+      std::__throw_format_error("End of input while parsing format specifier precision");
 
     if (*__begin == _CharT('{')) {
-      __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
+      __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __ctx);
       __precision_as_arg_ = true;
       __precision_ = __arg_id.__value;
-      __begin = __arg_id.__ptr;
+      __begin = __arg_id.__last;
       return true;
     }
 
     if (*__begin < _CharT('0') || *__begin > _CharT('9'))
-      std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id");
+      std::__throw_format_error("The precision option does not contain a value or an argument index");
 
     __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
     __precision_ = __r.__value;
     __precision_as_arg_ = false;
-    __begin = __r.__ptr;
+    __begin = __r.__last;
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(_Iterator& __begin) {
     if (*__begin != _CharT('L'))
       return false;
 
@@ -511,7 +775,18 @@ private:
     return true;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_clear_brackets(_Iterator& __begin) {
+    if (*__begin != _CharT('n'))
+      return false;
+
+    __clear_brackets_ = true;
+    ++__begin;
+    return true;
+  }
+
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) {
     // Determines the type. It does not validate whether the selected type is
     // valid. Most formatters have optional fields that are only allowed for
     // certain types. These parsers need to do validation after the type has
@@ -561,7 +836,10 @@ private:
       __type_ = __type::__octal;
       break;
     case 'p':
-      __type_ = __type::__pointer;
+      __type_ = __type::__pointer_lower_case;
+      break;
+    case 'P':
+      __type_ = __type::__pointer_upper_case;
       break;
     case 's':
       __type_ = __type::__string;
@@ -569,7 +847,7 @@ private:
     case 'x':
       __type_ = __type::__hexadecimal_lower_case;
       break;
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
     case '?':
       __type_ = __type::__debug;
       break;
@@ -611,36 +889,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for a string argument");
+    std::__throw_format_error("The type option contains an invalid value for a string formatting argument");
   }
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) {
-  if (__parser.__sign_ != __sign::__default)
-    std::__throw_format_error("A sign field isn't allowed in this format-spec");
-
-  if (__parser.__alternate_form_)
-    std::__throw_format_error("An alternate form field isn't allowed in this format-spec");
-
-  if (__parser.__alignment_ == __alignment::__zero_padding)
-    std::__throw_format_error("A zero-padding field isn't allowed in this format-spec");
-
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser, const char* __id) {
+  __parser.__validate(__format_spec::__fields_bool, __id);
   if (__parser.__alignment_ == __alignment::__default)
     __parser.__alignment_ = __alignment::__left;
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) {
-  __format_spec::__process_display_type_bool_string(__parser);
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser, const char* __id) {
+  __format_spec::__process_display_type_bool_string(__parser, __id);
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser, const char* __id) {
   switch (__parser.__type_) {
   case __format_spec::__type::__default:
   case __format_spec::__type::__string:
-    __format_spec::__process_display_type_bool_string(__parser);
+    __format_spec::__process_display_type_bool_string(__parser, __id);
     break;
 
   case __format_spec::__type::__binary_lower_case:
@@ -652,17 +922,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for a bool argument");
+    __format_spec::__throw_invalid_type_format_error(__id);
   }
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser, const char* __id) {
   switch (__parser.__type_) {
   case __format_spec::__type::__default:
   case __format_spec::__type::__char:
   case __format_spec::__type::__debug:
-    __format_spec::__process_display_type_char(__parser);
+    __format_spec::__process_display_type_char(__parser, __id);
     break;
 
   case __format_spec::__type::__binary_lower_case:
@@ -674,12 +944,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for a char argument");
+    __format_spec::__throw_invalid_type_format_error(__id);
   }
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser, const char* __id) {
   switch (__parser.__type_) {
   case __format_spec::__type::__default:
   case __format_spec::__type::__binary_lower_case:
@@ -691,16 +961,16 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>&
     break;
 
   case __format_spec::__type::__char:
-    __format_spec::__process_display_type_char(__parser);
+    __format_spec::__process_display_type_char(__parser, __id);
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for an integer argument");
+    __format_spec::__throw_invalid_type_format_error(__id);
   }
 }
 
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser, const char* __id) {
   switch (__parser.__type_) {
   case __format_spec::__type::__default:
   case __format_spec::__type::__hexfloat_lower_case:
@@ -719,33 +989,34 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_C
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument");
+    __format_spec::__throw_invalid_type_format_error(__id);
   }
 }
 
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type, const char* __id) {
   switch (__type) {
   case __format_spec::__type::__default:
-  case __format_spec::__type::__pointer:
+  case __format_spec::__type::__pointer_lower_case:
+  case __format_spec::__type::__pointer_upper_case:
     break;
 
   default:
-    std::__throw_format_error("The format-spec type has a type not supported for a pointer argument");
+    __format_spec::__throw_invalid_type_format_error(__id);
   }
 }
 
-template <class _CharT>
+template <contiguous_iterator _Iterator>
 struct __column_width_result {
   /// The number of output columns.
   size_t __width_;
   /// One beyond the last code unit used in the estimation.
   ///
   /// This limits the original output to fit in the wanted number of columns.
-  const _CharT* __last_;
+  _Iterator __last_;
 };
 
-template <class _CharT>
-__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>;
 
 /// Since a column width can be two it's possible that the requested column
 /// width can't be achieved. Depending on the intended usage the policy can be
@@ -761,66 +1032,16 @@ enum class __column_width_rounding { __down, __up };
 #  ifndef _LIBCPP_HAS_NO_UNICODE
 
 namespace __detail {
-
-/// Converts a code point to the column width.
-///
-/// The estimations are conforming to [format.string.general]/11
-///
-/// This version expects a value less than 0x1'0000, which is a 3-byte UTF-8
-/// character.
-_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_3(uint32_t __c) noexcept {
-  _LIBCPP_ASSERT(__c < 0x10000, "Use __column_width_4 or __column_width for larger values");
-
-  // clang-format off
-  return 1 + (__c >= 0x1100 && (__c <= 0x115f ||
-             (__c >= 0x2329 && (__c <= 0x232a ||
-             (__c >= 0x2e80 && (__c <= 0x303e ||
-             (__c >= 0x3040 && (__c <= 0xa4cf ||
-             (__c >= 0xac00 && (__c <= 0xd7a3 ||
-             (__c >= 0xf900 && (__c <= 0xfaff ||
-             (__c >= 0xfe10 && (__c <= 0xfe19 ||
-             (__c >= 0xfe30 && (__c <= 0xfe6f ||
-             (__c >= 0xff00 && (__c <= 0xff60 ||
-             (__c >= 0xffe0 && (__c <= 0xffe6
-             ))))))))))))))))))));
-  // clang-format on
-}
-
-/// @overload
-///
-/// This version expects a value greater than or equal to 0x1'0000, which is a
-/// 4-byte UTF-8 character.
-_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_4(uint32_t __c) noexcept {
-  _LIBCPP_ASSERT(__c >= 0x10000, "Use __column_width_3 or __column_width for smaller values");
-
-  // clang-format off
-  return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f ||
-             (__c >= 0x1'f900 && (__c <= 0x1'f9ff ||
-             (__c >= 0x2'0000 && (__c <= 0x2'fffd ||
-             (__c >= 0x3'0000 && (__c <= 0x3'fffd
-             ))))))));
-  // clang-format on
-}
-
-/// @overload
-///
-/// The general case, accepting all values.
-_LIBCPP_HIDE_FROM_ABI constexpr int __column_width(uint32_t __c) noexcept {
-  if (__c < 0x10000)
-    return __detail::__column_width_3(__c);
-
-  return __detail::__column_width_4(__c);
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering(
-    const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width_grapheme_clustering(
+    _Iterator __first, _Iterator __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+  using _CharT = iter_value_t<_Iterator>;
   __unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last};
 
-  __column_width_result<_CharT> __result{0, __first};
+  __column_width_result<_Iterator> __result{0, __first};
   while (__result.__last_ != __last && __result.__width_ <= __maximum) {
     typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume();
-    int __width = __detail::__column_width(__cluster.__code_point_);
+    int __width = __width_estimation_table::__estimated_width(__cluster.__code_point_);
 
     // When the next entry would exceed the maximum width the previous width
     // might be returned. For example when a width of 100 is requested the
@@ -884,8 +1105,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ascii(char32_t __c) { return __c < 0x8
 /// \param __rounding Selects the rounding method.
 ///                   \c __down result.__width_ <= __maximum
 ///                   \c __up result.__width_ <= __maximum + 1
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width(
+template <class _CharT, class _Iterator = typename basic_string_view<_CharT>::const_iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width(
     basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept {
   // The width estimation is done in two steps:
   // - Quickly process for the ASCII part. ASCII has the following properties
@@ -904,7 +1125,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
   // need to scan one code unit beyond the requested precision. When this code
   // unit is non-ASCII we omit the current code unit and let the Grapheme
   // clustering algorithm do its work.
-  const _CharT* __it = __str.begin();
+  auto __it = __str.begin();
   if (__format_spec::__is_ascii(*__it)) {
     do {
       --__maximum;
@@ -932,7 +1153,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
 }
 #  else // !defined(_LIBCPP_HAS_NO_UNICODE)
 template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<typename basic_string_view<_CharT>::const_iterator>
 __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept {
   // When Unicode isn't supported assume ASCII and every code unit is one code
   // point. In ASCII the estimated column width is always one. Thus there's no
@@ -945,7 +1166,7 @@ __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __col
 
 } // namespace __format_spec
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/range_default_formatter.h
@@ -14,22 +14,25 @@
 #  pragma GCC system_header
 #endif
 
-#include <__availability>
+#include <__algorithm/ranges_copy.h>
 #include <__chrono/statically_widen.h>
 #include <__concepts/same_as.h>
 #include <__config>
 #include <__format/concepts.h>
 #include <__format/formatter.h>
 #include <__format/range_formatter.h>
+#include <__iterator/back_insert_iterator.h>
 #include <__ranges/concepts.h>
+#include <__ranges/data.h>
+#include <__ranges/size.h>
+#include <__type_traits/conditional.h>
 #include <__type_traits/remove_cvref.h>
 #include <__utility/pair.h>
 #include <string_view>
-#include <tuple>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 template <class _Rp, class _CharT>
 concept __const_formattable_range =
@@ -83,40 +86,23 @@ inline constexpr range_format format_kind<_Rp> = [] {
     return range_format::sequence;
 }();
 
-// This is a non-standard work-around to fix instantiation of
-//   formatter<const _CharT[N], _CharT>
-// const _CharT[N] satisfies the ranges::input_range concept.
-// remove_cvref_t<const _CharT[N]> is _CharT[N] so it does not satisfy the
-// requirement of the above specialization. Instead it will instantiate the
-// primary template, which is ill-formed.
-//
-// An alternative solution is to remove the offending formatter.
-//
-// https://godbolt.org/z/bqjhhaexx
-//
-// The removal is proposed in LWG3833, but use the work-around until the issue
-// has been adopted.
-// TODO FMT Implement LWG3833.
-template <class _CharT, size_t N>
-inline constexpr range_format format_kind<const _CharT[N]> = range_format::disabled;
-
 template <range_format _Kp, ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter;
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter;
 
 // Required specializations
 
 template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> {
 private:
   using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
   range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
     __underlying_.set_separator(__separator);
   }
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
     __underlying_.set_brackets(__opening_bracket, __closing_bracket);
   }
 
@@ -125,14 +111,15 @@ public:
     return __underlying_.parse(__ctx);
   }
 
-  template <class FormatContext>
-  _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const {
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(__maybe_const_r& __range, _FormatContext& __ctx) const {
     return __underlying_.format(__range, __ctx);
   }
 };
 
 template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> {
 private:
   using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>;
   using __element_type    = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
@@ -160,7 +147,7 @@ public:
 };
 
 template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> {
 private:
   using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>;
   using __element_type    = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
@@ -185,16 +172,48 @@ public:
 
 template <range_format _Kp, ranges::input_range _Rp, class _CharT>
   requires(_Kp == range_format::string || _Kp == range_format::debug_string)
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> {
-  __range_default_formatter() = delete; // TODO FMT Implement
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<_Kp, _Rp, _CharT> {
+private:
+  // This deviates from the Standard, there the exposition only type is
+  //   formatter<basic_string<charT>, charT> underlying_;
+  // Using a string_view allows the format function to avoid a copy of the
+  // input range when it is a contigious range.
+  formatter<basic_string_view<_CharT>, _CharT> __underlying_;
+
+public:
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    typename _ParseContext::iterator __i = __underlying_.parse(__ctx);
+    if constexpr (_Kp == range_format::debug_string)
+      __underlying_.set_debug_format();
+    return __i;
+  }
+
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(conditional_t<ranges::input_range<const _Rp>, const _Rp&, _Rp&> __range, _FormatContext& __ctx) const {
+    // When the range is contiguous use a basic_string_view instead to avoid a
+    // copy of the underlying data. The basic_string_view formatter
+    // specialization is the "basic" string formatter in libc++.
+    if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>)
+      return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx);
+    else {
+      // P2106's from_range has not been implemented yet. Instead use a simple
+      // copy operation.
+      // TODO FMT use basic_string's "from_range" constructor.
+      // return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx);
+      basic_string<_CharT> __str;
+      std::ranges::copy(__range, back_insert_iterator{__str});
+      return __underlying_.format(static_cast<basic_string_view<_CharT>>(__str), __ctx);
+    }
+  }
 };
 
 template <ranges::input_range _Rp, class _CharT>
   requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
-    : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
 
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/range_formatter.h
@@ -15,13 +15,11 @@
 #endif
 
 #include <__algorithm/ranges_copy.h>
-#include <__availability>
 #include <__chrono/statically_widen.h>
 #include <__concepts/same_as.h>
 #include <__config>
 #include <__format/buffer.h>
 #include <__format/concepts.h>
-#include <__format/format_args.h>
 #include <__format/format_context.h>
 #include <__format/format_error.h>
 #include <__format/formatter.h>
@@ -36,54 +34,73 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 template <class _Tp, class _CharT = char>
   requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
-  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+struct _LIBCPP_TEMPLATE_VIS range_formatter {
+  _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
     __separator_ = __separator;
   }
   _LIBCPP_HIDE_FROM_ABI constexpr void
-  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+  set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
     __opening_bracket_ = __opening_bracket;
     __closing_bracket_ = __closing_bracket;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; }
-  _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() noexcept { return __underlying_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const noexcept { return __underlying_; }
 
   template <class _ParseContext>
-  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
-    const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
-    const _CharT* __end   = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_range);
+    auto __end   = __ctx.end();
+    // Note the cases where __begin == __end in this code only happens when the
+    // replacement-field has no terminating }, or when the parse is manually
+    // called with a format-spec. The former is an error and the latter means
+    // using a formatter without the format functions or print.
+    if (__begin == __end) [[unlikely]]
+      return __parse_empty_range_underlying_spec(__ctx, __begin);
 
     // The n field overrides a possible m type, therefore delay applying the
     // effect of n until the type has been procesed.
-    bool __clear_brackets = (*__begin == _CharT('n'));
-    if (__clear_brackets) {
-      ++__begin;
-      if (__begin == __end) {
-        // Since there is no more data, clear the brackets before returning.
-        set_brackets({}, {});
-        return __begin;
-      }
-    }
-
     __parse_type(__begin, __end);
-    if (__clear_brackets)
+    if (__parser_.__clear_brackets_)
       set_brackets({}, {});
-    if (__begin == __end)
-      return __begin;
+    if (__begin == __end) [[unlikely]]
+      return __parse_empty_range_underlying_spec(__ctx, __begin);
 
     bool __has_range_underlying_spec = *__begin == _CharT(':');
+    if (__has_range_underlying_spec) {
+      // range-underlying-spec:
+      //   :  format-spec
+      ++__begin;
+    } else if (__begin != __end && *__begin != _CharT('}'))
+      // When there is no underlaying range the current parse should have
+      // consumed the format-spec. If not, the not consumed input will be
+      // processed by the underlying. For example {:-} for a range in invalid,
+      // the sign field is not present. Without this check the underlying_ will
+      // get -} as input which my be valid.
+      std::__throw_format_error("The format specifier should consume the input or end with a '}'");
+
+    __ctx.advance_to(__begin);
+    __begin = __underlying_.parse(__ctx);
+
+    // This test should not be required if __has_range_underlying_spec is false.
+    // However this test makes sure the underlying formatter left the parser in
+    // a valid state. (Note this is not a full protection against evil parsers.
+    // For example
+    //   } this is test for the next argument {}
+    //   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
+    // could consume more than it should.
+    if (__begin != __end && *__begin != _CharT('}'))
+      std::__throw_format_error("The format specifier should consume the input or end with a '}'");
+
     if (__parser_.__type_ != __format_spec::__type::__default) {
       // [format.range.formatter]/6
       //   If the range-type is s or ?s, then there shall be no n option and no
       //   range-underlying-spec.
-      if (__clear_brackets) {
+      if (__parser_.__clear_brackets_) {
         if (__parser_.__type_ == __format_spec::__type::__string)
           std::__throw_format_error("The n option and type s can't be used together");
         std::__throw_format_error("The n option and type ?s can't be used together");
@@ -96,20 +113,6 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
     } else if (!__has_range_underlying_spec)
       std::__set_debug_format(__underlying_);
 
-    if (__has_range_underlying_spec) {
-      // range-underlying-spec:
-      //   :  format-spec
-      ++__begin;
-      if (__begin == __end)
-        return __begin;
-
-      __parse_ctx.advance_to(__begin);
-      __begin = __underlying_.parse(__parse_ctx);
-    }
-
-    if (__begin != __end && *__begin != _CharT('}'))
-      std::__throw_format_error("The format-spec should consume the input or end with a '}'");
-
     return __begin;
   }
 
@@ -211,7 +214,8 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
   __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
 
 private:
-  _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) {
+  template <contiguous_iterator _Iterator>
+  _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin, _Iterator __end) {
     switch (*__begin) {
     case _CharT('m'):
       if constexpr (__fmt_pair_like<_Tp>) {
@@ -219,7 +223,7 @@ private:
         set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", "));
         ++__begin;
       } else
-        std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple");
+        std::__throw_format_error("Type m requires a pair or a tuple with two elements");
       break;
 
     case _CharT('s'):
@@ -227,28 +231,39 @@ private:
         __parser_.__type_ = __format_spec::__type::__string;
         ++__begin;
       } else
-        std::__throw_format_error("The range-format-spec type s requires formatting a character type");
+        std::__throw_format_error("Type s requires character type as formatting argument");
       break;
 
     case _CharT('?'):
       ++__begin;
       if (__begin == __end || *__begin != _CharT('s'))
-        std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+        std::__throw_format_error("The format specifier should consume the input or end with a '}'");
       if constexpr (same_as<_Tp, _CharT>) {
         __parser_.__type_ = __format_spec::__type::__debug;
         ++__begin;
       } else
-        std::__throw_format_error("The range-format-spec type ?s requires formatting a character type");
+        std::__throw_format_error("Type ?s requires character type as formatting argument");
     }
   }
 
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
+  __parse_empty_range_underlying_spec(_ParseContext& __ctx, typename _ParseContext::iterator __begin) {
+    __ctx.advance_to(__begin);
+    [[maybe_unused]] typename _ParseContext::iterator __result = __underlying_.parse(__ctx);
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __result == __begin,
+        "the underlying's parse function should not advance the input beyond the end of the input");
+    return __begin;
+  }
+
   formatter<_Tp, _CharT> __underlying_;
   basic_string_view<_CharT> __separator_       = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
   basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "[");
   basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
 };
 
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/unicode.h
@@ -11,11 +11,13 @@
 #define _LIBCPP___FORMAT_UNICODE_H
 
 #include <__assert>
+#include <__bit/countl.h>
+#include <__concepts/same_as.h>
 #include <__config>
 #include <__format/extended_grapheme_cluster_table.h>
-#include <__type_traits/make_unsigned.h>
-#include <__utility/unreachable.h>
-#include <bit>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
+#include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -23,27 +25,32 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace __unicode {
 
-#  if _LIBCPP_STD_VER > 20
-
-/// The result of consuming a code point using P2286' semantics
-///
-/// TODO FMT Combine __consume and  __consume_p2286 in one function.
-struct __consume_p2286_result {
-  // A size of 0 means well formed. This to differenciate between
-  // a valid code point and a code unit that's invalid like 0b11111xxx.
-  int __ill_formed_size;
-
-  // If well formed the consumed code point.
-  // Otherwise the ill-formed code units as unsigned 8-bit values. They are
-  // stored in reverse order, to make it easier to extract the values.
-  char32_t __value;
+// Helper struct for the result of a consume operation.
+//
+// The status value for a correct code point is 0. This allows a valid value to
+// be used without masking.
+// When the decoding fails it know the number of code units affected. For the
+// current use-cases that value is not needed, therefore it is not stored.
+// The escape routine needs the number of code units for both a valid and
+// invalid character and keeps track of it itself. Doing it in this result
+// unconditionally would give some overhead when the value is unneeded.
+struct __consume_result {
+  // When __status == __ok it contains the decoded code point.
+  // Else it contains the replacement character U+FFFD
+  char32_t __code_point : 31;
+
+  enum : char32_t {
+    // Consumed a well-formed code point.
+    __ok = 0,
+    // Encountered invalid UTF-8
+    __error = 1
+  } __status : 1 {__ok};
 };
-
-#  endif // _LIBCPP_STD_VER > 20
+static_assert(sizeof(__consume_result) == sizeof(char32_t));
 
 #  ifndef _LIBCPP_HAS_NO_UNICODE
 
@@ -62,9 +69,41 @@ struct __consume_p2286_result {
 
 inline constexpr char32_t __replacement_character = U'\ufffd';
 
-_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) {
+// The error of a consume operation.
+//
+// This sets the code point to the replacement character. This code point does
+// not participate in the grapheme clustering, so grapheme clustering code can
+// ignore the error status and always use the code point.
+inline constexpr __consume_result __consume_result_error{__replacement_character, __consume_result::__error};
+
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_high_surrogate(char32_t __value) {
+  return __value >= 0xd800 && __value <= 0xdbff;
+}
+
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_low_surrogate(char32_t __value) {
+  return __value >= 0xdc00 && __value <= 0xdfff;
+}
+
+// https://www.unicode.org/glossary/#surrogate_code_point
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_surrogate(char32_t __value) {
+  return __value >= 0xd800 && __value <= 0xdfff;
+}
+
+// https://www.unicode.org/glossary/#code_point
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_code_point(char32_t __value) {
+  return __value <= 0x10ffff;
+}
+
+// https://www.unicode.org/glossary/#unicode_scalar_value
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_scalar_value(char32_t __value) {
+  return __unicode::__is_code_point(__value) && !__unicode::__is_surrogate(__value);
+}
+
+template <contiguous_iterator _Iterator>
+  requires same_as<iter_value_t<_Iterator>, char>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) {
   do {
-    if ((*__char & 0b1000'0000) != 0b1000'0000)
+    if ((*__char & 0b1100'0000) != 0b1000'0000)
       return false;
     --__count;
     ++__char;
@@ -82,133 +121,116 @@ class __code_point_view;
 /// UTF-8 specialization.
 template <>
 class __code_point_view<char> {
+  using _Iterator = basic_string_view<char>::const_iterator;
+
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
       : __first_(__first), __last_(__last) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
-  _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+  // https://www.unicode.org/versions/latest/ch03.pdf#G7404
+  // Based on Table 3-7, Well-Formed UTF-8 Byte Sequences
+  //
+  // Code Points        First Byte Second Byte Third Byte Fourth Byte  Remarks
+  // U+0000..U+007F     00..7F                                         U+0000..U+007F 1 code unit range
+  //                    C0..C1     80..BF                              invalid overlong encoding
+  // U+0080..U+07FF     C2..DF     80..BF                              U+0080..U+07FF 2 code unit range
+  //                    E0         80..9F      80..BF                  invalid overlong encoding
+  // U+0800..U+0FFF     E0         A0..BF      80..BF                  U+0800..U+FFFF 3 code unit range
+  // U+1000..U+CFFF     E1..EC     80..BF      80..BF
+  // U+D000..U+D7FF     ED         80..9F      80..BF
+  // U+D800..U+DFFF     ED         A0..BF      80..BF                  invalid encoding of surrogate code point
+  // U+E000..U+FFFF     EE..EF     80..BF      80..BF
+  //                    F0         80..8F      80..BF     80..BF       invalid overlong encoding
+  // U+10000..U+3FFFF   F0         90..BF      80..BF     80..BF       U+10000..U+10FFFF 4 code unit range
+  // U+40000..U+FFFFF   F1..F3     80..BF      80..BF     80..BF
+  // U+100000..U+10FFFF F4         80..8F      80..BF     80..BF
+  //                    F4         90..BF      80..BF     80..BF       U+110000.. invalid code point range
+  //
+  // Unlike other parsers, these invalid entries are tested after decoding.
+  // - The parser always needs to consume these code units
+  // - The code is optimized for well-formed UTF-8
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
 
     // Based on the number of leading 1 bits the number of code units in the
     // code point can be determined. See
     // https://en.wikipedia.org/wiki/UTF-8#Encoding
-    switch (_VSTD::countl_one(static_cast<unsigned char>(*__first_))) {
+    switch (std::countl_one(static_cast<unsigned char>(*__first_))) {
     case 0:
-      return *__first_++;
+      return {static_cast<unsigned char>(*__first_++)};
 
-    case 2:
+    case 2: {
       if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]]
         break;
-      else {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        return __value;
-      }
 
-    case 3:
-      if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
-        break;
-      else {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        return __value;
-      }
+      char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
 
-    case 4:
-      if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
-        break;
-      else {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        return __value;
-      }
-    }
-    // An invalid number of leading ones can be garbage or a code unit in the
-    // middle of a code point. By consuming one code unit the parser may get
-    // "in sync" after a few code units.
-    ++__first_;
-    return __replacement_character;
-  }
-
-#    if _LIBCPP_STD_VER > 20
-  _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+      // These values should be encoded in 1 UTF-8 code unit.
+      if (__value < 0x0080) [[unlikely]]
+        return __consume_result_error;
 
-    // Based on the number of leading 1 bits the number of code units in the
-    // code point can be determined. See
-    // https://en.wikipedia.org/wiki/UTF-8#Encoding
-    switch (std::countl_one(static_cast<unsigned char>(*__first_))) {
-    case 0:
-      return {0, static_cast<unsigned char>(*__first_++)};
+      return {__value};
+    }
 
-    case 2:
-      if (__last_ - __first_ < 2) [[unlikely]]
+    case 3: {
+      if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
         break;
 
-      if (__unicode::__is_continuation(__first_ + 1, 1)) {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        return {0, __value};
-      }
-      break;
+      char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
 
-    case 3:
-      if (__last_ - __first_ < 3) [[unlikely]]
-        break;
+      // These values should be encoded in 1 or 2 UTF-8 code units.
+      if (__value < 0x0800) [[unlikely]]
+        return __consume_result_error;
 
-      if (__unicode::__is_continuation(__first_ + 1, 2)) {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        return {0, __value};
-      }
-      break;
+      // A surrogate value is always encoded in 3 UTF-8 code units.
+      if (__unicode::__is_surrogate(__value)) [[unlikely]]
+        return __consume_result_error;
+
+      return {__value};
+    }
 
-    case 4:
-      if (__last_ - __first_ < 4) [[unlikely]]
+    case 4: {
+      if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
         break;
 
-      if (__unicode::__is_continuation(__first_ + 1, 3)) {
-        char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
-        __value <<= 6;
-        __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+      char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+      __value <<= 6;
+      __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
 
-        if (__value > 0x10FFFF) // Outside the valid Unicode range?
-          return {4, __value};
+      // These values should be encoded in 1, 2, or 3 UTF-8 code units.
+      if (__value < 0x10000) [[unlikely]]
+        return __consume_result_error;
 
-        return {0, __value};
-      }
-      break;
+      // A value too large is always encoded in 4 UTF-8 code units.
+      if (!__unicode::__is_code_point(__value)) [[unlikely]]
+        return __consume_result_error;
+
+      return {__value};
+    }
     }
     // An invalid number of leading ones can be garbage or a code unit in the
     // middle of a code point. By consuming one code unit the parser may get
     // "in sync" after a few code units.
-    return {1, static_cast<unsigned char>(*__first_++)};
+    ++__first_;
+    return __consume_result_error;
   }
-#    endif // _LIBCPP_STD_VER > 20
 
 private:
-  const char* __first_;
-  const char* __last_;
+  _Iterator __first_;
+  _Iterator __last_;
 };
 
 #    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -225,75 +247,48 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) {
 /// - 4 UTF-32 (for example Linux)
 template <>
 class __code_point_view<wchar_t> {
+  using _Iterator = typename basic_string_view<wchar_t>::const_iterator;
+
 public:
   static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value");
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
       : __first_(__first), __last_(__last) {}
 
-  _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
   _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
 
+    char32_t __value = static_cast<char32_t>(*__first_++);
     if constexpr (sizeof(wchar_t) == 2) {
-      char32_t __result = *__first_++;
-      // Is the code unit part of a surrogate pair? See
-      // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
-      if (__result >= 0xd800 && __result <= 0xDfff) {
-        // Malformed Unicode.
-        if (__first_ == __last_) [[unlikely]]
-          return __replacement_character;
-
-        __result -= 0xd800;
-        __result <<= 10;
-        __result += *__first_++ - 0xdc00;
-        __result += 0x10000;
-      }
-      return __result;
+      if (__unicode::__is_low_surrogate(__value)) [[unlikely]]
+        return __consume_result_error;
 
-    } else if constexpr (sizeof(wchar_t) == 4) {
-      char32_t __result = *__first_++;
-      if (__result > 0x10FFFF) [[unlikely]]
-        return __replacement_character;
-      return __result;
-    } else {
-      __libcpp_unreachable();
-    }
-  }
+      if (__unicode::__is_high_surrogate(__value)) {
+        if (__first_ == __last_ || !__unicode::__is_low_surrogate(static_cast<char32_t>(*__first_))) [[unlikely]]
+          return __consume_result_error;
 
-#      if _LIBCPP_STD_VER > 20
-  _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+        __value -= 0xd800;
+        __value <<= 10;
+        __value += static_cast<char32_t>(*__first_++) - 0xdc00;
+        __value += 0x10000;
 
-    char32_t __result = *__first_++;
-    if constexpr (sizeof(wchar_t) == 2) {
-      // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
-      if (__is_surrogate_pair_high(__result)) {
-        // Malformed Unicode.
-        if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]]
-          return {1, __result};
-
-        __result -= 0xd800;
-        __result <<= 10;
-        __result += *__first_++ - 0xdc00;
-        __result += 0x10000;
-      } else if (__is_surrogate_pair_low(__result))
-        // A code point shouldn't start with the low surrogate pair
-        return {1, __result};
+        if (!__unicode::__is_code_point(__value)) [[unlikely]]
+          return __consume_result_error;
+      }
     } else {
-      if (__result > 0x10FFFF) [[unlikely]]
-        return {1, __result};
+      if (!__unicode::__is_scalar_value(__value)) [[unlikely]]
+        return __consume_result_error;
     }
 
-    return {0, __result};
+    return {__value};
   }
-#      endif // _LIBCPP_STD_VER > 20
 
 private:
-  const wchar_t* __first_;
-  const wchar_t* __last_;
+  _Iterator __first_;
+  _Iterator __last_;
 };
 #    endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
@@ -310,8 +305,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break(
 
   // *** Break at the start and end of text, unless the text is empty. ***
 
-  _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1
-  _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller");      // GB2
+  _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__sot, "should be handled in the constructor"); // GB1
+  _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__eot, "should be handled by our caller");      // GB2
 
   // *** Do not break between a CR and LF. Otherwise, break before and after controls. ***
   if (__prev == __property::__CR && __next == __property::__LF) // GB3
@@ -384,10 +379,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break(
 /// Therefore only this code point is extracted.
 template <class _CharT>
 class __extended_grapheme_cluster_view {
+  using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last)
       : __code_point_view_(__first, __last),
-        __next_code_point_(__code_point_view_.__consume()),
+        __next_code_point_(__code_point_view_.__consume().__code_point),
         __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {}
 
   struct __cluster {
@@ -401,13 +398,14 @@ public:
     ///
     /// It's expected the caller has the start position and thus can determine
     /// the code unit range of the extended grapheme cluster.
-    const _CharT* __last_;
+    _Iterator __last_;
   };
 
   _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() {
-    _LIBCPP_ASSERT(
+    _LIBCPP_ASSERT_UNCATEGORIZED(
         __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot,
         "can't move beyond the end of input");
+
     char32_t __code_point = __next_code_point_;
     if (!__code_point_view_.__at_end())
       return {__code_point, __get_break()};
@@ -422,17 +420,17 @@ private:
   char32_t __next_code_point_;
   __extended_grapheme_custer_property_boundary::__property __next_prop_;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() {
     bool __ri_break_allowed         = true;
     bool __has_extened_pictographic = false;
     while (true) {
-      const _CharT* __result                                          = __code_point_view_.__position();
+      _Iterator __result                                              = __code_point_view_.__position();
       __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_;
       if (__code_point_view_.__at_end()) {
         __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot;
         return __result;
       }
-      __next_code_point_ = __code_point_view_.__consume();
+      __next_code_point_ = __code_point_view_.__consume().__code_point;
       __next_prop_       = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_);
 
       __has_extened_pictographic |=
@@ -444,8 +442,8 @@ private:
   }
 };
 
-template <class _CharT>
-__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>;
+template <contiguous_iterator _Iterator>
+__extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>;
 
 #  else //  _LIBCPP_HAS_NO_UNICODE
 
@@ -453,36 +451,30 @@ __extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_gra
 // This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define.
 template <class _CharT>
 class __code_point_view {
+  using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
 public:
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
       : __first_(__first), __last_(__last) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; }
-
-  _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
-    return *__first_++;
-  }
-
-#    if _LIBCPP_STD_VER > 20
-  _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
-    _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+  _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
 
-    return {0, std::make_unsigned_t<_CharT>(*__first_++)};
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
+    return {static_cast<char32_t>(*__first_++)};
   }
-#    endif // _LIBCPP_STD_VER > 20
 
 private:
-  const _CharT* __first_;
-  const _CharT* __last_;
+  _Iterator __first_;
+  _Iterator __last_;
 };
 
 #  endif //  _LIBCPP_HAS_NO_UNICODE
 
 } // namespace __unicode
 
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__format/width_estimation_table.h
@@ -0,0 +1,271 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING, this entire header is generated by
+// utils/generate_width_estimation_table.py
+// DO NOT MODIFY!
+
+// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+//
+// See Terms of Use <https://www.unicode.org/copyright.html>
+// for definitions of Unicode Inc.'s Data Files and Software.
+//
+// NOTICE TO USER: Carefully read the following legal agreement.
+// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
+// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
+// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+// TERMS AND CONDITIONS OF THIS AGREEMENT.
+// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
+// THE DATA FILES OR SOFTWARE.
+//
+// COPYRIGHT AND PERMISSION NOTICE
+//
+// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved.
+// Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of the Unicode data files and any associated documentation
+// (the "Data Files") or Unicode software and any associated documentation
+// (the "Software") to deal in the Data Files or Software
+// without restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, and/or sell copies of
+// the Data Files or Software, and to permit persons to whom the Data Files
+// or Software are furnished to do so, provided that either
+// (a) this copyright and permission notice appear with all copies
+// of the Data Files or Software, or
+// (b) this copyright and permission notice appear in associated
+// Documentation.
+//
+// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+//
+// Except as contained in this notice, the name of a copyright holder
+// shall not be used in advertising or otherwise to promote the sale,
+// use or other dealings in these Data Files or Software without prior
+// written authorization of the copyright holder.
+
+#ifndef _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
+#define _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
+
+#include <__algorithm/ranges_upper_bound.h>
+#include <__config>
+#include <cstddef>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace __width_estimation_table {
+
+/// The entries of the characters with an estimated width of 2.
+///
+/// Contains the entries for [format.string.std]/12
+///  -  Any code point with the East_Asian_Width="W" or East_Asian_Width="F"
+///     Derived Extracted Property as described by UAX #44
+/// - U+4DC0 - U+4DFF (Yijing Hexagram Symbols)
+/// - U+1F300 - U+1F5FF (Miscellaneous Symbols and Pictographs)
+/// - U+1F900 - U+1F9FF (Supplemental Symbols and Pictographs)
+///
+/// The data is generated from
+/// - https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
+/// - The "overrides" in [format.string.std]/12
+///
+/// The format of EastAsianWidth.txt is two fields separated by a semicolon.
+/// Field 0: Unicode code point value or range of code point values
+/// Field 1: East_Asian_Width property, consisting of one of the following values:
+///         "A", "F", "H", "N", "Na", "W"
+///  - All code points, assigned or unassigned, that are not listed
+///      explicitly are given the value "N".
+///  - The unassigned code points in the following blocks default to "W":
+///         CJK Unified Ideographs Extension A: U+3400..U+4DBF
+///         CJK Unified Ideographs:             U+4E00..U+9FFF
+///         CJK Compatibility Ideographs:       U+F900..U+FAFF
+///  - All undesignated code points in Planes 2 and 3, whether inside or
+///      outside of allocated blocks, default to "W":
+///         Plane 2:                            U+20000..U+2FFFD
+///         Plane 3:                            U+30000..U+3FFFD
+///
+/// The table is similar to the table
+///  __extended_grapheme_custer_property_boundary::__entries
+/// which explains the details of these classes. The only difference is this
+/// table lacks a property, thus having more bits available for the size.
+///
+/// The maximum code point that has an estimated width of 2 is U+3FFFD. This
+/// value can be encoded in 18 bits. Thus the upper 3 bits of the code point
+/// are always 0. These 3 bits are used to enlarge the offset range. This
+/// optimization reduces the table in Unicode 15 from 184 to 104 entries,
+/// saving 320 bytes.
+///
+/// The data has 2 values:
+/// - bits [0, 13] The size of the range, allowing 16384 elements.
+/// - bits [14, 31] The lower bound code point of the range. The upper bound of
+///   the range is lower bound + size.
+inline constexpr uint32_t __entries[108] = {
+    0x0440005f /* 00001100 - 0000115f [   96] */, //
+    0x08c68001 /* 0000231a - 0000231b [    2] */, //
+    0x08ca4001 /* 00002329 - 0000232a [    2] */, //
+    0x08fa4003 /* 000023e9 - 000023ec [    4] */, //
+    0x08fc0000 /* 000023f0 - 000023f0 [    1] */, //
+    0x08fcc000 /* 000023f3 - 000023f3 [    1] */, //
+    0x097f4001 /* 000025fd - 000025fe [    2] */, //
+    0x09850001 /* 00002614 - 00002615 [    2] */, //
+    0x0992000b /* 00002648 - 00002653 [   12] */, //
+    0x099fc000 /* 0000267f - 0000267f [    1] */, //
+    0x09a4c000 /* 00002693 - 00002693 [    1] */, //
+    0x09a84000 /* 000026a1 - 000026a1 [    1] */, //
+    0x09aa8001 /* 000026aa - 000026ab [    2] */, //
+    0x09af4001 /* 000026bd - 000026be [    2] */, //
+    0x09b10001 /* 000026c4 - 000026c5 [    2] */, //
+    0x09b38000 /* 000026ce - 000026ce [    1] */, //
+    0x09b50000 /* 000026d4 - 000026d4 [    1] */, //
+    0x09ba8000 /* 000026ea - 000026ea [    1] */, //
+    0x09bc8001 /* 000026f2 - 000026f3 [    2] */, //
+    0x09bd4000 /* 000026f5 - 000026f5 [    1] */, //
+    0x09be8000 /* 000026fa - 000026fa [    1] */, //
+    0x09bf4000 /* 000026fd - 000026fd [    1] */, //
+    0x09c14000 /* 00002705 - 00002705 [    1] */, //
+    0x09c28001 /* 0000270a - 0000270b [    2] */, //
+    0x09ca0000 /* 00002728 - 00002728 [    1] */, //
+    0x09d30000 /* 0000274c - 0000274c [    1] */, //
+    0x09d38000 /* 0000274e - 0000274e [    1] */, //
+    0x09d4c002 /* 00002753 - 00002755 [    3] */, //
+    0x09d5c000 /* 00002757 - 00002757 [    1] */, //
+    0x09e54002 /* 00002795 - 00002797 [    3] */, //
+    0x09ec0000 /* 000027b0 - 000027b0 [    1] */, //
+    0x09efc000 /* 000027bf - 000027bf [    1] */, //
+    0x0ac6c001 /* 00002b1b - 00002b1c [    2] */, //
+    0x0ad40000 /* 00002b50 - 00002b50 [    1] */, //
+    0x0ad54000 /* 00002b55 - 00002b55 [    1] */, //
+    0x0ba00019 /* 00002e80 - 00002e99 [   26] */, //
+    0x0ba6c058 /* 00002e9b - 00002ef3 [   89] */, //
+    0x0bc000d5 /* 00002f00 - 00002fd5 [  214] */, //
+    0x0bfc000b /* 00002ff0 - 00002ffb [   12] */, //
+    0x0c00003e /* 00003000 - 0000303e [   63] */, //
+    0x0c104055 /* 00003041 - 00003096 [   86] */, //
+    0x0c264066 /* 00003099 - 000030ff [  103] */, //
+    0x0c41402a /* 00003105 - 0000312f [   43] */, //
+    0x0c4c405d /* 00003131 - 0000318e [   94] */, //
+    0x0c640053 /* 00003190 - 000031e3 [   84] */, //
+    0x0c7c002e /* 000031f0 - 0000321e [   47] */, //
+    0x0c880027 /* 00003220 - 00003247 [   40] */, //
+    0x0c943fff /* 00003250 - 0000724f [16384] */, //
+    0x1c94323c /* 00007250 - 0000a48c [12861] */, //
+    0x29240036 /* 0000a490 - 0000a4c6 [   55] */, //
+    0x2a58001c /* 0000a960 - 0000a97c [   29] */, //
+    0x2b002ba3 /* 0000ac00 - 0000d7a3 [11172] */, //
+    0x3e4001ff /* 0000f900 - 0000faff [  512] */, //
+    0x3f840009 /* 0000fe10 - 0000fe19 [   10] */, //
+    0x3f8c0022 /* 0000fe30 - 0000fe52 [   35] */, //
+    0x3f950012 /* 0000fe54 - 0000fe66 [   19] */, //
+    0x3f9a0003 /* 0000fe68 - 0000fe6b [    4] */, //
+    0x3fc0405f /* 0000ff01 - 0000ff60 [   96] */, //
+    0x3ff80006 /* 0000ffe0 - 0000ffe6 [    7] */, //
+    0x5bf80004 /* 00016fe0 - 00016fe4 [    5] */, //
+    0x5bfc0001 /* 00016ff0 - 00016ff1 [    2] */, //
+    0x5c0017f7 /* 00017000 - 000187f7 [ 6136] */, //
+    0x620004d5 /* 00018800 - 00018cd5 [ 1238] */, //
+    0x63400008 /* 00018d00 - 00018d08 [    9] */, //
+    0x6bfc0003 /* 0001aff0 - 0001aff3 [    4] */, //
+    0x6bfd4006 /* 0001aff5 - 0001affb [    7] */, //
+    0x6bff4001 /* 0001affd - 0001affe [    2] */, //
+    0x6c000122 /* 0001b000 - 0001b122 [  291] */, //
+    0x6c4c8000 /* 0001b132 - 0001b132 [    1] */, //
+    0x6c540002 /* 0001b150 - 0001b152 [    3] */, //
+    0x6c554000 /* 0001b155 - 0001b155 [    1] */, //
+    0x6c590003 /* 0001b164 - 0001b167 [    4] */, //
+    0x6c5c018b /* 0001b170 - 0001b2fb [  396] */, //
+    0x7c010000 /* 0001f004 - 0001f004 [    1] */, //
+    0x7c33c000 /* 0001f0cf - 0001f0cf [    1] */, //
+    0x7c638000 /* 0001f18e - 0001f18e [    1] */, //
+    0x7c644009 /* 0001f191 - 0001f19a [   10] */, //
+    0x7c800002 /* 0001f200 - 0001f202 [    3] */, //
+    0x7c84002b /* 0001f210 - 0001f23b [   44] */, //
+    0x7c900008 /* 0001f240 - 0001f248 [    9] */, //
+    0x7c940001 /* 0001f250 - 0001f251 [    2] */, //
+    0x7c980005 /* 0001f260 - 0001f265 [    6] */, //
+    0x7cc0034f /* 0001f300 - 0001f64f [  848] */, //
+    0x7da00045 /* 0001f680 - 0001f6c5 [   70] */, //
+    0x7db30000 /* 0001f6cc - 0001f6cc [    1] */, //
+    0x7db40002 /* 0001f6d0 - 0001f6d2 [    3] */, //
+    0x7db54002 /* 0001f6d5 - 0001f6d7 [    3] */, //
+    0x7db70003 /* 0001f6dc - 0001f6df [    4] */, //
+    0x7dbac001 /* 0001f6eb - 0001f6ec [    2] */, //
+    0x7dbd0008 /* 0001f6f4 - 0001f6fc [    9] */, //
+    0x7df8000b /* 0001f7e0 - 0001f7eb [   12] */, //
+    0x7dfc0000 /* 0001f7f0 - 0001f7f0 [    1] */, //
+    0x7e4000ff /* 0001f900 - 0001f9ff [  256] */, //
+    0x7e9c000c /* 0001fa70 - 0001fa7c [   13] */, //
+    0x7ea00008 /* 0001fa80 - 0001fa88 [    9] */, //
+    0x7ea4002d /* 0001fa90 - 0001fabd [   46] */, //
+    0x7eafc006 /* 0001fabf - 0001fac5 [    7] */, //
+    0x7eb3800d /* 0001face - 0001fadb [   14] */, //
+    0x7eb80008 /* 0001fae0 - 0001fae8 [    9] */, //
+    0x7ebc0008 /* 0001faf0 - 0001faf8 [    9] */, //
+    0x80003fff /* 00020000 - 00023fff [16384] */, //
+    0x90003fff /* 00024000 - 00027fff [16384] */, //
+    0xa0003fff /* 00028000 - 0002bfff [16384] */, //
+    0xb0003ffd /* 0002c000 - 0002fffd [16382] */, //
+    0xc0003fff /* 00030000 - 00033fff [16384] */, //
+    0xd0003fff /* 00034000 - 00037fff [16384] */, //
+    0xe0003fff /* 00038000 - 0003bfff [16384] */, //
+    0xf0003ffd /* 0003c000 - 0003fffd [16382] */};
+
+/// The upper bound entry of EastAsianWidth.txt.
+///
+/// Values greater than this value may have more than 18 significant bits.
+/// They always have a width of 1. This property makes it possible to store
+/// the table in its compact form.
+inline constexpr uint32_t __table_upper_bound = 0x0003fffd;
+
+/// Returns the estimated width of a Unicode code point.
+///
+/// \pre The code point is a valid Unicode code point.
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int __estimated_width(const char32_t __code_point) noexcept {
+  // Since __table_upper_bound contains the unshifted range do the
+  // comparison without shifting.
+  if (__code_point > __table_upper_bound) [[unlikely]]
+    return 1;
+
+  // When the code-point is less than the first element in the table
+  // the lookup is quite expensive. Since quite some scripts are in
+  // that range, it makes sense to validate that first.
+  // The std_format_spec_string_unicode benchmark gives a measurable
+  // improvement.
+  if (__code_point < (__entries[0] >> 14))
+    return 1;
+
+  ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries;
+  if (__i == 0)
+    return 1;
+
+  --__i;
+  uint32_t __upper_bound = (__entries[__i] >> 14) + (__entries[__i] & 0x3fffu);
+  return 1 + (__code_point <= __upper_bound);
+}
+
+} // namespace __width_estimation_table
+
+#endif //_LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
lib/libcxx/include/__format/write_escaped.h
@@ -0,0 +1,222 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___FORMAT_WRITE_ESCAPED_H
+#define _LIBCPP___FORMAT_WRITE_ESCAPED_H
+
+#include <__algorithm/ranges_copy.h>
+#include <__algorithm/ranges_for_each.h>
+#include <__charconv/to_chars_integral.h>
+#include <__charconv/to_chars_result.h>
+#include <__chrono/statically_widen.h>
+#include <__format/escaped_output_table.h>
+#include <__format/formatter_output.h>
+#include <__format/parser_std_format_spec.h>
+#include <__format/unicode.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__memory/addressof.h>
+#include <__system_error/errc.h>
+#include <__type_traits/make_unsigned.h>
+#include <__utility/move.h>
+#include <string_view>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+
+namespace __formatter {
+
+#if _LIBCPP_STD_VER >= 20
+
+/// Writes a string using format's width estimation algorithm.
+///
+/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
+/// input is ASCII.
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __write_string(
+    basic_string_view<_CharT> __str,
+    output_iterator<const _CharT&> auto __out_it,
+    __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
+  if (!__specs.__has_precision())
+    return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs);
+
+  int __size = __formatter::__truncate(__str, __specs.__precision_);
+
+  return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
+}
+
+#  endif // _LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+
+struct __nul_terminator {};
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) {
+  return *__cstr == _CharT('\0');
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI void
+__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) {
+  back_insert_iterator __out_it{__str};
+  std::ranges::copy(__prefix, __nul_terminator{}, __out_it);
+
+  char __buffer[8];
+  to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16);
+  _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
+  std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it);
+
+  __str += _CharT('}');
+}
+
+// [format.string.escaped]/2.2.1.2
+// ...
+// then the sequence \u{hex-digit-sequence} is appended to E, where
+// hex-digit-sequence is the shortest hexadecimal representation of C using
+// lower-case hexadecimal digits.
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) {
+  __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
+}
+
+// [format.string.escaped]/2.2.3
+// Otherwise (X is a sequence of ill-formed code units), each code unit U is
+// appended to E in order as the sequence \x{hex-digit-sequence}, where
+// hex-digit-sequence is the shortest hexadecimal representation of U using
+// lower-case hexadecimal digits.
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) {
+  __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
+}
+
+template <class _CharT>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) {
+#    ifdef _LIBCPP_HAS_NO_UNICODE
+  // For ASCII assume everything above 127 is printable.
+  if (__value > 127)
+    return false;
+#    endif
+
+  if (!__escaped_output_table::__needs_escape(__value))
+    return false;
+
+  __formatter::__write_well_formed_escaped_code_unit(__str, __value);
+  return true;
+}
+
+template <class _CharT>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) {
+  return static_cast<make_unsigned_t<_CharT>>(__value);
+}
+
+enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote };
+
+// [format.string.escaped]/2
+template <class _CharT>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
+__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) {
+  // 2.2.1.1 - Mapped character in [tab:format.escape.sequences]
+  switch (__value) {
+  case _CharT('\t'):
+    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t");
+    return true;
+  case _CharT('\n'):
+    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n");
+    return true;
+  case _CharT('\r'):
+    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r");
+    return true;
+  case _CharT('\''):
+    if (__mark == __escape_quotation_mark::__apostrophe)
+      __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')");
+    else
+      __str += __value;
+    return true;
+  case _CharT('"'):
+    if (__mark == __escape_quotation_mark::__double_quote)
+      __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")");
+    else
+      __str += __value;
+    return true;
+  case _CharT('\\'):
+    __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)");
+    return true;
+
+  // 2.2.1.2 - Space
+  case _CharT(' '):
+    __str += __value;
+    return true;
+  }
+
+  // 2.2.2
+  //   Otherwise, if X is a shift sequence, the effect on E and further
+  //   decoding of S is unspecified.
+  // For now shift sequences are ignored and treated as Unicode. Other parts
+  // of the format library do the same. It's unknown how ostream treats them.
+  // TODO FMT determine what to do with shift sequences.
+
+  // 2.2.1.2.1 and 2.2.1.2.2 - Escape
+  return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value));
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI void
+__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) {
+  __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()};
+
+  while (!__view.__at_end()) {
+    auto __first                                  = __view.__position();
+    typename __unicode::__consume_result __result = __view.__consume();
+    if (__result.__status == __unicode::__consume_result::__ok) {
+      if (!__formatter::__is_escaped_sequence_written(__str, __result.__code_point, __mark))
+        // 2.2.1.3 - Add the character
+        ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str));
+    } else {
+      // 2.2.3 sequence of ill-formed code units
+      ranges::for_each(__first, __view.__position(), [&](_CharT __value) {
+        __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value));
+      });
+    }
+  }
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto
+__format_escaped_char(_CharT __value,
+                      output_iterator<const _CharT&> auto __out_it,
+                      __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
+  basic_string<_CharT> __str;
+  __str += _CharT('\'');
+  __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe);
+  __str += _CharT('\'');
+  return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size());
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto
+__format_escaped_string(basic_string_view<_CharT> __values,
+                        output_iterator<const _CharT&> auto __out_it,
+                        __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
+  basic_string<_CharT> __str;
+  __str += _CharT('"');
+  __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote);
+  __str += _CharT('"');
+  return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs);
+}
+
+#  endif // _LIBCPP_STD_VER >= 23
+
+} // namespace __formatter
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_WRITE_ESCAPED_H
lib/libcxx/include/__functional/bind.h
@@ -13,9 +13,11 @@
 #include <__config>
 #include <__functional/invoke.h>
 #include <__functional/weak_result_type.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_reference_wrapper.h>
+#include <__type_traits/is_void.h>
 #include <cstddef>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -30,9 +32,9 @@ struct is_bind_expression : _If<
     is_bind_expression<__remove_cvref_t<_Tp> >
 > {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
+inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value;
 #endif
 
 template<class _Tp>
@@ -42,9 +44,9 @@ struct is_placeholder : _If<
     is_placeholder<__remove_cvref_t<_Tp> >
 > {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
+inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value;
 #endif
 
 namespace placeholders
@@ -52,29 +54,24 @@ namespace placeholders
 
 template <int _Np> struct __ph {};
 
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-_LIBCPP_FUNC_VIS extern const __ph<1>   _1;
-_LIBCPP_FUNC_VIS extern const __ph<2>   _2;
-_LIBCPP_FUNC_VIS extern const __ph<3>   _3;
-_LIBCPP_FUNC_VIS extern const __ph<4>   _4;
-_LIBCPP_FUNC_VIS extern const __ph<5>   _5;
-_LIBCPP_FUNC_VIS extern const __ph<6>   _6;
-_LIBCPP_FUNC_VIS extern const __ph<7>   _7;
-_LIBCPP_FUNC_VIS extern const __ph<8>   _8;
-_LIBCPP_FUNC_VIS extern const __ph<9>   _9;
-_LIBCPP_FUNC_VIS extern const __ph<10> _10;
-#else
-/* inline */ constexpr __ph<1>   _1{};
-/* inline */ constexpr __ph<2>   _2{};
-/* inline */ constexpr __ph<3>   _3{};
-/* inline */ constexpr __ph<4>   _4{};
-/* inline */ constexpr __ph<5>   _5{};
-/* inline */ constexpr __ph<6>   _6{};
-/* inline */ constexpr __ph<7>   _7{};
-/* inline */ constexpr __ph<8>   _8{};
-/* inline */ constexpr __ph<9>   _9{};
-/* inline */ constexpr __ph<10> _10{};
-#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+// C++17 recommends that we implement placeholders as `inline constexpr`, but allows
+// implementing them as `extern <implementation-defined>`. Libc++ implements them as
+// `extern const` in all standard modes to avoid an ABI break in C++03: making them
+// `inline constexpr` requires removing their definition in the shared library to
+// avoid ODR violations, which is an ABI break.
+//
+// In practice, since placeholders are empty, `extern const` is almost impossible
+// to distinguish from `inline constexpr` from a usage stand point.
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<1>   _1;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<2>   _2;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<3>   _3;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<4>   _4;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<5>   _5;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<6>   _6;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<7>   _7;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<8>   _8;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<9>   _9;
+_LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10;
 
 } // namespace placeholders
 
@@ -86,7 +83,7 @@ struct is_placeholder<placeholders::__ph<_Np> >
 #ifndef _LIBCPP_CXX03_LANG
 
 template <class _Tp, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 _Tp&
 __mu(reference_wrapper<_Tp> __t, _Uj&)
 {
@@ -94,7 +91,7 @@ __mu(reference_wrapper<_Tp> __t, _Uj&)
 }
 
 template <class _Ti, class ..._Uj, size_t ..._Indx>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename __invoke_of<_Ti&, _Uj...>::type
 __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
 {
@@ -102,7 +99,7 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
 }
 
 template <class _Ti, class ..._Uj>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename __enable_if_t
 <
     is_bind_expression<_Ti>::value,
@@ -124,7 +121,7 @@ struct __mu_return2<true, _Ti, _Uj>
 };
 
 template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
     0 < is_placeholder<_Ti>::value,
@@ -132,12 +129,12 @@ typename enable_if
 >::type
 __mu(_Ti&, _Uj& __uj)
 {
-    const size_t _Indx = is_placeholder<_Ti>::value - 1;
-    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
+    const size_t __indx = is_placeholder<_Ti>::value - 1;
+    return _VSTD::forward<typename tuple_element<__indx, _Uj>::type>(_VSTD::get<__indx>(__uj));
 }
 
 template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
     !is_bind_expression<_Ti>::value &&
@@ -255,7 +252,7 @@ struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
 };
 
 template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename __bind_return<_Fp, _BoundArgs, _Args>::type
 __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
                 _Args&& __args)
@@ -264,11 +261,11 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
 }
 
 template<class _Fp, class ..._BoundArgs>
-class __bind : public __weak_result_type<typename decay<_Fp>::type>
+class __bind : public __weak_result_type<__decay_t<_Fp> >
 {
 protected:
-    typedef typename decay<_Fp>::type _Fd;
-    typedef tuple<typename decay<_BoundArgs>::type...> _Td;
+    using _Fd = __decay_t<_Fp>;
+    typedef tuple<__decay_t<_BoundArgs>...> _Td;
 private:
     _Fd __f_;
     _Td __bound_args_;
lib/libcxx/include/__functional/bind_back.h
@@ -13,10 +13,10 @@
 #include <__config>
 #include <__functional/invoke.h>
 #include <__functional/perfect_forward.h>
+#include <__type_traits/decay.h>
 #include <__utility/forward.h>
 #include <__utility/integer_sequence.h>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,7 +24,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <size_t _NBound, class = make_index_sequence<_NBound>>
 struct __bind_back_op;
@@ -57,7 +57,7 @@ constexpr auto __bind_back(_Fn&& __f, _Args&&... __args)
     -> decltype(      __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))
     { return          __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/bind_front.h
@@ -13,8 +13,12 @@
 #include <__config>
 #include <__functional/invoke.h>
 #include <__functional/perfect_forward.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_move_constructible.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,7 +26,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 struct __bind_front_op {
     template <class ..._Args>
@@ -51,7 +55,7 @@ constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
     return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/binder1st.h
@@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
 
-template <class __Operation>
+template <class _Operation>
 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
-    : public __unary_function<typename __Operation::second_argument_type, typename __Operation::result_type>
+    : public __unary_function<typename _Operation::second_argument_type, typename _Operation::result_type>
 {
 protected:
-    __Operation                               op;
-    typename __Operation::first_argument_type value;
+    _Operation                               op;
+    typename _Operation::first_argument_type value;
 public:
-    _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
-                               const typename __Operation::first_argument_type __y)
+    _LIBCPP_INLINE_VISIBILITY binder1st(const _Operation& __x,
+                               const typename _Operation::first_argument_type __y)
         : op(__x), value(__y) {}
-    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
-        (typename __Operation::second_argument_type& __x) const
+    _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
+        (typename _Operation::second_argument_type& __x) const
             {return op(value, __x);}
-    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
-        (const typename __Operation::second_argument_type& __x) const
+    _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
+        (const typename _Operation::second_argument_type& __x) const
             {return op(value, __x);}
 };
 
-template <class __Operation, class _Tp>
+template <class _Operation, class _Tp>
 _LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
-binder1st<__Operation>
-bind1st(const __Operation& __op, const _Tp& __x)
-    {return binder1st<__Operation>(__op, __x);}
+binder1st<_Operation>
+bind1st(const _Operation& __op, const _Tp& __x)
+    {return binder1st<_Operation>(__op, __x);}
 
 #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
 
lib/libcxx/include/__functional/binder2nd.h
@@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
 
-template <class __Operation>
+template <class _Operation>
 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
-    : public __unary_function<typename __Operation::first_argument_type, typename __Operation::result_type>
+    : public __unary_function<typename _Operation::first_argument_type, typename _Operation::result_type>
 {
 protected:
-    __Operation                                op;
-    typename __Operation::second_argument_type value;
+    _Operation                                op;
+    typename _Operation::second_argument_type value;
 public:
     _LIBCPP_INLINE_VISIBILITY
-    binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
+    binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y)
         : op(__x), value(__y) {}
-    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
-        (      typename __Operation::first_argument_type& __x) const
+    _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
+        (      typename _Operation::first_argument_type& __x) const
             {return op(__x, value);}
-    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
-        (const typename __Operation::first_argument_type& __x) const
+    _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
+        (const typename _Operation::first_argument_type& __x) const
             {return op(__x, value);}
 };
 
-template <class __Operation, class _Tp>
+template <class _Operation, class _Tp>
 _LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
-binder2nd<__Operation>
-bind2nd(const __Operation& __op, const _Tp& __x)
-    {return binder2nd<__Operation>(__op, __x);}
+binder2nd<_Operation>
+bind2nd(const _Operation& __op, const _Tp& __x)
+    {return binder2nd<_Operation>(__op, __x);}
 
 #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
 
lib/libcxx/include/__functional/boyer_moore_searcher.h
@@ -20,12 +20,13 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/shared_ptr.h>
+#include <__type_traits/make_unsigned.h>
 #include <__utility/pair.h>
 #include <array>
 #include <unordered_map>
 #include <vector>
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
@@ -113,6 +114,7 @@ private:
                                       && is_same_v<_BinaryPredicate, equal_to<>>>;
 
 public:
+  _LIBCPP_HIDE_FROM_ABI
   boyer_moore_searcher(_RandomAccessIterator1 __first,
                        _RandomAccessIterator1 __last,
                        _Hash __hash = _Hash(),
@@ -134,7 +136,7 @@ public:
   }
 
   template <class _RandomAccessIterator2>
-  pair<_RandomAccessIterator2, _RandomAccessIterator2>
+  _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
   operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
     static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
                                     typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
@@ -158,7 +160,7 @@ private:
   shared_ptr<difference_type[]> __suffix_;
 
   template <class _RandomAccessIterator2>
-  pair<_RandomAccessIterator2, _RandomAccessIterator2>
+  _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
   __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
     _RandomAccessIterator2 __current = __f;
     const _RandomAccessIterator2 __last = __l - __pattern_length_;
@@ -183,7 +185,8 @@ private:
   }
 
   template <class _Iterator, class _Container>
-  void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
+  _LIBCPP_HIDE_FROM_ABI void
+  __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
     const size_t __count = __last - __first;
 
     __prefix[0] = 0;
@@ -199,7 +202,8 @@ private:
     }
   }
 
-  void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
+  _LIBCPP_HIDE_FROM_ABI void
+  __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
     const size_t __count = __last - __first;
 
     if (__count == 0)
@@ -241,6 +245,7 @@ private:
                                       && is_same_v<_Hash, hash<value_type>>
                                       && is_same_v<_BinaryPredicate, equal_to<>>>;
 public:
+  _LIBCPP_HIDE_FROM_ABI
   boyer_moore_horspool_searcher(_RandomAccessIterator1 __first,
                                 _RandomAccessIterator1 __last,
                                 _Hash __hash = _Hash(),
@@ -262,7 +267,7 @@ public:
   }
 
   template <class _RandomAccessIterator2>
-  pair<_RandomAccessIterator2, _RandomAccessIterator2>
+  _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
   operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
     static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
                                     typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
@@ -286,7 +291,7 @@ private:
   shared_ptr<__skip_table_type> __skip_table_;
 
   template <class _RandomAccessIterator2>
-  pair<_RandomAccessIterator2, _RandomAccessIterator2>
+  _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
   __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
     _RandomAccessIterator2 __current = __f;
     const _RandomAccessIterator2 __last = __l - __pattern_length_;
@@ -310,6 +315,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
lib/libcxx/include/__functional/compose.h
@@ -13,8 +13,8 @@
 #include <__config>
 #include <__functional/invoke.h>
 #include <__functional/perfect_forward.h>
+#include <__type_traits/decay.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 struct __compose_op {
     template<class _Fn1, class _Fn2, class ..._Args>
@@ -45,7 +45,7 @@ constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2)
     -> decltype(      __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))
     { return          __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/default_searcher.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 // default searcher
 template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
@@ -50,7 +50,7 @@ private:
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher);
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/function.h
@@ -12,6 +12,7 @@
 
 #include <__assert>
 #include <__config>
+#include <__exception/exception.h>
 #include <__functional/binary_function.h>
 #include <__functional/invoke.h>
 #include <__functional/unary_function.h>
@@ -23,15 +24,21 @@
 #include <__memory/builtin_new_allocator.h>
 #include <__memory/compressed_pair.h>
 #include <__memory/unique_ptr.h>
+#include <__type_traits/aligned_storage.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_core_convertible.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/is_void.h>
 #include <__type_traits/strip_signature.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/piecewise_construct.h>
 #include <__utility/swap.h>
-#include <exception>
+#include <__verbose_abort>
 #include <new>
 #include <tuple>
-#include <type_traits>
 #include <typeinfo>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -46,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 _LIBCPP_DIAGNOSTIC_PUSH
 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
-class _LIBCPP_EXCEPTION_ABI bad_function_call
+class _LIBCPP_EXPORTED_FROM_ABI bad_function_call
     : public exception
 {
 public:
@@ -56,7 +63,7 @@ public:
 #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
     ~bad_function_call() _NOEXCEPT override;
 #else
-    ~bad_function_call() _NOEXCEPT override {}
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
 #endif
 
 #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
@@ -68,10 +75,10 @@ _LIBCPP_DIAGNOSTIC_POP
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_bad_function_call()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw bad_function_call();
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
 #endif
 }
 
@@ -201,7 +208,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
     _LIBCPP_INLINE_VISIBILITY
     void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
 
-    static void __destroy_and_delete(__alloc_func* __f) {
+    _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
       typedef allocator_traits<_Alloc> __alloc_traits;
       typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
       _FunAlloc __a(__f->__get_allocator());
@@ -245,7 +252,7 @@ public:
   _LIBCPP_INLINE_VISIBILITY
   void destroy() _NOEXCEPT { __f_.~_Target(); }
 
-  static void __destroy_and_delete(__default_alloc_func* __f) {
+  _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
     __f->destroy();
       __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
   }
@@ -300,14 +307,14 @@ public:
     explicit __func(_Fp&& __f, _Alloc&& __a)
         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
 
-    virtual __base<_Rp(_ArgTypes...)>* __clone() const;
-    virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
-    virtual void destroy() _NOEXCEPT;
-    virtual void destroy_deallocate() _NOEXCEPT;
-    virtual _Rp operator()(_ArgTypes&&... __arg);
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
 #ifndef _LIBCPP_HAS_NO_RTTI
-    virtual const void* target(const type_info&) const _NOEXCEPT;
-    virtual const std::type_info& target_type() const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
 #endif // _LIBCPP_HAS_NO_RTTI
 };
 
@@ -389,7 +396,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
     typedef __base<_Rp(_ArgTypes...)> __func;
     __func* __f_;
 
-    _LIBCPP_NO_CFI static __func* __as_base(void* __p)
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p)
     {
         return reinterpret_cast<__func*>(__p);
     }
@@ -427,7 +434,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
     }
 
     template <class _Fp,
-        class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
+        class = typename enable_if<!is_same<__decay_t<_Fp>, __value_func>::value>::type>
     _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
         : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
 
@@ -614,33 +621,34 @@ struct __policy
     _LIBCPP_INLINE_VISIBILITY
     static const __policy* __create_empty()
     {
-        static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
-                                                             true,
+        static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr,
+                                                            true,
 #ifndef _LIBCPP_HAS_NO_RTTI
-                                                             &typeid(void)
+                                                            &typeid(void)
 #else
-                                                             nullptr
+                                                            nullptr
 #endif
         };
-        return &__policy_;
+        return &__policy;
     }
 
   private:
-    template <typename _Fun> static void* __large_clone(const void* __s)
+    template <typename _Fun>
+    _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s)
     {
         const _Fun* __f = static_cast<const _Fun*>(__s);
         return __f->__clone();
     }
 
     template <typename _Fun>
-    static void __large_destroy(void* __s) {
+    _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
       _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
     }
 
     template <typename _Fun>
     _LIBCPP_INLINE_VISIBILITY static const __policy*
     __choose_policy(/* is_small = */ false_type) {
-      static const _LIBCPP_CONSTEXPR __policy __policy_ = {
+      static const _LIBCPP_CONSTEXPR __policy __policy = {
           &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
 #ifndef _LIBCPP_HAS_NO_RTTI
           &typeid(typename _Fun::_Target)
@@ -648,14 +656,14 @@ struct __policy
           nullptr
 #endif
       };
-        return &__policy_;
+        return &__policy;
     }
 
     template <typename _Fun>
     _LIBCPP_INLINE_VISIBILITY static const __policy*
         __choose_policy(/* is_small = */ true_type)
     {
-        static const _LIBCPP_CONSTEXPR __policy __policy_ = {
+        static const _LIBCPP_CONSTEXPR __policy __policy = {
             nullptr, nullptr, false,
 #ifndef _LIBCPP_HAS_NO_RTTI
             &typeid(typename _Fun::_Target)
@@ -663,7 +671,7 @@ struct __policy
             nullptr
 #endif
         };
-        return &__policy_;
+        return &__policy;
     }
 };
 
@@ -699,14 +707,14 @@ struct __policy_invoker<_Rp(_ArgTypes...)>
     _LIBCPP_INLINE_VISIBILITY
     explicit __policy_invoker(__Call __c) : __call_(__c) {}
 
-    static _Rp __call_empty(const __policy_storage*,
+    _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*,
                             __fast_forward<_ArgTypes>...)
     {
         __throw_bad_function_call();
     }
 
     template <typename _Fun>
-    static _Rp __call_impl(const __policy_storage* __buf,
+    _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf,
                            __fast_forward<_ArgTypes>... __args)
     {
         _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
@@ -770,7 +778,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
         }
     }
 
-    template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
+    template <class _Fp, class = typename enable_if<!is_same<__decay_t<_Fp>, __policy_func>::value>::type>
     _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
         : __policy_(__policy::__create_empty()) {
       typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
@@ -915,7 +923,7 @@ public:
     { }
 
     virtual __base<_Rp(_ArgTypes...)>* __clone() const {
-        _LIBCPP_ASSERT(false,
+        _LIBCPP_ASSERT_INTERNAL(false,
             "Block pointers are just pointers, so they should always fit into "
             "std::function's small buffer optimization. This function should "
             "never be invoked.");
@@ -935,7 +943,7 @@ public:
     }
 
     virtual void destroy_deallocate() _NOEXCEPT {
-        _LIBCPP_ASSERT(false,
+        _LIBCPP_ASSERT_INTERNAL(false,
             "Block pointers are just pointers, so they should always fit into "
             "std::function's small buffer optimization. This function should "
             "never be invoked.");
@@ -1002,11 +1010,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     function() _NOEXCEPT { }
     _LIBCPP_INLINE_VISIBILITY
-    function(nullptr_t) _NOEXCEPT {}
-    function(const function&);
-    function(function&&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
+    _LIBCPP_HIDE_FROM_ABI function(const function&);
+    _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
     template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
-    function(_Fp);
+    _LIBCPP_HIDE_FROM_ABI function(_Fp);
 
 #if _LIBCPP_STD_VER <= 14
     template<class _Alloc>
@@ -1016,23 +1024,23 @@ public:
       _LIBCPP_INLINE_VISIBILITY
       function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
     template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, const function&);
+    _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
     template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, function&&);
+    _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
     template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
-      function(allocator_arg_t, const _Alloc& __a, _Fp __f);
+    _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
 #endif
 
-    function& operator=(const function&);
-    function& operator=(function&&) _NOEXCEPT;
-    function& operator=(nullptr_t) _NOEXCEPT;
-    template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
-    function& operator=(_Fp&&);
+    _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
+    _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
+    template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
+    _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
 
-    ~function();
+    _LIBCPP_HIDE_FROM_ABI ~function();
 
     // function modifiers:
-    void swap(function&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
 
 #if _LIBCPP_STD_VER <= 14
     template<class _Fp, class _Alloc>
@@ -1050,17 +1058,21 @@ public:
     // deleted overloads close possible hole in the type system
     template<class _R2, class... _ArgTypes2>
       bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
+#if _LIBCPP_STD_VER <= 17
     template<class _R2, class... _ArgTypes2>
       bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
+#endif
 public:
     // function invocation:
-    _Rp operator()(_ArgTypes...) const;
+    _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
 
 #ifndef _LIBCPP_HAS_NO_RTTI
     // function target access:
-    const std::type_info& target_type() const _NOEXCEPT;
-    template <typename _Tp> _Tp* target() _NOEXCEPT;
-    template <typename _Tp> const _Tp* target() const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
+    template <typename _Tp>
+    _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
+    template <typename _Tp>
+    _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
 #endif // _LIBCPP_HAS_NO_RTTI
 };
 
@@ -1188,6 +1200,8 @@ inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Rp, class... _ArgTypes>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1203,6 +1217,8 @@ inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
 
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Rp, class... _ArgTypes>
 inline _LIBCPP_INLINE_VISIBILITY
 void
lib/libcxx/include/__functional/hash.h
@@ -13,7 +13,7 @@
 #include <__functional/invoke.h>
 #include <__functional/unary_function.h>
 #include <__fwd/hash.h>
-#include <__tuple_dir/sfinae_helpers.h>
+#include <__tuple/sfinae_helpers.h>
 #include <__type_traits/is_copy_constructible.h>
 #include <__type_traits/is_default_constructible.h>
 #include <__type_traits/is_enum.h>
@@ -35,7 +35,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 _Size
 __loadword(const void* __p)
 {
@@ -53,73 +53,113 @@ struct __murmur2_or_cityhash;
 template <class _Size>
 struct __murmur2_or_cityhash<_Size, 32>
 {
-    inline _Size operator()(const void* __key, _Size __len)
-         _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+    _Size operator()(const void* __key, _Size __len) const {
+      // murmur2
+      const _Size __m = 0x5bd1e995;
+      const _Size __r = 24;
+      _Size __h = __len;
+      const unsigned char* __data = static_cast<const unsigned char*>(__key);
+      for (; __len >= 4; __data += 4, __len -= 4)
+      {
+          _Size __k = std::__loadword<_Size>(__data);
+          __k *= __m;
+          __k ^= __k >> __r;
+          __k *= __m;
+          __h *= __m;
+          __h ^= __k;
+      }
+      switch (__len)
+      {
+      case 3:
+          __h ^= static_cast<_Size>(__data[2] << 16);
+          _LIBCPP_FALLTHROUGH();
+      case 2:
+          __h ^= static_cast<_Size>(__data[1] << 8);
+          _LIBCPP_FALLTHROUGH();
+      case 1:
+          __h ^= __data[0];
+          __h *= __m;
+      }
+      __h ^= __h >> 13;
+      __h *= __m;
+      __h ^= __h >> 15;
+      return __h;
+    }
 };
 
-// murmur2
 template <class _Size>
-_Size
-__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
+struct __murmur2_or_cityhash<_Size, 64>
 {
-    const _Size __m = 0x5bd1e995;
-    const _Size __r = 24;
-    _Size __h = __len;
-    const unsigned char* __data = static_cast<const unsigned char*>(__key);
-    for (; __len >= 4; __data += 4, __len -= 4)
-    {
-        _Size __k = std::__loadword<_Size>(__data);
-        __k *= __m;
-        __k ^= __k >> __r;
-        __k *= __m;
-        __h *= __m;
-        __h ^= __k;
-    }
-    switch (__len)
-    {
-    case 3:
-        __h ^= static_cast<_Size>(__data[2] << 16);
-        _LIBCPP_FALLTHROUGH();
-    case 2:
-        __h ^= static_cast<_Size>(__data[1] << 8);
-        _LIBCPP_FALLTHROUGH();
-    case 1:
-        __h ^= __data[0];
-        __h *= __m;
+  // cityhash64
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  _Size operator()(const void* __key, _Size __len) const {
+    const char* __s = static_cast<const char*>(__key);
+    if (__len <= 32) {
+        if (__len <= 16) {
+        return __hash_len_0_to_16(__s, __len);
+        } else {
+        return __hash_len_17_to_32(__s, __len);
+        }
+    } else if (__len <= 64) {
+        return __hash_len_33_to_64(__s, __len);
     }
-    __h ^= __h >> 13;
-    __h *= __m;
-    __h ^= __h >> 15;
-    return __h;
-}
 
-template <class _Size>
-struct __murmur2_or_cityhash<_Size, 64>
-{
-    inline _Size operator()(const void* __key, _Size __len)  _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
+    // For strings over 64 bytes we hash the end first, and then as we
+    // loop we keep 56 bytes of state: v, w, x, y, and z.
+    _Size __x = std::__loadword<_Size>(__s + __len - 40);
+    _Size __y = std::__loadword<_Size>(__s + __len - 16) +
+                std::__loadword<_Size>(__s + __len - 56);
+    _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len,
+                            std::__loadword<_Size>(__s + __len - 24));
+    pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
+    pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
+    __x = __x * __k1 + std::__loadword<_Size>(__s);
+
+    // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
+    __len = (__len - 1) & ~static_cast<_Size>(63);
+    do {
+        __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1;
+        __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1;
+        __x ^= __w.second;
+        __y += __v.first + std::__loadword<_Size>(__s + 40);
+        __z = __rotate(__z + __w.first, 33) * __k1;
+        __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
+        __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
+                                            __y + std::__loadword<_Size>(__s + 16));
+        _VSTD::swap(__z, __x);
+        __s += 64;
+        __len -= 64;
+    } while (__len != 0);
+    return __hash_len_16(
+        __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
+        __hash_len_16(__v.second, __w.second) + __x);
+  }
 
- private:
-  // Some primes between 2^63 and 2^64.
-  static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
-  static const _Size __k1 = 0xb492b66fbe98f273ULL;
-  static const _Size __k2 = 0x9ae16a3b2f90404fULL;
-  static const _Size __k3 = 0xc949d7c7509e6557ULL;
+  private:
+    // Some primes between 2^63 and 2^64.
+    static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
+    static const _Size __k1 = 0xb492b66fbe98f273ULL;
+    static const _Size __k2 = 0x9ae16a3b2f90404fULL;
+    static const _Size __k3 = 0xc949d7c7509e6557ULL;
 
+  _LIBCPP_HIDE_FROM_ABI
   static _Size __rotate(_Size __val, int __shift) {
     return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
   }
 
+  _LIBCPP_HIDE_FROM_ABI
   static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
     return (__val >> __shift) | (__val << (64 - __shift));
   }
 
+  _LIBCPP_HIDE_FROM_ABI
   static _Size __shift_mix(_Size __val) {
     return __val ^ (__val >> 47);
   }
 
-  static _Size __hash_len_16(_Size __u, _Size __v)
-     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-  {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  static _Size __hash_len_16(_Size __u, _Size __v) {
     const _Size __mul = 0x9ddfea08eb382d69ULL;
     _Size __a = (__u ^ __v) * __mul;
     __a ^= (__a >> 47);
@@ -129,9 +169,8 @@ struct __murmur2_or_cityhash<_Size, 64>
     return __b;
   }
 
-  static _Size __hash_len_0_to_16(const char* __s, _Size __len)
-     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-  {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  static _Size __hash_len_0_to_16(const char* __s, _Size __len) {
     if (__len > 8) {
       const _Size __a = std::__loadword<_Size>(__s);
       const _Size __b = std::__loadword<_Size>(__s + __len - 8);
@@ -158,9 +197,8 @@ struct __murmur2_or_cityhash<_Size, 64>
     return __k2;
   }
 
-  static _Size __hash_len_17_to_32(const char *__s, _Size __len)
-     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-  {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  static _Size __hash_len_17_to_32(const char *__s, _Size __len) {
     const _Size __a = std::__loadword<_Size>(__s) * __k1;
     const _Size __b = std::__loadword<_Size>(__s + 8);
     const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2;
@@ -171,9 +209,9 @@ struct __murmur2_or_cityhash<_Size, 64>
 
   // Return a 16-byte hash for 48 bytes.  Quick and dirty.
   // Callers do best to use "random-looking" values for a and b.
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
   static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
       _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
-        _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
   {
     __a += __w;
     __b = __rotate(__b + __a + __z, 21);
@@ -185,9 +223,9 @@ struct __murmur2_or_cityhash<_Size, 64>
   }
 
   // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
   static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
       const char* __s, _Size __a, _Size __b)
-    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
   {
     return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s),
                                          std::__loadword<_Size>(__s + 8),
@@ -198,9 +236,8 @@ struct __murmur2_or_cityhash<_Size, 64>
   }
 
   // Return an 8-byte hash for 33 to 64 bytes.
-  static _Size __hash_len_33_to_64(const char *__s, size_t __len)
-    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-  {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  static _Size __hash_len_33_to_64(const char *__s, size_t __len) {
     _Size __z = std::__loadword<_Size>(__s + 24);
     _Size __a = std::__loadword<_Size>(__s) +
                 (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0;
@@ -225,53 +262,6 @@ struct __murmur2_or_cityhash<_Size, 64>
   }
 };
 
-// cityhash64
-template <class _Size>
-_Size
-__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
-{
-  const char* __s = static_cast<const char*>(__key);
-  if (__len <= 32) {
-    if (__len <= 16) {
-      return __hash_len_0_to_16(__s, __len);
-    } else {
-      return __hash_len_17_to_32(__s, __len);
-    }
-  } else if (__len <= 64) {
-    return __hash_len_33_to_64(__s, __len);
-  }
-
-  // For strings over 64 bytes we hash the end first, and then as we
-  // loop we keep 56 bytes of state: v, w, x, y, and z.
-  _Size __x = std::__loadword<_Size>(__s + __len - 40);
-  _Size __y = std::__loadword<_Size>(__s + __len - 16) +
-              std::__loadword<_Size>(__s + __len - 56);
-  _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len,
-                          std::__loadword<_Size>(__s + __len - 24));
-  pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
-  pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
-  __x = __x * __k1 + std::__loadword<_Size>(__s);
-
-  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
-  __len = (__len - 1) & ~static_cast<_Size>(63);
-  do {
-    __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1;
-    __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1;
-    __x ^= __w.second;
-    __y += __v.first + std::__loadword<_Size>(__s + 40);
-    __z = __rotate(__z + __w.first, 33) * __k1;
-    __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
-    __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
-                                        __y + std::__loadword<_Size>(__s + 16));
-    _VSTD::swap(__z, __x);
-    __s += 64;
-    __len -= 64;
-  } while (__len != 0);
-  return __hash_len_16(
-      __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
-      __hash_len_16(__v.second, __w.second) + __x);
-}
-
 template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
 struct __scalar_hash;
 
@@ -279,7 +269,7 @@ template <class _Tp>
 struct __scalar_hash<_Tp, 0>
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         union
@@ -297,7 +287,7 @@ template <class _Tp>
 struct __scalar_hash<_Tp, 1>
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         union
@@ -314,7 +304,7 @@ template <class _Tp>
 struct __scalar_hash<_Tp, 2>
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         union
@@ -335,7 +325,7 @@ template <class _Tp>
 struct __scalar_hash<_Tp, 3>
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         union
@@ -357,7 +347,7 @@ template <class _Tp>
 struct __scalar_hash<_Tp, 4>
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         union
@@ -381,7 +371,7 @@ struct _PairT {
   size_t second;
 };
 
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_HIDE_FROM_ABI
 inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
     typedef __scalar_hash<_PairT> _HashT;
     const _PairT __p = {__lhs, __rhs};
@@ -392,7 +382,7 @@ template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
     : public __unary_function<_Tp*, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp* __v) const _NOEXCEPT
     {
         union
@@ -409,7 +399,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<bool>
     : public __unary_function<bool, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -417,7 +407,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char>
     : public __unary_function<char, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -425,7 +415,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<signed char>
     : public __unary_function<signed char, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -433,7 +423,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
     : public __unary_function<unsigned char, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -442,7 +432,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
     : public __unary_function<char8_t, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 #endif // !_LIBCPP_HAS_NO_CHAR8_T
@@ -451,7 +441,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
     : public __unary_function<char16_t, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -459,7 +449,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
     : public __unary_function<char32_t, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -468,7 +458,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
     : public __unary_function<wchar_t, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -477,7 +467,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<short>
     : public __unary_function<short, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -485,7 +475,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
     : public __unary_function<unsigned short, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -493,7 +483,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<int>
     : public __unary_function<int, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -501,7 +491,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
     : public __unary_function<unsigned int, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -509,7 +499,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<long>
     : public __unary_function<long, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -517,7 +507,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
     : public __unary_function<unsigned long, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
@@ -553,7 +543,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<float>
     : public __scalar_hash<float>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(float __v) const _NOEXCEPT
     {
         // -0.0 and 0.0 should return same hash
@@ -567,7 +557,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<double>
     : public __scalar_hash<double>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(double __v) const _NOEXCEPT
     {
         // -0.0 and 0.0 should return same hash
@@ -581,7 +571,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS hash<long double>
     : public __scalar_hash<long double>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(long double __v) const _NOEXCEPT
     {
         // -0.0 and 0.0 should return same hash
@@ -631,7 +621,7 @@ template <class _Tp, bool = is_enum<_Tp>::value>
 struct _LIBCPP_TEMPLATE_VIS __enum_hash
     : public __unary_function<_Tp, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
         typedef typename underlying_type<_Tp>::type type;
@@ -650,13 +640,13 @@ struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
 {
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
   : public __unary_function<nullptr_t, size_t>
 {
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     size_t operator()(nullptr_t) const _NOEXCEPT {
         return 662607004ull;
     }
@@ -677,7 +667,7 @@ using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant<bool,
     is_default_constructible<_Hash>::value
 >;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Type, class>
 using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type;
 
lib/libcxx/include/__functional/identity.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___FUNCTIONAL_IDENTITY_H
 
 #include <__config>
+#include <__type_traits/integral_constant.h>
 #include <__utility/forward.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,27 +20,37 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _Tp>
+struct __is_identity : false_type {};
+
 struct __identity {
   template <class _Tp>
-  _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT {
+  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT {
     return std::forward<_Tp>(__t);
   }
 
   using is_transparent = void;
 };
 
-#if _LIBCPP_STD_VER > 17
+template <>
+struct __is_identity<__identity> : true_type {};
+
+#if _LIBCPP_STD_VER >= 20
 
 struct identity {
     template<class _Tp>
-    _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept
+    _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept
     {
         return _VSTD::forward<_Tp>(__t);
     }
 
     using is_transparent = void;
 };
-#endif // _LIBCPP_STD_VER > 17
+
+template <>
+struct __is_identity<identity> : true_type {};
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/invoke.h
@@ -11,525 +11,16 @@
 #define _LIBCPP___FUNCTIONAL_INVOKE_H
 
 #include <__config>
-#include <__type_traits/add_lvalue_reference.h>
-#include <__type_traits/apply_cv.h>
-#include <__type_traits/conditional.h>
-#include <__type_traits/decay.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_base_of.h>
-#include <__type_traits/is_core_convertible.h>
-#include <__type_traits/is_member_function_pointer.h>
-#include <__type_traits/is_member_object_pointer.h>
-#include <__type_traits/is_reference_wrapper.h>
-#include <__type_traits/is_same.h>
-#include <__type_traits/is_void.h>
-#include <__type_traits/nat.h>
-#include <__type_traits/remove_cv.h>
-#include <__utility/declval.h>
+#include <__type_traits/invoke.h>
 #include <__utility/forward.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-// TODO: Disentangle the type traits and std::invoke properly
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-struct __any
-{
-    __any(...);
-};
-
-template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
-struct __member_pointer_traits_imp
-{
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
-{
-    typedef _Class _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
-{
-    typedef _Class _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
-{
-    typedef _Class const _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
-{
-    typedef _Class const _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
-{
-    typedef _Class volatile _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
-{
-    typedef _Class volatile _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
-{
-    typedef _Class const volatile _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
-{
-    typedef _Class const volatile _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
-{
-    typedef _Class& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
-{
-    typedef _Class& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
-{
-    typedef _Class const& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
-{
-    typedef _Class const& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
-{
-    typedef _Class volatile& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
-{
-    typedef _Class volatile& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
-{
-    typedef _Class const volatile& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
-{
-    typedef _Class const volatile& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
-{
-    typedef _Class&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
-{
-    typedef _Class&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
-{
-    typedef _Class const&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
-{
-    typedef _Class const&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
-{
-    typedef _Class volatile&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
-{
-    typedef _Class volatile&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
-{
-    typedef _Class const volatile&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
-{
-    typedef _Class const volatile&& _ClassType;
-    typedef _Rp _ReturnType;
-    typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class>
-struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
-{
-    typedef _Class _ClassType;
-    typedef _Rp _ReturnType;
-};
-
-template <class _MP>
-struct __member_pointer_traits
-    : public __member_pointer_traits_imp<__remove_cv_t<_MP>,
-                    is_member_function_pointer<_MP>::value,
-                    is_member_object_pointer<_MP>::value>
-{
-//     typedef ... _ClassType;
-//     typedef ... _ReturnType;
-//     typedef ... _FnType;
-};
-
-template <class _DecayedFp>
-struct __member_pointer_class_type {};
-
-template <class _Ret, class _ClassType>
-struct __member_pointer_class_type<_Ret _ClassType::*> {
-  typedef _ClassType type;
-};
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type,
-         class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet1 = typename enable_if
-    <
-        is_member_function_pointer<_DecayFp>::value
-        && is_base_of<_ClassT, _DecayA0>::value
-    >::type;
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type>
-using __enable_if_bullet2 = typename enable_if
-    <
-        is_member_function_pointer<_DecayFp>::value
-        && __is_reference_wrapper<_DecayA0>::value
-    >::type;
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type,
-         class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet3 = typename enable_if
-    <
-        is_member_function_pointer<_DecayFp>::value
-        && !is_base_of<_ClassT, _DecayA0>::value
-        && !__is_reference_wrapper<_DecayA0>::value
-    >::type;
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type,
-         class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet4 = typename enable_if
-    <
-        is_member_object_pointer<_DecayFp>::value
-        && is_base_of<_ClassT, _DecayA0>::value
-    >::type;
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type>
-using __enable_if_bullet5 = typename enable_if
-    <
-        is_member_object_pointer<_DecayFp>::value
-        && __is_reference_wrapper<_DecayA0>::value
-    >::type;
-
-template <class _Fp, class _A0,
-         class _DecayFp = typename decay<_Fp>::type,
-         class _DecayA0 = typename decay<_A0>::type,
-         class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet6 = typename enable_if
-    <
-        is_member_object_pointer<_DecayFp>::value
-        && !is_base_of<_ClassT, _DecayA0>::value
-        && !__is_reference_wrapper<_DecayA0>::value
-    >::type;
-
-// __invoke forward declarations
-
-// fall back - none of the bullets
-
-template <class ..._Args>
-__nat __invoke(__any, _Args&& ...__args);
-
-// bullets 1, 2 and 3
-
-template <class _Fp, class _A0, class ..._Args,
-          class = __enable_if_bullet1<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-    _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
-    { return           (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
-          class = __enable_if_bullet2<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-    _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
-    { return          (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
-          class = __enable_if_bullet3<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-    _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
-    { return          ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
-
-// bullets 4, 5 and 6
-
-template <class _Fp, class _A0,
-          class = __enable_if_bullet4<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>())
-__invoke(_Fp&& __f, _A0&& __a0)
-    _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
-    { return          static_cast<_A0&&>(__a0).*__f; }
-
-template <class _Fp, class _A0,
-          class = __enable_if_bullet5<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>())
-__invoke(_Fp&& __f, _A0&& __a0)
-    _NOEXCEPT_(noexcept(__a0.get().*__f))
-    { return          __a0.get().*__f; }
-
-template <class _Fp, class _A0,
-          class = __enable_if_bullet6<_Fp, _A0> >
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>())
-__invoke(_Fp&& __f, _A0&& __a0)
-    _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
-    { return          (*static_cast<_A0&&>(__a0)).*__f; }
-
-// bullet 7
-
-template <class _Fp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...))
-__invoke(_Fp&& __f, _Args&& ...__args)
-    _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
-    { return          static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
-
-// __invokable
-template <class _Ret, class _Fp, class ..._Args>
-struct __invokable_r
-{
-  template <class _XFp, class ..._XArgs>
-  static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int);
-  template <class _XFp, class ..._XArgs>
-  static __nat __try_call(...);
-
-  // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
-  // or incomplete array types as required by the standard.
-  using _Result = decltype(__try_call<_Fp, _Args...>(0));
-
-  using type = __conditional_t<
-      _IsNotSame<_Result, __nat>::value,
-      __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >,
-      false_type>;
-  static const bool value = type::value;
-};
-template <class _Fp, class ..._Args>
-using __invokable = __invokable_r<void, _Fp, _Args...>;
-
-template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp {
-  static const bool value = false;
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
-{
-    typedef __nothrow_invokable_r_imp _ThisT;
-
-    template <class _Tp>
-    static void __test_noexcept(_Tp) _NOEXCEPT;
-
-#ifdef _LIBCPP_CXX03_LANG
-    static const bool value = false;
-#else
-    static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
-        _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)));
-#endif
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
-{
-#ifdef _LIBCPP_CXX03_LANG
-    static const bool value = false;
-#else
-    static const bool value = noexcept(
-        _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...));
-#endif
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-using __nothrow_invokable_r =
-    __nothrow_invokable_r_imp<
-            __invokable_r<_Ret, _Fp, _Args...>::value,
-            is_void<_Ret>::value,
-            _Ret, _Fp, _Args...
-    >;
-
-template <class _Fp, class ..._Args>
-using __nothrow_invokable =
-    __nothrow_invokable_r_imp<
-            __invokable<_Fp, _Args...>::value,
-            true, void, _Fp, _Args...
-    >;
-
-template <class _Fp, class ..._Args>
-struct __invoke_of
-    : public enable_if<
-        __invokable<_Fp, _Args...>::value,
-        typename __invokable_r<void, _Fp, _Args...>::_Result>
-{
-};
-
-template <class _Ret, bool = is_void<_Ret>::value>
-struct __invoke_void_return_wrapper
-{
-    template <class ..._Args>
-    static _Ret __call(_Args&&... __args) {
-        return std::__invoke(std::forward<_Args>(__args)...);
-    }
-};
-
-template <class _Ret>
-struct __invoke_void_return_wrapper<_Ret, true>
-{
-    template <class ..._Args>
-    static void __call(_Args&&... __args) {
-        std::__invoke(std::forward<_Args>(__args)...);
-    }
-};
-
-#if _LIBCPP_STD_VER > 14
-
-// is_invocable
-
-template <class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable
-    : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
-
-template <class _Ret, class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable_r
-    : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
-
-template <class _Fn, class ..._Args>
-inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
-
-template <class _Ret, class _Fn, class ..._Args>
-inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
-
-// is_nothrow_invocable
-
-template <class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
-    : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
-
-template <class _Ret, class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
-    : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
-
-template <class _Fn, class ..._Args>
-inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
-
-template <class _Ret, class _Fn, class ..._Args>
-inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
-
-template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS invoke_result
-    : __invoke_of<_Fn, _Args...>
-{
-};
-
-template <class _Fn, class... _Args>
-using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Fn, class ..._Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...>
@@ -539,7 +30,26 @@ invoke(_Fn&& __f, _Args&&... __args)
     return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
+
+#if _LIBCPP_STD_VER >= 23
+template <class _Result, class _Fn, class... _Args>
+  requires is_invocable_r_v<_Result, _Fn, _Args...>
+_LIBCPP_HIDE_FROM_ABI constexpr _Result
+invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result, _Fn, _Args...>) {
+    if constexpr (is_void_v<_Result>) {
+        static_cast<void>(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...));
+    } else {
+        // TODO: Use reference_converts_from_temporary_v once implemented
+        // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>;
+        // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>,
+        static_assert(true,
+            "Returning from invoke_r would bind a temporary object to the reference return type, "
+            "which would result in a dangling reference.");
+        return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
+    }
+}
+#endif
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/is_transparent.h
@@ -11,7 +11,8 @@
 #define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
 
 #include <__config>
-#include <type_traits>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/void_t.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -19,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template <class _Tp, class, class = void>
 struct __is_transparent : false_type {};
lib/libcxx/include/__functional/mem_fn.h
@@ -15,7 +15,6 @@
 #include <__functional/invoke.h>
 #include <__functional/weak_result_type.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__functional/not_fn.h
@@ -13,8 +13,11 @@
 #include <__config>
 #include <__functional/invoke.h>
 #include <__functional/perfect_forward.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_move_constructible.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,7 +25,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 struct __not_fn_op {
     template <class... _Args>
@@ -47,7 +50,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) {
     return __not_fn_t<decay_t<_Fn>>(_VSTD::forward<_Fn>(__f));
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/operations.h
@@ -13,6 +13,9 @@
 #include <__config>
 #include <__functional/binary_function.h>
 #include <__functional/unary_function.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/operation_traits.h>
+#include <__type_traits/predicate_traits.h>
 #include <__utility/forward.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -23,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Arithmetic operations
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -38,7 +41,15 @@ struct _LIBCPP_TEMPLATE_VIS plus
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
 
-#if _LIBCPP_STD_VER > 11
+template <class _Tp>
+struct __is_trivial_plus_operation<plus<_Tp>, _Tp, _Tp> : true_type {};
+
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp, class _Up>
+struct __is_trivial_plus_operation<plus<>, _Tp, _Up> : true_type {};
+#endif
+
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS plus<void>
 {
@@ -52,7 +63,7 @@ struct _LIBCPP_TEMPLATE_VIS plus<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -67,7 +78,7 @@ struct _LIBCPP_TEMPLATE_VIS minus
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS minus<void>
 {
@@ -81,7 +92,7 @@ struct _LIBCPP_TEMPLATE_VIS minus<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -96,7 +107,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS multiplies<void>
 {
@@ -110,7 +121,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -125,7 +136,7 @@ struct _LIBCPP_TEMPLATE_VIS divides
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS divides<void>
 {
@@ -139,7 +150,7 @@ struct _LIBCPP_TEMPLATE_VIS divides<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -154,7 +165,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS modulus<void>
 {
@@ -168,7 +179,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -183,7 +194,7 @@ struct _LIBCPP_TEMPLATE_VIS negate
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS negate<void>
 {
@@ -199,7 +210,7 @@ struct _LIBCPP_TEMPLATE_VIS negate<void>
 
 // Bitwise operations
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -214,7 +225,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS bit_and<void>
 {
@@ -228,7 +239,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 struct _LIBCPP_TEMPLATE_VIS bit_not
     : __unary_function<_Tp, _Tp>
@@ -252,7 +263,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -267,7 +278,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS bit_or<void>
 {
@@ -281,7 +292,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -296,7 +307,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
 {
@@ -312,7 +323,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
 
 // Comparison operations
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -327,7 +338,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS equal_to<void>
 {
@@ -341,7 +352,15 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+template <class _Tp>
+struct __is_trivial_equality_predicate<equal_to<_Tp>, _Tp, _Tp> : true_type {};
+
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+struct __is_trivial_equality_predicate<equal_to<>, _Tp, _Tp> : true_type {};
+#endif
+
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -356,7 +375,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
 {
@@ -370,7 +389,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -385,7 +404,7 @@ struct _LIBCPP_TEMPLATE_VIS less
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS less<void>
 {
@@ -399,7 +418,7 @@ struct _LIBCPP_TEMPLATE_VIS less<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -414,7 +433,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS less_equal<void>
 {
@@ -428,7 +447,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -443,7 +462,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
 {
@@ -457,7 +476,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -472,7 +491,7 @@ struct _LIBCPP_TEMPLATE_VIS greater
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS greater<void>
 {
@@ -488,7 +507,7 @@ struct _LIBCPP_TEMPLATE_VIS greater<void>
 
 // Logical operations
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -503,7 +522,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS logical_and<void>
 {
@@ -517,7 +536,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -532,7 +551,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS logical_not<void>
 {
@@ -546,7 +565,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not<void>
 };
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 #else
 template <class _Tp>
@@ -561,7 +580,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_or
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <>
 struct _LIBCPP_TEMPLATE_VIS logical_or<void>
 {
lib/libcxx/include/__functional/perfect_forward.h
@@ -11,19 +11,25 @@
 #define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
 
 #include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_constructible.h>
 #include <__utility/declval.h>
 #include <__utility/forward.h>
+#include <__utility/integer_sequence.h>
 #include <__utility/move.h>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Op, class _Indices, class... _BoundArgs>
 struct __perfect_forward_impl;
@@ -37,14 +43,14 @@ public:
   template <class... _Args, class = enable_if_t<
     is_constructible_v<tuple<_BoundArgs...>, _Args&&...>
   >>
-  explicit constexpr __perfect_forward_impl(_Args&&... __bound_args)
+  _LIBCPP_HIDE_FROM_ABI explicit constexpr __perfect_forward_impl(_Args&&... __bound_args)
     : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {}
 
-  __perfect_forward_impl(__perfect_forward_impl const&) = default;
-  __perfect_forward_impl(__perfect_forward_impl&&) = default;
+  _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default;
 
-  __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
-  __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
+  _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
 
   template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
   _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &
@@ -87,8 +93,10 @@ public:
 template <class _Op, class ..._Args>
 using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
lib/libcxx/include/__functional/ranges_operations.h
@@ -13,6 +13,8 @@
 #include <__concepts/equality_comparable.h>
 #include <__concepts/totally_ordered.h>
 #include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/predicate_traits.h>
 #include <__utility/forward.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -21,14 +23,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
 struct equal_to {
   template <class _Tp, class _Up>
   requires equality_comparable_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) {
     return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u);
   }
@@ -39,7 +41,7 @@ struct equal_to {
 struct not_equal_to {
   template <class _Tp, class _Up>
   requires equality_comparable_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) {
     return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u));
   }
@@ -50,7 +52,7 @@ struct not_equal_to {
 struct less {
   template <class _Tp, class _Up>
   requires totally_ordered_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) {
     return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u);
   }
@@ -61,7 +63,7 @@ struct less {
 struct less_equal {
   template <class _Tp, class _Up>
   requires totally_ordered_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) {
     return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t));
   }
@@ -72,7 +74,7 @@ struct less_equal {
 struct greater {
   template <class _Tp, class _Up>
   requires totally_ordered_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) {
     return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t);
   }
@@ -83,7 +85,7 @@ struct greater {
 struct greater_equal {
   template <class _Tp, class _Up>
   requires totally_ordered_with<_Tp, _Up>
-  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
       noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) {
     return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u));
   }
@@ -93,7 +95,10 @@ struct greater_equal {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+template <class _Lhs, class _Rhs>
+struct __is_trivial_equality_predicate<ranges::equal_to, _Lhs, _Rhs> : true_type {};
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__functional/reference_wrapper.h
@@ -55,12 +55,18 @@ public:
     template <class... _ArgTypes>
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     typename __invoke_of<type&, _ArgTypes...>::type
-    operator() (_ArgTypes&&... __args) const {
+    operator() (_ArgTypes&&... __args) const
+#if _LIBCPP_STD_VER >= 17
+        // Since is_nothrow_invocable requires C++17 LWG3764 is not backported
+        // to earlier versions.
+        noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>)
+#endif
+    {
         return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
     }
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
 #endif
lib/libcxx/include/__fwd/fstream.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_FSTREAM_H
+#define _LIBCPP___FWD_FSTREAM_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_filebuf;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_ifstream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_ofstream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_fstream;
+
+using filebuf  = basic_filebuf<char>;
+using ifstream = basic_ifstream<char>;
+using ofstream = basic_ofstream<char>;
+using fstream  = basic_fstream<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wfilebuf  = basic_filebuf<wchar_t>;
+using wifstream = basic_ifstream<wchar_t>;
+using wofstream = basic_ofstream<wchar_t>;
+using wfstream  = basic_fstream<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf;
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream;
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream;
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_FSTREAM_H
lib/libcxx/include/__fwd/get.h
@@ -15,7 +15,7 @@
 #include <__fwd/pair.h>
 #include <__fwd/subrange.h>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/tuple_element.h>
+#include <__tuple/tuple_element.h>
 #include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/__fwd/ios.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_IOS_H
+#define _LIBCPP___FWD_IOS_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_ios;
+
+using ios = basic_ios<char>;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wios = basic_ios<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
+
+#if defined(_NEWLIB_VERSION)
+// On newlib, off_t is 'long int'
+using streamoff = long int; // for char_traits in <string>
+#else
+using streamoff = long long; // for char_traits in <string>
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_IOS_H
lib/libcxx/include/__fwd/istream.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_ISTREAM_H
+#define _LIBCPP___FWD_ISTREAM_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_istream;
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_iostream;
+
+using istream  = basic_istream<char>;
+using iostream = basic_iostream<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wistream  = basic_istream<wchar_t>;
+using wiostream = basic_iostream<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream;
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_ISTREAM_H
lib/libcxx/include/__fwd/mdspan.h
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_LAYOUTS_H
+#define _LIBCPP___MDSPAN_LAYOUTS_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+// Layout policy with a mapping which corresponds to FORTRAN-style array layouts
+struct layout_left {
+  template <class _Extents>
+  class mapping;
+};
+
+// Layout policy with a mapping which corresponds to C-style array layouts
+struct layout_right {
+  template <class _Extents>
+  class mapping;
+};
+
+/*
+// Will be implemented with follow on revision
+// Layout policy with a unique mapping where strides are arbitrary
+struct layout_stride {
+  template<class Extents>
+    class mapping;
+};
+*/
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_LAYOUTS_H
lib/libcxx/include/__fwd/memory_resource.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H
 #define _LIBCPP___FWD_MEMORY_RESOURCE_H
 
+#include <__availability>
 #include <__config>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace pmr {
 template <class _ValueType>
-class _LIBCPP_TEMPLATE_VIS polymorphic_allocator;
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator;
 } // namespace pmr
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__fwd/ostream.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_OSTREAM_H
+#define _LIBCPP___FWD_OSTREAM_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_ostream;
+
+using ostream = basic_ostream<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wostream = basic_ostream<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_OSTREAM_H
lib/libcxx/include/__fwd/span.h
@@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
 template <typename _Tp, size_t _Extent = dynamic_extent> class span;
lib/libcxx/include/__fwd/sstream.h
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_SSTREAM_H
+#define _LIBCPP___FWD_SSTREAM_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_stringbuf;
+
+template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_istringstream;
+template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_ostringstream;
+template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_stringstream;
+
+using stringbuf     = basic_stringbuf<char>;
+using istringstream = basic_istringstream<char>;
+using ostringstream = basic_ostringstream<char>;
+using stringstream  = basic_stringstream<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wstringbuf     = basic_stringbuf<wchar_t>;
+using wistringstream = basic_istringstream<wchar_t>;
+using wostringstream = basic_ostringstream<wchar_t>;
+using wstringstream  = basic_stringstream<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf;
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_PREFERRED_NAME(istringstream)
+    _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream;
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_PREFERRED_NAME(ostringstream)
+    _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream;
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_PREFERRED_NAME(stringstream)
+    _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_SSTREAM_H
lib/libcxx/include/__fwd/streambuf.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_STREAMBUF_H
+#define _LIBCPP___FWD_STREAMBUF_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_streambuf;
+
+using streambuf = basic_streambuf<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wstreambuf = basic_streambuf<wchar_t>;
+#endif
+
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_STREAMBUF_H
lib/libcxx/include/__fwd/string.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___FWD_STRING_H
 #define _LIBCPP___FWD_STRING_H
 
+#include <__availability>
 #include <__config>
 #include <__fwd/memory_resource.h>
 
@@ -61,21 +62,20 @@ using u32string = basic_string<char32_t>;
 
 namespace pmr {
 template <class _CharT, class _Traits = char_traits<_CharT>>
-using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
+using basic_string _LIBCPP_AVAILABILITY_PMR = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
 
-using string = basic_string<char>;
+using string _LIBCPP_AVAILABILITY_PMR = basic_string<char>;
 
 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wstring = basic_string<wchar_t>;
+using wstring _LIBCPP_AVAILABILITY_PMR = basic_string<wchar_t>;
 #  endif
 
 #  ifndef _LIBCPP_HAS_NO_CHAR8_T
-using u8string = basic_string<char8_t>;
+using u8string _LIBCPP_AVAILABILITY_PMR = basic_string<char8_t>;
 #  endif
 
-using u16string = basic_string<char16_t>;
-using u32string = basic_string<char32_t>;
-
+using u16string _LIBCPP_AVAILABILITY_PMR = basic_string<char16_t>;
+using u32string _LIBCPP_AVAILABILITY_PMR = basic_string<char32_t>;
 } // namespace pmr
 
 #endif // _LIBCPP_STD_VER >= 17
lib/libcxx/include/__iterator/access.h
@@ -69,7 +69,7 @@ end(const _Cp& __c) -> decltype(__c.end())
     return __c.end();
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template <class _Cp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
lib/libcxx/include/__iterator/advance.h
@@ -23,13 +23,15 @@
 #include <__utility/declval.h>
 #include <__utility/move.h>
 #include <__utility/unreachable.h>
-#include <cstdlib>
 #include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIter>
@@ -64,12 +66,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
 void advance(_InputIter& __i, _Distance __orig_n) {
   typedef typename iterator_traits<_InputIter>::difference_type _Difference;
   _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n));
-  _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
-                 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
+                               "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
   _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.iter.op.advance]
 
@@ -101,8 +103,8 @@ public:
   template <input_or_output_iterator _Ip>
   _LIBCPP_HIDE_FROM_ABI
   constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
-    _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
-                   "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || bidirectional_iterator<_Ip>,
+                                 "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
 
     // If `I` models `random_access_iterator`, equivalent to `i += n`.
     if constexpr (random_access_iterator<_Ip>) {
@@ -148,8 +150,8 @@ public:
   template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
   _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n,
                                                                     _Sp __bound_sentinel) const {
-    _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
-                   "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
+    _LIBCPP_ASSERT_UNCATEGORIZED((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
+                                 "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
     // If `S` and `I` model `sized_sentinel_for<S, I>`:
     if constexpr (sized_sentinel_for<_Sp, _Ip>) {
       // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`.
@@ -159,9 +161,9 @@ public:
                __a > 0  ? __a >= __b :
                           __a <= __b;
       };
-      if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) {
+      if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) {
         (*this)(__i, __bound_sentinel);
-        return __n - __M;
+        return __n - __m;
       }
 
       // Otherwise, equivalent to `ranges::advance(i, n)`.
@@ -196,8 +198,10 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_ADVANCE_H
lib/libcxx/include/__iterator/back_insert_iterator.h
@@ -21,6 +21,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
@@ -36,7 +39,7 @@ protected:
 public:
     typedef output_iterator_tag iterator_category;
     typedef void value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t difference_type;
 #else
     typedef void difference_type;
@@ -70,4 +73,6 @@ back_inserter(_Container& __x)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/bounded_iter.h
@@ -23,6 +23,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Iterator wrapper that carries the valid range it is allowed to access.
@@ -35,14 +38,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // Arithmetic operations are allowed and the bounds of the resulting iterator
 // are not checked. Hence, it is possible to create an iterator pointing outside
 // its range, but it is not possible to dereference it.
-template <class _Iterator, class = __enable_if_t< __is_cpp17_contiguous_iterator<_Iterator>::value > >
+template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > >
 struct __bounded_iter {
   using value_type        = typename iterator_traits<_Iterator>::value_type;
   using difference_type   = typename iterator_traits<_Iterator>::difference_type;
   using pointer           = typename iterator_traits<_Iterator>::pointer;
   using reference         = typename iterator_traits<_Iterator>::reference;
   using iterator_category = typename iterator_traits<_Iterator>::iterator_category;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   using iterator_concept = contiguous_iterator_tag;
 #endif
 
@@ -78,7 +81,7 @@ private:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter(
       _Iterator __current, _Iterator __begin, _Iterator __end)
       : __current_(__current), __begin_(__begin), __end_(__end) {
-    _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
+    _LIBCPP_ASSERT_INTERNAL(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
   }
 
   template <class _It>
@@ -89,19 +92,19 @@ public:
   //
   // These operations check that the iterator is dereferenceable, that is within [begin, end).
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT {
-    _LIBCPP_ASSERT(
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
         __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator");
     return *__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
-    _LIBCPP_ASSERT(
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
         __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator");
     return std::__to_address(__current_);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
-    _LIBCPP_ASSERT(
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
         __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
     return __current_[__n];
   }
@@ -212,7 +215,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(
 
 #if _LIBCPP_STD_VER <= 17
 template <class _Iterator>
-struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
+struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
 #endif
 
 template <class _Iterator>
@@ -228,4 +231,6 @@ struct pointer_traits<__bounded_iter<_Iterator> > {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H
lib/libcxx/include/__iterator/common_iterator.h
@@ -25,6 +25,7 @@
 #include <__iterator/iter_swap.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/readable_traits.h>
+#include <__memory/addressof.h>
 #include <__type_traits/is_pointer.h>
 #include <__utility/declval.h>
 #include <variant>
@@ -33,9 +34,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<class _Iter>
 concept __can_use_postfix_proxy =
@@ -46,14 +50,14 @@ template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
   requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
 class common_iterator {
   struct __proxy {
-    constexpr const iter_value_t<_Iter>* operator->() const noexcept {
+    _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept {
       return _VSTD::addressof(__value_);
     }
     iter_value_t<_Iter> __value_;
   };
 
   struct __postfix_proxy {
-    constexpr const iter_value_t<_Iter>& operator*() const noexcept {
+    _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept {
       return __value_;
     }
     iter_value_t<_Iter> __value_;
@@ -62,16 +66,17 @@ class common_iterator {
 public:
   variant<_Iter, _Sent> __hold_;
 
-  common_iterator() requires default_initializable<_Iter> = default;
+  _LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default;
 
-  constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
-  constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
 
   template<class _I2, class _S2>
     requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent>
-  constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
+  _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
     : __hold_([&]() -> variant<_Iter, _Sent> {
-      _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator");
+      _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(),
+                                   "Attempted to construct from a valueless common_iterator");
       if (__other.__hold_.index() == 0)
         return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)};
       return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)};
@@ -80,8 +85,9 @@ public:
   template<class _I2, class _S2>
     requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> &&
              assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&>
-  common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
-    _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator");
+  _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(),
+                                 "Attempted to assign from a valueless common_iterator");
 
     auto __idx = __hold_.index();
     auto __other_idx = __other.__hold_.index();
@@ -101,27 +107,30 @@ public:
     return *this;
   }
 
-  constexpr decltype(auto) operator*()
+  _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*()
   {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
+                                 "Attempted to dereference a non-dereferenceable common_iterator");
     return *_VSTD::__unchecked_get<_Iter>(__hold_);
   }
 
-  constexpr decltype(auto) operator*() const
+  _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
     requires __dereferenceable<const _Iter>
   {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
+                                 "Attempted to dereference a non-dereferenceable common_iterator");
     return *_VSTD::__unchecked_get<_Iter>(__hold_);
   }
 
   template<class _I2 = _Iter>
-  decltype(auto) operator->() const
+  _LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const
     requires indirectly_readable<const _I2> &&
     (requires(const _I2& __i) { __i.operator->(); } ||
      is_reference_v<iter_reference_t<_I2>> ||
      constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
   {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
+                                 "Attempted to dereference a non-dereferenceable common_iterator");
     if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); })    {
       return _VSTD::__unchecked_get<_Iter>(__hold_);
     } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
@@ -132,13 +141,15 @@ public:
     }
   }
 
-  common_iterator& operator++() {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
+  _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() {
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
+                                 "Attempted to increment a non-dereferenceable common_iterator");
     ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
   }
 
-  decltype(auto) operator++(int) {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
+  _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
+                                 "Attempted to increment a non-dereferenceable common_iterator");
     if constexpr (forward_iterator<_Iter>) {
       auto __tmp = *this;
       ++*this;
@@ -157,8 +168,10 @@ public:
     requires sentinel_for<_Sent, _I2>
   _LIBCPP_HIDE_FROM_ABI
   friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
-    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
-    _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
+                                 "Attempted to compare a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
+                                 "Attempted to compare a valueless common_iterator");
 
     auto __x_index = __x.__hold_.index();
     auto __y_index = __y.__hold_.index();
@@ -176,8 +189,10 @@ public:
     requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2>
   _LIBCPP_HIDE_FROM_ABI
   friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
-    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
-    _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
+                                 "Attempted to compare a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
+                                 "Attempted to compare a valueless common_iterator");
 
     auto __x_index = __x.__hold_.index();
     auto __y_index = __y.__hold_.index();
@@ -198,8 +213,10 @@ public:
     requires sized_sentinel_for<_Sent, _I2>
   _LIBCPP_HIDE_FROM_ABI
   friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
-    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator");
-    _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
+                                 "Attempted to subtract from a valueless common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
+                                 "Attempted to subtract a valueless common_iterator");
 
     auto __x_index = __x.__hold_.index();
     auto __y_index = __y.__hold_.index();
@@ -220,7 +237,8 @@ public:
     noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>())))
       requires input_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__i.__hold_),
+                                 "Attempted to iter_move a non-dereferenceable common_iterator");
     return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
   }
 
@@ -228,8 +246,10 @@ public:
   _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
       noexcept(noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>())))
   {
-    _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
-    _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__x.__hold_),
+                                 "Attempted to iter_swap a non-dereferenceable common_iterator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_I2>(__y.__hold_),
+                                 "Attempted to iter_swap a non-dereferenceable common_iterator");
     return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_));
   }
 };
@@ -274,8 +294,10 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> {
   using reference = iter_reference_t<_Iter>;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H
lib/libcxx/include/__iterator/concepts.h
@@ -46,7 +46,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [iterator.concept.readable]
 template<class _In>
@@ -293,7 +293,7 @@ concept indirectly_copyable_storable =
 // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
 // (both iter_swap and indirectly_swappable require indirectly_readable).
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/counted_iterator.h
@@ -34,9 +34,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<class>
 struct __counted_iterator_concept {};
@@ -83,7 +86,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI
   constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n)
    : __current_(_VSTD::move(__iter)), __count_(__n) {
-    _LIBCPP_ASSERT(__n >= 0, "__n must not be negative.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "__n must not be negative.");
   }
 
   template<class _I2>
@@ -112,7 +115,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI
   constexpr decltype(auto) operator*() {
-    _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end.");
     return *__current_;
   }
 
@@ -120,7 +123,7 @@ public:
   constexpr decltype(auto) operator*() const
     requires __dereferenceable<const _Iter>
   {
-    _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end.");
     return *__current_;
   }
 
@@ -133,7 +136,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI
   constexpr counted_iterator& operator++() {
-    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
     ++__current_;
     --__count_;
     return *this;
@@ -141,21 +144,21 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI
   decltype(auto) operator++(int) {
-    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
     --__count_;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try { return __current_++; }
     catch(...) { ++__count_; throw; }
 #else
     return __current_++;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
   }
 
   _LIBCPP_HIDE_FROM_ABI
   constexpr counted_iterator operator++(int)
     requires forward_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
     counted_iterator __tmp = *this;
     ++*this;
     return __tmp;
@@ -198,7 +201,7 @@ public:
   constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n)
     requires random_access_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __count_, "Cannot advance iterator past end.");
     __current_ += __n;
     __count_ -= __n;
     return *this;
@@ -237,9 +240,10 @@ public:
   constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n)
     requires random_access_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: "
-                                     "counted_iterator would be decremented before the "
-                                     "first element of its range.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(-__n <= __count_,
+                                 "Attempt to subtract too large of a size: "
+                                 "counted_iterator would be decremented before the "
+                                 "first element of its range.");
     __current_ -= __n;
     __count_ += __n;
     return *this;
@@ -249,7 +253,7 @@ public:
   constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
     requires random_access_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n < __count_, "Subscript argument must be less than size.");
     return __current_[__n];
   }
 
@@ -280,7 +284,7 @@ public:
     noexcept(noexcept(ranges::iter_move(__i.__current_)))
       requires input_iterator<_Iter>
   {
-    _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__i.__count_ > 0, "Iterator must not be past end of range.");
     return ranges::iter_move(__i.__current_);
   }
 
@@ -289,8 +293,8 @@ public:
   friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y)
     noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
   {
-    _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0,
-                   "Iterators must not be past end of range.");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__x.__count_ > 0 && __y.__count_ > 0,
+                                 "Iterators must not be past end of range.");
     return ranges::iter_swap(__x.__current_, __y.__current_);
   }
 };
@@ -303,8 +307,10 @@ struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
                                 add_pointer_t<iter_reference_t<_Iter>>, void>;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
lib/libcxx/include/__iterator/cpp17_iterator_concepts.h
@@ -0,0 +1,185 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
+#define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
+
+#include <__concepts/boolean_testable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/is_void.h>
+#include <__utility/as_const.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+concept __cpp17_move_constructible = is_move_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs = std::move(__rhs) } -> same_as<_Tp&>;
+};
+
+template <class _Tp>
+concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs = __rhs } -> same_as<_Tp&>;
+  { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>;
+};
+
+template <class _Tp>
+concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); };
+
+template <class _Tp>
+concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs == __rhs } -> __boolean_testable;
+  { std::as_const(__lhs) == __rhs } -> __boolean_testable;
+  { __lhs == std::as_const(__rhs) } -> __boolean_testable;
+  { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable;
+};
+
+template <class _Tp>
+concept __cpp17_default_constructible = is_default_constructible_v<_Tp>;
+
+template <class _Iter>
+concept __cpp17_iterator =
+    __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> &&
+    (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>)&&requires(_Iter __iter) {
+      { *__iter };
+      { ++__iter } -> same_as<_Iter&>;
+    };
+
+template <class _Iter>
+concept __cpp17_input_iterator =
+    __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) {
+      { __lhs != __rhs } -> __boolean_testable;
+      { std::as_const(__lhs) != __rhs } -> __boolean_testable;
+      { __lhs != std::as_const(__rhs) } -> __boolean_testable;
+      { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable;
+
+      { *__lhs } -> same_as<__iter_reference<_Iter>>;
+      { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>;
+
+      { ++__lhs } -> same_as<_Iter&>;
+      { (void)__lhs++ };
+      { *__lhs++ };
+    };
+
+template <class _Iter, class _WriteTo>
+concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) {
+  { *__iter = std::forward<_WriteTo>(__write) };
+  { ++__iter } -> same_as<_Iter&>;
+  { __iter++ } -> convertible_to<const _Iter&>;
+  { *__iter++ = std::forward<_WriteTo>(__write) };
+};
+
+template <class _Iter>
+concept __cpp17_forward_iterator =
+    __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) {
+      { __iter++ } -> convertible_to<const _Iter&>;
+      { *__iter++ } -> same_as<__iter_reference<_Iter>>;
+    };
+
+template <class _Iter>
+concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) {
+  { --__iter } -> same_as<_Iter&>;
+  { __iter-- } -> convertible_to<const _Iter&>;
+  { *__iter-- } -> same_as<__iter_reference<_Iter>>;
+};
+
+template <class _Iter>
+concept __cpp17_random_access_iterator =
+    __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) {
+      { __iter += __n } -> same_as<_Iter&>;
+
+      { __iter + __n } -> same_as<_Iter>;
+      { __n + __iter } -> same_as<_Iter>;
+      { std::as_const(__iter) + __n } -> same_as<_Iter>;
+      { __n + std::as_const(__iter) } -> same_as<_Iter>;
+
+      { __iter -= __n } -> same_as<_Iter&>;
+      { __iter - __n } -> same_as<_Iter>;
+      { std::as_const(__iter) - __n } -> same_as<_Iter>;
+
+      { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>;
+      { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>;
+      { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
+      { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
+
+      { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>;
+      { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>;
+
+      { __iter < __iter } -> __boolean_testable;
+      { std::as_const(__iter) < __iter } -> __boolean_testable;
+      { __iter < std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter > __iter } -> __boolean_testable;
+      { std::as_const(__iter) > __iter } -> __boolean_testable;
+      { __iter > std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter >= __iter } -> __boolean_testable;
+      { std::as_const(__iter) >= __iter } -> __boolean_testable;
+      { __iter >= std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter <= __iter } -> __boolean_testable;
+      { std::as_const(__iter) <= __iter } -> __boolean_testable;
+      { __iter <= std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable;
+    };
+
+_LIBCPP_END_NAMESPACE_STD
+
+#  ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS
+#    define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) static_assert(::std::__cpp17_input_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)                                                     \
+      static_assert(::std::__cpp17_output_iterator<iter_t, write_t>);
+#    define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) static_assert(::std::__cpp17_forward_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)                                                       \
+      static_assert(::std::__cpp17_bidirectional_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)                                                       \
+      static_assert(::std::__cpp17_random_access_iterator<iter_t>);
+#  else
+#    define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
+#    define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+#  endif
+
+#else // _LIBCPP_STD_VER >= 20
+
+#  define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
+#  define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
lib/libcxx/include/__iterator/data.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Cont> constexpr
 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__iterator/default_sentinel.h
@@ -18,12 +18,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 struct default_sentinel_t { };
 inline constexpr default_sentinel_t default_sentinel{};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/distance.h
@@ -53,7 +53,7 @@ distance(_InputIter __first, _InputIter __last)
     return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.iter.op.distance]
 
@@ -101,7 +101,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/empty.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Cont>
 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
@@ -37,7 +37,7 @@ template <class _Ep>
 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
 constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/erase_if_container.h
@@ -16,6 +16,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Container, class _Predicate>
@@ -37,4 +40,6 @@ __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
lib/libcxx/include/__iterator/front_insert_iterator.h
@@ -21,6 +21,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
@@ -36,7 +39,7 @@ protected:
 public:
     typedef output_iterator_tag iterator_category;
     typedef void value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t difference_type;
 #else
     typedef void difference_type;
@@ -68,4 +71,6 @@ front_inserter(_Container& __x)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/incrementable_traits.h
@@ -26,7 +26,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [incrementable.traits]
 template<class> struct incrementable_traits {};
@@ -71,7 +71,7 @@ using iter_difference_t = typename conditional_t<__is_primary_template<iterator_
                                                  incrementable_traits<remove_cvref_t<_Ip> >,
                                                  iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/indirectly_comparable.h
@@ -21,13 +21,13 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity>
 concept indirectly_comparable =
   indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/insert_iterator.h
@@ -22,9 +22,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Container>
 using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
 #else
@@ -46,7 +49,7 @@ protected:
 public:
     typedef output_iterator_tag iterator_category;
     typedef void value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t difference_type;
 #else
     typedef void difference_type;
@@ -78,4 +81,6 @@ inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/istream_iterator.h
@@ -47,9 +47,9 @@ private:
     _Tp __value_;
 public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
         {
             if (!(*__in_stream_ >> __value_))
@@ -73,11 +73,11 @@ public:
     operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
                const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) {
       return __i.__in_stream_ == nullptr;
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _Tp, class _CharT, class _Traits, class _Distance>
lib/libcxx/include/__iterator/istreambuf_iterator.h
@@ -67,10 +67,10 @@ private:
     }
 public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept
         : istreambuf_iterator() {}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
         : __sbuf_(__s.rdbuf()) {}
     _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
@@ -93,11 +93,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
         {return __test_for_eof() == __b.__test_for_eof();}
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) {
       return __i.__test_for_eof();
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _CharT, class _Traits>
lib/libcxx/include/__iterator/iter_move.h
@@ -23,9 +23,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [iterator.cust.move]
 
@@ -97,8 +100,10 @@ template<__dereferenceable _Tp>
   requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; }
 using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>()));
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_ITER_MOVE_H
lib/libcxx/include/__iterator/iter_swap.h
@@ -26,9 +26,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [iter.cust.swap]
 
@@ -106,8 +109,10 @@ concept indirectly_swappable =
     ranges::iter_swap(__i2, __i1);
   };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_ITER_SWAP_H
lib/libcxx/include/__iterator/iterator_traits.h
@@ -43,7 +43,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Tp>
 using __with_reference = _Tp&;
@@ -62,7 +62,7 @@ concept __dereferenceable = requires(_Tp& __t) {
 template<__dereferenceable _Tp>
 using iter_reference_t = decltype(*std::declval<_Tp&>());
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _Iter>
 struct _LIBCPP_TEMPLATE_VIS iterator_traits;
@@ -72,7 +72,7 @@ struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
 struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag       : public input_iterator_tag {};
 struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
 struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag    : public random_access_iterator_tag {};
 #endif
 
@@ -157,7 +157,7 @@ public:
     static const bool value = decltype(__test<_Tp>(nullptr))::value;
 };
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
 // from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to
@@ -190,7 +190,7 @@ template<class _Ip>
 concept __cpp17_forward_iterator =
   __cpp17_input_iterator<_Ip> &&
   constructible_from<_Ip> &&
-  is_lvalue_reference_v<iter_reference_t<_Ip>> &&
+  is_reference_v<iter_reference_t<_Ip>> &&
   same_as<remove_cvref_t<iter_reference_t<_Ip>>,
           typename indirectly_readable_traits<_Ip>::value_type> &&
   requires(_Ip __i) {
@@ -381,7 +381,7 @@ struct iterator_traits : __iterator_traits<_Ip> {
   using __primary_template = iterator_traits;
 };
 
-#else // _LIBCPP_STD_VER > 17
+#else // _LIBCPP_STD_VER >= 20
 
 template <class _Iter, bool> struct __iterator_traits {};
 
@@ -418,10 +418,10 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits
 
   using __primary_template = iterator_traits;
 };
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template<class _Tp>
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 requires is_object_v<_Tp>
 #endif
 struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
@@ -431,7 +431,7 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
     typedef _Tp* pointer;
     typedef _Tp& reference;
     typedef random_access_iterator_tag iterator_category;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef contiguous_iterator_tag    iterator_concept;
 #endif
 };
@@ -453,60 +453,60 @@ template <class _Tp, class _Up>
 struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
 
 template <class _Tp>
-struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
+using __has_input_iterator_category = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;
 
 template <class _Tp>
-struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
+using __has_forward_iterator_category = __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>;
 
 template <class _Tp>
-struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
+using __has_bidirectional_iterator_category = __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>;
 
 template <class _Tp>
-struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
+using __has_random_access_iterator_category = __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>;
 
-// __is_cpp17_contiguous_iterator determines if an iterator is known by
+// __libcpp_is_contiguous_iterator determines if an iterator is known by
 // libc++ to be contiguous, either because it advertises itself as such
 // (in C++20) or because it is a pointer type or a known trivial wrapper
 // around a (possibly fancy) pointer type, such as __wrap_iter<T*>.
 // Such iterators receive special "contiguous" optimizations in
 // std::copy and std::sort.
 //
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp>
-struct __is_cpp17_contiguous_iterator : _Or<
+struct __libcpp_is_contiguous_iterator : _Or<
     __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>,
     __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag>
 > {};
 #else
 template <class _Tp>
-struct __is_cpp17_contiguous_iterator : false_type {};
+struct __libcpp_is_contiguous_iterator : false_type {};
 #endif
 
 // Any native pointer which is an iterator is also a contiguous iterator.
 template <class _Up>
-struct __is_cpp17_contiguous_iterator<_Up*> : true_type {};
+struct __libcpp_is_contiguous_iterator<_Up*> : true_type {};
 
 
 template <class _Iter>
 class __wrap_iter;
 
 template <class _Tp>
-struct __is_exactly_cpp17_input_iterator
-    : public integral_constant<bool,
+using __has_exactly_input_iterator_category
+    = integral_constant<bool,
          __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
-        !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
+        !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>;
 
 template <class _Tp>
-struct __is_exactly_cpp17_forward_iterator
-    : public integral_constant<bool,
+using __has_exactly_forward_iterator_category
+    = integral_constant<bool,
          __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value &&
-        !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {};
+        !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>;
 
 template <class _Tp>
-struct __is_exactly_cpp17_bidirectional_iterator
-    : public integral_constant<bool,
+using __has_exactly_bidirectional_iterator_category
+    = integral_constant<bool,
          __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value &&
-        !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {};
+        !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>;
 
 template<class _InputIterator>
 using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
@@ -531,8 +531,23 @@ using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer;
 template <class _Iter>
 using __iter_diff_t = typename iterator_traits<_Iter>::difference_type;
 
-template<class _InputIterator>
-using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
+template <class _Iter>
+using __iter_reference = typename iterator_traits<_Iter>::reference;
+
+#if _LIBCPP_STD_VER >= 20
+
+// [readable.traits]
+
+// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
+// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
+// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
+// This has to be in this file and not readable_traits.h to break the include cycle between the two.
+template <class _Ip>
+using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
+                                            indirectly_readable_traits<remove_cvref_t<_Ip> >,
+                                            iterator_traits<remove_cvref_t<_Ip> > >::value_type;
+
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/mergeable.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Input1, class _Input2, class _Output,
           class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
@@ -34,7 +34,7 @@ concept mergeable =
     indirectly_copyable<_Input2, _Output> &&
     indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/move_iterator.h
@@ -39,9 +39,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template<class _Iter, class = void>
 struct __move_iter_category_base {};
 
@@ -59,18 +62,33 @@ template<class _Iter, class _Sent>
 concept __move_iter_comparable = requires {
     { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
 };
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _Iter>
 class _LIBCPP_TEMPLATE_VIS move_iterator
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     : public __move_iter_category_base<_Iter>
 #endif
 {
+    #if _LIBCPP_STD_VER >= 20
+private:
+    _LIBCPP_HIDE_FROM_ABI
+    static constexpr auto __get_iter_concept() {
+        if constexpr (random_access_iterator<_Iter>) {
+            return random_access_iterator_tag{};
+        } else if constexpr (bidirectional_iterator<_Iter>) {
+            return bidirectional_iterator_tag{};
+        } else if constexpr (forward_iterator<_Iter>) {
+            return forward_iterator_tag{};
+        } else {
+            return input_iterator_tag{};
+        }
+    }
+#endif // _LIBCPP_STD_VER >= 20
 public:
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using iterator_type = _Iter;
-    using iterator_concept = input_iterator_tag;
+    using iterator_concept = decltype(__get_iter_concept());
     // iterator_category is inherited and not always present
     using value_type = iter_value_t<_Iter>;
     using difference_type = iter_difference_t<_Iter>;
@@ -79,7 +97,7 @@ public:
 #else
     typedef _Iter iterator_type;
     typedef _If<
-        __is_cpp17_random_access_iterator<_Iter>::value,
+        __has_random_access_iterator_category<_Iter>::value,
         random_access_iterator_tag,
         typename iterator_traits<_Iter>::iterator_category
     > iterator_category;
@@ -93,7 +111,7 @@ public:
             __libcpp_remove_reference_t<__reference>&&,
             __reference
         >::type reference;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
@@ -104,7 +122,7 @@ public:
     _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     pointer operator->() const { return __current_; }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_HIDE_FROM_ABI constexpr
     move_iterator() requires is_constructible_v<_Iter> : __current_() {}
 
@@ -171,7 +189,7 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     move_iterator& operator--() { --__current_; return *this; }
@@ -186,7 +204,7 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template<sentinel_for<_Iter> _Sent>
     friend _LIBCPP_HIDE_FROM_ABI constexpr
     bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
@@ -223,7 +241,7 @@ public:
     {
         return ranges::iter_swap(__x.__current_, __y.__current_);
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 private:
     template<class _It2> friend class move_iterator;
@@ -276,7 +294,7 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _
     return __x.base() >= __y.base();
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
 inline _LIBCPP_HIDE_FROM_ABI constexpr
 auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
@@ -284,7 +302,7 @@ auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>&
 {
     return __x.base() <=> __y.base();
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Iter1, class _Iter2>
@@ -304,7 +322,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
 }
 #endif // !_LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Iter>
 inline _LIBCPP_HIDE_FROM_ABI constexpr
 move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
@@ -320,7 +338,7 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato
 {
     return move_iterator<_Iter>(__x.base() + __n);
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _Iter>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
@@ -332,4 +350,6 @@ make_move_iterator(_Iter __i)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
lib/libcxx/include/__iterator/move_sentinel.h
@@ -19,9 +19,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <semiregular _Sent>
 class _LIBCPP_TEMPLATE_VIS move_sentinel
@@ -44,7 +47,7 @@ public:
   move_sentinel& operator=(const move_sentinel<_S2>& __s)
     { __last_ = __s.base(); return *this; }
 
-  constexpr _Sent base() const { return __last_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; }
 
 private:
     _Sent __last_ = _Sent();
@@ -52,8 +55,10 @@ private:
 
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel);
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H
lib/libcxx/include/__iterator/next.h
@@ -26,16 +26,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIter>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
+    typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
     next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
-  _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
-                 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
+                               "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
 
   _VSTD::advance(__x, __n);
   return __x;
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.iter.op.next]
 
@@ -77,7 +77,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/ostream_iterator.h
@@ -34,7 +34,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
     typedef output_iterator_tag             iterator_category;
     typedef void                            value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t                       difference_type;
 #else
     typedef void                            difference_type;
lib/libcxx/include/__iterator/ostreambuf_iterator.h
@@ -33,7 +33,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
     typedef output_iterator_tag                 iterator_category;
     typedef void                                value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t                           difference_type;
 #else
     typedef void                                difference_type;
lib/libcxx/include/__iterator/permutable.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Iterator>
 concept permutable =
@@ -28,7 +28,7 @@ concept permutable =
     indirectly_movable_storable<_Iterator, _Iterator> &&
     indirectly_swappable<_Iterator, _Iterator>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/prev.h
@@ -26,15 +26,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIter>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
+    typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
     prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
-  _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
-                 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
+                               "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
   _VSTD::advance(__x, -__n);
   return __x;
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.iter.op.prev]
 
@@ -70,7 +70,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/projected.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
 struct projected {
@@ -34,7 +34,7 @@ struct incrementable_traits<projected<_It, _Proj>> {
   using difference_type = iter_difference_t<_It>;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/ranges_iterator_traits.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___ITERATOR_RANGES_ITERATOR_TRAITS_H
+#define _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H
+
+#include <__config>
+#include <__fwd/pair.h>
+#include <__ranges/concepts.h>
+#include <__type_traits/add_const.h>
+#include <__type_traits/remove_const.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range>
+using __range_key_type = __remove_const_t<typename ranges::range_value_t<_Range>::first_type>;
+
+template <ranges::input_range _Range>
+using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type;
+
+template <ranges::input_range _Range>
+using __range_to_alloc_type =
+    pair<add_const_t<typename ranges::range_value_t<_Range>::first_type>,
+         typename ranges::range_value_t<_Range>::second_type>;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H
lib/libcxx/include/__iterator/readable_traits.h
@@ -26,7 +26,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [readable.traits]
 template<class> struct __cond_value_type {};
@@ -74,18 +74,7 @@ template<__has_member_value_type _Tp>
 struct indirectly_readable_traits<_Tp>
   : __cond_value_type<typename _Tp::value_type> {};
 
-template <class>
-struct iterator_traits;
-
-// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
-// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
-// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
-template <class _Ip>
-using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
-                                            indirectly_readable_traits<remove_cvref_t<_Ip> >,
-                                            iterator_traits<remove_cvref_t<_Ip> > >::value_type;
-
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/reverse_access.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template <class _Tp, size_t _Np>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
@@ -93,7 +93,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
     return _VSTD::rend(__c);
 }
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/reverse_iterator.h
@@ -63,21 +63,21 @@ private:
     _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
 #endif
 
-#if _LIBCPP_STD_VER > 17
-    static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>,
+#if _LIBCPP_STD_VER >= 20
+    static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>,
         "reverse_iterator<It> requires It to be a bidirectional iterator.");
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 protected:
     _Iter current;
 public:
     using iterator_type = _Iter;
 
-    using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value,
+    using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value,
                                   random_access_iterator_tag,
                                   typename iterator_traits<_Iter>::iterator_category>;
     using pointer = typename iterator_traits<_Iter>::pointer;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>;
     using value_type = iter_value_t<_Iter>;
     using difference_type = iter_difference_t<_Iter>;
@@ -144,7 +144,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference operator*() const {_Iter __tmp = current; return *--__tmp;}
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     constexpr pointer operator->() const
       requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
@@ -160,7 +160,7 @@ public:
     pointer operator->() const {
       return std::addressof(operator*());
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reverse_iterator& operator++() {--current; return *this;}
@@ -181,7 +181,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference operator[](difference_type __n) const {return *(*this + __n);}
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_HIDE_FROM_ABI friend constexpr
     iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
       noexcept(is_nothrow_copy_constructible_v<_Iter> &&
@@ -200,18 +200,18 @@ public:
       auto __ytmp = __y.base();
       ranges::iter_swap(--__xtmp, --__ytmp);
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
       { __x.base() == __y.base() } -> convertible_to<bool>;
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() == __y.base();
 }
@@ -220,11 +220,11 @@ template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
         { __x.base() > __y.base() } -> convertible_to<bool>;
       }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() > __y.base();
 }
@@ -233,11 +233,11 @@ template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
       { __x.base() != __y.base() } -> convertible_to<bool>;
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() != __y.base();
 }
@@ -246,11 +246,11 @@ template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
         { __x.base() < __y.base() } -> convertible_to<bool>;
       }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() < __y.base();
 }
@@ -259,11 +259,11 @@ template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
         { __x.base() <= __y.base() } -> convertible_to<bool>;
       }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() <= __y.base();
 }
@@ -272,16 +272,16 @@ template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 bool
 operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     requires requires {
         { __x.base() >= __y.base() } -> convertible_to<bool>;
       }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 {
     return __x.base() >= __y.base();
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
 _LIBCPP_HIDE_FROM_ABI constexpr
 compare_three_way_result_t<_Iter1, _Iter2>
@@ -289,7 +289,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
 {
     return __y.base() <=> __x.base();
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Iter1, class _Iter2>
@@ -318,13 +318,13 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i
     return reverse_iterator<_Iter>(__x.base() - __n);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Iter1, class _Iter2>
   requires (!sized_sentinel_for<_Iter1, _Iter2>)
 inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Iter>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
@@ -365,11 +365,11 @@ class __unconstrained_reverse_iterator {
   _Iter __iter_;
 
 public:
-  static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>);
+  static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>);
 
   using iterator_type = _Iter;
   using iterator_category =
-      _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
+      _If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
   using pointer = __iterator_pointer_type<_Iter>;
   using value_type = iter_value_t<_Iter>;
   using difference_type = iter_difference_t<_Iter>;
@@ -498,7 +498,7 @@ struct __unwrap_reverse_iter_impl {
   }
 };
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <ranges::bidirectional_range _Range>
 _LIBCPP_HIDE_FROM_ABI constexpr ranges::
     subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>>
@@ -512,7 +512,7 @@ template <class _Iter, bool __b>
 struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b>
     : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {};
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Iter, bool __b>
 struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
@@ -526,7 +526,7 @@ template <class _Iter, bool __b>
 struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
     : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/size.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Cont>
 _LIBCPP_INLINE_VISIBILITY
@@ -34,7 +34,7 @@ template <class _Tp, size_t _Sz>
 _LIBCPP_INLINE_VISIBILITY
 constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Cont>
 _LIBCPP_INLINE_VISIBILITY
 constexpr auto ssize(const _Cont& __c)
@@ -52,7 +52,7 @@ constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
 _LIBCPP_DIAGNOSTIC_POP
 #endif
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/sortable.h
@@ -23,14 +23,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Iter, class _Comp = ranges::less, class _Proj = identity>
 concept sortable =
   permutable<_Iter> &&
   indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/unreachable_sentinel.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 struct unreachable_sentinel_t {
   template<weakly_incrementable _Iter>
@@ -31,7 +31,7 @@ struct unreachable_sentinel_t {
 
 inline constexpr unreachable_sentinel_t unreachable_sentinel{};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__iterator/wrap_iter.h
@@ -11,12 +11,12 @@
 #define _LIBCPP___ITERATOR_WRAP_ITER_H
 
 #include <__config>
-#include <__debug>
 #include <__iterator/iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/pointer_traits.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_convertible.h>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -34,7 +34,7 @@ public:
     typedef typename iterator_traits<iterator_type>::pointer           pointer;
     typedef typename iterator_traits<iterator_type>::reference         reference;
     typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef contiguous_iterator_tag                                    iterator_concept;
 #endif
 
@@ -44,60 +44,23 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT
                 : __i_()
     {
-        _VSTD::__debug_db_insert_i(this);
     }
     template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
         __wrap_iter(const __wrap_iter<_Up>& __u,
             typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
             : __i_(__u.base())
     {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-      if (!__libcpp_is_constant_evaluated())
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__u));
-#endif
-    }
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-    __wrap_iter(const __wrap_iter& __x)
-        : __i_(__x.base())
-    {
-      if (!__libcpp_is_constant_evaluated())
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
-    }
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-    __wrap_iter& operator=(const __wrap_iter& __x)
-    {
-        if (this != _VSTD::addressof(__x))
-        {
-            if (!__libcpp_is_constant_evaluated())
-                __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
-            __i_ = __x.__i_;
-        }
-        return *this;
-    }
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    ~__wrap_iter()
-    {
-      if (!__libcpp_is_constant_evaluated())
-        __get_db()->__erase_i(this);
     }
-#endif
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable iterator");
         return *__i_;
     }
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable iterator");
         return _VSTD::__to_address(__i_);
     }
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to increment a non-incrementable iterator");
         ++__i_;
         return *this;
     }
@@ -106,8 +69,6 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
-                             "Attempted to decrement a non-decrementable iterator");
         --__i_;
         return *this;
     }
@@ -117,8 +78,6 @@ public:
         {__wrap_iter __w(*this); __w += __n; return __w;}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n),
-                             "Attempted to add/subtract an iterator outside its valid range");
         __i_ += __n;
         return *this;
     }
@@ -128,8 +87,6 @@ public:
         {*this += -__n; return *this;}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference    operator[](difference_type __n) const _NOEXCEPT
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n),
-                             "Attempted to subscript an iterator outside its valid range");
         return __i_[__n];
     }
 
@@ -137,13 +94,8 @@ public:
 
 private:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-    explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i_(__x)
+    explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x)
     {
-        (void)__p;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-      if (!__libcpp_is_constant_evaluated())
-        __get_db()->__insert_ic(this, __p);
-#endif
     }
 
     template <class _Up> friend class __wrap_iter;
@@ -170,8 +122,6 @@ template <class _Iter1>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
-                         "Attempted to compare incomparable iterators");
     return __x.base() < __y.base();
 }
 
@@ -179,8 +129,6 @@ template <class _Iter1, class _Iter2>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
-                         "Attempted to compare incomparable iterators");
     return __x.base() < __y.base();
 }
 
@@ -250,8 +198,6 @@ typename __wrap_iter<_Iter1>::difference_type
 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 #endif // C++03
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
-                         "Attempted to subtract incompatible iterators");
     return __x.base() - __y.base();
 }
 
@@ -265,7 +211,7 @@ __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n,
 
 #if _LIBCPP_STD_VER <= 17
 template <class _It>
-struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {};
+struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};
 #endif
 
 template <class _It>
lib/libcxx/include/__bsd_locale_defaults.h → lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
@@ -11,8 +11,8 @@
 // we will define the mapping from an internal macro to the real BSD symbol.
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H
-#define _LIBCPP___BSD_LOCALE_DEFAULTS_H
+#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
+#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -33,4 +33,4 @@
 #define __libcpp_asprintf_l(...)                            asprintf_l(__VA_ARGS__)
 #define __libcpp_sscanf_l(...)                              sscanf_l(__VA_ARGS__)
 
-#endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H
+#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
lib/libcxx/include/__bsd_locale_fallbacks.h → lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -10,12 +10,18 @@
 // of those functions for non-BSD platforms.
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H
-#define _LIBCPP___BSD_LOCALE_FALLBACKS_H
+#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
+#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 
+#include <__locale_dir/locale_base_api/locale_guard.h>
+#include <cstdio>
 #include <stdarg.h>
 #include <stdlib.h>
 
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  include <cwchar>
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
@@ -139,4 +145,4 @@ int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...)
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H
+#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
lib/libcxx/include/__locale_dir/locale_base_api/locale_guard.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
+#define _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
+
+#include <__config>
+#include <clocale>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
+struct __libcpp_locale_guard {
+  _LIBCPP_INLINE_VISIBILITY __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
+
+  _LIBCPP_INLINE_VISIBILITY ~__libcpp_locale_guard() {
+    if (__old_loc_)
+      uselocale(__old_loc_);
+  }
+
+  locale_t __old_loc_;
+
+private:
+  __libcpp_locale_guard(__libcpp_locale_guard const&);
+  __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
+};
+#elif defined(_LIBCPP_MSVCRT_LIKE)
+struct __libcpp_locale_guard {
+    __libcpp_locale_guard(locale_t __l) :
+        __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
+      // Setting the locale can be expensive even when the locale given is
+      // already the current locale, so do an explicit check to see if the
+      // current locale is already the one we want.
+      const char* __lc = __setlocale(nullptr);
+      // If every category is the same, the locale string will simply be the
+      // locale name, otherwise it will be a semicolon-separated string listing
+      // each category.  In the second case, we know at least one category won't
+      // be what we want, so we only have to check the first case.
+      if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
+        __locale_all = _strdup(__lc);
+        if (__locale_all == nullptr)
+          __throw_bad_alloc();
+        __setlocale(__l.__get_locale());
+      }
+    }
+    ~__libcpp_locale_guard() {
+      // The CRT documentation doesn't explicitly say, but setlocale() does the
+      // right thing when given a semicolon-separated list of locale settings
+      // for the different categories in the same format as returned by
+      // setlocale(LC_ALL, nullptr).
+      if (__locale_all != nullptr) {
+        __setlocale(__locale_all);
+        free(__locale_all);
+      }
+      _configthreadlocale(__status);
+    }
+    static const char* __setlocale(const char* __locale) {
+      const char* __new_locale = setlocale(LC_ALL, __locale);
+      if (__new_locale == nullptr)
+        __throw_bad_alloc();
+      return __new_locale;
+    }
+    int __status;
+    char* __locale_all = nullptr;
+};
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
lib/libcxx/include/__mdspan/default_accessor.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
+#define _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
+
+#include <__config>
+#include <__type_traits/is_abstract.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/remove_const.h>
+#include <cinttypes>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _ElementType>
+struct default_accessor {
+  static_assert(!is_array_v<_ElementType>, "default_accessor: template argument may not be an array type");
+  static_assert(!is_abstract_v<_ElementType>, "default_accessor: template argument may not be an abstract class");
+
+  using offset_policy    = default_accessor;
+  using element_type     = _ElementType;
+  using reference        = _ElementType&;
+  using data_handle_type = _ElementType*;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr default_accessor() noexcept = default;
+  template <class _OtherElementType>
+    requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]>)
+  _LIBCPP_HIDE_FROM_ABI constexpr default_accessor(default_accessor<_OtherElementType>) noexcept {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr reference access(data_handle_type __p, size_t __i) const noexcept { return __p[__i]; }
+  _LIBCPP_HIDE_FROM_ABI constexpr data_handle_type offset(data_handle_type __p, size_t __i) const noexcept {
+    return __p + __i;
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
lib/libcxx/include/__mdspan/extents.h
@@ -0,0 +1,519 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_EXTENTS_H
+#define _LIBCPP___MDSPAN_EXTENTS_H
+
+#include <__assert>
+#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/make_unsigned.h>
+#include <__utility/integer_sequence.h>
+#include <__utility/unreachable.h>
+#include <array>
+#include <cinttypes>
+#include <concepts>
+#include <cstddef>
+#include <limits>
+#include <span>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace __mdspan_detail {
+
+// ------------------------------------------------------------------
+// ------------ __static_array --------------------------------------
+// ------------------------------------------------------------------
+// array like class which provides an array of static values with get
+template <class _Tp, _Tp... _Values>
+struct __static_array {
+  static constexpr array<_Tp, sizeof...(_Values)> __array = {_Values...};
+
+public:
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Values); }
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get(size_t __index) noexcept { return __array[__index]; }
+
+  template <size_t _Index>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get() {
+    return __get(_Index);
+  }
+};
+
+// ------------------------------------------------------------------
+// ------------ __possibly_empty_array  -----------------------------
+// ------------------------------------------------------------------
+
+// array like class which provides get function and operator [], and
+// has a specialization for the size 0 case.
+// This is needed to make the __maybe_static_array be truly empty, for
+// all static values.
+
+template <class _Tp, size_t _Size>
+struct __possibly_empty_array {
+  _Tp __vals_[_Size];
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t __index) { return __vals_[__index]; }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __index) const { return __vals_[__index]; }
+};
+
+template <class _Tp>
+struct __possibly_empty_array<_Tp, 0> {
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t) { __libcpp_unreachable(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t) const { __libcpp_unreachable(); }
+};
+
+// ------------------------------------------------------------------
+// ------------ static_partial_sums ---------------------------------
+// ------------------------------------------------------------------
+
+// Provides a compile time partial sum one can index into
+
+template <size_t... _Values>
+struct __static_partial_sums {
+  _LIBCPP_HIDE_FROM_ABI static constexpr array<size_t, sizeof...(_Values)> __static_partial_sums_impl() {
+    array<size_t, sizeof...(_Values)> __values{_Values...};
+    array<size_t, sizeof...(_Values)> __partial_sums{{}};
+    size_t __running_sum = 0;
+    for (int __i = 0; __i != sizeof...(_Values); ++__i) {
+      __partial_sums[__i] = __running_sum;
+      __running_sum += __values[__i];
+    }
+    return __partial_sums;
+  }
+  static constexpr array<size_t, sizeof...(_Values)> __result{__static_partial_sums_impl()};
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __get(size_t __index) { return __result[__index]; }
+};
+
+// ------------------------------------------------------------------
+// ------------ __maybe_static_array --------------------------------
+// ------------------------------------------------------------------
+
+// array like class which has a mix of static and runtime values but
+// only stores the runtime values.
+// The type of the static and the runtime values can be different.
+// The position of a dynamic value is indicated through a tag value.
+template <class _TDynamic, class _TStatic, _TStatic _DynTag, _TStatic... _Values>
+struct __maybe_static_array {
+  static_assert(is_convertible<_TStatic, _TDynamic>::value,
+                "__maybe_static_array: _TStatic must be convertible to _TDynamic");
+  static_assert(is_convertible<_TDynamic, _TStatic>::value,
+                "__maybe_static_array: _TDynamic must be convertible to _TStatic");
+
+private:
+  // Static values member
+  static constexpr size_t __size_         = sizeof...(_Values);
+  static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0);
+  using _StaticValues                     = __static_array<_TStatic, _Values...>;
+  using _DynamicValues                    = __possibly_empty_array<_TDynamic, __size_dynamic_>;
+
+  // Dynamic values member
+  _LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_;
+
+  // static mapping of indices to the position in the dynamic values array
+  using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>;
+
+  template <size_t... Indices>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<Indices...>) noexcept {
+    return _DynamicValues{((void)Indices, 0)...};
+  }
+
+public:
+  _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept
+      : __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {}
+
+  // constructors from dynamic values only -- this covers the case for rank() == 0
+  template <class... _DynVals>
+    requires(sizeof...(_DynVals) == __size_dynamic_)
+  _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals)
+      : __dyn_vals_{static_cast<_TDynamic>(__vals)...} {}
+
+  template <class _Tp, size_t _Size >
+    requires(_Size == __size_dynamic_)
+  _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array([[maybe_unused]] const span<_Tp, _Size>& __vals) {
+    if constexpr (_Size > 0) {
+      for (size_t __i = 0; __i < _Size; __i++)
+        __dyn_vals_[__i] = static_cast<_TDynamic>(__vals[__i]);
+    }
+  }
+
+  // constructors from all values -- here rank will be greater than 0
+  template <class... _DynVals>
+    requires(sizeof...(_DynVals) != __size_dynamic_)
+  _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) {
+    static_assert((sizeof...(_DynVals) == __size_), "Invalid number of values.");
+    _TDynamic __values[__size_] = {static_cast<_TDynamic>(__vals)...};
+    for (size_t __i = 0; __i < __size_; __i++) {
+      _TStatic __static_val = _StaticValues::__get(__i);
+      if (__static_val == _DynTag) {
+        __dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
+      } else
+        // Not catching this could lead to out of bounds errors later
+        // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5);
+        // Right-hand-side construction looks ok with allocation and size matching,
+        // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            __values[__i] == static_cast<_TDynamic>(__static_val),
+            "extents construction: mismatch of provided arguments with static extents.");
+    }
+  }
+
+  template <class _Tp, size_t _Size>
+    requires(_Size != __size_dynamic_)
+  _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) {
+    static_assert((_Size == __size_) || (__size_ == dynamic_extent));
+    for (size_t __i = 0; __i < __size_; __i++) {
+      _TStatic __static_val = _StaticValues::__get(__i);
+      if (__static_val == _DynTag) {
+        __dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
+      } else
+        // Not catching this could lead to out of bounds errors later
+        // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N));
+        // Right-hand-side construction looks ok with allocation and size matching,
+        // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
+            "extents construction: mismatch of provided arguments with static extents.");
+    }
+  }
+
+  // access functions
+  _LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
+    return _StaticValues::__get(__i);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
+    _TStatic __static_val = _StaticValues::__get(__i);
+    return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val);
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const {
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
+    return __value(__i);
+  }
+
+  // observers
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return __size_; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size_dynamic() { return __size_dynamic_; }
+};
+
+// Function to check whether a value is representable as another type
+// value must be a positive integer otherwise returns false
+// if _From is not an integral, we just check positivity
+template <integral _To, class _From>
+  requires(integral<_From>)
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
+  using _To_u   = make_unsigned_t<_To>;
+  using _From_u = make_unsigned_t<_From>;
+  if constexpr (is_signed_v<_From>) {
+    if (__value < 0)
+      return false;
+  }
+  if constexpr (static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(numeric_limits<_From>::max())) {
+    return true;
+  } else {
+    return static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(__value);
+  }
+}
+
+template <integral _To, class _From>
+  requires(!integral<_From>)
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
+  if constexpr (is_signed_v<_To>) {
+    if (static_cast<_To>(__value) < 0)
+      return false;
+  }
+  return true;
+}
+
+template <integral _To, class... _From>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(_From... __values) {
+  return (__mdspan_detail::__is_representable_as<_To>(__values) && ... && true);
+}
+
+template <integral _To, class _From, size_t _Size>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(span<_From, _Size> __values) {
+  for (size_t __i = 0; __i < _Size; __i++)
+    if (!__mdspan_detail::__is_representable_as<_To>(__values[__i]))
+      return false;
+  return true;
+}
+
+} // namespace __mdspan_detail
+
+// ------------------------------------------------------------------
+// ------------ extents ---------------------------------------------
+// ------------------------------------------------------------------
+
+// Class to describe the extents of a multi dimensional array.
+// Used by mdspan, mdarray and layout mappings.
+// See ISO C++ standard [mdspan.extents]
+
+template <class _IndexType, size_t... _Extents>
+class extents {
+public:
+  // typedefs for integral types used
+  using index_type = _IndexType;
+  using size_type  = make_unsigned_t<index_type>;
+  using rank_type  = size_t;
+
+  static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value,
+                "extents::index_type must be a signed or unsigned integer type");
+  static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
+                "extents ctor: arguments must be representable as index_type and nonnegative");
+
+private:
+  static constexpr rank_type __rank_         = sizeof...(_Extents);
+  static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0);
+
+  // internal storage type using __maybe_static_array
+  using _Values = __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>;
+  [[no_unique_address]] _Values __vals_;
+
+public:
+  // [mdspan.extents.obs], observers of multidimensional index space
+  _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); }
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
+    return _Values::__static_value(__r);
+  }
+
+  // [mdspan.extents.cons], constructors
+  _LIBCPP_HIDE_FROM_ABI constexpr extents() noexcept = default;
+
+  // Construction from just dynamic or all values.
+  // Precondition check is deferred to __maybe_static_array constructor
+  template <class... _OtherIndexTypes>
+    requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
+             (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
+             (sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
+      : __vals_(static_cast<index_type>(__dynvals)...) {
+    // Not catching this could lead to out of bounds errors later
+    // e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
+                                        "extents ctor: arguments must be representable as index_type and nonnegative");
+  }
+
+  template <class _OtherIndexType, size_t _Size>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
+             (_Size == __rank_ || _Size == __rank_dynamic_))
+  explicit(_Size != __rank_dynamic_)
+      _LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
+      : __vals_(span(__exts)) {
+    // Not catching this could lead to out of bounds errors later
+    // e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
+                                        "extents ctor: arguments must be representable as index_type and nonnegative");
+  }
+
+  template <class _OtherIndexType, size_t _Size>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
+             (_Size == __rank_ || _Size == __rank_dynamic_))
+  explicit(_Size != __rank_dynamic_)
+      _LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
+      : __vals_(__exts) {
+    // Not catching this could lead to out of bounds errors later
+    // e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56
+    // on m
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts),
+                                        "extents ctor: arguments must be representable as index_type and nonnegative");
+  }
+
+private:
+  // Function to construct extents storage from other extents.
+  template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
+    requires(_Idx < __rank_)
+  _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
+      integral_constant<size_t, _DynCount>,
+      integral_constant<size_t, _Idx>,
+      const _OtherExtents& __exts,
+      _DynamicValues... __dynamic_values) noexcept {
+    if constexpr (static_extent(_Idx) == dynamic_extent)
+      return __construct_vals_from_extents(
+          integral_constant<size_t, _DynCount + 1>(),
+          integral_constant<size_t, _Idx + 1>(),
+          __exts,
+          __dynamic_values...,
+          __exts.extent(_Idx));
+    else
+      return __construct_vals_from_extents(
+          integral_constant<size_t, _DynCount>(), integral_constant<size_t, _Idx + 1>(), __exts, __dynamic_values...);
+  }
+
+  template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
+    requires((_Idx == __rank_) && (_DynCount == __rank_dynamic_))
+  _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
+      integral_constant<size_t, _DynCount>,
+      integral_constant<size_t, _Idx>,
+      const _OtherExtents&,
+      _DynamicValues... __dynamic_values) noexcept {
+    return _Values{static_cast<index_type>(__dynamic_values)...};
+  }
+
+public:
+  // Converting constructor from other extents specializations
+  template <class _OtherIndexType, size_t... _OtherExtents>
+    requires((sizeof...(_OtherExtents) == sizeof...(_Extents)) &&
+             ((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...))
+  explicit((((_Extents != dynamic_extent) && (_OtherExtents == dynamic_extent)) || ...) ||
+           (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
+            static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())))
+      _LIBCPP_HIDE_FROM_ABI constexpr extents(const extents<_OtherIndexType, _OtherExtents...>& __other) noexcept
+      : __vals_(
+            __construct_vals_from_extents(integral_constant<size_t, 0>(), integral_constant<size_t, 0>(), __other)) {
+    if constexpr (rank() > 0) {
+      for (size_t __r = 0; __r < rank(); __r++) {
+        if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
+                      static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
+          // Not catching this could lead to out of bounds errors later
+          // e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e
+          _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+              __mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
+              "extents ctor: arguments must be representable as index_type and nonnegative");
+        }
+        // Not catching this could lead to out of bounds errors later
+        // e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5);
+        // Right-hand-side construction was ok, but m now thinks its range is 10 not 5
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            (_Values::__static_value(__r) == dynamic_extent) ||
+                (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
+            "extents construction: mismatch of provided arguments with static extents.");
+      }
+    }
+  }
+
+  // Comparison operator
+  template <class _OtherIndexType, size_t... _OtherExtents>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+  operator==(const extents& __lhs, const extents<_OtherIndexType, _OtherExtents...>& __rhs) noexcept {
+    if constexpr (rank() != sizeof...(_OtherExtents)) {
+      return false;
+    } else {
+      for (rank_type __r = 0; __r < __rank_; __r++) {
+        // avoid warning when comparing signed and unsigner integers and pick the wider of two types
+        using _CommonType = common_type_t<index_type, _OtherIndexType>;
+        if (static_cast<_CommonType>(__lhs.extent(__r)) != static_cast<_CommonType>(__rhs.extent(__r))) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+};
+
+// Recursive helper classes to implement dextents alias for extents
+namespace __mdspan_detail {
+
+template <class _IndexType, size_t _Rank, class _Extents = extents<_IndexType>>
+struct __make_dextents;
+
+template <class _IndexType, size_t _Rank, size_t... _ExtentsPack>
+struct __make_dextents< _IndexType, _Rank, extents<_IndexType, _ExtentsPack...>> {
+  using type =
+      typename __make_dextents< _IndexType, _Rank - 1, extents<_IndexType, dynamic_extent, _ExtentsPack...>>::type;
+};
+
+template <class _IndexType, size_t... _ExtentsPack>
+struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> {
+  using type = extents<_IndexType, _ExtentsPack...>;
+};
+
+} // end namespace __mdspan_detail
+
+// [mdspan.extents.dextents], alias template
+template <class _IndexType, size_t _Rank>
+using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type;
+
+// Deduction guide for extents
+template <class... _IndexTypes>
+extents(_IndexTypes...) -> extents<size_t, size_t((_IndexTypes(), dynamic_extent))...>;
+
+namespace __mdspan_detail {
+
+// Helper type traits for identifying a class as extents.
+template <class _Tp>
+struct __is_extents : false_type {};
+
+template <class _IndexType, size_t... _ExtentsPack>
+struct __is_extents<extents<_IndexType, _ExtentsPack...>> : true_type {};
+
+template <class _Tp>
+inline constexpr bool __is_extents_v = __is_extents<_Tp>::value;
+
+// Function to check whether a set of indices are a multidimensional
+// index into extents. This is a word of power in the C++ standard
+// requiring that the indices are larger than 0 and smaller than
+// the respective extents.
+
+template <integral _IndexType, class _From>
+  requires(integral<_From>)
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
+  if constexpr (is_signed_v<_From>) {
+    if (__value < 0)
+      return false;
+  }
+  using _Tp = common_type_t<_IndexType, _From>;
+  return static_cast<_Tp>(__value) < static_cast<_Tp>(__extent);
+}
+
+template <integral _IndexType, class _From>
+  requires(!integral<_From>)
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
+  if constexpr (is_signed_v<_IndexType>) {
+    if (static_cast<_IndexType>(__value) < 0)
+      return false;
+  }
+  return static_cast<_IndexType>(__value) < __extent;
+}
+
+template <size_t... _Idxs, class _Extents, class... _From>
+_LIBCPP_HIDE_FROM_ABI constexpr bool
+__is_multidimensional_index_in_impl(index_sequence<_Idxs...>, const _Extents& __ext, _From... __values) {
+  return (__mdspan_detail::__is_index_in_extent(__ext.extent(_Idxs), __values) && ...);
+}
+
+template <class _Extents, class... _From>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_multidimensional_index_in(const _Extents& __ext, _From... __values) {
+  return __mdspan_detail::__is_multidimensional_index_in_impl(
+      make_index_sequence<_Extents::rank()>(), __ext, __values...);
+}
+
+} // namespace __mdspan_detail
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_EXTENTS_H
lib/libcxx/include/__mdspan/layout_left.h
@@ -0,0 +1,189 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_LAYOUT_LEFT_H
+#define _LIBCPP___MDSPAN_LAYOUT_LEFT_H
+
+#include <__assert>
+#include <__config>
+#include <__fwd/mdspan.h>
+#include <__mdspan/extents.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/integer_sequence.h>
+#include <array>
+#include <cinttypes>
+#include <cstddef>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Extents>
+class layout_left::mapping {
+public:
+  static_assert(__mdspan_detail::__is_extents<_Extents>::value,
+                "layout_left::mapping template argument must be a specialization of extents.");
+
+  using extents_type = _Extents;
+  using index_type   = typename extents_type::index_type;
+  using size_type    = typename extents_type::size_type;
+  using rank_type    = typename extents_type::rank_type;
+  using layout_type  = layout_left;
+
+private:
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) {
+    if constexpr (extents_type::rank() == 0)
+      return true;
+
+    index_type __prod = __ext.extent(0);
+    for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
+      bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod);
+      if (__overflowed)
+        return false;
+    }
+    return true;
+  }
+
+  static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()),
+                "layout_left::mapping product of static extents must be representable as index_type.");
+
+public:
+  // [mdspan.layout.left.cons], constructors
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept               = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(10, 3) == -126
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __required_span_size_is_representable(__ext),
+        "layout_left::mapping extents ctor: product of extents must be representable as index_type.");
+  }
+
+  template <class _OtherExtents>
+    requires(is_constructible_v<extents_type, _OtherExtents>)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
+      mapping(const mapping<_OtherExtents>& __other) noexcept
+      : __extents_(__other.extents()) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(10, 3) == -126
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
+        "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+  }
+
+  template <class _OtherExtents>
+    requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
+      mapping(const layout_right::mapping<_OtherExtents>& __other) noexcept
+      : __extents_(__other.extents()) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
+    //       and thus this assertion should never be triggered, but keeping it here for consistency
+    // layout_left::mapping<dextents<char, 1>> map(
+    //           layout_right::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
+    //           -56
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
+        "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+  }
+
+// FIXME: add when we add other layouts
+#  if 0
+    template<class _OtherExtents>
+      constexpr explicit(extents_type::rank() > 0)
+        mapping(const layout_stride::mapping_<OtherExtents>&) noexcept;
+#  endif
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default;
+
+  // [mdspan.layout.left.obs], observers
+  _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept {
+    index_type __size = 1;
+    for (size_t __r = 0; __r < extents_type::rank(); __r++)
+      __size *= __extents_.extent(__r);
+    return __size;
+  }
+
+  template <class... _Indices>
+    requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
+             (is_nothrow_constructible_v<index_type, _Indices> && ...))
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
+    // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
+    // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
+    // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
+    // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
+    _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
+                   "layout_left::mapping: out of bounds indexing");
+    array<index_type, extents_type::rank()> __idx_a{static_cast<index_type>(__idx)...};
+    return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
+      index_type __res = 0;
+      ((__res = __idx_a[extents_type::rank() - 1 - _Pos] + __extents_.extent(extents_type::rank() - 1 - _Pos) * __res),
+       ...);
+      return __res;
+    }(make_index_sequence<sizeof...(_Indices)>());
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; }
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
+    requires(extents_type::rank() > 0)
+  {
+    // While it would be caught by extents itself too, using a too large __r
+    // is functionally an out of bounds access on the stored information needed to compute strides
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __r < extents_type::rank(), "layout_left::mapping::stride(): invalid rank index");
+    index_type __s = 1;
+    for (rank_type __i = 0; __i < __r; __i++)
+      __s *= __extents_.extent(__i);
+    return __s;
+  }
+
+  template <class _OtherExtents>
+    requires(_OtherExtents::rank() == extents_type::rank())
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+  operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept {
+    return __lhs.extents() == __rhs.extents();
+  }
+
+private:
+  _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{};
+};
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_LAYOUT_LEFT_H
lib/libcxx/include/__mdspan/layout_right.h
@@ -0,0 +1,186 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
+#define _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
+
+#include <__assert>
+#include <__config>
+#include <__fwd/mdspan.h>
+#include <__mdspan/extents.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/integer_sequence.h>
+#include <cinttypes>
+#include <cstddef>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Extents>
+class layout_right::mapping {
+public:
+  static_assert(__mdspan_detail::__is_extents<_Extents>::value,
+                "layout_right::mapping template argument must be a specialization of extents.");
+
+  using extents_type = _Extents;
+  using index_type   = typename extents_type::index_type;
+  using size_type    = typename extents_type::size_type;
+  using rank_type    = typename extents_type::rank_type;
+  using layout_type  = layout_right;
+
+private:
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) {
+    if constexpr (extents_type::rank() == 0)
+      return true;
+
+    index_type __prod = __ext.extent(0);
+    for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
+      bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod);
+      if (__overflowed)
+        return false;
+    }
+    return true;
+  }
+
+  static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()),
+                "layout_right::mapping product of static extents must be representable as index_type.");
+
+public:
+  // [mdspan.layout.right.cons], constructors
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept               = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(3, 10) == -126
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __required_span_size_is_representable(__ext),
+        "layout_right::mapping extents ctor: product of extents must be representable as index_type.");
+  }
+
+  template <class _OtherExtents>
+    requires(is_constructible_v<extents_type, _OtherExtents>)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
+      mapping(const mapping<_OtherExtents>& __other) noexcept
+      : __extents_(__other.extents()) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(3, 10) == -126
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
+        "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+  }
+
+  template <class _OtherExtents>
+    requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
+      mapping(const layout_left::mapping<_OtherExtents>& __other) noexcept
+      : __extents_(__other.extents()) {
+    // not catching this could lead to out-of-bounds access later when used inside mdspan
+    // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
+    //       and thus this assertion should never be triggered, but keeping it here for consistency
+    // layout_right::mapping<dextents<char, 1>> map(
+    //           layout_left::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
+    //           -56
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
+        "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+  }
+
+// FIXME: add when we add other layouts
+#  if 0
+    template<class _OtherExtents>
+      constexpr explicit(extents_type::rank() > 0)
+        mapping(const layout_stride::mapping_<OtherExtents>&) noexcept;
+#  endif
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default;
+
+  // [mdspan.layout.right.obs], observers
+  _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept {
+    index_type __size = 1;
+    for (size_t __r = 0; __r < extents_type::rank(); __r++)
+      __size *= __extents_.extent(__r);
+    return __size;
+  }
+
+  template <class... _Indices>
+    requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
+             (is_nothrow_constructible_v<index_type, _Indices> && ...))
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
+    // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
+    // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
+    // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
+    // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
+    _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
+                   "layout_right::mapping: out of bounds indexing");
+    return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
+      index_type __res = 0;
+      ((__res = static_cast<index_type>(__idx) + __extents_.extent(_Pos) * __res), ...);
+      return __res;
+    }(make_index_sequence<sizeof...(_Indices)>());
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; }
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
+    requires(extents_type::rank() > 0)
+  {
+    // While it would be caught by extents itself too, using a too large __r
+    // is functionally an out of bounds access on the stored information needed to compute strides
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index");
+    index_type __s = 1;
+    for (rank_type __i = extents_type::rank() - 1; __i > __r; __i--)
+      __s *= __extents_.extent(__i);
+    return __s;
+  }
+
+  template <class _OtherExtents>
+    requires(_OtherExtents::rank() == extents_type::rank())
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+  operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept {
+    return __lhs.extents() == __rhs.extents();
+  }
+
+private:
+  _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{};
+};
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
lib/libcxx/include/__mdspan/mdspan.h
@@ -0,0 +1,308 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_MDSPAN_H
+#define _LIBCPP___MDSPAN_MDSPAN_H
+
+#include <__assert>
+#include <__config>
+#include <__fwd/mdspan.h>
+#include <__mdspan/default_accessor.h>
+#include <__mdspan/extents.h>
+#include <__type_traits/extent.h>
+#include <__type_traits/is_abstract.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/rank.h>
+#include <__type_traits/remove_all_extents.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/integer_sequence.h>
+#include <array>
+#include <cinttypes>
+#include <cstddef>
+#include <limits>
+#include <span>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+// Helper for lightweight test checking that one did pass a layout policy as LayoutPolicy template argument
+namespace __mdspan_detail {
+template <class _Layout, class _Extents>
+concept __has_invalid_mapping = !requires { typename _Layout::template mapping<_Extents>; };
+} // namespace __mdspan_detail
+
+template <class _ElementType,
+          class _Extents,
+          class _LayoutPolicy   = layout_right,
+          class _AccessorPolicy = default_accessor<_ElementType> >
+class mdspan {
+private:
+  static_assert(__mdspan_detail::__is_extents_v<_Extents>,
+                "mdspan: Extents template parameter must be a specialization of extents.");
+  static_assert(!is_array_v<_ElementType>, "mdspan: ElementType template parameter may not be an array type");
+  static_assert(!is_abstract_v<_ElementType>, "mdspan: ElementType template parameter may not be an abstract class");
+  static_assert(is_same_v<_ElementType, typename _AccessorPolicy::element_type>,
+                "mdspan: ElementType template parameter must match AccessorPolicy::element_type");
+  static_assert(!__mdspan_detail::__has_invalid_mapping<_LayoutPolicy, _Extents>,
+                "mdspan: LayoutPolicy template parameter is invalid. A common mistake is to pass a layout mapping "
+                "instead of a layout policy");
+
+public:
+  using extents_type     = _Extents;
+  using layout_type      = _LayoutPolicy;
+  using accessor_type    = _AccessorPolicy;
+  using mapping_type     = typename layout_type::template mapping<extents_type>;
+  using element_type     = _ElementType;
+  using value_type       = remove_cv_t<element_type>;
+  using index_type       = typename extents_type::index_type;
+  using size_type        = typename extents_type::size_type;
+  using rank_type        = typename extents_type::rank_type;
+  using data_handle_type = typename accessor_type::data_handle_type;
+  using reference        = typename accessor_type::reference;
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
+  _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
+    return extents_type::static_extent(__r);
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
+    return __map_.extents().extent(__r);
+  };
+
+public:
+  //--------------------------------------------------------------------------------
+  // [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan()
+    requires((extents_type::rank_dynamic() > 0) && is_default_constructible_v<data_handle_type> &&
+             is_default_constructible_v<mapping_type> && is_default_constructible_v<accessor_type>)
+  = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan(const mdspan&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan(mdspan&&)      = default;
+
+  template <class... _OtherIndexTypes>
+    requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
+             (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
+             ((sizeof...(_OtherIndexTypes) == rank()) || (sizeof...(_OtherIndexTypes) == rank_dynamic())) &&
+             is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type>)
+  _LIBCPP_HIDE_FROM_ABI explicit constexpr mdspan(data_handle_type __p, _OtherIndexTypes... __exts)
+      : __ptr_(std::move(__p)), __map_(extents_type(static_cast<index_type>(std::move(__exts))...)), __acc_{} {}
+
+  template <class _OtherIndexType, size_t _Size>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
+             ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> &&
+             is_default_constructible_v<accessor_type>)
+  explicit(_Size != rank_dynamic())
+      _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const array<_OtherIndexType, _Size>& __exts)
+      : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {}
+
+  template <class _OtherIndexType, size_t _Size>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
+             ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> &&
+             is_default_constructible_v<accessor_type>)
+  explicit(_Size != rank_dynamic())
+      _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, span<_OtherIndexType, _Size> __exts)
+      : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const extents_type& __exts)
+    requires(is_default_constructible_v<accessor_type> && is_constructible_v<mapping_type, const extents_type&>)
+      : __ptr_(std::move(__p)), __map_(__exts), __acc_{} {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m)
+    requires(is_default_constructible_v<accessor_type>)
+      : __ptr_(std::move(__p)), __map_(__m), __acc_{} {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m, const accessor_type& __a)
+      : __ptr_(std::move(__p)), __map_(__m), __acc_(__a) {}
+
+  template <class _OtherElementType, class _OtherExtents, class _OtherLayoutPolicy, class _OtherAccessor>
+    requires(is_constructible_v<mapping_type, const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&> &&
+             is_constructible_v<accessor_type, const _OtherAccessor&>)
+  explicit(!is_convertible_v<const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&, mapping_type> ||
+           !is_convertible_v<const _OtherAccessor&, accessor_type>)
+      _LIBCPP_HIDE_FROM_ABI constexpr mdspan(
+          const mdspan<_OtherElementType, _OtherExtents, _OtherLayoutPolicy, _OtherAccessor>& __other)
+      : __ptr_(__other.__ptr_), __map_(__other.__map_), __acc_(__other.__acc_) {
+    static_assert(is_constructible_v<data_handle_type, const typename _OtherAccessor::data_handle_type&>,
+                  "mdspan: incompatible data_handle_type for mdspan construction");
+    static_assert(
+        is_constructible_v<extents_type, _OtherExtents>, "mdspan: incompatible extents for mdspan construction");
+
+    // The following precondition is part of the standard, but is unlikely to be triggered.
+    // The extents constructor checks this and the mapping must be storing the extents, since
+    // its extents() function returns a const reference to extents_type.
+    // The only way this can be triggered is if the mapping conversion constructor would for example
+    // always construct its extents() only from the dynamic extents, instead of from the other extents.
+    if constexpr (rank() > 0) {
+      for (size_t __r = 0; __r < rank(); __r++) {
+        // Not catching this could lead to out of bounds errors later
+        // e.g. mdspan<int, dextents<char,1>, non_checking_layout> m =
+        //        mdspan<int, dextents<unsigned, 1>, non_checking_layout>(ptr, 200); leads to an extent of -56 on m
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            (static_extent(__r) == dynamic_extent) ||
+                (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(static_extent(__r))),
+            "mdspan: conversion mismatch of source dynamic extents with static extents");
+      }
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(const mdspan&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(mdspan&&)      = default;
+
+  //--------------------------------------------------------------------------------
+  // [mdspan.mdspan.members], members
+
+  template <class... _OtherIndexTypes>
+    requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
+             (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
+             (sizeof...(_OtherIndexTypes) == rank()))
+  _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
+    // Note the standard layouts would also check this, but user provided ones may not, so we
+    // check the precondition here
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
+                                        "mdspan: operator[] out of bounds access");
+    return __acc_.access(__ptr_, __map_(static_cast<index_type>(std::move(__indices))...));
+  }
+
+  template <class _OtherIndexType>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
+  _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const {
+    return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
+      return __map_(__indices[_Idxs]...);
+    }(make_index_sequence<rank()>()));
+  }
+
+  template <class _OtherIndexType>
+    requires(is_convertible_v<const _OtherIndexType&, index_type> &&
+             is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
+  _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
+    return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
+      return __map_(__indices[_Idxs]...);
+    }(make_index_sequence<rank()>()));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept {
+    // Could leave this as only checked in debug mode: semantically size() is never
+    // guaranteed to be related to any accessible range
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        false == ([&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
+          size_type __prod = 1;
+          return (__builtin_mul_overflow(__prod, extent(_Idxs), &__prod) || ... || false);
+        }(make_index_sequence<rank()>())),
+        "mdspan: size() is not representable as size_type");
+    return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
+      return ((static_cast<size_type>(__map_.extents().extent(_Idxs))) * ... * size_type(1));
+    }(make_index_sequence<rank()>());
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept {
+    return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
+      return (rank() > 0) && ((__map_.extents().extent(_Idxs) == index_type(0)) || ... || false);
+    }(make_index_sequence<rank()>());
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(mdspan& __x, mdspan& __y) noexcept {
+    swap(__x.__ptr_, __y.__ptr_);
+    swap(__x.__map_, __y.__map_);
+    swap(__x.__acc_, __y.__acc_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); };
+  _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; };
+  _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
+  _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); };
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); };
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); };
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
+  _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
+  _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); };
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); };
+
+private:
+  _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{};
+  _LIBCPP_NO_UNIQUE_ADDRESS mapping_type __map_{};
+  _LIBCPP_NO_UNIQUE_ADDRESS accessor_type __acc_{};
+
+  template <class, class, class, class>
+  friend class mdspan;
+};
+
+template <class _ElementType, class... _OtherIndexTypes>
+  requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0))
+explicit mdspan(_ElementType*, _OtherIndexTypes...)
+    -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>;
+
+template <class _Pointer>
+  requires(is_pointer_v<remove_reference_t<_Pointer>>)
+mdspan(_Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>;
+
+template <class _CArray>
+  requires(is_array_v<_CArray> && (rank_v<_CArray> == 1))
+mdspan(_CArray&) -> mdspan<remove_all_extents_t<_CArray>, extents<size_t, extent_v<_CArray, 0>>>;
+
+template <class _ElementType, class _OtherIndexType, size_t _Size>
+mdspan(_ElementType*, const array<_OtherIndexType, _Size>&) -> mdspan<_ElementType, dextents<size_t, _Size>>;
+
+template <class _ElementType, class _OtherIndexType, size_t _Size>
+mdspan(_ElementType*, span<_OtherIndexType, _Size>) -> mdspan<_ElementType, dextents<size_t, _Size>>;
+
+// This one is necessary because all the constructors take `data_handle_type`s, not
+// `_ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which
+// seems to throw off automatic deduction guides.
+template <class _ElementType, class _OtherIndexType, size_t... _ExtentsPack>
+mdspan(_ElementType*, const extents<_OtherIndexType, _ExtentsPack...>&)
+    -> mdspan<_ElementType, extents<_OtherIndexType, _ExtentsPack...>>;
+
+template <class _ElementType, class _MappingType>
+mdspan(_ElementType*, const _MappingType&)
+    -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>;
+
+template <class _MappingType, class _AccessorType>
+mdspan(const typename _AccessorType::data_handle_type, const _MappingType&, const _AccessorType&)
+    -> mdspan<typename _AccessorType::element_type,
+              typename _MappingType::extents_type,
+              typename _MappingType::layout_type,
+              _AccessorType>;
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_MDSPAN_H
lib/libcxx/include/__memory/align.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
+_LIBCPP_EXPORTED_FROM_ABI void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__memory/aligned_alloc.h
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ALIGNED_ALLOC_H
+#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H
+
+#include <__config>
+#include <cstddef>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+
+// Low-level helpers to call the aligned allocation and deallocation functions
+// on the target platform. This is used to implement libc++'s own memory
+// allocation routines -- if you need to allocate memory inside the library,
+// chances are that you want to use `__libcpp_allocate` instead.
+//
+// Returns the allocated memory, or `nullptr` on failure.
+inline _LIBCPP_HIDE_FROM_ABI
+void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+#  if defined(_LIBCPP_MSVCRT_LIKE)
+    return ::_aligned_malloc(__size, __alignment);
+#  elif _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
+    // aligned_alloc() requires that __size is a multiple of __alignment,
+    // but for C++ [new.delete.general], only states "if the value of an
+    // alignment argument passed to any of these functions is not a valid
+    // alignment value, the behavior is undefined".
+    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
+    // round __size up to the next multiple of __alignment.
+    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
+    // Rounding up could have wrapped around to zero, so we have to add another
+    // max() ternary to the actual call site to avoid succeeded in that case.
+    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
+#  else
+    void* __result = nullptr;
+    (void)::posix_memalign(&__result, __alignment, __size);
+    // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
+    return __result;
+#  endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void __libcpp_aligned_free(void* __ptr) {
+#if defined(_LIBCPP_MSVCRT_LIKE)
+  ::_aligned_free(__ptr);
+#else
+  ::free(__ptr);
+#endif
+}
+
+#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H
lib/libcxx/include/__memory/allocate_at_least.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _Pointer>
 struct allocation_result {
   _Pointer ptr;
@@ -55,7 +55,7 @@ __allocation_result<typename allocator_traits<_Alloc>::pointer> __allocate_at_le
   return {__alloc.allocate(__n), __n};
 }
 
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__memory/allocation_guard.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_ALLOCATION_GUARD_H
 
 #include <__config>
+#include <__memory/addressof.h>
 #include <__memory/allocator_traits.h>
 #include <__utility/move.h>
 #include <cstddef>
@@ -19,6 +20,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Helper class to allocate memory using an Allocator in an exception safe
@@ -55,9 +59,29 @@ struct __allocation_guard {
 
     _LIBCPP_HIDE_FROM_ABI
     ~__allocation_guard() _NOEXCEPT {
-        if (__ptr_ != nullptr) {
-            allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
+        __destroy();
+    }
+
+    _LIBCPP_HIDE_FROM_ABI __allocation_guard(const __allocation_guard&) = delete;
+    _LIBCPP_HIDE_FROM_ABI __allocation_guard(__allocation_guard&& __other) _NOEXCEPT
+        : __alloc_(std::move(__other.__alloc_))
+        , __n_(__other.__n_)
+        , __ptr_(__other.__ptr_) {
+      __other.__ptr_ = nullptr;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(const __allocation_guard& __other) = delete;
+    _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(__allocation_guard&& __other) _NOEXCEPT {
+        if (std::addressof(__other) != this) {
+            __destroy();
+
+            __alloc_ = std::move(__other.__alloc_);
+            __n_ = __other.__n_;
+            __ptr_ = __other.__ptr_;
+            __other.__ptr_ = nullptr;
         }
+
+        return *this;
     }
 
     _LIBCPP_HIDE_FROM_ABI
@@ -73,6 +97,13 @@ struct __allocation_guard {
     }
 
 private:
+    _LIBCPP_HIDE_FROM_ABI
+    void __destroy() _NOEXCEPT {
+        if (__ptr_ != nullptr) {
+            allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
+        }
+    }
+
     _Alloc __alloc_;
     _Size __n_;
     _Pointer __ptr_;
@@ -80,4 +111,6 @@ private:
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H
lib/libcxx/include/__memory/allocator.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_ALLOCATOR_H
 
 #include <__config>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
 #include <__memory/allocator_traits.h>
 #include <__type_traits/is_constant_evaluated.h>
@@ -20,7 +21,6 @@
 #include <__utility/forward.h>
 #include <cstddef>
 #include <new>
-#include <stdexcept>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -98,8 +98,7 @@ public:
     typedef true_type   propagate_on_container_move_assignment;
     typedef true_type   is_always_equal;
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-    allocator() _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default;
 
     template <class _Up>
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -116,7 +115,7 @@ public:
         }
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
     allocation_result<_Tp*> allocate_at_least(size_t __n) {
         return {allocate(__n), __n};
@@ -187,8 +186,7 @@ public:
     typedef true_type   propagate_on_container_move_assignment;
     typedef true_type   is_always_equal;
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-    allocator() _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default;
 
     template <class _Up>
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -205,7 +203,7 @@ public:
         }
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
     allocation_result<const _Tp*> allocate_at_least(size_t __n) {
         return {allocate(__n), __n};
@@ -264,10 +262,14 @@ template <class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+inline _LIBCPP_INLINE_VISIBILITY
 bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
 
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___MEMORY_ALLOCATOR_H
lib/libcxx/include/__memory/allocator_arg_t.h
@@ -25,10 +25,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
 
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
-#else
-/* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#if _LIBCPP_STD_VER >= 17
+inline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#elif !defined(_LIBCPP_CXX03_LANG)
+constexpr allocator_arg_t allocator_arg = allocator_arg_t();
 #endif
 
 #ifndef _LIBCPP_CXX03_LANG
lib/libcxx/include/__memory/allocator_traits.h
@@ -300,7 +300,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
         __enable_if_t<!__has_construct<allocator_type, _Tp*, _Args...>::value> >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static void construct(allocator_type&, _Tp* __p, _Args&&... __args) {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
 #else
         ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
@@ -319,7 +319,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
         __enable_if_t<!__has_destroy<allocator_type, _Tp*>::value> >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static void destroy(allocator_type&, _Tp* __p) {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         _VSTD::destroy_at(__p);
 #else
         __p->~_Tp();
@@ -401,6 +401,25 @@ struct __is_cpp17_copy_insertable<_Alloc, __enable_if_t<
     : __is_cpp17_move_insertable<_Alloc>
 { };
 
+// ASan choices
+#ifndef _LIBCPP_HAS_NO_ASAN
+#   define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1
+#endif
+
+#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
+template <class _Alloc>
+struct __asan_annotate_container_with_allocator
+#   if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600
+      : true_type {};
+#   else
+      // TODO(LLVM-18): Remove the special-casing
+      : false_type {};
+#   endif
+
+template <class _Tp>
+struct __asan_annotate_container_with_allocator<allocator<_Tp> > : true_type {};
+#endif
+
 #undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/assume_aligned.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <size_t _Np, class _Tp>
 [[nodiscard]]
@@ -34,12 +34,12 @@ constexpr _Tp* assume_aligned(_Tp* __ptr) {
   if (is_constant_evaluated()) {
     return __ptr;
   } else {
-    _LIBCPP_ASSERT(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated");
+    _LIBCPP_ASSERT_UNCATEGORIZED(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated");
     return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Np));
   }
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__memory/builtin_new_allocator.h
@@ -28,10 +28,10 @@ struct __builtin_new_allocator {
   struct __builtin_new_deleter {
     typedef void* pointer_type;
 
-    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
         : __size_(__size), __align_(__align) {}
 
-    void operator()(void* __p) const _NOEXCEPT {
+    _LIBCPP_HIDE_FROM_ABI void operator()(void* __p) const _NOEXCEPT {
         _VSTD::__libcpp_deallocate(__p, __size_, __align_);
     }
 
@@ -42,25 +42,25 @@ struct __builtin_new_allocator {
 
   typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
 
-  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
+  _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_bytes(size_t __s, size_t __align) {
       return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
                      __builtin_new_deleter(__s, __align));
   }
 
-  static void __deallocate_bytes(void* __p, size_t __s,
+  _LIBCPP_HIDE_FROM_ABI static void __deallocate_bytes(void* __p, size_t __s,
                                  size_t __align) _NOEXCEPT {
       _VSTD::__libcpp_deallocate(__p, __s, __align);
   }
 
   template <class _Tp>
   _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
-  static __holder_t __allocate_type(size_t __n) {
+  _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_type(size_t __n) {
       return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
   }
 
   template <class _Tp>
   _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
-  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
+  _LIBCPP_HIDE_FROM_ABI static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
       __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
   }
 };
lib/libcxx/include/__memory/compressed_pair.h
@@ -13,7 +13,7 @@
 #include <__config>
 #include <__fwd/get.h>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/tuple_indices.h>
+#include <__tuple/tuple_indices.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/dependent_type.h>
 #include <__type_traits/enable_if.h>
@@ -31,6 +31,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Tag used to default initialize one or both of the pair's elements.
@@ -46,7 +49,7 @@ struct __compressed_pair_elem {
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_() {}
 
-  template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
+  template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> >
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
   explicit __compressed_pair_elem(_Up&& __u) : __value_(std::forward<_Up>(__u)) {}
 
@@ -75,7 +78,7 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_type() {}
 
-  template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
+  template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> >
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
   explicit __compressed_pair_elem(_Up&& __u) : __value_type(std::forward<_Up>(__u)) {}
 
@@ -174,4 +177,6 @@ void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H
lib/libcxx/include/__memory/concepts.h
@@ -19,6 +19,7 @@
 #include <__ranges/concepts.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h> // TODO(modules): This should not be required
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,7 +27,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -62,7 +63,7 @@ concept __nothrow_forward_range =
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__memory/construct_at.h
@@ -26,26 +26,29 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // construct_at
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
-  _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
-  return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
+  _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at");
+  return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
 }
 
 #endif
 
 template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   return std::construct_at(__location, std::forward<_Args>(__args)...);
 #else
-  return _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at"),
+  return _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at"),
          ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
 #endif
 }
@@ -62,16 +65,16 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
 template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void __destroy_at(_Tp* __loc) {
-    _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
     __loc->~_Tp();
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void __destroy_at(_Tp* __loc) {
-    _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
-    _VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc));
+    _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
+    std::__destroy(std::begin(*__loc), std::end(*__loc));
 }
 #endif
 
@@ -79,7 +82,7 @@ template <class _ForwardIterator>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) {
     for (; __first != __last; ++__first)
-        _VSTD::__destroy_at(_VSTD::addressof(*__first));
+        std::__destroy_at(std::addressof(*__first));
     return __first;
 }
 
@@ -93,38 +96,40 @@ _BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _Bidire
     return __last;
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void destroy_at(_Tp* __loc) {
-    _VSTD::__destroy_at(__loc);
+    std::__destroy_at(__loc);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void destroy_at(_Tp* __loc) {
-  _VSTD::__destroy_at(__loc);
+  std::__destroy_at(__loc);
 }
 #endif
 
 template <class _ForwardIterator>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 void destroy(_ForwardIterator __first, _ForwardIterator __last) {
-  (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last));
+  (void)std::__destroy(std::move(__first), std::move(__last));
 }
 
 template <class _ForwardIterator, class _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
     for (; __n > 0; (void)++__first, --__n)
-        _VSTD::__destroy_at(_VSTD::addressof(*__first));
+        std::__destroy_at(std::addressof(*__first));
     return __first;
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H
lib/libcxx/include/__memory/pointer_traits.h
@@ -200,7 +200,7 @@ template <class _Pointer, class = __enable_if_t<
     _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value
 > >
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-typename decay<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>::type
+__decay_t<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>
 __to_address(const _Pointer& __p) _NOEXCEPT {
     return __to_address_helper<_Pointer>::__call(__p);
 }
@@ -223,7 +223,7 @@ struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to
     }
 };
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY constexpr
 auto to_address(_Tp *__p) noexcept {
lib/libcxx/include/__memory/ranges_construct_at.h
@@ -13,7 +13,7 @@
 #include <__concepts/destructible.h>
 #include <__config>
 #include <__iterator/incrementable_traits.h>
-#include <__iterator/readable_traits.h>
+#include <__iterator/iterator_traits.h>
 #include <__memory/concepts.h>
 #include <__memory/construct_at.h>
 #include <__ranges/access.h>
@@ -28,9 +28,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 namespace ranges {
 
 // construct_at
@@ -118,8 +121,10 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H
lib/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -33,7 +33,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -45,7 +45,7 @@ struct __fn {
   template <__nothrow_forward_iterator _ForwardIterator,
             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return _VSTD::__uninitialized_default_construct<_ValueType>(
         _VSTD::move(__first), _VSTD::move(__last));
@@ -53,7 +53,7 @@ struct __fn {
 
   template <__nothrow_forward_range _ForwardRange>
     requires default_initializable<range_value_t<_ForwardRange>>
-  borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
 };
@@ -71,7 +71,7 @@ namespace __uninitialized_default_construct_n {
 struct __fn {
   template <__nothrow_forward_iterator _ForwardIterator>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _ForwardIterator operator()(_ForwardIterator __first,
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
                               iter_difference_t<_ForwardIterator> __n) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n);
@@ -92,7 +92,7 @@ struct __fn {
   template <__nothrow_forward_iterator _ForwardIterator,
             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return _VSTD::__uninitialized_value_construct<_ValueType>(
         _VSTD::move(__first), _VSTD::move(__last));
@@ -100,7 +100,7 @@ struct __fn {
 
   template <__nothrow_forward_range _ForwardRange>
     requires default_initializable<range_value_t<_ForwardRange>>
-  borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
 };
@@ -118,7 +118,7 @@ namespace __uninitialized_value_construct_n {
 struct __fn {
   template <__nothrow_forward_iterator _ForwardIterator>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _ForwardIterator operator()(_ForwardIterator __first,
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
                               iter_difference_t<_ForwardIterator> __n) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n);
@@ -140,14 +140,14 @@ struct __fn {
             __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
             class _Tp>
     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
-  _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x);
   }
 
   template <__nothrow_forward_range _ForwardRange, class _Tp>
     requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
-  borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
     return (*this)(ranges::begin(__range), ranges::end(__range), __x);
   }
 };
@@ -165,7 +165,7 @@ namespace __uninitialized_fill_n {
 struct __fn {
   template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
-  _ForwardIterator operator()(_ForwardIterator __first,
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
                               iter_difference_t<_ForwardIterator> __n,
                               const _Tp& __x) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
@@ -192,7 +192,7 @@ struct __fn {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
-  uninitialized_copy_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
 
@@ -203,7 +203,7 @@ struct __fn {
 
   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
-  uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
   operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const {
     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
                    ranges::begin(__out_range), ranges::end(__out_range));
@@ -228,7 +228,7 @@ struct __fn {
            __nothrow_forward_iterator _OutputIterator,
            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
-  uninitialized_copy_n_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
              _OutputIterator __ofirst, _Sentinel __olast) const {
     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
@@ -257,7 +257,7 @@ struct __fn {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
-  uninitialized_move_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
@@ -268,7 +268,7 @@ struct __fn {
 
   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
     requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
-  uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
                    ranges::begin(__out_range), ranges::end(__out_range));
@@ -293,7 +293,7 @@ struct __fn {
            __nothrow_forward_iterator _OutputIterator,
            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
-  uninitialized_move_n_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
              _OutputIterator __ofirst, _Sentinel __olast) const {
     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
@@ -312,7 +312,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__memory/raw_storage_iterator.h
@@ -39,7 +39,7 @@ private:
 public:
     typedef output_iterator_tag iterator_category;
     typedef void                value_type;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef ptrdiff_t           difference_type;
 #else
     typedef void                difference_type;
lib/libcxx/include/__memory/shared_ptr.h
@@ -29,17 +29,32 @@
 #include <__memory/pointer_traits.h>
 #include <__memory/uninitialized_algorithms.h>
 #include <__memory/unique_ptr.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_bounded_array.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_unbounded_array.h>
+#include <__type_traits/nat.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_extent.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
+#include <__verbose_abort>
 #include <cstddef>
-#include <cstdlib> // abort
 #include <iosfwd>
 #include <new>
 #include <stdexcept>
 #include <typeinfo>
 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
-#  include <atomic>
+#  include <__atomic/memory_order.h>
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -105,12 +120,12 @@ __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
 #endif
 }
 
-class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
+class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr
     : public std::exception
 {
 public:
-    bad_weak_ptr() _NOEXCEPT = default;
-    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
     ~bad_weak_ptr() _NOEXCEPT override;
     const char* what() const  _NOEXCEPT override;
 };
@@ -118,16 +133,16 @@ public:
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_bad_weak_ptr()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw bad_weak_ptr();
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
 #endif
 }
 
 template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
 
-class _LIBCPP_TYPE_VIS __shared_count
+class _LIBCPP_EXPORTED_FROM_ABI __shared_count
 {
     __shared_count(const __shared_count&);
     __shared_count& operator=(const __shared_count&);
@@ -166,7 +181,7 @@ public:
     }
 };
 
-class _LIBCPP_TYPE_VIS __shared_weak_count
+class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count
     : private __shared_count
 {
     long __shared_weak_owners_;
@@ -220,12 +235,12 @@ public:
         :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
 
 #ifndef _LIBCPP_HAS_NO_RTTI
-    const void* __get_deleter(const type_info&) const _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override;
 #endif
 
 private:
-    void __on_zero_shared() _NOEXCEPT override;
-    void __on_zero_shared_weak() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override;
 };
 
 #ifndef _LIBCPP_HAS_NO_RTTI
@@ -295,8 +310,8 @@ struct __shared_ptr_emplace
     _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
 
 private:
-    void __on_zero_shared() _NOEXCEPT override {
-#if _LIBCPP_STD_VER > 17
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
+#if _LIBCPP_STD_VER >= 20
         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
             __get_elem()->~_Tp();
         } else {
@@ -309,7 +324,7 @@ private:
 #endif
     }
 
-    void __on_zero_shared_weak() _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
         using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
         using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
         _ControlBlockAlloc __tmp(*__get_alloc());
@@ -336,13 +351,13 @@ private:
         _LIBCPP_HIDE_FROM_ABI ~_Storage() {
             __get_alloc()->~_Alloc();
         }
-        _Alloc* __get_alloc() _NOEXCEPT {
+        _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {
             _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
             typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
             _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
             return __alloc;
         }
-        _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
+        _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
             _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
             typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
             _Tp *__elem = reinterpret_cast<_Tp*>(__second);
@@ -433,10 +448,10 @@ struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : tru
 
 template <class _Dp, class _Pt,
     class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>
-static true_type __well_formed_deleter_test(int);
+true_type __well_formed_deleter_test(int);
 
 template <class, class>
-static false_type __well_formed_deleter_test(...);
+false_type __well_formed_deleter_test(...);
 
 template <class _Dp, class _Pt>
 struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
@@ -450,7 +465,7 @@ struct __shared_ptr_deleter_ctor_reqs
 };
 
 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
-#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
 #else
 #  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
 #endif
@@ -459,7 +474,7 @@ template<class _Tp>
 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
 {
 public:
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef weak_ptr<_Tp> weak_type;
     typedef remove_extent_t<_Tp> element_type;
 #else
@@ -494,7 +509,7 @@ public:
 #endif
         >::value
     > >
-    explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
+    _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
         unique_ptr<_Yp> __hold(__p);
         typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
         typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
@@ -508,10 +523,10 @@ public:
     shared_ptr(_Yp* __p, _Dp __d)
         : __ptr_(__p)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
             typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
 #ifndef _LIBCPP_CXX03_LANG
@@ -520,14 +535,14 @@ public:
             __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
 #endif // not _LIBCPP_CXX03_LANG
             __enable_weak_this(__p, __p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __d(__p);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 
     template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
@@ -535,10 +550,10 @@ public:
     shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
         : __ptr_(__p)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
             typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
             typedef __allocator_destructor<_A2> _D2;
@@ -552,14 +567,14 @@ public:
 #endif // not _LIBCPP_CXX03_LANG
             __cntrl_ = _VSTD::addressof(*__hold2.release());
             __enable_weak_this(__p, __p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __d(__p);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 
     template<class _Dp>
@@ -567,10 +582,10 @@ public:
     shared_ptr(nullptr_t __p, _Dp __d)
         : __ptr_(nullptr)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
             typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
 #ifndef _LIBCPP_CXX03_LANG
@@ -578,14 +593,14 @@ public:
 #else
             __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
 #endif // not _LIBCPP_CXX03_LANG
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __d(__p);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 
     template<class _Dp, class _Alloc>
@@ -593,10 +608,10 @@ public:
     shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
         : __ptr_(nullptr)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
             typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
             typedef __allocator_destructor<_A2> _D2;
@@ -609,14 +624,14 @@ public:
                 _CntrlBlk(__p, __d, __a);
 #endif // not _LIBCPP_CXX03_LANG
             __cntrl_ = _VSTD::addressof(*__hold2.release());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __d(__p);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 
     template<class _Yp>
@@ -629,6 +644,18 @@ public:
             __cntrl_->__add_shared();
     }
 
+// LWG-2996
+// We don't backport because it is an evolutionary change.
+#if _LIBCPP_STD_VER >= 20
+    template <class _Yp>
+    _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
+        : __ptr_(__p),
+          __cntrl_(__r.__cntrl_) {
+      __r.__ptr_   = nullptr;
+      __r.__cntrl_ = nullptr;
+    }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI
     shared_ptr(const shared_ptr& __r) _NOEXCEPT
         : __ptr_(__r.__ptr_),
@@ -699,7 +726,7 @@ public:
     shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
         : __ptr_(__r.get())
     {
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
         if (__ptr_ == nullptr)
             __cntrl_ = nullptr;
         else
@@ -722,7 +749,7 @@ public:
     shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
         : __ptr_(__r.get())
     {
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
         if (__ptr_ == nullptr)
             __cntrl_ = nullptr;
         else
@@ -895,7 +922,7 @@ public:
         return __cntrl_ == __p.__cntrl_;
     }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_HIDE_FROM_ABI
     __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const
     {
@@ -975,7 +1002,7 @@ private:
     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Tp>
 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
 template<class _Tp, class _Dp>
@@ -1024,7 +1051,7 @@ shared_ptr<_Tp> make_shared_for_overwrite()
 
 #endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <size_t _Alignment>
 struct __sp_aligned_storage {
@@ -1084,7 +1111,7 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
     ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
 
 private:
-    void __on_zero_shared() _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
 #if _LIBCPP_STD_VER >= 20
         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
             std::__reverse_destroy(__data_, __data_ + __count_);
@@ -1098,7 +1125,7 @@ private:
 #endif
     }
 
-    void __on_zero_shared_weak() _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
         using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
         using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
         using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
@@ -1170,7 +1197,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
     ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
 
 private:
-    void __on_zero_shared() _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
 #if _LIBCPP_STD_VER >= 20
         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
             std::__reverse_destroy(__data_, __data_ + _Count);
@@ -1184,7 +1211,7 @@ private:
 #endif
     }
 
-    void __on_zero_shared_weak() _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
         using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
         using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
 
@@ -1214,9 +1241,9 @@ shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...
     return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // bounded array variants
 template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
@@ -1308,7 +1335,7 @@ shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
     return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template<class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1368,7 +1395,7 @@ operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
 
 #endif // _LIBCPP_STD_VER <= 17
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template<class _Tp, class _Up>
 _LIBCPP_HIDE_FROM_ABI strong_ordering
 operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept
@@ -1477,7 +1504,7 @@ operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
 
 #endif // _LIBCPP_STD_VER <= 17
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI strong_ordering
 operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept
@@ -1504,6 +1531,15 @@ static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
                                typename shared_ptr<_Tp>::element_type*>(__r.get()));
 }
 
+// LWG-2996
+// We don't backport because it is an evolutionary change.
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+  return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
+}
+#endif
+
 template<class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
 shared_ptr<_Tp>
@@ -1514,6 +1550,16 @@ dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
     return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
 }
 
+// LWG-2996
+// We don't backport because it is an evolutionary change.
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+  auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
+  return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
+}
+#endif
+
 template<class _Tp, class _Up>
 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
 const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
@@ -1522,6 +1568,15 @@ const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
     return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
 }
 
+// LWG-2996
+// We don't backport because it is an evolutionary change.
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+  return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
+}
+#endif
+
 template<class _Tp, class _Up>
 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
@@ -1531,6 +1586,15 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
                                typename shared_ptr<_Tp>::element_type*>(__r.get()));
 }
 
+// LWG-2996
+// We don't backport because it is an evolutionary change.
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+  return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
+}
+#endif
+
 #ifndef _LIBCPP_HAS_NO_RTTI
 
 template<class _Dp, class _Tp>
@@ -1547,7 +1611,7 @@ template<class _Tp>
 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
 {
 public:
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef remove_extent_t<_Tp> element_type;
 #else
     typedef _Tp element_type;
@@ -1574,7 +1638,7 @@ public:
     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
                    typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
                          _NOEXCEPT;
-    ~weak_ptr();
+    _LIBCPP_HIDE_FROM_ABI ~weak_ptr();
 
     _LIBCPP_INLINE_VISIBILITY
     weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
@@ -1618,7 +1682,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     bool expired() const _NOEXCEPT
         {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
-    shared_ptr<_Tp> lock() const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
     template<class _Up>
         _LIBCPP_INLINE_VISIBILITY
         bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
@@ -1632,7 +1696,7 @@ public:
     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Tp>
 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
 #endif
@@ -1808,7 +1872,7 @@ weak_ptr<_Tp>::lock() const _NOEXCEPT
     return __r;
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp = void> struct owner_less;
 #else
 template <class _Tp> struct owner_less;
@@ -1845,7 +1909,7 @@ struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
         {return __x.owner_before(__y);}
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <>
 struct _LIBCPP_TEMPLATE_VIS owner_less<void>
 {
@@ -1891,7 +1955,7 @@ public:
     shared_ptr<_Tp const> shared_from_this() const
         {return shared_ptr<const _Tp>(__weak_this_);}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     weak_ptr<_Tp> weak_from_this() _NOEXCEPT
        { return __weak_this_; }
@@ -1899,7 +1963,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
         { return __weak_this_; }
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
     template <class _Up> friend class shared_ptr;
 };
@@ -1929,7 +1993,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
 
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 
-class _LIBCPP_TYPE_VIS __sp_mut
+class _LIBCPP_EXPORTED_FROM_ABI __sp_mut
 {
     void* __lx_;
 public:
@@ -1941,10 +2005,10 @@ private:
     __sp_mut(const __sp_mut&);
     __sp_mut& operator=(const __sp_mut&);
 
-    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
+    friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);
 };
 
-_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
 __sp_mut& __get_sp_mut(const void*);
 
 template <class _Tp>
lib/libcxx/include/__memory/swap_allocator.h
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <typename _Alloc>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2, true_type)
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _NOEXCEPT
 #else
     _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
@@ -39,7 +39,7 @@ __swap_allocator(_Alloc&, _Alloc&, false_type) _NOEXCEPT {}
 
 template <typename _Alloc>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2)
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _NOEXCEPT
 #else
     _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
lib/libcxx/include/__memory/temp_value.h
@@ -32,7 +32,7 @@ struct __temp_value {
 #endif
     _Alloc &__a;
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() {
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() {
 #ifdef _LIBCPP_CXX03_LANG
         return reinterpret_cast<_Tp*>(std::addressof(__v));
 #else
@@ -40,15 +40,15 @@ struct __temp_value {
 #endif
     }
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &   get() { return *__addr(); }
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & get() { return *__addr(); }
 
     template<class... _Args>
-    _LIBCPP_NO_CFI
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI
     _LIBCPP_CONSTEXPR_SINCE_CXX20 __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
       _Traits::construct(__a, __addr(), std::forward<_Args>(__args)...);
     }
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); }
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); }
 };
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/uninitialized_algorithms.h
@@ -12,6 +12,8 @@
 
 #include <__algorithm/copy.h>
 #include <__algorithm/move.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__algorithm/unwrap_range.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
@@ -58,12 +60,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
 __uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast,
                      _ForwardIterator __ofirst, _Sentinel2 __olast) {
   _ForwardIterator __idx = __ofirst;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
 #endif
     for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx)
       ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
     _VSTD::__destroy(__ofirst, __idx);
     throw;
@@ -90,12 +92,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
 __uninitialized_copy_n(_InputIterator __ifirst, _Size __n,
                        _ForwardIterator __ofirst, _Sentinel __olast) {
   _ForwardIterator __idx = __ofirst;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
 #endif
     for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n)
       ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
     _VSTD::__destroy(__ofirst, __idx);
     throw;
@@ -121,13 +123,13 @@ inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x)
 {
     _ForwardIterator __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
 #endif
         for (; __idx != __last; ++__idx)
             ::new (_VSTD::__voidify(*__idx)) _ValueType(__x);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -154,13 +156,13 @@ inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
 {
     _ForwardIterator __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
 #endif
         for (; __n > 0; ++__idx, (void) --__n)
             ::new (_VSTD::__voidify(*__idx)) _ValueType(__x);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -180,7 +182,7 @@ _ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const
     return _VSTD::__uninitialized_fill_n<_ValueType>(__first, __n, __x);
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 // uninitialized_default_construct
 
@@ -188,12 +190,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel>
 inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
     auto __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif
     for (; __idx != __last; ++__idx)
         ::new (_VSTD::__voidify(*__idx)) _ValueType;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
         _VSTD::__destroy(__first, __idx);
         throw;
@@ -217,12 +219,12 @@ template <class _ValueType, class _ForwardIterator, class _Size>
 inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
     auto __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif
     for (; __n > 0; ++__idx, (void) --__n)
         ::new (_VSTD::__voidify(*__idx)) _ValueType;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
         _VSTD::__destroy(__first, __idx);
         throw;
@@ -245,12 +247,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel>
 inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) {
     auto __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif
     for (; __idx != __last; ++__idx)
         ::new (_VSTD::__voidify(*__idx)) _ValueType();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
         _VSTD::__destroy(__first, __idx);
         throw;
@@ -274,12 +276,12 @@ template <class _ValueType, class _ForwardIterator, class _Size>
 inline _LIBCPP_HIDE_FROM_ABI
 _ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
     auto __idx = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif
     for (; __n > 0; ++__idx, (void) --__n)
         ::new (_VSTD::__voidify(*__idx)) _ValueType();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
         _VSTD::__destroy(__first, __idx);
         throw;
@@ -304,13 +306,13 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
 __uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast,
                      _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) {
   auto __idx = __ofirst;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
 #endif
     for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) {
       ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst));
     }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
     _VSTD::__destroy(__ofirst, __idx);
     throw;
@@ -338,12 +340,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
 __uninitialized_move_n(_InputIterator __ifirst, _Size __n,
                        _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) {
   auto __idx = __ofirst;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
 #endif
     for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n)
       ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   } catch (...) {
     _VSTD::__destroy(__ofirst, __idx);
     throw;
@@ -371,7 +373,7 @@ uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir
 // This function assumes that destructors do not throw, and that the allocator is bound to
 // the correct type.
 template<class _Alloc, class _BidirIter, class = __enable_if_t<
-    __is_cpp17_bidirectional_iterator<_BidirIter>::value
+    __has_bidirectional_iterator_category<_BidirIter>::value
 >>
 _LIBCPP_HIDE_FROM_ABI
 constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter __first, _BidirIter __last) noexcept {
@@ -512,7 +514,7 @@ __uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _B
     __guard.__complete();
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 // Destroy all elements in [__first, __last) from left to right using allocator destruction.
 template <class _Alloc, class _Iter, class _Sent>
@@ -545,7 +547,7 @@ private:
 // already copied elements are destroyed in reverse order of their construction.
 template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
-__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
+__uninitialized_allocator_copy_impl(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
   auto __destruct_first = __first2;
   auto __guard =
       std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
@@ -565,14 +567,16 @@ template <class _Type>
 struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_type {};
 
 template <class _Alloc,
-          class _Type,
-          class _RawType = __remove_const_t<_Type>,
+          class _In,
+          class _RawTypeIn = __remove_const_t<_In>,
+          class _Out,
           __enable_if_t<
-              // using _RawType because of the allocator<T const> extension
-              is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
-              __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
-__uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) {
+              // using _RawTypeIn because of the allocator<T const> extension
+              is_trivially_copy_constructible<_RawTypeIn>::value && is_trivially_copy_assignable<_RawTypeIn>::value &&
+              is_same<__remove_const_t<_In>, __remove_const_t<_Out> >::value &&
+              __allocator_has_trivial_copy_construct<_Alloc, _RawTypeIn>::value>* = nullptr>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Out*
+__uninitialized_allocator_copy_impl(_Alloc&, _In* __first1, _In* __last1, _Out* __first2) {
   // TODO: Remove the const_cast once we drop support for std::allocator<T const>
   if (__libcpp_is_constant_evaluated()) {
     while (__first1 != __last1) {
@@ -582,10 +586,17 @@ __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __la
     }
     return __first2;
   } else {
-    return std::copy(__first1, __last1, const_cast<_RawType*>(__first2));
+    return std::copy(__first1, __last1, const_cast<_RawTypeIn*>(__first2));
   }
 }
 
+template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
+    auto __unwrapped_range = std::__unwrap_range(__first1, __last1);
+    auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2));
+    return std::__rewrap_iter(__first2, __result);
+}
+
 // Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
 // if the move constructor is noexcept, where N is distance(__first1, __last1).
 //
@@ -600,7 +611,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_alloc
   auto __guard =
       std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
   while (__first1 != __last1) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1));
 #else
     allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move(*__first1));
lib/libcxx/include/__memory/unique_ptr.h
@@ -44,6 +44,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
@@ -115,7 +118,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
 };
 
 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
-#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
 #else
 #  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
 #endif
@@ -556,7 +559,7 @@ bool
 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
 
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _T1, class _D1, class _T2, class _D2>
 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer,
                                    typename unique_ptr<_T2, _D2>::pointer>
@@ -650,7 +653,7 @@ operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
   return !(nullptr < __x);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _T1, class _D1>
   requires three_way_comparable<
       typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
@@ -660,7 +663,7 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
 }
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template<class _Tp>
 struct __unique_if
@@ -697,7 +700,7 @@ template<class _Tp, class... _Args>
     typename __unique_if<_Tp>::__unique_array_known_bound
     make_unique(_Args&&...) = delete;
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 #if _LIBCPP_STD_VER >= 20
 
@@ -743,4 +746,6 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H
lib/libcxx/include/__memory/uses_allocator.h
@@ -49,9 +49,9 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator
 {
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Alloc>
-inline constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
+inline constexpr bool uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/uses_allocator_construction.h
@@ -23,6 +23,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER >= 17
@@ -83,7 +86,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, _Up&& __u, _Vp&& __v)
       std::forward_as_tuple(std::forward<_Vp>(__v)));
 }
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
 template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI constexpr auto
 __uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>& __pair) noexcept {
@@ -109,7 +112,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>&& __pai
       std::forward_as_tuple(std::get<1>(std::move(__pair))));
 }
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
 template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI constexpr auto
 __uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&& __pair) noexcept {
@@ -218,4 +221,6 @@ uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Ar
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
lib/libcxx/include/__memory_resource/memory_resource.h
@@ -9,14 +9,16 @@
 #ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
 #define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
 
+#include <__availability>
 #include <__config>
+#include <__fwd/memory_resource.h>
 #include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -24,7 +26,7 @@ namespace pmr {
 
 // [mem.res.class]
 
-class _LIBCPP_TYPE_VIS memory_resource {
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource {
   static const size_t __max_align = alignof(max_align_t);
 
 public:
@@ -51,25 +53,38 @@ private:
 
 // [mem.res.eq]
 
-inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
+inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool
+operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
   return &__lhs == &__rhs || __lhs.is_equal(__rhs);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
+#  if _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool
+operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
   return !(__lhs == __rhs);
 }
 
+#  endif
+
 // [mem.res.global]
 
-[[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept;
-[[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept;
-[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept;
-[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept;
+[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
+get_default_resource() noexcept;
+
+[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
+set_default_resource(memory_resource*) noexcept;
+
+[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
+new_delete_resource() noexcept;
+
+[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
+null_memory_resource() noexcept;
 
 } // namespace pmr
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
lib/libcxx/include/__memory_resource/monotonic_buffer_resource.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
 #define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
 
+#include <__availability>
 #include <__config>
 #include <__memory/addressof.h>
 #include <__memory_resource/memory_resource.h>
@@ -18,7 +19,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -26,7 +27,7 @@ namespace pmr {
 
 // [mem.res.monotonic.buffer]
 
-class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI monotonic_buffer_resource : public memory_resource {
   static const size_t __default_buffer_capacity  = 1024;
   static const size_t __default_buffer_alignment = 16;
 
@@ -35,7 +36,9 @@ class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
     char* __start_;
     char* __cur_;
     size_t __align_;
-    size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
+    _LIBCPP_HIDE_FROM_ABI size_t __allocation_size() {
+      return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this);
+    }
     void* __try_allocate_from_chunk(size_t, size_t);
   };
 
@@ -115,6 +118,6 @@ private:
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
lib/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H
 
 #include <__assert>
+#include <__availability>
 #include <__config>
 #include <__memory_resource/memory_resource.h>
 #include <__utility/exception_guard.h>
@@ -26,7 +27,7 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -39,7 +40,7 @@ template <class _ValueType
           = byte
 #  endif
           >
-class _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
 
 public:
   using value_type = _ValueType;
@@ -50,7 +51,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* __r) noexcept : __res_(__r) {}
 
-  polymorphic_allocator(const polymorphic_allocator&) = default;
+  _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator&) = default;
 
   template <class _Tp>
   _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator<_Tp>& __other) noexcept
@@ -68,35 +69,35 @@ public:
   }
 
   _LIBCPP_HIDE_FROM_ABI void deallocate(_ValueType* __p, size_t __n) {
-    _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(), "deallocate called for size which exceeds max_size()");
     __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
   }
 
 #  if _LIBCPP_STD_VER >= 20
 
-  [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] void*
+  [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] _LIBCPP_HIDE_FROM_ABI void*
   allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
     return __res_->allocate(__nbytes, __alignment);
   }
 
-  void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
+  _LIBCPP_HIDE_FROM_ABI void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
     __res_->deallocate(__ptr, __nbytes, __alignment);
   }
 
   template <class _Type>
-  [[nodiscard]] _Type* allocate_object(size_t __n = 1) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* allocate_object(size_t __n = 1) {
     if (numeric_limits<size_t>::max() / sizeof(_Type) < __n)
       std::__throw_bad_array_new_length();
     return static_cast<_Type*>(allocate_bytes(__n * sizeof(_Type), alignof(_Type)));
   }
 
   template <class _Type>
-  void deallocate_object(_Type* __ptr, size_t __n = 1) {
+  _LIBCPP_HIDE_FROM_ABI void deallocate_object(_Type* __ptr, size_t __n = 1) {
     deallocate_bytes(__ptr, __n * sizeof(_Type), alignof(_Type));
   }
 
   template <class _Type, class... _CtorArgs>
-  [[nodiscard]] _Type* new_object(_CtorArgs&&... __ctor_args) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* new_object(_CtorArgs&&... __ctor_args) {
     _Type* __ptr = allocate_object<_Type>();
     auto __guard = std::__make_exception_guard([&] { deallocate_object(__ptr); });
     construct(__ptr, std::forward<_CtorArgs>(__ctor_args)...);
@@ -105,7 +106,7 @@ public:
   }
 
   template <class _Type>
-  void delete_object(_Type* __ptr) {
+  _LIBCPP_HIDE_FROM_ABI void delete_object(_Type* __ptr) {
     destroy(__ptr);
     deallocate_object(__ptr);
   }
@@ -207,17 +208,21 @@ operator==(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<
   return *__lhs.resource() == *__rhs.resource();
 }
 
+#  if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Up>
 inline _LIBCPP_HIDE_FROM_ABI bool
 operator!=(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<_Up>& __rhs) noexcept {
   return !(__lhs == __rhs);
 }
 
+#  endif
+
 } // namespace pmr
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_POP_MACROS
 
lib/libcxx/include/__memory_resource/pool_options.h
@@ -16,7 +16,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -24,7 +24,7 @@ namespace pmr {
 
 // [mem.res.pool.options]
 
-struct _LIBCPP_TYPE_VIS pool_options {
+struct _LIBCPP_EXPORTED_FROM_ABI pool_options {
   size_t max_blocks_per_chunk        = 0;
   size_t largest_required_pool_block = 0;
 };
@@ -33,6 +33,6 @@ struct _LIBCPP_TYPE_VIS pool_options {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H
lib/libcxx/include/__memory_resource/synchronized_pool_resource.h
@@ -9,20 +9,19 @@
 #ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
 #define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
 
+#include <__availability>
 #include <__config>
 #include <__memory_resource/memory_resource.h>
 #include <__memory_resource/pool_options.h>
 #include <__memory_resource/unsynchronized_pool_resource.h>
 #include <cstddef>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-#  include <mutex>
-#endif
+#include <mutex>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -30,7 +29,7 @@ namespace pmr {
 
 // [mem.res.pool.overview]
 
-class _LIBCPP_TYPE_VIS synchronized_pool_resource : public memory_resource {
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI synchronized_pool_resource : public memory_resource {
 public:
   _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream)
       : __unsync_(__opts, __upstream) {}
@@ -46,7 +45,7 @@ public:
 
   synchronized_pool_resource(const synchronized_pool_resource&) = delete;
 
-  ~synchronized_pool_resource() override = default;
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~synchronized_pool_resource() override = default;
 
   synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;
 
@@ -89,6 +88,6 @@ private:
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
lib/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
 #define _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
 
+#include <__availability>
 #include <__config>
 #include <__memory_resource/memory_resource.h>
 #include <__memory_resource/pool_options.h>
@@ -19,7 +20,7 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -27,7 +28,7 @@ namespace pmr {
 
 // [mem.res.pool.overview]
 
-class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource {
+class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI unsynchronized_pool_resource : public memory_resource {
   class __fixed_pool;
 
   class __adhoc_pool {
@@ -101,6 +102,6 @@ private:
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
lib/libcxx/include/__mutex/lock_guard.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___MUTEX_LOCK_GUARD_H
+#define _LIBCPP___MUTEX_LOCK_GUARD_H
+
+#include <__config>
+#include <__mutex/tag_types.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Mutex>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard {
+public:
+  typedef _Mutex mutex_type;
+
+private:
+  mutex_type& __m_;
+
+public:
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
+      : __m_(__m) {
+    __m_.lock();
+  }
+
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
+      : __m_(__m) {}
+  _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
+
+private:
+  lock_guard(lock_guard const&)            = delete;
+  lock_guard& operator=(lock_guard const&) = delete;
+};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP___MUTEX_LOCK_GUARD_H
lib/libcxx/include/__mutex/mutex.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___MUTEX_MUTEX_H
+#define _LIBCPP___MUTEX_MUTEX_H
+
+#include <__config>
+#include <__threading_support>
+#include <__type_traits/is_nothrow_default_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex {
+  __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR mutex() = default;
+
+  mutex(const mutex&)            = delete;
+  mutex& operator=(const mutex&) = delete;
+
+#  if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
+  _LIBCPP_HIDE_FROM_ABI ~mutex() = default;
+#  else
+  ~mutex() _NOEXCEPT;
+#  endif
+
+  void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
+  bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
+  void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
+
+  typedef __libcpp_mutex_t* native_handle_type;
+  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
+};
+
+static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow");
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP___MUTEX_MUTEX_H
lib/libcxx/include/__mutex/tag_types.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___MUTEX_TAG_TYPES_H
+#define _LIBCPP___MUTEX_TAG_TYPES_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
+  explicit defer_lock_t() = default;
+};
+
+struct _LIBCPP_EXPORTED_FROM_ABI try_to_lock_t {
+  explicit try_to_lock_t() = default;
+};
+
+struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
+  explicit adopt_lock_t() = default;
+};
+
+#  if _LIBCPP_STD_VER >= 17
+inline constexpr defer_lock_t defer_lock   = defer_lock_t();
+inline constexpr try_to_lock_t try_to_lock = try_to_lock_t();
+inline constexpr adopt_lock_t adopt_lock   = adopt_lock_t();
+#  elif !defined(_LIBCPP_CXX03_LANG)
+constexpr defer_lock_t defer_lock   = defer_lock_t();
+constexpr try_to_lock_t try_to_lock = try_to_lock_t();
+constexpr adopt_lock_t adopt_lock   = adopt_lock_t();
+#  endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP___MUTEX_TAG_TYPES_H
lib/libcxx/include/__mutex/unique_lock.h
@@ -0,0 +1,173 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___MUTEX_UNIQUE_LOCK_H
+#define _LIBCPP___MUTEX_UNIQUE_LOCK_H
+
+#include <__chrono/duration.h>
+#include <__chrono/time_point.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__mutex/tag_types.h>
+#include <__system_error/system_error.h>
+#include <__utility/swap.h>
+#include <cerrno>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Mutex>
+class _LIBCPP_TEMPLATE_VIS unique_lock {
+public:
+  typedef _Mutex mutex_type;
+
+private:
+  mutex_type* __m_;
+  bool __owns_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
+  _LIBCPP_HIDE_FROM_ABI explicit unique_lock(mutex_type& __m) : __m_(std::addressof(__m)), __owns_(true) {
+    __m_->lock();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
+      : __m_(std::addressof(__m)),
+        __owns_(false) {}
+
+  _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, try_to_lock_t)
+      : __m_(std::addressof(__m)), __owns_(__m.try_lock()) {}
+
+  _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, adopt_lock_t) : __m_(std::addressof(__m)), __owns_(true) {}
+
+  template <class _Clock, class _Duration>
+  _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
+      : __m_(std::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
+
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
+      : __m_(std::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
+
+  _LIBCPP_HIDE_FROM_ABI ~unique_lock() {
+    if (__owns_)
+      __m_->unlock();
+  }
+
+  unique_lock(unique_lock const&)            = delete;
+  unique_lock& operator=(unique_lock const&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI unique_lock(unique_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) {
+    __u.__m_    = nullptr;
+    __u.__owns_ = false;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT {
+    if (__owns_)
+      __m_->unlock();
+
+    __m_        = __u.__m_;
+    __owns_     = __u.__owns_;
+    __u.__m_    = nullptr;
+    __u.__owns_ = false;
+    return *this;
+  }
+
+  void lock();
+  bool try_lock();
+
+  template <class _Rep, class _Period>
+  bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
+
+  template <class _Clock, class _Duration>
+  bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+
+  void unlock();
+
+  _LIBCPP_HIDE_FROM_ABI void swap(unique_lock& __u) _NOEXCEPT {
+    std::swap(__m_, __u.__m_);
+    std::swap(__owns_, __u.__owns_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT {
+    mutex_type* __m = __m_;
+    __m_            = nullptr;
+    __owns_         = false;
+    return __m;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; }
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; }
+  _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; }
+};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock);
+
+template <class _Mutex>
+void unique_lock<_Mutex>::lock() {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
+  __m_->lock();
+  __owns_ = true;
+}
+
+template <class _Mutex>
+bool unique_lock<_Mutex>::try_lock() {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
+  __owns_ = __m_->try_lock();
+  return __owns_;
+}
+
+template <class _Mutex>
+template <class _Rep, class _Period>
+bool unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
+  __owns_ = __m_->try_lock_for(__d);
+  return __owns_;
+}
+
+template <class _Mutex>
+template <class _Clock, class _Duration>
+bool unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
+  __owns_ = __m_->try_lock_until(__t);
+  return __owns_;
+}
+
+template <class _Mutex>
+void unique_lock<_Mutex>::unlock() {
+  if (!__owns_)
+    __throw_system_error(EPERM, "unique_lock::unlock: not locked");
+  __m_->unlock();
+  __owns_ = false;
+}
+
+template <class _Mutex>
+inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT {
+  __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
lib/libcxx/include/__numeric/accumulate.h
@@ -17,6 +17,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator, class _Tp>
@@ -25,7 +28,7 @@ _Tp
 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
 {
     for (; __first != __last; ++__first)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         __init = _VSTD::move(__init) + *__first;
 #else
         __init = __init + *__first;
@@ -39,7 +42,7 @@ _Tp
 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
 {
     for (; __first != __last; ++__first)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         __init = __binary_op(_VSTD::move(__init), *__first);
 #else
         __init = __binary_op(__init, *__first);
@@ -49,4 +52,6 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___NUMERIC_ACCUMULATE_H
lib/libcxx/include/__numeric/adjacent_difference.h
@@ -18,6 +18,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator, class _OutputIterator>
@@ -32,7 +35,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
         for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             typename iterator_traits<_InputIterator>::value_type __val(*__first);
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
             *__result = __val - _VSTD::move(__acc);
 #else
             *__result = __val - __acc;
@@ -56,7 +59,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
         for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             typename iterator_traits<_InputIterator>::value_type __val(*__first);
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
             *__result = __binary_op(__val, _VSTD::move(__acc));
 #else
             *__result = __binary_op(__val, __acc);
@@ -69,4 +72,6 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H
lib/libcxx/include/__numeric/exclusive_scan.h
@@ -18,9 +18,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
@@ -46,8 +49,10 @@ exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __
   return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H
lib/libcxx/include/__numeric/gcd_lcm.h
@@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __ct_abs;
 
@@ -87,7 +87,7 @@ lcm(_Tp __m, _Up __n)
     using _Rp = common_type_t<_Tp,_Up>;
     _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n);
     _Rp __val2 = __ct_abs<_Rp, _Up>()(__n);
-    _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm");
+    _LIBCPP_ASSERT_UNCATEGORIZED((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm");
     return __val1 * __val2;
 }
 
lib/libcxx/include/__numeric/inclusive_scan.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
@@ -53,7 +53,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator inclusiv
   return _VSTD::inclusive_scan(__first, __last, __result, _VSTD::plus<>());
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__numeric/inner_product.h
@@ -17,6 +17,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator1, class _InputIterator2, class _Tp>
@@ -25,7 +28,7 @@ _Tp
 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
 {
     for (; __first1 != __last1; ++__first1, (void) ++__first2)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         __init = _VSTD::move(__init) + *__first1 * *__first2;
 #else
         __init = __init + *__first1 * *__first2;
@@ -40,7 +43,7 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
               _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
 {
     for (; __first1 != __last1; ++__first1, (void) ++__first2)
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         __init = __binary_op1(_VSTD::move(__init), __binary_op2(*__first1, *__first2));
 #else
         __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
@@ -50,4 +53,6 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___NUMERIC_INNER_PRODUCT_H
lib/libcxx/include/__numeric/midpoint.h
@@ -33,7 +33,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
 enable_if_t<is_integral_v<_Tp> && !is_same_v<bool, _Tp> && !is_null_pointer_v<_Tp>, _Tp>
@@ -86,7 +86,7 @@ midpoint(_Fp __a, _Fp __b) noexcept
       __a/2 + __b/2;                                         // otherwise correctly rounded
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__numeric/partial_sum.h
@@ -18,6 +18,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator, class _OutputIterator>
@@ -31,7 +34,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
         *__result = __t;
         for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
             __t = _VSTD::move(__t) + *__first;
 #else
             __t = __t + *__first;
@@ -54,7 +57,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
         *__result = __t;
         for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
             __t = __binary_op(_VSTD::move(__t), *__first);
 #else
             __t = __binary_op(__t, *__first);
@@ -67,4 +70,6 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___NUMERIC_PARTIAL_SUM_H
lib/libcxx/include/__numeric/pstl_reduce.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___NUMERIC_PSTL_REDUCE_H
+#define _LIBCPP___NUMERIC_PSTL_REDUCE_H
+
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/iterator_traits.h>
+#include <__numeric/pstl_transform_reduce.h>
+#include <__type_traits/is_execution_policy.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+void __pstl_reduce();
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _BinaryOperation                              = plus<>,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp
+reduce(_ExecutionPolicy&& __policy,
+       _ForwardIterator __first,
+       _ForwardIterator __last,
+       _Tp __init,
+       _BinaryOperation __op = {}) {
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce),
+      [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Tp __g_init, _BinaryOperation __g_op) {
+        return std::transform_reduce(
+            __policy, std::move(__g_first), std::move(__g_last), std::move(__g_init), std::move(__g_op), __identity{});
+      },
+      std::move(__first),
+      std::move(__last),
+      std::move(__init),
+      std::move(__op));
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
+reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+  return std::__pstl_frontend_dispatch(
+      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce),
+      [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last) {
+        return std::reduce(__policy, __g_first, __g_last, __iter_value_type<_ForwardIterator>());
+      },
+      std::move(__first),
+      std::move(__last));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___NUMERIC_PSTL_REDUCE_H
lib/libcxx/include/__numeric/pstl_transform_reduce.h
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___NUMERIC_PSTL_TRANSFORM_REDUCE_H
+#define _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
+
+#include <__algorithm/pstl_backend.h>
+#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__numeric/transform_reduce.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <__utility/terminate_on_exception.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _Tp,
+          class _BinaryOperation1,
+          class _BinaryOperation2,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _Tp __init,
+    _BinaryOperation1 __reduce,
+    _BinaryOperation2 __transform) {
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_transform_reduce<_RawPolicy>(
+      _Backend{},
+      std::move(__first1),
+      std::move(__last1),
+      std::move(__first2),
+      std::move(__init),
+      std::move(__reduce),
+      std::move(__transform));
+}
+
+// This overload doesn't get a customization point because it's trivial to detect (through e.g.
+// __is_trivial_plus_operation) when specializing the more general variant, which should always be preferred
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _Tp,
+          enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
+    _ExecutionPolicy&& __policy,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _Tp __init) {
+  return std::transform_reduce(__policy, __first1, __last1, __first2, __init, plus{}, multiplies{});
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Tp,
+          class _BinaryOperation,
+          class _UnaryOperation,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Tp __init,
+    _BinaryOperation __reduce,
+    _UnaryOperation __transform) {
+  using _Backend = typename __select_backend<_RawPolicy>::type;
+  return std::__pstl_transform_reduce<_RawPolicy>(
+      _Backend{},
+      std::move(__first),
+      std::move(__last),
+      std::move(__init),
+      std::move(__reduce),
+      std::move(__transform));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
lib/libcxx/include/__numeric/reduce.h
@@ -13,6 +13,7 @@
 #include <__config>
 #include <__functional/operations.h>
 #include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -20,12 +21,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _InputIterator, class _Tp, class _BinaryOp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp reduce(_InputIterator __first, _InputIterator __last,
                                                                    _Tp __init, _BinaryOp __b) {
   for (; __first != __last; ++__first)
-    __init = __b(__init, *__first);
+    __init = __b(std::move(__init), *__first);
   return __init;
 }
 
lib/libcxx/include/__numeric/transform_exclusive_scan.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _InputIterator, class _OutputIterator, class _Tp,
           class _BinaryOp, class _UnaryOp>
@@ -42,7 +42,7 @@ transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
     return __result;
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__numeric/transform_inclusive_scan.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -51,7 +51,7 @@ transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
     return __result;
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__numeric/transform_reduce.h
@@ -20,13 +20,13 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_InputIterator __first,
                                                                              _InputIterator __last, _Tp __init,
                                                                              _BinaryOp __b, _UnaryOp __u) {
   for (; __first != __last; ++__first)
-    __init = __b(__init, __u(*__first));
+    __init = __b(std::move(__init), __u(*__first));
   return __init;
 }
 
@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_In
                                                                              _InputIterator2 __first2, _Tp __init,
                                                                              _BinaryOp1 __b1, _BinaryOp2 __b2) {
   for (; __first1 != __last1; ++__first1, (void)++__first2)
-    __init = __b1(__init, __b2(*__first1, *__first2));
+    __init = __b1(std::move(__init), __b2(*__first1, *__first2));
   return __init;
 }
 
lib/libcxx/include/__pstl/internal/omp/parallel_for.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
+
+#include <cstddef>
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <class _Index, class _Fp>
+void
+__parallel_for_body(_Index __first, _Index __last, _Fp __f)
+{
+    // initial partition of the iteration space into chunks
+    auto __policy = __omp_backend::__chunk_partitioner(__first, __last);
+
+    // To avoid over-subscription we use taskloop for the nested parallelism
+    _PSTL_PRAGMA(omp taskloop untied mergeable)
+    for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
+    {
+        __pstl::__omp_backend::__process_chunk(__policy, __first, __chunk, __f);
+    }
+}
+
+//------------------------------------------------------------------------
+// Notation:
+// Evaluation of brick f[i,j) for each subrange [i,j) of [first, last)
+//------------------------------------------------------------------------
+
+template <class _ExecutionPolicy, class _Index, class _Fp>
+void
+__parallel_for(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
+{
+    if (omp_in_parallel())
+    {
+        // we don't create a nested parallel region in an existing parallel
+        // region: just create tasks
+        __pstl::__omp_backend::__parallel_for_body(__first, __last, __f);
+    }
+    else
+    {
+        // in any case (nested or non-nested) one parallel region is created and
+        // only one thread creates a set of tasks
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_body(__first, __last, __f); }
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
lib/libcxx/include/__pstl/internal/omp/parallel_for_each.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <class _ForwardIterator, class _Fp>
+void
+__parallel_for_each_body(_ForwardIterator __first, _ForwardIterator __last, _Fp __f)
+{
+    using DifferenceType = typename std::iterator_traits<_ForwardIterator>::difference_type;
+    // TODO: Think of an approach to remove the std::distance call
+    auto __size = std::distance(__first, __last);
+
+    _PSTL_PRAGMA(omp taskloop untied mergeable)
+    for (DifferenceType __index = 0; __index < __size; ++__index)
+    {
+        // TODO: Think of an approach to remove the increment here each time.
+        auto __iter = std::next(__first, __index);
+        __f(*__iter);
+    }
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Fp>
+void
+__parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Fp __f)
+{
+    if (omp_in_parallel())
+    {
+        // we don't create a nested parallel region in an existing parallel
+        // region: just create tasks
+        __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f);
+    }
+    else
+    {
+        // in any case (nested or non-nested) one parallel region is created and
+        // only one thread creates a set of tasks
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f); }
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
lib/libcxx/include/__pstl/internal/omp/parallel_invoke.h
@@ -0,0 +1,50 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <typename _F1, typename _F2>
+void
+__parallel_invoke_body(_F1&& __f1, _F2&& __f2)
+{
+    _PSTL_PRAGMA(omp taskgroup)
+    {
+        _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F1>(__f1)(); }
+        _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F2>(__f2)(); }
+    }
+}
+
+template <class _ExecutionPolicy, typename _F1, typename _F2>
+void
+__parallel_invoke(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
+{
+    if (omp_in_parallel())
+    {
+        __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2));
+    }
+    else
+    {
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait)
+        __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2));
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
lib/libcxx/include/__pstl/internal/omp/parallel_merge.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
+          typename _Compare, typename _LeafMerge>
+void
+__parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessIterator1 __xs,
+                      _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
+                      _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
+{
+
+    if (__size_x + __size_y <= __omp_backend::__default_chunk_size)
+    {
+        __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp);
+        return;
+    }
+
+    _RandomAccessIterator1 __xm;
+    _RandomAccessIterator2 __ym;
+
+    if (__size_x < __size_y)
+    {
+        __ym = __ys + (__size_y / 2);
+        __xm = std::upper_bound(__xs, __xe, *__ym, __comp);
+    }
+    else
+    {
+        __xm = __xs + (__size_x / 2);
+        __ym = std::lower_bound(__ys, __ye, *__xm, __comp);
+    }
+
+    auto __zm = __zs + (__xm - __xs) + (__ym - __ys);
+
+    _PSTL_PRAGMA(omp task untied mergeable default(none)
+                     firstprivate(__xs, __xm, __ys, __ym, __zs, __comp, __leaf_merge))
+    __pstl::__omp_backend::__parallel_merge_body(__xm - __xs, __ym - __ys, __xs, __xm, __ys, __ym, __zs, __comp,
+                                                      __leaf_merge);
+
+    _PSTL_PRAGMA(omp task untied mergeable default(none)
+                     firstprivate(__xm, __xe, __ym, __ye, __zm, __comp, __leaf_merge))
+    __pstl::__omp_backend::__parallel_merge_body(__xe - __xm, __ye - __ym, __xm, __xe, __ym, __ye, __zm, __comp,
+                                                      __leaf_merge);
+
+    _PSTL_PRAGMA(omp taskwait)
+}
+
+template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
+          typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
+void
+__parallel_merge(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs,
+                 _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
+                 _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
+
+{
+    std::size_t __size_x = __xe - __xs;
+    std::size_t __size_y = __ye - __ys;
+
+    /*
+     * Run the merge in parallel by chunking it up. Use the smaller range (if any) as the iteration range, and the
+     * larger range as the search range.
+     */
+
+    if (omp_in_parallel())
+    {
+        __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp,
+                                                          __leaf_merge);
+    }
+    else
+    {
+        _PSTL_PRAGMA(omp parallel)
+        {
+            _PSTL_PRAGMA(omp single nowait)
+            __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp,
+                                                              __leaf_merge);
+        }
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
lib/libcxx/include/__pstl/internal/omp/parallel_reduce.h
@@ -0,0 +1,73 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
+_Value
+__parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity,
+                       _RealBody __real_body, _Reduction __reduce)
+{
+    if (__should_run_serial(__first, __last))
+    {
+        return __real_body(__first, __last, __identity);
+    }
+
+    auto __middle = __first + ((__last - __first) / 2);
+    _Value __v1(__identity), __v2(__identity);
+    __parallel_invoke_body(
+        [&]() { __v1 = __parallel_reduce_body(__first, __middle, __identity, __real_body, __reduce); },
+        [&]() { __v2 = __parallel_reduce_body(__middle, __last, __identity, __real_body, __reduce); });
+
+    return __reduce(__v1, __v2);
+}
+
+//------------------------------------------------------------------------
+// Notation:
+//      r(i,j,init) returns reduction of init with reduction over [i,j)
+//      c(x,y) combines values x and y that were the result of r
+//------------------------------------------------------------------------
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
+_Value
+__parallel_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
+                  _RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction)
+{
+    // We don't create a nested parallel region in an existing parallel region:
+    // just create tasks.
+    if (omp_in_parallel())
+    {
+        return __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction);
+    }
+
+    // In any case (nested or non-nested) one parallel region is created and only
+    // one thread creates a set of tasks.
+    _Value __res = __identity;
+
+    _PSTL_PRAGMA(omp parallel)
+    _PSTL_PRAGMA(omp single nowait)
+    {
+        __res = __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction);
+    }
+
+    return __res;
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
lib/libcxx/include/__pstl/internal/omp/parallel_scan.h
@@ -0,0 +1,136 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
+
+#include "parallel_invoke.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <typename _Index>
+_Index
+__split(_Index __m)
+{
+    _Index __k = 1;
+    while (2 * __k < __m)
+        __k *= 2;
+    return __k;
+}
+
+template <typename _Index, typename _Tp, typename _Rp, typename _Cp>
+void
+__upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine)
+{
+    if (__m == 1)
+        __r[0] = __reduce(__i * __tilesize, __lastsize);
+    else
+    {
+        _Index __k = __split(__m);
+        __omp_backend::__parallel_invoke_body(
+            [=] { __omp_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
+            [=] {
+                __omp_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine);
+            });
+        if (__m == 2 * __k)
+            __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]);
+    }
+}
+
+template <typename _Index, typename _Tp, typename _Cp, typename _Sp>
+void
+__downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine,
+            _Sp __scan)
+{
+    if (__m == 1)
+        __scan(__i * __tilesize, __lastsize, __initial);
+    else
+    {
+        const _Index __k = __split(__m);
+        __omp_backend::__parallel_invoke_body(
+            [=] { __omp_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
+            // Assumes that __combine never throws.
+            // TODO: Consider adding a requirement for user functors to be constant.
+            [=, &__combine]
+            {
+                __omp_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
+                                           __combine(__initial, __r[__k - 1]), __combine, __scan);
+            });
+    }
+}
+
+template <typename _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp,
+          typename _Ap>
+void
+__parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
+{
+    _Index __p = omp_get_num_threads();
+    const _Index __slack = 4;
+    _Index __tilesize = (__n - 1) / (__slack * __p) + 1;
+    _Index __m = (__n - 1) / __tilesize;
+    __buffer<_Tp> __buf(__m + 1);
+    _Tp* __r = __buf.get();
+
+    __omp_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, __combine);
+
+    std::size_t __k = __m + 1;
+    _Tp __t = __r[__k - 1];
+    while ((__k &= __k - 1))
+    {
+        __t = __combine(__r[__k - 1], __t);
+    }
+
+    __apex(__combine(__initial, __t));
+    __omp_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial,
+                               __combine, __scan);
+}
+
+template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
+void
+__parallel_strict_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
+                       _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
+{
+    if (__n <= __default_chunk_size)
+    {
+        _Tp __sum = __initial;
+        if (__n)
+        {
+            __sum = __combine(__sum, __reduce(_Index(0), __n));
+        }
+        __apex(__sum);
+        if (__n)
+        {
+            __scan(_Index(0), __n, __initial);
+        }
+        return;
+    }
+
+    if (omp_in_parallel())
+    {
+        __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine,
+                                                                             __scan, __apex);
+    }
+    else
+    {
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait)
+        {
+            __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine,
+                                                                                 __scan, __apex);
+        }
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
lib/libcxx/include/__pstl/internal/omp/parallel_stable_partial_sort.h
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
+void
+__parallel_stable_partial_sort(__pstl::__internal::__openmp_backend_tag, _RandomAccessIterator __xs,
+                               _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
+                               std::size_t /* __nsort */)
+{
+    // TODO: "Parallel partial sort needs to be implemented.");
+    __leaf_sort(__xs, __xe, __comp);
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
lib/libcxx/include/__pstl/internal/omp/parallel_stable_sort.h
@@ -0,0 +1,160 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
+
+#include "util.h"
+#include "parallel_merge.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+namespace __sort_details
+{
+struct __move_value
+{
+    template <typename _Iterator, typename _OutputIterator>
+    void
+    operator()(_Iterator __x, _OutputIterator __z) const
+    {
+        *__z = std::move(*__x);
+    }
+};
+
+template <typename _RandomAccessIterator, typename _OutputIterator>
+_OutputIterator
+__parallel_move_range(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first)
+{
+    std::size_t __size = __last1 - __first1;
+
+    // Perform serial moving of small chunks
+
+    if (__size <= __default_chunk_size)
+    {
+        return std::move(__first1, __last1, __d_first);
+    }
+
+    // Perform parallel moving of larger chunks
+    auto __policy = __pstl::__omp_backend::__chunk_partitioner(__first1, __last1);
+
+    _PSTL_PRAGMA(omp taskloop)
+    for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
+    {
+        __pstl::__omp_backend::__process_chunk(__policy, __first1, __chunk,
+                                       [&](auto __chunk_first, auto __chunk_last)
+                                       {
+                                           auto __chunk_offset = __chunk_first - __first1;
+                                           auto __output_it = __d_first + __chunk_offset;
+                                           std::move(__chunk_first, __chunk_last, __output_it);
+                                       });
+    }
+
+    return __d_first + __size;
+}
+
+struct __move_range
+{
+    template <typename _RandomAccessIterator, typename _OutputIterator>
+    _OutputIterator
+    operator()(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first) const
+    {
+        return __pstl::__omp_backend::__sort_details::__parallel_move_range(__first1, __last1, __d_first);
+    }
+};
+} // namespace __sort_details
+
+template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
+void
+__parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp,
+                            _LeafSort __leaf_sort)
+{
+    using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type;
+    using _VecType = typename std::vector<_ValueType>;
+    using _OutputIterator = typename _VecType::iterator;
+    using _MoveValue = typename __omp_backend::__sort_details::__move_value;
+    using _MoveRange = __omp_backend::__sort_details::__move_range;
+
+    if (__should_run_serial(__xs, __xe))
+    {
+        __leaf_sort(__xs, __xe, __comp);
+    }
+    else
+    {
+        std::size_t __size = __xe - __xs;
+        auto __mid = __xs + (__size / 2);
+        __pstl::__omp_backend::__parallel_invoke_body(
+            [&]() { __parallel_stable_sort_body(__xs, __mid, __comp, __leaf_sort); },
+            [&]() { __parallel_stable_sort_body(__mid, __xe, __comp, __leaf_sort); });
+
+        // Perform a parallel merge of the sorted ranges into __output_data.
+        _VecType __output_data(__size);
+        _MoveValue __move_value;
+        _MoveRange __move_range;
+        __utils::__serial_move_merge __merge(__size);
+        __pstl::__omp_backend::__parallel_merge_body(
+            __mid - __xs, __xe - __mid, __xs, __mid, __mid, __xe, __output_data.begin(), __comp,
+            [&__merge, &__move_value, &__move_range](_RandomAccessIterator __as, _RandomAccessIterator __ae,
+                                                     _RandomAccessIterator __bs, _RandomAccessIterator __be,
+                                                     _OutputIterator __cs, _Compare __comp)
+            { __merge(__as, __ae, __bs, __be, __cs, __comp, __move_value, __move_value, __move_range, __move_range); });
+
+        // Move the values from __output_data back in the original source range.
+        __pstl::__omp_backend::__sort_details::__parallel_move_range(__output_data.begin(), __output_data.end(), __xs);
+    }
+}
+
+template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
+void
+__parallel_stable_sort(__pstl::__internal::__openmp_backend_tag __tag, _ExecutionPolicy&& /*__exec*/,
+                       _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
+                       std::size_t __nsort = 0)
+{
+    auto __count = static_cast<std::size_t>(__xe - __xs);
+    if (__count <= __default_chunk_size || __nsort < __count)
+    {
+        __leaf_sort(__xs, __xe, __comp);
+        return;
+    }
+
+    // TODO: the partial sort implementation should
+    // be shared with the other backends.
+
+    if (omp_in_parallel())
+    {
+        if (__count <= __nsort)
+        {
+            __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort);
+        }
+        else
+        {
+            __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
+        }
+    }
+    else
+    {
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait)
+        if (__count <= __nsort)
+        {
+            __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort);
+        }
+        else
+        {
+            __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
+        }
+    }
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
lib/libcxx/include/__pstl/internal/omp/parallel_transform_reduce.h
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+//------------------------------------------------------------------------
+// parallel_transform_reduce
+//
+// Notation:
+//      r(i,j,init) returns reduction of init with reduction over [i,j)
+//      u(i) returns f(i,i+1,identity) for a hypothetical left identity element
+//      of r c(x,y) combines values x and y that were the result of r or u
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner, class _Reduction>
+auto
+__transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init,
+                        _Combiner __combiner, _Reduction __reduction)
+{
+    const std::size_t __num_threads = omp_get_num_threads();
+    const std::size_t __size = __last - __first;
+
+    // Initial partition of the iteration space into chunks. If the range is too small,
+    // this will result in a nonsense policy, so we check on the size as well below.
+    auto __policy = __omp_backend::__chunk_partitioner(__first + __num_threads, __last);
+
+    if (__size <= __num_threads || __policy.__n_chunks < 2)
+    {
+        return __reduction(__first, __last, __init);
+    }
+
+    // Here, we cannot use OpenMP UDR because we must store the init value in
+    // the combiner and it will be used several times. Although there should be
+    // the only one; we manually generate the identity elements for each thread.
+    std::vector<_Value> __accums;
+    __accums.reserve(__num_threads);
+
+    // initialize accumulators for all threads
+    for (std::size_t __i = 0; __i < __num_threads; ++__i)
+    {
+        __accums.emplace_back(__unary_op(__first + __i));
+    }
+
+    // main loop
+    _PSTL_PRAGMA(omp taskloop shared(__accums))
+    for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
+    {
+        __pstl::__omp_backend::__process_chunk(__policy, __first + __num_threads, __chunk,
+                                       [&](auto __chunk_first, auto __chunk_last)
+                                       {
+                                           auto __thread_num = omp_get_thread_num();
+                                           __accums[__thread_num] =
+                                               __reduction(__chunk_first, __chunk_last, __accums[__thread_num]);
+                                       });
+    }
+
+    // combine by accumulators
+    for (std::size_t __i = 0; __i < __num_threads; ++__i)
+    {
+        __init = __combiner(__init, __accums[__i]);
+    }
+
+    return __init;
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner,
+          class _Reduction>
+_Value
+__parallel_transform_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
+                            _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, _Combiner __combiner,
+                            _Reduction __reduction)
+{
+    _Value __result = __init;
+    if (omp_in_parallel())
+    {
+        // We don't create a nested parallel region in an existing parallel
+        // region: just create tasks
+        __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner,
+                                                                  __reduction);
+    }
+    else
+    {
+        // Create a parallel region, and a single thread will create tasks
+        // for the region.
+        _PSTL_PRAGMA(omp parallel)
+        _PSTL_PRAGMA(omp single nowait)
+        {
+            __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner,
+                                                                      __reduction);
+        }
+    }
+
+    return __result;
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
lib/libcxx/include/__pstl/internal/omp/parallel_transform_scan.h
@@ -0,0 +1,32 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
+#define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
+
+#include "util.h"
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
+_Tp
+__parallel_transform_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */,
+                          _Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan)
+{
+    // TODO: parallelize this function.
+    return __scan(_Index(0), __n, __init);
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+#endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
lib/libcxx/include/__pstl/internal/omp/util.h
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_INTERNAL_OMP_UTIL_H
+#define _PSTL_INTERNAL_OMP_UTIL_H
+
+#include <algorithm>
+#include <atomic>
+#include <iterator>
+#include <cstddef>
+#include <cstdio>
+#include <memory>
+#include <vector>
+#include <omp.h>
+
+#include "../parallel_backend_utils.h"
+#include "../unseq_backend_simd.h"
+#include "../utils.h"
+
+// Portability "#pragma" definition
+#ifdef _MSC_VER
+#    define _PSTL_PRAGMA(x) __pragma(x)
+#else
+#    define _PSTL_PRAGMA(x) _Pragma(#    x)
+#endif
+
+namespace __pstl
+{
+namespace __omp_backend
+{
+
+//------------------------------------------------------------------------
+// use to cancel execution
+//------------------------------------------------------------------------
+inline void
+__cancel_execution()
+{
+    // TODO: Figure out how to make cancelation work.
+}
+
+//------------------------------------------------------------------------
+// raw buffer
+//------------------------------------------------------------------------
+
+template <typename _Tp>
+class __buffer
+{
+    std::allocator<_Tp> __allocator_;
+    _Tp* __ptr_;
+    const std::size_t __buf_size_;
+    __buffer(const __buffer&) = delete;
+    void
+    operator=(const __buffer&) = delete;
+
+  public:
+    __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
+
+    operator bool() const { return __ptr_ != nullptr; }
+
+    _Tp*
+    get() const
+    {
+        return __ptr_;
+    }
+    ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
+};
+
+// Preliminary size of each chunk: requires further discussion
+inline constexpr std::size_t __default_chunk_size = 2048;
+
+// Convenience function to determine when we should run serial.
+template <typename _Iterator, std::enable_if_t<!std::is_integral<_Iterator>::value, bool> = true>
+constexpr auto
+__should_run_serial(_Iterator __first, _Iterator __last) -> bool
+{
+    using _difference_type = typename std::iterator_traits<_Iterator>::difference_type;
+    auto __size = std::distance(__first, __last);
+    return __size <= static_cast<_difference_type>(__default_chunk_size);
+}
+
+template <typename _Index, std::enable_if_t<std::is_integral<_Index>::value, bool> = true>
+constexpr auto
+__should_run_serial(_Index __first, _Index __last) -> bool
+{
+    using _difference_type = _Index;
+    auto __size = __last - __first;
+    return __size <= static_cast<_difference_type>(__default_chunk_size);
+}
+
+struct __chunk_metrics
+{
+    std::size_t __n_chunks;
+    std::size_t __chunk_size;
+    std::size_t __first_chunk_size;
+};
+
+// The iteration space partitioner according to __requested_chunk_size
+template <class _RandomAccessIterator, class _Size = std::size_t>
+auto
+__chunk_partitioner(_RandomAccessIterator __first, _RandomAccessIterator __last,
+                    _Size __requested_chunk_size = __default_chunk_size) -> __chunk_metrics
+{
+    /*
+     * This algorithm improves distribution of elements in chunks by avoiding
+     * small tail chunks. The leftover elements that do not fit neatly into
+     * the chunk size are redistributed to early chunks. This improves
+     * utilization of the processor's prefetch and reduces the number of
+     * tasks needed by 1.
+     */
+
+    const _Size __n = __last - __first;
+    _Size __n_chunks = 0;
+    _Size __chunk_size = 0;
+    _Size __first_chunk_size = 0;
+    if (__n < __requested_chunk_size)
+    {
+        __chunk_size = __n;
+        __first_chunk_size = __n;
+        __n_chunks = 1;
+        return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
+    }
+
+    __n_chunks = (__n / __requested_chunk_size) + 1;
+    __chunk_size = __n / __n_chunks;
+    __first_chunk_size = __chunk_size;
+    const _Size __n_leftover_items = __n - (__n_chunks * __chunk_size);
+
+    if (__n_leftover_items == __chunk_size)
+    {
+        __n_chunks += 1;
+        return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
+    }
+    else if (__n_leftover_items == 0)
+    {
+        __first_chunk_size = __chunk_size;
+        return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
+    }
+
+    const _Size __n_extra_items_per_chunk = __n_leftover_items / __n_chunks;
+    const _Size __n_final_leftover_items = __n_leftover_items - (__n_extra_items_per_chunk * __n_chunks);
+
+    __chunk_size += __n_extra_items_per_chunk;
+    __first_chunk_size = __chunk_size + __n_final_leftover_items;
+
+    return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
+}
+
+template <typename _Iterator, typename _Index, typename _Func>
+void
+__process_chunk(const __chunk_metrics& __metrics, _Iterator __base, _Index __chunk_index, _Func __f)
+{
+    auto __this_chunk_size = __chunk_index == 0 ? __metrics.__first_chunk_size : __metrics.__chunk_size;
+    auto __index = __chunk_index == 0 ? 0
+                                      : (__chunk_index * __metrics.__chunk_size) +
+                                            (__metrics.__first_chunk_size - __metrics.__chunk_size);
+    auto __first = __base + __index;
+    auto __last = __first + __this_chunk_size;
+    __f(__first, __last);
+}
+
+} // namespace __omp_backend
+} // namespace __pstl
+
+#endif // _PSTL_INTERNAL_OMP_UTIL_H
lib/libcxx/include/__pstl/internal/algorithm_fwd.h
@@ -0,0 +1,1768 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_ALGORITHM_FWD_H
+#define _PSTL_ALGORITHM_FWD_H
+
+#include <__config>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+
+namespace __pstl {
+namespace __internal {
+
+//------------------------------------------------------------------------
+// walk1 (pseudo)
+//
+// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _Function>
+void __brick_walk1(_ForwardIterator,
+                   _ForwardIterator,
+                   _Function,
+                   /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _Function>
+void __brick_walk1(_RandomAccessIterator,
+                   _RandomAccessIterator,
+                   _Function,
+                   /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function>
+void __pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function>
+void __pattern_walk1(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function);
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick>
+void __pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick>
+void __pattern_walk_brick(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Brick);
+
+//------------------------------------------------------------------------
+// walk1_n
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _Size, class _Function>
+_ForwardIterator __brick_walk1_n(
+    _ForwardIterator,
+    _Size,
+    _Function,
+    /*_IsVectorTag=*/std::false_type);
+
+template <class _RandomAccessIterator, class _DifferenceType, class _Function>
+_RandomAccessIterator __brick_walk1_n(
+    _RandomAccessIterator,
+    _DifferenceType,
+    _Function,
+    /*vectorTag=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
+_ForwardIterator __pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function>
+_RandomAccessIterator
+__pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function);
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
+_ForwardIterator __pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
+_RandomAccessIterator
+__pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick);
+
+//------------------------------------------------------------------------
+// walk2 (pseudo)
+//
+// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
+_ForwardIterator2 __brick_walk2(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _Function,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function>
+_RandomAccessIterator2 __brick_walk2(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _Function,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
+_ForwardIterator2 __brick_walk2_n(
+    _ForwardIterator1,
+    _Size,
+    _ForwardIterator2,
+    _Function,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function>
+_RandomAccessIterator2 __brick_walk2_n(
+    _RandomAccessIterator1,
+    _Size,
+    _RandomAccessIterator2,
+    _Function,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function>
+_ForwardIterator2
+__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Function>
+_RandomAccessIterator2 __pattern_walk2(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _Function);
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _Size,
+          class _ForwardIterator2,
+          class _Function>
+_ForwardIterator2
+__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _Size,
+          class _RandomAccessIterator2,
+          class _Function>
+_RandomAccessIterator2 __pattern_walk2_n(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function);
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
+_ForwardIterator2 __pattern_walk2_brick(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Brick>
+_RandomAccessIterator2 __pattern_walk2_brick(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _Brick);
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _Size,
+          class _ForwardIterator2,
+          class _Brick>
+_ForwardIterator2
+__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _Size,
+          class _RandomAccessIterator2,
+          class _Brick>
+_RandomAccessIterator2 __pattern_walk2_brick_n(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick);
+
+//------------------------------------------------------------------------
+// walk3 (pseudo)
+//
+// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
+_ForwardIterator3 __brick_walk3(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator3,
+    _Function,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
+_RandomAccessIterator3 __brick_walk3(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator3,
+    _Function,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator3,
+          class _Function>
+_ForwardIterator3 __pattern_walk3(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator3,
+    _Function) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Function>
+_RandomAccessIterator3 __pattern_walk3(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator3,
+    _Function);
+
+//------------------------------------------------------------------------
+// equal
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __brick_equal(_ForwardIterator1,
+                   _ForwardIterator1,
+                   _ForwardIterator2,
+                   _BinaryPredicate,
+                   /* is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+bool __brick_equal(_RandomAccessIterator1,
+                   _RandomAccessIterator1,
+                   _RandomAccessIterator2,
+                   _BinaryPredicate,
+                   /* is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __pattern_equal(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+bool __pattern_equal(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _BinaryPredicate);
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __brick_equal(_ForwardIterator1,
+                   _ForwardIterator1,
+                   _ForwardIterator2,
+                   _ForwardIterator2,
+                   _BinaryPredicate,
+                   /* is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+bool __brick_equal(_RandomAccessIterator1,
+                   _RandomAccessIterator1,
+                   _RandomAccessIterator2,
+                   _RandomAccessIterator2,
+                   _BinaryPredicate,
+                   /* is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __pattern_equal(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+bool __pattern_equal(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate);
+
+//------------------------------------------------------------------------
+// find_end
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __brick_find_end(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_find_end(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_find_end(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_find_end(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// find_first_of
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __brick_find_first_of(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_find_first_of(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_find_first_of(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_find_first_of(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// search
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __brick_search(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_search(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_search(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_search(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _BinaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// search_n
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+_ForwardIterator __brick_search_n(
+    _ForwardIterator,
+    _ForwardIterator,
+    _Size,
+    const _Tp&,
+    _BinaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate>
+_RandomAccessIterator __brick_search_n(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Size,
+    const _Tp&,
+    _BinaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+_ForwardIterator __pattern_search_n(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _Size,
+          class _Tp,
+          class _BinaryPredicate>
+_RandomAccessIterator __pattern_search_n(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Size,
+    const _Tp&,
+    _BinaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// copy_n
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _Size, class _OutputIterator>
+_OutputIterator __brick_copy_n(_ForwardIterator,
+                               _Size,
+                               _OutputIterator,
+                               /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _Size, class _OutputIterator>
+_OutputIterator __brick_copy_n(_RandomAccessIterator,
+                               _Size,
+                               _OutputIterator,
+                               /*vector=*/std::true_type) noexcept;
+
+//------------------------------------------------------------------------
+// copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_copy(_ForwardIterator,
+                             _ForwardIterator,
+                             _OutputIterator,
+                             /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __brick_copy(_RandomAccessIterator,
+                             _RandomAccessIterator,
+                             _OutputIterator,
+                             /*vector=*/std::true_type) noexcept;
+
+//------------------------------------------------------------------------
+// move
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_move(_ForwardIterator,
+                             _ForwardIterator,
+                             _OutputIterator,
+                             /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __brick_move(_RandomAccessIterator,
+                             _RandomAccessIterator,
+                             _OutputIterator,
+                             /*vector=*/std::true_type) noexcept;
+
+//------------------------------------------------------------------------
+// swap_ranges
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_swap_ranges(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __brick_swap_ranges(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    /*vector=*/std::true_type) noexcept;
+
+//------------------------------------------------------------------------
+// copy_if
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
+_OutputIterator __brick_copy_if(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    _UnaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator, class _UnaryPredicate>
+_OutputIterator __brick_copy_if(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _UnaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
+std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
+    _ForwardIterator,
+    _ForwardIterator,
+    bool* __restrict,
+    _UnaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
+std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    bool* __restrict,
+    _UnaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _ForwardIterator, class _OutputIterator>
+void __brick_copy_by_mask(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    bool*,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+void __brick_copy_by_mask(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    bool* __restrict,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
+void __brick_partition_by_mask(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    bool*,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2>
+void __brick_partition_by_mask(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    bool*,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
+_OutputIterator __pattern_copy_if(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryPredicate>
+_OutputIterator __pattern_copy_if(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _UnaryPredicate);
+
+//------------------------------------------------------------------------
+// count
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _Predicate>
+typename std::iterator_traits<_RandomAccessIterator>::difference_type __brick_count(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Predicate,
+    /* is_vector = */ std::true_type) noexcept;
+
+template <class _ForwardIterator, class _Predicate>
+typename std::iterator_traits<_ForwardIterator>::difference_type __brick_count(
+    _ForwardIterator,
+    _ForwardIterator,
+    _Predicate,
+    /* is_vector = */ std::false_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+typename std::iterator_traits<_ForwardIterator>::difference_type
+__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate>
+typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate);
+
+//------------------------------------------------------------------------
+// unique
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator __brick_unique(
+    _ForwardIterator,
+    _ForwardIterator,
+    _BinaryPredicate,
+    /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __brick_unique(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _BinaryPredicate,
+    /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator
+__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __pattern_unique(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _BinaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// unique_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
+OutputIterator __brick_unique_copy(
+    _ForwardIterator,
+    _ForwardIterator,
+    OutputIterator,
+    _BinaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate>
+_OutputIterator __brick_unique_copy(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _BinaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate>
+_OutputIterator __pattern_unique_copy(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate) noexcept;
+
+template <class _ExecutionPolicy, class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
+_DifferenceType __brick_calc_mask_2(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    bool* __restrict,
+    _BinaryPredicate,
+    /*vector=*/std::false_type) noexcept;
+
+template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
+_DifferenceType __brick_calc_mask_2(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    bool* __restrict,
+    _BinaryPredicate,
+    /*vector=*/std::true_type) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _BinaryPredicate>
+_OutputIterator __pattern_unique_copy(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _BinaryPredicate);
+
+//------------------------------------------------------------------------
+// reverse
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator>
+void __brick_reverse(_BidirectionalIterator,
+                     _BidirectionalIterator,
+                     /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator>
+void __brick_reverse(_RandomAccessIterator,
+                     _RandomAccessIterator,
+                     /*__is_vector=*/std::true_type) noexcept;
+
+template <class _BidirectionalIterator>
+void __brick_reverse(_BidirectionalIterator,
+                     _BidirectionalIterator,
+                     _BidirectionalIterator,
+                     /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator>
+void __brick_reverse(_RandomAccessIterator,
+                     _RandomAccessIterator,
+                     _RandomAccessIterator,
+                     /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator>
+void __pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
+void __pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator);
+
+//------------------------------------------------------------------------
+// reverse_copy
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator, class _OutputIterator>
+_OutputIterator __brick_reverse_copy(
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _OutputIterator,
+    /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __brick_reverse_copy(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator>
+_OutputIterator __pattern_reverse_copy(
+    _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __pattern_reverse_copy(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator);
+
+//------------------------------------------------------------------------
+// rotate
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator>
+_ForwardIterator __brick_rotate(
+    _ForwardIterator,
+    _ForwardIterator,
+    _ForwardIterator,
+    /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator>
+_RandomAccessIterator __brick_rotate(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator>
+_ForwardIterator
+__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
+_RandomAccessIterator __pattern_rotate(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator);
+
+//------------------------------------------------------------------------
+// rotate_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_rotate_copy(
+    _ForwardIterator,
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __brick_rotate_copy(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator>
+_OutputIterator __pattern_rotate_copy(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator>
+_OutputIterator __pattern_rotate_copy(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator);
+
+//------------------------------------------------------------------------
+// is_partitioned
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _UnaryPredicate>
+bool __brick_is_partitioned(_ForwardIterator,
+                            _ForwardIterator,
+                            _UnaryPredicate,
+                            /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+bool __brick_is_partitioned(_RandomAccessIterator,
+                            _RandomAccessIterator,
+                            _UnaryPredicate,
+                            /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+bool __pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+bool __pattern_is_partitioned(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate);
+
+//------------------------------------------------------------------------
+// partition
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __brick_partition(
+    _ForwardIterator,
+    _ForwardIterator,
+    _UnaryPredicate,
+    /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_partition(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _UnaryPredicate,
+    /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator
+__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_partition(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate);
+
+//------------------------------------------------------------------------
+// stable_partition
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator, class _UnaryPredicate>
+_BidirectionalIterator __brick_stable_partition(
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _UnaryPredicate,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_stable_partition(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _UnaryPredicate,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
+_BidirectionalIterator __pattern_stable_partition(
+    _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_stable_partition(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _UnaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// partition_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    _UnaryPredicate,
+    /*is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    _UnaryPredicate,
+    /*is_vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _OutputIterator1,
+          class _OutputIterator2,
+          class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    _UnaryPredicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator1,
+          class _OutputIterator2,
+          class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator1,
+    _OutputIterator2,
+    _UnaryPredicate);
+
+//------------------------------------------------------------------------
+// sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible>
+void __pattern_sort(
+    _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsMoveConstructible) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_sort(__parallel_tag<_IsVector>,
+                    _ExecutionPolicy&&,
+                    _RandomAccessIterator,
+                    _RandomAccessIterator,
+                    _Compare,
+                    /*is_move_constructible=*/std::true_type);
+
+//------------------------------------------------------------------------
+// stable_sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_stable_sort(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
+
+//------------------------------------------------------------------------
+// partial_sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_partial_sort(
+    _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_partial_sort(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// partial_sort_copy
+//------------------------------------------------------------------------
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+_RandomAccessIterator2 __pattern_partial_sort_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+_RandomAccessIterator2 __pattern_partial_sort_copy(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Compare);
+
+//------------------------------------------------------------------------
+// adjacent_find
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __brick_adjacent_find(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _BinaryPredicate,
+    /* IsVector = */ std::true_type,
+    bool) noexcept;
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator __brick_adjacent_find(
+    _ForwardIterator,
+    _ForwardIterator,
+    _BinaryPredicate,
+    /* IsVector = */ std::false_type,
+    bool) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator
+__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, bool) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __pattern_adjacent_find(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _BinaryPredicate,
+    bool);
+
+//------------------------------------------------------------------------
+// nth_element
+//------------------------------------------------------------------------
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_nth_element(
+    _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_nth_element(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare) noexcept;
+
+//------------------------------------------------------------------------
+// fill, fill_n
+//------------------------------------------------------------------------
+template <class _RandomAccessIterator, class _Tp>
+void __brick_fill(_RandomAccessIterator,
+                  _RandomAccessIterator,
+                  const _Tp&,
+                  /* __is_vector = */ std::true_type) noexcept;
+
+template <class _ForwardIterator, class _Tp>
+void __brick_fill(_ForwardIterator,
+                  _ForwardIterator,
+                  const _Tp&,
+                  /* __is_vector = */ std::false_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+void __pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp>
+_RandomAccessIterator
+__pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&);
+
+template <class _RandomAccessIterator, class _Size, class _Tp>
+_RandomAccessIterator
+__brick_fill_n(_RandomAccessIterator,
+               _Size,
+               const _Tp&,
+               /* __is_vector = */ std::true_type) noexcept;
+
+template <class _OutputIterator, class _Size, class _Tp>
+_OutputIterator
+__brick_fill_n(_OutputIterator,
+               _Size,
+               const _Tp&,
+               /* __is_vector = */ std::false_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp>
+_OutputIterator __pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Tp>
+_RandomAccessIterator
+__pattern_fill_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&);
+
+//------------------------------------------------------------------------
+// generate, generate_n
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _Generator>
+void __brick_generate(_RandomAccessIterator,
+                      _RandomAccessIterator,
+                      _Generator,
+                      /* is_vector = */ std::true_type) noexcept;
+
+template <class _ForwardIterator, class _Generator>
+void __brick_generate(_ForwardIterator,
+                      _ForwardIterator,
+                      _Generator,
+                      /* is_vector = */ std::false_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator>
+void __pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator>
+_RandomAccessIterator __pattern_generate(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Generator);
+
+template <class _RandomAccessIterator, class Size, class _Generator>
+_RandomAccessIterator __brick_generate_n(
+    _RandomAccessIterator,
+    Size,
+    _Generator,
+    /* is_vector = */ std::true_type) noexcept;
+
+template <class OutputIterator, class Size, class _Generator>
+OutputIterator __brick_generate_n(
+    OutputIterator,
+    Size,
+    _Generator,
+    /* is_vector = */ std::false_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class OutputIterator, class Size, class _Generator>
+OutputIterator __pattern_generate_n(_Tag, _ExecutionPolicy&&, OutputIterator, Size, _Generator) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class Size, class _Generator>
+_RandomAccessIterator
+__pattern_generate_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, Size, _Generator);
+
+//------------------------------------------------------------------------
+// remove
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __brick_remove_if(
+    _ForwardIterator,
+    _ForwardIterator,
+    _UnaryPredicate,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_remove_if(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _UnaryPredicate,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator
+__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_remove_if(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _UnaryPredicate) noexcept;
+
+//------------------------------------------------------------------------
+// merge
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_merge(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_merge(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_merge(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_merge(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// inplace_merge
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator, class _Compare>
+void __brick_inplace_merge(
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _Compare>
+void __brick_inplace_merge(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
+void __pattern_inplace_merge(
+    _Tag,
+    _ExecutionPolicy&&,
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _BidirectionalIterator,
+    _Compare) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_inplace_merge(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __pattern_includes(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+bool __pattern_includes(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Compare);
+
+//------------------------------------------------------------------------
+// set_union
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_union(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_union(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_union(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_union(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// set_intersection
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_intersection(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_intersection(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_intersection(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_intersection(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// set_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_difference(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_difference(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_difference(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_difference(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// set_symmetric_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_symmetric_difference(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_symmetric_difference(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare,
+    /*__is_vector=*/std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_symmetric_difference(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _OutputIterator,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_symmetric_difference(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _OutputIterator,
+    _Compare);
+
+//------------------------------------------------------------------------
+// is_heap_until
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __brick_is_heap_until(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __brick_is_heap_until(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator
+__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __pattern_is_heap_until(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
+
+//------------------------------------------------------------------------
+// min_element
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _Compare>
+_ForwardIterator __brick_min_element(
+    _ForwardIterator,
+    _ForwardIterator,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <typename _RandomAccessIterator, typename _Compare>
+_RandomAccessIterator __brick_min_element(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
+_ForwardIterator __pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept;
+
+template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
+_RandomAccessIterator __pattern_min_element(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
+
+//------------------------------------------------------------------------
+// minmax_element
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _Compare>
+std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(
+    _ForwardIterator,
+    _ForwardIterator,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <typename _RandomAccessIterator, typename _Compare>
+std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
+std::pair<_ForwardIterator, _ForwardIterator>
+__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept;
+
+template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
+std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element(
+    __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
+
+//------------------------------------------------------------------------
+// mismatch
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _Predicate,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate>
+std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Predicate,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _Predicate) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Predicate>
+std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Predicate) noexcept;
+
+//------------------------------------------------------------------------
+// lexicographical_compare
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __brick_lexicographical_compare(
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _Compare,
+    /* __is_vector = */ std::false_type) noexcept;
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare>
+bool __brick_lexicographical_compare(
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Compare,
+    /* __is_vector = */ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __pattern_lexicographical_compare(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1,
+    _ForwardIterator1,
+    _ForwardIterator2,
+    _ForwardIterator2,
+    _Compare) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+bool __pattern_lexicographical_compare(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator1,
+    _RandomAccessIterator1,
+    _RandomAccessIterator2,
+    _RandomAccessIterator2,
+    _Compare) noexcept;
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif /* _PSTL_ALGORITHM_FWD_H */
lib/libcxx/include/__pstl/internal/algorithm_impl.h
@@ -0,0 +1,4174 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_ALGORITHM_IMPL_H
+#define _PSTL_ALGORITHM_IMPL_H
+
+#include <__assert>
+#include <__config>
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+
+#include "execution_impl.h"
+#include "memory_impl.h"
+#include "parallel_backend.h"
+#include "parallel_backend_utils.h"
+#include "parallel_impl.h"
+#include "unseq_backend_simd.h"
+
+namespace __pstl {
+namespace __internal {
+
+// [alg.foreach]
+// for_each_n with no policy
+
+template <class _ForwardIterator, class _Size, class _Function>
+_ForwardIterator __for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) {
+  for (; __n > 0; ++__first, --__n)
+    __f(__first);
+  return __first;
+}
+
+//------------------------------------------------------------------------
+// walk1 (pseudo)
+//
+// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _Function>
+void __brick_walk1(
+    _ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept {
+  std::for_each(__first, __last, __f);
+}
+
+template <class _RandomAccessIterator, class _Function>
+void __brick_walk1(_RandomAccessIterator __first,
+                   _RandomAccessIterator __last,
+                   _Function __f,
+                   /*vector=*/std::true_type) noexcept {
+  __unseq_backend::__simd_walk_1(__first, __last - __first, __f);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function>
+void __pattern_walk1(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept {
+  __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function>
+void __pattern_walk1(__parallel_tag<_IsVector> __tag,
+                     _ExecutionPolicy&& __exec,
+                     _RandomAccessIterator __first,
+                     _RandomAccessIterator __last,
+                     _Function __f) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) {
+          __internal::__brick_walk1(__i, __j, __f, _IsVector{});
+        });
+  });
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick>
+void __pattern_walk_brick(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick) noexcept {
+  __brick(__first, __last);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick>
+void __pattern_walk_brick(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Brick __brick) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j); });
+  });
+}
+
+//------------------------------------------------------------------------
+// walk1_n
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _Size, class _Function>
+_ForwardIterator __brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type) {
+  return __internal::__for_each_n_it_serial(__first, __n, [&__f](_ForwardIterator __it) {
+    __f(*__it);
+  }); // calling serial version
+}
+
+template <class _RandomAccessIterator, class _DifferenceType, class _Function>
+_RandomAccessIterator
+__brick_walk1_n(_RandomAccessIterator __first,
+                _DifferenceType __n,
+                _Function __f,
+                /*vectorTag=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_walk_1(__first, __n, __f);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
+_ForwardIterator
+__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept {
+  return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function>
+_RandomAccessIterator __pattern_walk1_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _Size __n,
+    _Function __f) {
+  __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f);
+
+  return __first + __n;
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
+_ForwardIterator
+__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept {
+  return __brick(__first, __n);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
+_RandomAccessIterator __pattern_walk_brick_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _Size __n,
+    _Brick __brick) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __first + __n,
+        [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); });
+    return __first + __n;
+  });
+}
+
+//------------------------------------------------------------------------
+// walk2 (pseudo)
+//
+// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
+//------------------------------------------------------------------------
+template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
+_ForwardIterator2
+__brick_walk2(_ForwardIterator1 __first1,
+              _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2,
+              _Function __f,
+              /*vector=*/std::false_type) noexcept {
+  for (; __first1 != __last1; ++__first1, ++__first2)
+    __f(*__first1, *__first2);
+  return __first2;
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function>
+_RandomAccessIterator2
+__brick_walk2(_RandomAccessIterator1 __first1,
+              _RandomAccessIterator1 __last1,
+              _RandomAccessIterator2 __first2,
+              _Function __f,
+              /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f);
+}
+
+template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
+_ForwardIterator2 __brick_walk2_n(
+    _ForwardIterator1 __first1,
+    _Size __n,
+    _ForwardIterator2 __first2,
+    _Function __f,
+    /*vector=*/std::false_type) noexcept {
+  for (; __n > 0; --__n, ++__first1, ++__first2)
+    __f(*__first1, *__first2);
+  return __first2;
+}
+
+template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function>
+_RandomAccessIterator2 __brick_walk2_n(
+    _RandomAccessIterator1 __first1,
+    _Size __n,
+    _RandomAccessIterator2 __first2,
+    _Function __f,
+    /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function>
+_ForwardIterator2 __pattern_walk2(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _Function __f) noexcept {
+  return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Function>
+_RandomAccessIterator2 __pattern_walk2(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _Function __f) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{});
+        });
+    return __first2 + (__last1 - __first1);
+  });
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _Size,
+          class _ForwardIterator2,
+          class _Function>
+_ForwardIterator2 __pattern_walk2_n(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _Size __n,
+    _ForwardIterator2 __first2,
+    _Function __f) noexcept {
+  return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _Size,
+          class _RandomAccessIterator2,
+          class _Function>
+_RandomAccessIterator2 __pattern_walk2_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _Size __n,
+    _RandomAccessIterator2 __first2,
+    _Function __f) {
+  return __internal::__pattern_walk2(
+      __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
+_ForwardIterator2 __pattern_walk2_brick(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _Brick __brick) noexcept {
+  return __brick(__first1, __last1, __first2);
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Brick>
+_RandomAccessIterator2 __pattern_walk2_brick(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _Brick __brick) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          __brick(__i, __j, __first2 + (__i - __first1));
+        });
+    return __first2 + (__last1 - __first1);
+  });
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _Size,
+          class _ForwardIterator2,
+          class _Brick>
+_ForwardIterator2 __pattern_walk2_brick_n(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _Size __n,
+    _ForwardIterator2 __first2,
+    _Brick __brick) noexcept {
+  return __brick(__first1, __n, __first2);
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _Size,
+          class _RandomAccessIterator2,
+          class _Brick>
+_RandomAccessIterator2 __pattern_walk2_brick_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _Size __n,
+    _RandomAccessIterator2 __first2,
+    _Brick __brick) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __first1 + __n,
+        [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          __brick(__i, __j - __i, __first2 + (__i - __first1));
+        });
+    return __first2 + __n;
+  });
+}
+
+//------------------------------------------------------------------------
+// walk3 (pseudo)
+//
+// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
+//------------------------------------------------------------------------
+template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
+_ForwardIterator3 __brick_walk3(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator3 __first3,
+    _Function __f,
+    /*vector=*/std::false_type) noexcept {
+  for (; __first1 != __last1; ++__first1, ++__first2, ++__first3)
+    __f(*__first1, *__first2, *__first3);
+  return __first3;
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
+_RandomAccessIterator3 __brick_walk3(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator3 __first3,
+    _Function __f,
+    /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f);
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator3,
+          class _Function>
+_ForwardIterator3 __pattern_walk3(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator3 __first3,
+    _Function __f) noexcept {
+  return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Function>
+_RandomAccessIterator3 __pattern_walk3(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator3 __first3,
+    _Function __f) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          __internal::__brick_walk3(
+              __i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, _IsVector{});
+        });
+    return __first3 + (__last1 - __first1);
+  });
+}
+
+//------------------------------------------------------------------------
+// equal
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __brick_equal(_ForwardIterator1 __first1,
+                   _ForwardIterator1 __last1,
+                   _ForwardIterator2 __first2,
+                   _ForwardIterator2 __last2,
+                   _BinaryPredicate __p,
+                   /* IsVector = */ std::false_type) noexcept {
+  return std::equal(__first1, __last1, __first2, __last2, __p);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+bool __brick_equal(_RandomAccessIterator1 __first1,
+                   _RandomAccessIterator1 __last1,
+                   _RandomAccessIterator2 __first2,
+                   _RandomAccessIterator2 __last2,
+                   _BinaryPredicate __p,
+                   /* is_vector = */ std::true_type) noexcept {
+  if (__last1 - __first1 != __last2 - __first2)
+    return false;
+
+  return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __pattern_equal(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _BinaryPredicate __p) noexcept {
+  return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+bool __pattern_equal(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _BinaryPredicate __p) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__last1 - __first1 != __last2 - __first2)
+    return false;
+
+  return __internal::__except_handler([&]() {
+    return !__internal::__parallel_or(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          return !__internal::__brick_equal(
+              __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __p, _IsVector{});
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// equal version for sequences with equal length
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __brick_equal(_ForwardIterator1 __first1,
+                   _ForwardIterator1 __last1,
+                   _ForwardIterator2 __first2,
+                   _BinaryPredicate __p,
+                   /* IsVector = */ std::false_type) noexcept {
+  return std::equal(__first1, __last1, __first2, __p);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+bool __brick_equal(_RandomAccessIterator1 __first1,
+                   _RandomAccessIterator1 __last1,
+                   _RandomAccessIterator2 __first2,
+                   _BinaryPredicate __p,
+                   /* is_vector = */ std::true_type) noexcept {
+  return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool __pattern_equal(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _BinaryPredicate __p) noexcept {
+  return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+bool __pattern_equal(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _BinaryPredicate __p) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    return !__internal::__parallel_or(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{});
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// find_end
+//------------------------------------------------------------------------
+
+// find the first occurrence of the subsequence [s_first, s_last)
+//   or the  last occurrence of the subsequence in the range [first, last)
+// b_first determines what occurrence we want to find (first or last)
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate, class _IsVector>
+_RandomAccessIterator1 __find_subrange(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator1 __global_last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred,
+    bool __b_first,
+    _IsVector __is_vector) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType;
+  auto __n2 = __s_last - __s_first;
+  if (__n2 < 1) {
+    return __b_first ? __first : __last;
+  }
+
+  auto __n1 = __global_last - __first;
+  if (__n1 < __n2) {
+    return __last;
+  }
+
+  auto __cur = __last;
+  while (__first != __last && (__global_last - __first >= __n2)) {
+    // find position of *s_first in [first, last) (it can be start of subsequence)
+    __first = __internal::__brick_find_if(
+        __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector);
+
+    // if position that was found previously is the start of subsequence
+    // then we can exit the loop (b_first == true) or keep the position
+    // (b_first == false)
+    if (__first != __last && (__global_last - __first >= __n2) &&
+        __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector)) {
+      if (__b_first) {
+        return __first;
+      } else {
+        __cur = __first;
+      }
+    } else if (__first == __last) {
+      break;
+    } else {
+    }
+
+    // in case of b_first == false we try to find new start position
+    // for the next subsequence
+    ++__first;
+  }
+  return __cur;
+}
+
+template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate, class _IsVector>
+_RandomAccessIterator __find_subrange(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _RandomAccessIterator __global_last,
+    _Size __count,
+    const _Tp& __value,
+    _BinaryPredicate __pred,
+    _IsVector __is_vector) noexcept {
+  if (static_cast<_Size>(__global_last - __first) < __count || __count < 1) {
+    return __last; // According to the standard last shall be returned when count < 1
+  }
+
+  auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred);
+  while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count)) {
+    __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector);
+
+    // check that all of elements in [first+1, first+count) equal to value
+    if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) &&
+        !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector)) {
+      return __first;
+    } else if (__first == __last) {
+      break;
+    } else {
+      ++__first;
+    }
+  }
+  return __last;
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __brick_find_end(
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::find_end(__first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_find_end(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*__is_vector=*/std::true_type) noexcept {
+  return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type());
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_find_end(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_find_end(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__last - __first == __s_last - __s_first) {
+    const bool __res =
+        __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred);
+    return __res ? __first : __last;
+  } else {
+    return __internal::__except_handler([&]() {
+      return __internal::__parallel_find(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __last,
+          [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+            return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, _IsVector{});
+          },
+          std::greater<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
+          /*is_first=*/false);
+    });
+  }
+}
+
+//------------------------------------------------------------------------
+// find_first_of
+//------------------------------------------------------------------------
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __brick_find_first_of(
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::find_first_of(__first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_find_first_of(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*__is_vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_find_first_of(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_find_first_of(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    return __internal::__parallel_find(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{});
+        },
+        std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
+        /*is_first=*/true);
+  });
+}
+
+//------------------------------------------------------------------------
+// search
+//------------------------------------------------------------------------
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_search(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  return std::search(__first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator1 __brick_search(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+  return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type());
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_ForwardIterator1 __pattern_search(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator1 __pattern_search(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __s_first,
+    _RandomAccessIterator2 __s_last,
+    _BinaryPredicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__last - __first == __s_last - __s_first) {
+    const bool __res =
+        __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred);
+    return __res ? __first : __last;
+  } else {
+    return __internal::__except_handler([&]() {
+      return __internal::__parallel_find(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __last,
+          [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+            return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, _IsVector{});
+          },
+          std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
+          /*is_first=*/true);
+    });
+  }
+}
+
+//------------------------------------------------------------------------
+// search_n
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+_ForwardIterator __brick_search_n(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Size __count,
+    const _Tp& __value,
+    _BinaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  return std::search_n(__first, __last, __count, __value, __pred);
+}
+
+template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate>
+_RandomAccessIterator __brick_search_n(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Size __count,
+    const _Tp& __value,
+    _BinaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+  return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type());
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+_ForwardIterator __pattern_search_n(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Size __count,
+    const _Tp& __value,
+    _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _Size,
+          class _Tp,
+          class _BinaryPredicate>
+_RandomAccessIterator __pattern_search_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Size __count,
+    const _Tp& __value,
+    _BinaryPredicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (static_cast<_Size>(__last - __first) == __count) {
+    const bool __result = !__internal::__pattern_any_of(
+        __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value, &__pred](const _Tp& __val) {
+          return !__pred(__val, __value);
+        });
+    return __result ? __first : __last;
+  } else {
+    return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred]() {
+      return __internal::__parallel_find(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __last,
+          [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) {
+            return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{});
+          },
+          std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(),
+          /*is_first=*/true);
+    });
+  }
+}
+
+//------------------------------------------------------------------------
+// copy_n
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _Size, class _OutputIterator>
+_OutputIterator
+__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept {
+  return std::copy_n(__first, __n, __result);
+}
+
+template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2>
+_RandomAccessIterator2
+__brick_copy_n(_RandomAccessIterator1 __first,
+               _Size __n,
+               _RandomAccessIterator2 __result,
+               /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_assign(
+      __first, __n, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
+        *__result = *__first;
+      });
+}
+
+//------------------------------------------------------------------------
+// copy
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator
+__brick_copy(_ForwardIterator __first,
+             _ForwardIterator __last,
+             _OutputIterator __result,
+             /*vector=*/std::false_type) noexcept {
+  return std::copy(__first, __last, __result);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2
+__brick_copy(_RandomAccessIterator1 __first,
+             _RandomAccessIterator1 __last,
+             _RandomAccessIterator2 __result,
+             /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_assign(
+      __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
+        *__result = *__first;
+      });
+}
+
+//------------------------------------------------------------------------
+// move
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator
+__brick_move(_ForwardIterator __first,
+             _ForwardIterator __last,
+             _OutputIterator __result,
+             /*vector=*/std::false_type) noexcept {
+  return std::move(__first, __last, __result);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2
+__brick_move(_RandomAccessIterator1 __first,
+             _RandomAccessIterator1 __last,
+             _RandomAccessIterator2 __result,
+             /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_assign(
+      __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
+        *__result = std::move(*__first);
+      });
+}
+
+struct __brick_move_destroy {
+  template <typename _RandomAccessIterator1, typename _RandomAccessIterator2>
+  _RandomAccessIterator2
+  operator()(_RandomAccessIterator1 __first,
+             _RandomAccessIterator1 __last,
+             _RandomAccessIterator2 __result,
+             /*vec*/ std::true_type) const {
+    using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
+
+    return __unseq_backend::__simd_assign(
+        __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
+          *__result = std::move(*__first);
+          (*__first).~_IteratorValueType();
+        });
+  }
+
+  template <typename _RandomAccessIterator1, typename _RandomAccessIterator2>
+  _RandomAccessIterator2
+  operator()(_RandomAccessIterator1 __first,
+             _RandomAccessIterator1 __last,
+             _RandomAccessIterator2 __result,
+             /*vec*/ std::false_type) const {
+    using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
+
+    for (; __first != __last; ++__first, ++__result) {
+      *__result = std::move(*__first);
+      (*__first).~_IteratorValueType();
+    }
+    return __result;
+  }
+};
+
+//------------------------------------------------------------------------
+// swap_ranges
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_swap_ranges(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    /*vector=*/std::false_type) noexcept {
+  return std::swap_ranges(__first, __last, __result);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2 __brick_swap_ranges(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    /*vector=*/std::true_type) noexcept {
+  using std::iter_swap;
+  return __unseq_backend::__simd_assign(
+      __first, __last - __first, __result, iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>);
+}
+
+//------------------------------------------------------------------------
+// copy_if
+//------------------------------------------------------------------------
+template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
+_OutputIterator __brick_copy_if(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    _UnaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  return std::copy_if(__first, __last, __result, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _UnaryPredicate>
+_RandomAccessIterator2 __brick_copy_if(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    _UnaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred);
+#else
+  return std::copy_if(__first, __last, __result, __pred);
+#endif
+}
+
+// TODO: Try to use transform_reduce for combining __brick_copy_if_phase1 on IsVector.
+template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
+std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    bool* __restrict __mask,
+    _UnaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  auto __count_true = _DifferenceType(0);
+  auto __size       = __last - __first;
+
+  static_assert(__are_random_access_iterators<_ForwardIterator>::value,
+                "Pattern-brick error. Should be a random access iterator.");
+
+  for (; __first != __last; ++__first, ++__mask) {
+    *__mask = __pred(*__first);
+    if (*__mask) {
+      ++__count_true;
+    }
+  }
+  return std::make_pair(__count_true, __size - __count_true);
+}
+
+template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
+std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    bool* __mask,
+    _UnaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+  auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred);
+  return std::make_pair(__result, (__last - __first) - __result);
+}
+
+template <class _ForwardIterator, class _OutputIterator, class _Assigner>
+void __brick_copy_by_mask(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    bool* __mask,
+    _Assigner __assigner,
+    /*vector=*/std::false_type) noexcept {
+  for (; __first != __last; ++__first, ++__mask) {
+    if (*__mask) {
+      __assigner(__first, __result);
+      ++__result;
+    }
+  }
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Assigner>
+void __brick_copy_by_mask(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    bool* __restrict __mask,
+    _Assigner __assigner,
+    /*vector=*/std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner);
+#else
+  __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type());
+#endif
+}
+
+template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
+void __brick_partition_by_mask(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator1 __out_true,
+    _OutputIterator2 __out_false,
+    bool* __mask,
+    /*vector=*/std::false_type) noexcept {
+  for (; __first != __last; ++__first, ++__mask) {
+    if (*__mask) {
+      *__out_true = *__first;
+      ++__out_true;
+    } else {
+      *__out_false = *__first;
+      ++__out_false;
+    }
+  }
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3>
+void __brick_partition_by_mask(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __out_true,
+    _RandomAccessIterator3 __out_false,
+    bool* __mask,
+    /*vector=*/std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask);
+#else
+  __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type());
+#endif
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
+_OutputIterator __pattern_copy_if(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _UnaryPredicate>
+_RandomAccessIterator2 __pattern_copy_if(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    _UnaryPredicate __pred) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
+  const _DifferenceType __n = __last - __first;
+  if (_DifferenceType(1) < __n) {
+    __par_backend::__buffer<bool> __mask_buf(__n);
+    return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() {
+      bool* __mask = __mask_buf.get();
+      _DifferenceType __m{};
+      __par_backend::__parallel_strict_scan(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __n,
+          _DifferenceType(0),
+          [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
+            return __internal::__brick_calc_mask_1<_DifferenceType>(
+                       __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{})
+                .first;
+          },
+          std::plus<_DifferenceType>(),                                                // Combine
+          [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
+            __internal::__brick_copy_by_mask(
+                __first + __i,
+                __first + (__i + __len),
+                __result + __initial,
+                __mask + __i,
+                [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; },
+                _IsVector{});
+          },
+          [&__m](_DifferenceType __total) { __m = __total; });
+      return __result + __m;
+    });
+  }
+  // trivial sequence - use serial algorithm
+  return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{});
+}
+
+//------------------------------------------------------------------------
+// count
+//------------------------------------------------------------------------
+template <class _RandomAccessIterator, class _Predicate>
+typename std::iterator_traits<_RandomAccessIterator>::difference_type
+__brick_count(_RandomAccessIterator __first,
+              _RandomAccessIterator __last,
+              _Predicate __pred,
+              /* is_vector = */ std::true_type) noexcept {
+  return __unseq_backend::__simd_count(__first, __last - __first, __pred);
+}
+
+template <class _ForwardIterator, class _Predicate>
+typename std::iterator_traits<_ForwardIterator>::difference_type
+__brick_count(_ForwardIterator __first,
+              _ForwardIterator __last,
+              _Predicate __pred,
+              /* is_vector = */ std::false_type) noexcept {
+  return std::count_if(__first, __last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+typename std::iterator_traits<_ForwardIterator>::difference_type __pattern_count(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept {
+  return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate>
+typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Predicate __pred) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
+  return __internal::__except_handler([&]() {
+    return __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        _SizeType(0),
+        [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType {
+          return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{});
+        },
+        std::plus<_SizeType>());
+  });
+}
+
+//------------------------------------------------------------------------
+// unique
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator
+__brick_unique(_RandomAccessIterator __first,
+               _RandomAccessIterator __last,
+               _BinaryPredicate __pred,
+               /*is_vector=*/std::false_type) noexcept {
+  return std::unique(__first, __last, __pred);
+}
+
+template <class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator
+__brick_unique(_RandomAccessIterator __first,
+               _RandomAccessIterator __last,
+               _BinaryPredicate __pred,
+               /*is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::unique(__first, __last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator __pattern_unique(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+// That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a
+// mask calculation is different. So, a caller passes _CalcMask brick into remove_elements.
+template <class _IsVector, class _ExecutionPolicy, class _ForwardIterator, class _CalcMask>
+_ForwardIterator __remove_elements(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _CalcMask __calc_mask) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType;
+  typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp;
+  _DifferenceType __n = __last - __first;
+  __par_backend::__buffer<bool> __mask_buf(__n);
+  // 1. find a first iterator that should be removed
+  return __internal::__except_handler([&]() {
+    bool* __mask          = __mask_buf.get();
+    _DifferenceType __min = __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        _DifferenceType(0),
+        __n,
+        __n,
+        [__first, __mask, &__calc_mask](
+            _DifferenceType __i, _DifferenceType __j, _DifferenceType __local_min) -> _DifferenceType {
+          // Create mask
+          __calc_mask(__mask + __i, __mask + __j, __first + __i);
+
+          // if minimum was found in a previous range we shouldn't do anymore
+          if (__local_min < __i) {
+            return __local_min;
+          }
+          // find first iterator that should be removed
+          bool* __result = __internal::__brick_find_if(
+              __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{});
+          if (__result - __mask == __j) {
+            return __local_min;
+          }
+          return std::min(__local_min, _DifferenceType(__result - __mask));
+        },
+        [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType {
+          return std::min(__local_min1, __local_min2);
+        });
+
+    // No elements to remove - exit
+    if (__min == __n) {
+      return __last;
+    }
+    __n -= __min;
+    __first += __min;
+
+    __par_backend::__buffer<_Tp> __buf(__n);
+    _Tp* __result = __buf.get();
+    __mask += __min;
+    _DifferenceType __m{};
+    // 2. Elements that doesn't satisfy pred are moved to result
+    __par_backend::__parallel_strict_scan(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __n,
+        _DifferenceType(0),
+        [__mask](_DifferenceType __i, _DifferenceType __len) {
+          return __internal::__brick_count(
+              __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{});
+        },
+        std::plus<_DifferenceType>(),
+        [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) {
+          __internal::__brick_copy_by_mask(
+              __first + __i,
+              __first + __i + __len,
+              __result + __initial,
+              __mask + __i,
+              [](_ForwardIterator __x, _Tp* __z) {
+                __internal::__invoke_if_else(
+                    std::is_trivial<_Tp>(),
+                    [&]() { *__z = std::move(*__x); },
+                    [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
+              },
+              _IsVector{});
+        },
+        [&__m](_DifferenceType __total) { __m = __total; });
+
+    // 3. Elements from result are moved to [first, last)
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __result,
+        __result + __m,
+        [__result, __first](_Tp* __i, _Tp* __j) {
+          __invoke_if_else(
+              std::is_trivial<_Tp>(),
+              [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); },
+              [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); });
+        });
+    return __first + __m;
+  });
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __pattern_unique(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _BinaryPredicate __pred) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
+
+  if (__first == __last) {
+    return __last;
+  }
+  if (__first + 1 == __last || __first + 2 == __last) {
+    // Trivial sequence - use serial algorithm
+    return __internal::__brick_unique(__first, __last, __pred, _IsVector{});
+  }
+  return __internal::__remove_elements(
+      __tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      ++__first,
+      __last,
+      [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) {
+        __internal::__brick_walk3(
+            __b,
+            __e,
+            __it - 1,
+            __it,
+            [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); },
+            _IsVector{});
+      });
+}
+
+//------------------------------------------------------------------------
+// unique_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
+OutputIterator __brick_unique_copy(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    OutputIterator __result,
+    _BinaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  return std::unique_copy(__first, __last, __result, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
+_RandomAccessIterator2 __brick_unique_copy(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    _BinaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred);
+#else
+  return std::unique_copy(__first, __last, __result, __pred);
+#endif
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate>
+_OutputIterator __pattern_unique_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    _BinaryPredicate __pred) noexcept {
+  return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
+_DifferenceType __brick_calc_mask_2(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    bool* __restrict __mask,
+    _BinaryPredicate __pred,
+    /*vector=*/std::false_type) noexcept {
+  _DifferenceType __count = 0;
+  for (; __first != __last; ++__first, ++__mask) {
+    *__mask = !__pred(*__first, *(__first - 1));
+    __count += *__mask;
+  }
+  return __count;
+}
+
+template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
+_DifferenceType __brick_calc_mask_2(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    bool* __restrict __mask,
+    _BinaryPredicate __pred,
+    /*vector=*/std::true_type) noexcept {
+  return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred);
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryPredicate>
+_RandomAccessIterator2 __pattern_unique_copy(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    _BinaryPredicate __pred) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
+  const _DifferenceType __n = __last - __first;
+  if (_DifferenceType(2) < __n) {
+    __par_backend::__buffer<bool> __mask_buf(__n);
+    if (_DifferenceType(2) < __n) {
+      return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() {
+        bool* __mask = __mask_buf.get();
+        _DifferenceType __m{};
+        __par_backend::__parallel_strict_scan(
+            __backend_tag{},
+            std::forward<_ExecutionPolicy>(__exec),
+            __n,
+            _DifferenceType(0),
+            [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce
+              _DifferenceType __extra = 0;
+              if (__i == 0) {
+                // Special boundary case
+                __mask[__i] = true;
+                if (--__len == 0)
+                  return 1;
+                ++__i;
+                ++__extra;
+              }
+              return __internal::__brick_calc_mask_2<_DifferenceType>(
+                         __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) +
+                     __extra;
+            },
+            std::plus<_DifferenceType>(),                                                // Combine
+            [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
+              // Phase 2 is same as for __pattern_copy_if
+              __internal::__brick_copy_by_mask(
+                  __first + __i,
+                  __first + (__i + __len),
+                  __result + __initial,
+                  __mask + __i,
+                  [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; },
+                  _IsVector{});
+            },
+            [&__m](_DifferenceType __total) { __m = __total; });
+        return __result + __m;
+      });
+    }
+  }
+  // trivial sequence - use serial algorithm
+  return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{});
+}
+
+//------------------------------------------------------------------------
+// reverse
+//------------------------------------------------------------------------
+template <class _BidirectionalIterator>
+void __brick_reverse(
+    _BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept {
+  std::reverse(__first, __last);
+}
+
+template <class _RandomAccessIterator>
+void __brick_reverse(
+    _RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
+
+  const auto __n = (__last - __first) / 2;
+  __unseq_backend::__simd_walk_2(
+      __first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), [](_ReferenceType __x, _ReferenceType __y) {
+        using std::swap;
+        swap(__x, __y);
+      });
+}
+
+// this brick is called in parallel version, so we can use iterator arithmetic
+template <class _BidirectionalIterator>
+void __brick_reverse(_BidirectionalIterator __first,
+                     _BidirectionalIterator __last,
+                     _BidirectionalIterator __d_last,
+                     /*is_vector=*/std::false_type) noexcept {
+  for (--__d_last; __first != __last; ++__first, --__d_last) {
+    using std::iter_swap;
+    iter_swap(__first, __d_last);
+  }
+}
+
+// this brick is called in parallel version, so we can use iterator arithmetic
+template <class _RandomAccessIterator>
+void __brick_reverse(_RandomAccessIterator __first,
+                     _RandomAccessIterator __last,
+                     _RandomAccessIterator __d_last,
+                     /*is_vector=*/std::true_type) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
+
+  __unseq_backend::__simd_walk_2(
+      __first,
+      __last - __first,
+      std::reverse_iterator<_RandomAccessIterator>(__d_last),
+      [](_ReferenceType __x, _ReferenceType __y) {
+        using std::swap;
+        swap(__x, __y);
+      });
+}
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator>
+void __pattern_reverse(
+    _Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept {
+  __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
+void __pattern_reverse(__parallel_tag<_IsVector> __tag,
+                       _ExecutionPolicy&& __exec,
+                       _RandomAccessIterator __first,
+                       _RandomAccessIterator __last) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __par_backend::__parallel_for(
+      __backend_tag{},
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __first + (__last - __first) / 2,
+      [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) {
+        __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{});
+      });
+}
+
+//------------------------------------------------------------------------
+// reverse_copy
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator, class _OutputIterator>
+_OutputIterator __brick_reverse_copy(
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __last,
+    _OutputIterator __d_first,
+    /*is_vector=*/std::false_type) noexcept {
+  return std::reverse_copy(__first, __last, __d_first);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2 __brick_reverse_copy(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __d_first,
+    /*is_vector=*/std::true_type) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
+  typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
+
+  return __unseq_backend::__simd_walk_2(
+      std::reverse_iterator<_RandomAccessIterator1>(__last),
+      __last - __first,
+      __d_first,
+      [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; });
+}
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator>
+_OutputIterator __pattern_reverse_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __last,
+    _OutputIterator __d_first) noexcept {
+  return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2 __pattern_reverse_copy(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __d_first) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  auto __len = __last - __first;
+  __par_backend::__parallel_for(
+      __backend_tag{},
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) {
+        __internal::__brick_reverse_copy(
+            __inner_first, __inner_last, __d_first + (__len - (__inner_last - __first)), _IsVector{});
+      });
+  return __d_first + __len;
+}
+
+//------------------------------------------------------------------------
+// rotate
+//------------------------------------------------------------------------
+template <class _ForwardIterator>
+_ForwardIterator
+__brick_rotate(_ForwardIterator __first,
+               _ForwardIterator __middle,
+               _ForwardIterator __last,
+               /*is_vector=*/std::false_type) noexcept {
+#if defined(_PSTL_CPP11_STD_ROTATE_BROKEN)
+  std::rotate(__first, __middle, __last);
+  return std::next(__first, std::distance(__middle, __last));
+#else
+  return std::rotate(__first, __middle, __last);
+#endif
+}
+
+template <class _RandomAccessIterator>
+_RandomAccessIterator
+__brick_rotate(_RandomAccessIterator __first,
+               _RandomAccessIterator __middle,
+               _RandomAccessIterator __last,
+               /*is_vector=*/std::true_type) noexcept {
+  auto __n                          = __last - __first;
+  auto __m                          = __middle - __first;
+  const _RandomAccessIterator __ret = __first + (__last - __middle);
+
+  bool __is_left = (__m <= __n / 2);
+  if (!__is_left)
+    __m = __n - __m;
+
+  while (__n > 1 && __m > 0) {
+    using std::iter_swap;
+    const auto __m_2 = __m * 2;
+    if (__is_left) {
+      for (; __last - __first >= __m_2; __first += __m) {
+        __unseq_backend::__simd_assign(
+            __first, __m, __first + __m, iter_swap<_RandomAccessIterator, _RandomAccessIterator>);
+      }
+    } else {
+      for (; __last - __first >= __m_2; __last -= __m) {
+        __unseq_backend::__simd_assign(
+            __last - __m, __m, __last - __m_2, iter_swap<_RandomAccessIterator, _RandomAccessIterator>);
+      }
+    }
+    __is_left = !__is_left;
+    __m       = __n % __m;
+    __n       = __last - __first;
+  }
+
+  return __ret;
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator>
+_ForwardIterator __pattern_rotate(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) noexcept {
+  return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
+_RandomAccessIterator __pattern_rotate(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __middle,
+    _RandomAccessIterator __last) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
+  auto __n = __last - __first;
+  auto __m = __middle - __first;
+  if (__m <= __n / 2) {
+    __par_backend::__buffer<_Tp> __buf(__n - __m);
+    return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() {
+      _Tp* __result = __buf.get();
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __middle,
+          __last,
+          [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) {
+            __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{});
+          });
+
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __middle,
+          [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) {
+            __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{});
+          });
+
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __result,
+          __result + (__n - __m),
+          [__first, __result](_Tp* __b, _Tp* __e) {
+            __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{});
+          });
+
+      return __first + (__last - __middle);
+    });
+  } else {
+    __par_backend::__buffer<_Tp> __buf(__m);
+    return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() {
+      _Tp* __result = __buf.get();
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __middle,
+          [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) {
+            __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{});
+          });
+
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __middle,
+          __last,
+          [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) {
+            __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{});
+          });
+
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __result,
+          __result + __m,
+          [__n, __m, __first, __result](_Tp* __b, _Tp* __e) {
+            __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{});
+          });
+
+      return __first + (__last - __middle);
+    });
+  }
+}
+
+//------------------------------------------------------------------------
+// rotate_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator>
+_OutputIterator __brick_rotate_copy(
+    _ForwardIterator __first,
+    _ForwardIterator __middle,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::rotate_copy(__first, __middle, __last, __result);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2 __brick_rotate_copy(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __middle,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result,
+    /*__is_vector=*/std::true_type) noexcept {
+  _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type());
+  return __internal::__brick_copy(__first, __middle, __res, std::true_type());
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator>
+_OutputIterator __pattern_rotate_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __middle,
+    _ForwardIterator __last,
+    _OutputIterator __result) noexcept {
+  return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_RandomAccessIterator2 __pattern_rotate_copy(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __middle,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __result) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __par_backend::__parallel_for(
+      __backend_tag{},
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) {
+        if (__b > __middle) {
+          __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{});
+        } else {
+          _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first));
+          if (__e < __middle) {
+            __internal::__brick_copy(__b, __e, __new_result, _IsVector{});
+          } else {
+            __internal::__brick_copy(__b, __middle, __new_result, _IsVector{});
+            __internal::__brick_copy(__middle, __e, __result, _IsVector{});
+          }
+        }
+      });
+  return __result + (__last - __first);
+}
+
+//------------------------------------------------------------------------
+// is_partitioned
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _UnaryPredicate>
+bool __brick_is_partitioned(_ForwardIterator __first,
+                            _ForwardIterator __last,
+                            _UnaryPredicate __pred,
+                            /*is_vector=*/std::false_type) noexcept {
+  return std::is_partitioned(__first, __last, __pred);
+}
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+bool __brick_is_partitioned(_RandomAccessIterator __first,
+                            _RandomAccessIterator __last,
+                            _UnaryPredicate __pred,
+                            /*is_vector=*/std::true_type) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
+  if (__first == __last) {
+    return true;
+  } else {
+    _RandomAccessIterator __result = __unseq_backend::__simd_first(
+        __first, _SizeType(0), __last - __first, [&__pred](_RandomAccessIterator __it, _SizeType __i) {
+          return !__pred(__it[__i]);
+        });
+    if (__result == __last) {
+      return true;
+    } else {
+      ++__result;
+      return !__unseq_backend::__simd_or(__result, __last - __result, __pred);
+    }
+  }
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+bool __pattern_is_partitioned(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+bool __pattern_is_partitioned(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred) {
+  if (__first == __last) {
+    return true;
+  } else {
+    using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+    return __internal::__except_handler([&]() {
+      // State of current range:
+      // broken     - current range is not partitioned by pred
+      // all_true   - all elements in current range satisfy pred
+      // all_false  - all elements in current range don't satisfy pred
+      // true_false - elements satisfy pred are placed before elements that don't satisfy pred
+      enum _ReduceType { __not_init = -1, __broken, __all_true, __all_false, __true_false };
+      _ReduceType __init = __not_init;
+
+      // Array with states that we'll have when state from the left branch is merged with state from the right branch.
+      // State is calculated by formula: new_state = table[left_state * 4 + right_state]
+      _ReduceType __table[] = {
+          __broken,
+          __broken,
+          __broken,
+          __broken,
+          __broken,
+          __all_true,
+          __true_false,
+          __true_false,
+          __broken,
+          __broken,
+          __all_false,
+          __broken,
+          __broken,
+          __broken,
+          __true_false,
+          __broken};
+
+      __init = __par_backend::__parallel_reduce(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __first,
+          __last,
+          __init,
+          [&__pred,
+           &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, _ReduceType __value) -> _ReduceType {
+            if (__value == __broken) {
+              return __broken;
+            }
+            _ReduceType __res = __not_init;
+            // if first element satisfy pred
+            if (__pred(*__i)) {
+              // find first element that don't satisfy pred
+              _RandomAccessIterator __x = __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{});
+              if (__x != __j) {
+                // find first element after "x" that satisfy pred
+                _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{});
+                // if it was found then range isn't partitioned by pred
+                if (__y != __j) {
+                  return __broken;
+                } else {
+                  __res = __true_false;
+                }
+              } else {
+                __res = __all_true;
+              }
+            } else { // if first element doesn't satisfy pred
+              // then we should find the first element that satisfy pred.
+              // If we found it then range isn't partitioned by pred
+              if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) {
+                return __broken;
+              } else {
+                __res = __all_false;
+              }
+            }
+            // if we have value from left range then we should calculate the result
+            return (__value == -1) ? __res : __table[__value * 4 + __res];
+          },
+
+          [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType {
+            if (__val1 == __broken || __val2 == __broken) {
+              return __broken;
+            }
+            // calculate the result for new big range
+            return __table[__val1 * 4 + __val2];
+          });
+      return __init != __broken;
+    });
+  }
+}
+
+//------------------------------------------------------------------------
+// partition
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __brick_partition(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _UnaryPredicate __pred,
+    /*is_vector=*/std::false_type) noexcept {
+  return std::partition(__first, __last, __pred);
+}
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_partition(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred,
+    /*is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::partition(__first, __last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __pattern_partition(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_partition(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  // partitioned range: elements before pivot satisfy pred (true part),
+  //                    elements after pivot don't satisfy pred (false part)
+  struct _PartitionRange {
+    _RandomAccessIterator __begin;
+    _RandomAccessIterator __pivot;
+    _RandomAccessIterator __end;
+  };
+
+  return __internal::__except_handler([&]() {
+    _PartitionRange __init{__last, __last, __last};
+
+    // lambda for merging two partitioned ranges to one partitioned range
+    auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
+      auto __size1     = __val1.__end - __val1.__pivot;
+      auto __size2     = __val2.__pivot - __val2.__begin;
+      auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);
+
+      // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
+      if (__val1.__end == __val1.__pivot) {
+        return {__new_begin, __val2.__pivot, __val2.__end};
+      }
+      // if true part of right range greater than false part of left range
+      // then we should swap the false part of left range and last part of true part of right range
+      else if (__size2 > __size1) {
+        __par_backend::__parallel_for(
+            __backend_tag{},
+            std::forward<_ExecutionPolicy>(__exec),
+            __val1.__pivot,
+            __val1.__pivot + __size1,
+            [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) {
+              __internal::__brick_swap_ranges(
+                  __i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), _IsVector{});
+            });
+        return {__new_begin, __val2.__pivot - __size1, __val2.__end};
+      }
+      // else we should swap the first part of false part of left range and true part of right range
+      else {
+        __par_backend::__parallel_for(
+            __backend_tag{},
+            std::forward<_ExecutionPolicy>(__exec),
+            __val1.__pivot,
+            __val1.__pivot + __size2,
+            [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) {
+              __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{});
+            });
+        return {__new_begin, __val1.__pivot + __size2, __val2.__end};
+      }
+    };
+
+    _PartitionRange __result = __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __init,
+        [__pred,
+         __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange {
+          // 1. serial partition
+          _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{});
+
+          // 2. merging of two ranges (left and right respectively)
+          return __reductor(__value, {__i, __pivot, __j});
+        },
+        __reductor);
+    return __result.__pivot;
+  });
+}
+
+//------------------------------------------------------------------------
+// stable_partition
+//------------------------------------------------------------------------
+
+template <class _BidirectionalIterator, class _UnaryPredicate>
+_BidirectionalIterator __brick_stable_partition(
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __last,
+    _UnaryPredicate __pred,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::stable_partition(__first, __last, __pred);
+}
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_stable_partition(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred,
+    /*__is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::stable_partition(__first, __last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
+_BidirectionalIterator __pattern_stable_partition(
+    _Tag,
+    _ExecutionPolicy&&,
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __last,
+    _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_stable_partition(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  // partitioned range: elements before pivot satisfy pred (true part),
+  //                    elements after pivot don't satisfy pred (false part)
+  struct _PartitionRange {
+    _RandomAccessIterator __begin;
+    _RandomAccessIterator __pivot;
+    _RandomAccessIterator __end;
+  };
+
+  return __internal::__except_handler([&]() {
+    _PartitionRange __init{__last, __last, __last};
+
+    // lambda for merging two partitioned ranges to one partitioned range
+    auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
+      auto __size1     = __val1.__end - __val1.__pivot;
+      auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);
+
+      // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
+      if (__val1.__end == __val1.__pivot) {
+        return {__new_begin, __val2.__pivot, __val2.__end};
+      }
+      // if true part of right range greater than false part of left range
+      // then we should swap the false part of left range and last part of true part of right range
+      else {
+        __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{});
+        return {__new_begin, __val2.__pivot - __size1, __val2.__end};
+      }
+    };
+
+    _PartitionRange __result = __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __init,
+        [&__pred,
+         __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange {
+          // 1. serial stable_partition
+          _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{});
+
+          // 2. merging of two ranges (left and right respectively)
+          return __reductor(__value, {__i, __pivot, __j});
+        },
+        __reductor);
+    return __result.__pivot;
+  });
+}
+
+//------------------------------------------------------------------------
+// partition_copy
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator1 __out_true,
+    _OutputIterator2 __out_false,
+    _UnaryPredicate __pred,
+    /*is_vector=*/std::false_type) noexcept {
+  return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
+}
+
+template <class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _UnaryPredicate>
+std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __brick_partition_copy(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __out_true,
+    _RandomAccessIterator3 __out_false,
+    _UnaryPredicate __pred,
+    /*is_vector=*/std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred);
+#else
+  return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
+#endif
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _OutputIterator1,
+          class _OutputIterator2,
+          class _UnaryPredicate>
+std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator1 __out_true,
+    _OutputIterator2 __out_false,
+    _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_partition_copy(
+      __first, __last, __out_true, __out_false, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _UnaryPredicate>
+std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __pattern_partition_copy(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __out_true,
+    _RandomAccessIterator3 __out_false,
+    _UnaryPredicate __pred) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
+  typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType;
+  const _DifferenceType __n = __last - __first;
+  if (_DifferenceType(1) < __n) {
+    __par_backend::__buffer<bool> __mask_buf(__n);
+    return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() {
+      bool* __mask = __mask_buf.get();
+      _ReturnType __m{};
+      __par_backend::__parallel_strict_scan(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __n,
+          std::make_pair(_DifferenceType(0), _DifferenceType(0)),
+          [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
+            return __internal::__brick_calc_mask_1<_DifferenceType>(
+                __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{});
+          },
+          [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType {
+            return std::make_pair(__x.first + __y.first, __x.second + __y.second);
+          },                                                                       // Combine
+          [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan
+            __internal::__brick_partition_by_mask(
+                __first + __i,
+                __first + (__i + __len),
+                __out_true + __initial.first,
+                __out_false + __initial.second,
+                __mask + __i,
+                _IsVector{});
+          },
+          [&__m](_ReturnType __total) { __m = __total; });
+      return std::make_pair(__out_true + __m.first, __out_false + __m.second);
+    });
+  }
+  // trivial sequence - use serial algorithm
+  return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{});
+}
+
+//------------------------------------------------------------------------
+// sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible>
+void __pattern_sort(_Tag,
+                    _ExecutionPolicy&&,
+                    _RandomAccessIterator __first,
+                    _RandomAccessIterator __last,
+                    _Compare __comp,
+                    _IsMoveConstructible) noexcept {
+  std::sort(__first, __last, __comp);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_sort(__parallel_tag<_IsVector> __tag,
+                    _ExecutionPolicy&& __exec,
+                    _RandomAccessIterator __first,
+                    _RandomAccessIterator __last,
+                    _Compare __comp,
+                    /*is_move_constructible=*/std::true_type) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __internal::__except_handler([&]() {
+    __par_backend::__parallel_stable_sort(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __comp,
+        [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+          std::sort(__first, __last, __comp);
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// stable_sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_stable_sort(
+    _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept {
+  std::stable_sort(__first, __last, __comp);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_stable_sort(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  __internal::__except_handler([&]() {
+    __par_backend::__parallel_stable_sort(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __comp,
+        [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+          std::stable_sort(__first, __last, __comp);
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// partial_sort
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_partial_sort(
+    _Tag,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __middle,
+    _RandomAccessIterator __last,
+    _Compare __comp) noexcept {
+  std::partial_sort(__first, __middle, __last, __comp);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_partial_sort(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __middle,
+    _RandomAccessIterator __last,
+    _Compare __comp) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  const auto __n = __middle - __first;
+  if (__n == 0)
+    return;
+
+  __internal::__except_handler([&]() {
+    __par_backend::__parallel_stable_sort(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __comp,
+        [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) {
+          if (__n < __end - __begin)
+            std::partial_sort(__begin, __begin + __n, __end, __comp);
+          else
+            std::sort(__begin, __end, __comp);
+        },
+        __n);
+  });
+}
+
+//------------------------------------------------------------------------
+// partial_sort_copy
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __pattern_partial_sort_copy(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _RandomAccessIterator __d_first,
+    _RandomAccessIterator __d_last,
+    _Compare __comp) noexcept {
+  return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp);
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+_RandomAccessIterator2 __pattern_partial_sort_copy(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __d_first,
+    _RandomAccessIterator2 __d_last,
+    _Compare __comp) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__last == __first || __d_last == __d_first) {
+    return __d_first;
+  }
+  auto __n1 = __last - __first;
+  auto __n2 = __d_last - __d_first;
+  return __internal::__except_handler([&]() {
+    if (__n2 >= __n1) {
+      __par_backend::__parallel_stable_sort(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __d_first,
+          __d_first + __n1,
+          __comp,
+          [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) {
+            _RandomAccessIterator1 __i1 = __first + (__i - __d_first);
+            _RandomAccessIterator1 __j1 = __first + (__j - __d_first);
+
+        // 1. Copy elements from input to output
+#if !defined(_PSTL_ICC_18_OMP_SIMD_BROKEN)
+            __internal::__brick_copy(__i1, __j1, __i, _IsVector{});
+#else
+            std::copy(__i1, __j1, __i);
+#endif
+            // 2. Sort elements in output sequence
+            std::sort(__i, __j, __comp);
+          },
+          __n1);
+      return __d_first + __n1;
+    } else {
+      typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1;
+      typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2;
+      __par_backend::__buffer<_T1> __buf(__n1);
+      _T1* __r = __buf.get();
+
+      __par_backend::__parallel_stable_sort(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __r,
+          __r + __n1,
+          __comp,
+          [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) {
+            _RandomAccessIterator1 __it = __first + (__i - __r);
+
+            // 1. Copy elements from input to raw memory
+            for (_T1* __k = __i; __k != __j; ++__k, ++__it) {
+              ::new (__k) _T2(*__it);
+            }
+
+            // 2. Sort elements in temporary __buffer
+            if (__n2 < __j - __i)
+              std::partial_sort(__i, __i + __n2, __j, __comp);
+            else
+              std::sort(__i, __j, __comp);
+          },
+          __n2);
+
+      // 3. Move elements from temporary __buffer to output
+      __par_backend::__parallel_for(
+          __backend_tag{},
+          std::forward<_ExecutionPolicy>(__exec),
+          __r,
+          __r + __n2,
+          [__r, __d_first](_T1* __i, _T1* __j) {
+            __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{});
+          });
+      __par_backend::__parallel_for(
+          __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1, [](_T1* __i, _T1* __j) {
+            __brick_destroy(__i, __j, _IsVector{});
+          });
+
+      return __d_first + __n2;
+    }
+  });
+}
+
+//------------------------------------------------------------------------
+// adjacent_find
+//------------------------------------------------------------------------
+template <class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __brick_adjacent_find(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _BinaryPredicate __pred,
+    /* IsVector = */ std::true_type,
+    bool __or_semantic) noexcept {
+  return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic);
+}
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator __brick_adjacent_find(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _BinaryPredicate __pred,
+    /* IsVector = */ std::false_type,
+    bool) noexcept {
+  return std::adjacent_find(__first, __last, __pred);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator __pattern_adjacent_find(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _BinaryPredicate __pred,
+    bool __or_semantic) noexcept {
+  return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
+_RandomAccessIterator __pattern_adjacent_find(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _BinaryPredicate __pred,
+    bool __or_semantic) {
+  if (__last - __first < 2)
+    return __last;
+
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    return __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        __last,
+        [__last, __pred, __or_semantic](
+            _RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __value)
+            -> _RandomAccessIterator {
+          // TODO: investigate performance benefits from the use of shared variable for the result,
+          // checking (compare_and_swap idiom) its __value at __first.
+          if (__or_semantic && __value < __last) { // found
+            __par_backend::__cancel_execution();
+            return __value;
+          }
+
+          if (__value > __begin) {
+            // modify __end to check the predicate on the boundary __values;
+            // TODO: to use a custom range with boundaries overlapping
+            // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1)
+            // then check the pair [__last-1, __last)
+            if (__end != __last)
+              ++__end;
+
+            // correct the global result iterator if the "brick" returns a local "__last"
+            const _RandomAccessIterator __res =
+                __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic);
+            if (__res < __end)
+              __value = __res;
+          }
+          return __value;
+        },
+        [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator {
+          return __x < __y ? __x : __y;
+        } // reduce a __value
+    );
+  });
+}
+
+//------------------------------------------------------------------------
+// nth_element
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_nth_element(
+    _Tag,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __nth,
+    _RandomAccessIterator __last,
+    _Compare __comp) noexcept {
+  std::nth_element(__first, __nth, __last, __comp);
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_nth_element(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __nth,
+    _RandomAccessIterator __last,
+    _Compare __comp) noexcept {
+  if (__first == __last || __nth == __last) {
+    return;
+  }
+
+  using std::iter_swap;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
+  _RandomAccessIterator __x;
+  do {
+    __x = __internal::__pattern_partition(
+        __tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, [&__comp, __first](const _Tp& __x) {
+          return __comp(__x, *__first);
+        });
+    --__x;
+    if (__x != __first) {
+      iter_swap(__first, __x);
+    }
+    // if x > nth then our new range for partition is [first, x)
+    if (__x - __nth > 0) {
+      __last = __x;
+    }
+    // if x < nth then our new range for partition is [x, last)
+    else if (__x - __nth < 0) {
+      // if *x == *nth then we can start new partition with x+1
+      if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth)) {
+        ++__x;
+      } else {
+        iter_swap(__nth, __x);
+      }
+      __first = __x;
+    }
+  } while (__x != __nth);
+}
+
+//------------------------------------------------------------------------
+// generate, generate_n
+//------------------------------------------------------------------------
+template <class _RandomAccessIterator, class _Generator>
+void __brick_generate(_RandomAccessIterator __first,
+                      _RandomAccessIterator __last,
+                      _Generator __g,
+                      /* is_vector = */ std::true_type) noexcept {
+  __unseq_backend::__simd_generate_n(__first, __last - __first, __g);
+}
+
+template <class _ForwardIterator, class _Generator>
+void __brick_generate(_ForwardIterator __first,
+                      _ForwardIterator __last,
+                      _Generator __g,
+                      /* is_vector = */ std::false_type) noexcept {
+  std::generate(__first, __last, __g);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator>
+void __pattern_generate(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept {
+  __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator>
+_RandomAccessIterator __pattern_generate(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Generator __g) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_for(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) {
+          __internal::__brick_generate(__begin, __end, __g, _IsVector{});
+        });
+    return __last;
+  });
+}
+
+template <class _RandomAccessIterator, class Size, class _Generator>
+_RandomAccessIterator __brick_generate_n(
+    _RandomAccessIterator __first,
+    Size __count,
+    _Generator __g,
+    /* is_vector = */ std::true_type) noexcept {
+  return __unseq_backend::__simd_generate_n(__first, __count, __g);
+}
+
+template <class OutputIterator, class Size, class _Generator>
+OutputIterator
+__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept {
+  return std::generate_n(__first, __count, __g);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Generator>
+_OutputIterator
+__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept {
+  return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Generator>
+_RandomAccessIterator __pattern_generate_n(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _Size __count,
+    _Generator __g) {
+  static_assert(__are_random_access_iterators<_RandomAccessIterator>::value,
+                "Pattern-brick error. Should be a random access iterator.");
+  return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g);
+}
+
+//------------------------------------------------------------------------
+// remove
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __brick_remove_if(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _UnaryPredicate __pred,
+    /* __is_vector = */ std::false_type) noexcept {
+  return std::remove_if(__first, __last, __pred);
+}
+
+template <class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __brick_remove_if(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred,
+    /* __is_vector = */ std::true_type) noexcept {
+#if defined(_PSTL_MONOTONIC_PRESENT)
+  return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred);
+#else
+  return std::remove_if(__first, __last, __pred);
+#endif
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+_ForwardIterator __pattern_remove_if(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
+  return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
+_RandomAccessIterator __pattern_remove_if(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _UnaryPredicate __pred) noexcept {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
+
+  if (__first == __last || __first + 1 == __last) {
+    // Trivial sequence - use serial algorithm
+    return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{});
+  }
+
+  return __internal::__remove_elements(
+      __tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) {
+        __internal::__brick_walk2(
+            __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{});
+      });
+}
+
+//------------------------------------------------------------------------
+// inplace_merge
+//------------------------------------------------------------------------
+template <class _BidirectionalIterator, class _Compare>
+void __brick_inplace_merge(
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __middle,
+    _BidirectionalIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  std::inplace_merge(__first, __middle, __last, __comp);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+void __brick_inplace_merge(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __middle,
+    _RandomAccessIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+  // TODO: vectorize
+  std::inplace_merge(__first, __middle, __last, __comp);
+}
+
+template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
+void __pattern_inplace_merge(
+    _Tag,
+    _ExecutionPolicy&&,
+    _BidirectionalIterator __first,
+    _BidirectionalIterator __middle,
+    _BidirectionalIterator __last,
+    _Compare __comp) noexcept {
+  __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+void __pattern_inplace_merge(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __middle,
+    _RandomAccessIterator __last,
+    _Compare __comp) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__first == __last || __first == __middle || __middle == __last) {
+    return;
+  }
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
+  auto __n = __last - __first;
+  __par_backend::__buffer<_Tp> __buf(__n);
+  _Tp* __r = __buf.get();
+  __internal::__except_handler([&]() {
+    auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) {
+      __internal::__invoke_if_else(
+          std::is_trivial<_Tp>(),
+          [&]() { *__z = std::move(*__x); },
+          [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
+    };
+
+    auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) {
+      return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector());
+    };
+
+    __par_backend::__parallel_merge(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __middle,
+        __middle,
+        __last,
+        __r,
+        __comp,
+        [__n, __move_values, __move_sequences](
+            _RandomAccessIterator __f1,
+            _RandomAccessIterator __l1,
+            _RandomAccessIterator __f2,
+            _RandomAccessIterator __l2,
+            _Tp* __f3,
+            _Compare __comp) {
+          (__utils::__serial_move_merge(__n))(
+              __f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values, __move_sequences, __move_sequences);
+          return __f3 + (__l1 - __f1) + (__l2 - __f2);
+        });
+    __par_backend::__parallel_for(
+        __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first](_Tp* __i, _Tp* __j) {
+          __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{});
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __pattern_includes(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Compare __comp) noexcept {
+  return std::includes(__first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+bool __pattern_includes(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _Compare __comp) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__first2 >= __last2)
+    return true;
+
+  if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1)))
+    return false;
+
+  __first1 = std::lower_bound(__first1, __last1, *__first2, __comp);
+  if (__first1 == __last1)
+    return false;
+
+  if (__last2 - __first2 == 1)
+    return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1);
+
+  return __internal::__except_handler([&]() {
+    return !__internal::__parallel_or(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first2,
+        __last2,
+        [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) {
+          _LIBCPP_ASSERT_UNCATEGORIZED(__j > __i, "");
+          //_LIBCPP_ASSERT_UNCATEGORIZED(__j - __i > 1, "");
+
+          // 1. moving boundaries to "consume" subsequence of equal elements
+          auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool {
+            return !__comp(*__a, *__b) && !__comp(*__b, *__a);
+          };
+
+          // 1.1 left bound, case "aaa[aaaxyz...]" - searching "x"
+          if (__i > __first2 && __is_equal(__i, __i - 1)) {
+            // whole subrange continues to content equal elements - return "no op"
+            if (__is_equal(__i, __j - 1))
+              return false;
+
+            __i = std::upper_bound(__i, __last2, *__i, __comp);
+          }
+
+          // 1.2 right bound, case "[...aaa]aaaxyz" - searching "x"
+          if (__j < __last2 && __is_equal(__j - 1, __j))
+            __j = std::upper_bound(__j, __last2, *__j, __comp);
+
+          // 2. testing is __a subsequence of the second range included into the first range
+          auto __b = std::lower_bound(__first1, __last1, *__i, __comp);
+
+          _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__last1 - 1), *__b), "");
+          _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__j - 1), *__i), "");
+          return !std::includes(__b, __last1, __i, __j, __comp);
+        });
+  });
+}
+
+constexpr auto __set_algo_cut_off = 1000;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare,
+          class _SizeFunction,
+          class _SetOP>
+_OutputIterator __parallel_set_op(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    _SizeFunction __size_func,
+    _SetOP __set_op) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
+  typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
+
+  struct _SetRange {
+    _DifferenceType __pos, __len, __buf_pos;
+    bool empty() const { return __len == 0; }
+  };
+
+  const _DifferenceType __n1 = __last1 - __first1;
+  const _DifferenceType __n2 = __last2 - __first2;
+
+  __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2));
+
+  return __internal::__except_handler(
+      [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() {
+        auto __buffer = __buf.get();
+        _DifferenceType __m{};
+        auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan
+          if (!__s.empty())
+            __brick_move_destroy()(
+                __buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos, _IsVector{});
+        };
+        __par_backend::__parallel_strict_scan(
+            __backend_tag{},
+            std::forward<_ExecutionPolicy>(__exec),
+            __n1,
+            _SetRange{0, 0, 0},                               //-1, 0},
+            [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
+              //[__b; __e) - a subrange of the first sequence, to reduce
+              _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len);
+
+              // try searching for the first element which not equal to *__b
+              if (__b != __first1)
+                __b = std::upper_bound(__b, __last1, *__b, __comp);
+
+              // try searching for the first element which not equal to *__e
+              if (__e != __last1)
+                __e = std::upper_bound(__e, __last1, *__e, __comp);
+
+              // check is [__b; __e) empty
+              if (__e - __b < 1) {
+                _ForwardIterator2 __bb = __last2;
+                if (__b != __last1)
+                  __bb = std::lower_bound(__first2, __last2, *__b, __comp);
+
+                const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
+                return _SetRange{0, 0, __buf_pos};
+              }
+
+              // try searching for "corresponding" subrange [__bb; __ee) in the second sequence
+              _ForwardIterator2 __bb = __first2;
+              if (__b != __first1)
+                __bb = std::lower_bound(__first2, __last2, *__b, __comp);
+
+              _ForwardIterator2 __ee = __last2;
+              if (__e != __last1)
+                __ee = std::lower_bound(__bb, __last2, *__e, __comp);
+
+              const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
+              auto __buffer_b                 = __buffer + __buf_pos;
+              auto __res                      = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp);
+
+              return _SetRange{0, __res - __buffer_b, __buf_pos};
+            },
+            [](const _SetRange& __a, const _SetRange& __b) { // Combine
+              if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty()))
+                return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos};
+              return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos};
+            },
+            __scan,                                     // Scan
+            [&__m, &__scan](const _SetRange& __total) { // Apex
+              // final scan
+              __scan(0, 0, __total);
+              __m = __total.__pos + __total.__len;
+            });
+        return __result + __m;
+      });
+}
+
+// a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference'
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare,
+          class _SetUnionOp>
+_OutputIterator __parallel_set_union_op(
+    _Tag __tag,
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    _SetUnionOp __set_union_op) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
+
+  const auto __n1 = __last1 - __first1;
+  const auto __n2 = __last2 - __first2;
+
+  auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
+    return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{});
+  };
+  auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) {
+    return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{});
+  };
+
+  // {1} {}: parallel copying just first sequence
+  if (__n2 == 0)
+    return __internal::__pattern_walk2_brick(
+        __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1);
+
+  // {} {2}: parallel copying justmake  second sequence
+  if (__n1 == 0)
+    return __internal::__pattern_walk2_brick(
+        __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2);
+
+  // testing  whether the sequences are intersected
+  _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
+
+  if (__left_bound_seq_1 == __last1) {
+    //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
+    __par_backend::__parallel_invoke(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1);
+        },
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result + __n1, copy_range2);
+        });
+    return __result + __n1 + __n2;
+  }
+
+  // testing  whether the sequences are intersected
+  _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
+
+  if (__left_bound_seq_2 == __last2) {
+    //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
+    __par_backend::__parallel_invoke(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2);
+        },
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result + __n2, copy_range1);
+        });
+    return __result + __n1 + __n2;
+  }
+
+  const auto __m1 = __left_bound_seq_1 - __first1;
+  if (__m1 > __set_algo_cut_off) {
+    auto __res_or = __result;
+    __result += __m1; // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
+    __par_backend::__parallel_invoke(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        // do parallel copying of [first1; left_bound_seq_1)
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1, __res_or, copy_range1);
+        },
+        [=, &__result] {
+          __result = __internal::__parallel_set_op(
+              __tag,
+              std::forward<_ExecutionPolicy>(__exec),
+              __left_bound_seq_1,
+              __last1,
+              __first2,
+              __last2,
+              __result,
+              __comp,
+              [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
+              __set_union_op);
+        });
+    return __result;
+  }
+
+  const auto __m2 = __left_bound_seq_2 - __first2;
+  _LIBCPP_ASSERT_UNCATEGORIZED(__m1 == 0 || __m2 == 0, "");
+  if (__m2 > __set_algo_cut_off) {
+    auto __res_or = __result;
+    __result += __m2; // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
+    __par_backend::__parallel_invoke(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        // do parallel copying of [first2; left_bound_seq_2)
+        [=] {
+          __internal::__pattern_walk2_brick(
+              __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2, __res_or, copy_range2);
+        },
+        [=, &__result] {
+          __result = __internal::__parallel_set_op(
+              __tag,
+              std::forward<_ExecutionPolicy>(__exec),
+              __first1,
+              __last1,
+              __left_bound_seq_2,
+              __last2,
+              __result,
+              __comp,
+              [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
+              __set_union_op);
+        });
+    return __result;
+  }
+
+  return __internal::__parallel_set_op(
+      __tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first1,
+      __last1,
+      __first2,
+      __last2,
+      __result,
+      __comp,
+      [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
+      __set_union_op);
+}
+
+//------------------------------------------------------------------------
+// set_union
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_union(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <typename _IsVector>
+struct __BrickCopyConstruct {
+  template <typename _ForwardIterator, typename _OutputIterator>
+  _OutputIterator operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result) {
+    return __brick_uninitialized_copy(__first, __last, __result, _IsVector());
+  }
+};
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_union(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    /*__is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_union(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp) noexcept {
+  return __internal::__brick_set_union(
+      __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_union(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp) {
+  const auto __n1 = __last1 - __first1;
+  const auto __n2 = __last2 - __first2;
+
+  // use serial algorithm
+  if (__n1 + __n2 <= __set_algo_cut_off)
+    return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
+
+  typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
+  return __parallel_set_union_op(
+      __tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first1,
+      __last1,
+      __first2,
+      __last2,
+      __result,
+      __comp,
+      [](_RandomAccessIterator1 __first1,
+         _RandomAccessIterator1 __last1,
+         _RandomAccessIterator2 __first2,
+         _RandomAccessIterator2 __last2,
+         _Tp* __result,
+         _Compare __comp) {
+        return __pstl::__utils::__set_union_construct(
+            __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
+      });
+}
+
+//------------------------------------------------------------------------
+// set_intersection
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_intersection(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
+_RandomAccessIterator3 __brick_set_intersection(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp,
+    /*__is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_intersection(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp) noexcept {
+  return __internal::__brick_set_intersection(
+      __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Compare>
+_RandomAccessIterator3 __pattern_set_intersection(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp) {
+  typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
+
+  const auto __n1 = __last1 - __first1;
+  const auto __n2 = __last2 - __first2;
+
+  // intersection is empty
+  if (__n1 == 0 || __n2 == 0)
+    return __result;
+
+  // testing  whether the sequences are intersected
+  _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
+  //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty
+  if (__left_bound_seq_1 == __last1)
+    return __result;
+
+  // testing  whether the sequences are intersected
+  _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
+  //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty
+  if (__left_bound_seq_2 == __last2)
+    return __result;
+
+  const auto __m1 = __last1 - __left_bound_seq_1 + __n2;
+  if (__m1 > __set_algo_cut_off) {
+    // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
+    return __internal::__parallel_set_op(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __left_bound_seq_1,
+        __last1,
+        __first2,
+        __last2,
+        __result,
+        __comp,
+        [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
+        [](_RandomAccessIterator1 __first1,
+           _RandomAccessIterator1 __last1,
+           _RandomAccessIterator2 __first2,
+           _RandomAccessIterator2 __last2,
+           _Tp* __result,
+           _Compare __comp) {
+          return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp);
+        });
+  }
+
+  const auto __m2 = __last2 - __left_bound_seq_2 + __n1;
+  if (__m2 > __set_algo_cut_off) {
+    // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
+    __result = __internal::__parallel_set_op(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        __left_bound_seq_2,
+        __last2,
+        __result,
+        __comp,
+        [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
+        [](_RandomAccessIterator1 __first1,
+           _RandomAccessIterator1 __last1,
+           _RandomAccessIterator2 __first2,
+           _RandomAccessIterator2 __last2,
+           _Tp* __result,
+           _Compare __comp) {
+          return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp);
+        });
+    return __result;
+  }
+
+  // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm
+  return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp);
+}
+
+//------------------------------------------------------------------------
+// set_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_difference(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
+_RandomAccessIterator3 __brick_set_difference(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp,
+    /*__is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_difference(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp) noexcept {
+  return __internal::__brick_set_difference(
+      __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Compare>
+_RandomAccessIterator3 __pattern_set_difference(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp) {
+  typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
+
+  const auto __n1 = __last1 - __first1;
+  const auto __n2 = __last2 - __first2;
+
+  // {} \ {2}: the difference is empty
+  if (__n1 == 0)
+    return __result;
+
+  // {1} \ {}: parallel copying just first sequence
+  if (__n2 == 0)
+    return __internal::__pattern_walk2_brick(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        __result,
+        [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
+          return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
+        });
+
+  // testing  whether the sequences are intersected
+  _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
+  //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence
+  if (__left_bound_seq_1 == __last1)
+    return __internal::__pattern_walk2_brick(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        __result,
+        [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
+          return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
+        });
+
+  // testing  whether the sequences are intersected
+  _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
+  //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence
+  if (__left_bound_seq_2 == __last2)
+    return __internal::__pattern_walk2_brick(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        __result,
+        [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
+          return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
+        });
+
+  if (__n1 + __n2 > __set_algo_cut_off)
+    return __parallel_set_op(
+        __tag,
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __last1,
+        __first2,
+        __last2,
+        __result,
+        __comp,
+        [](_DifferenceType __n, _DifferenceType) { return __n; },
+        [](_RandomAccessIterator1 __first1,
+           _RandomAccessIterator1 __last1,
+           _RandomAccessIterator2 __first2,
+           _RandomAccessIterator2 __last2,
+           _Tp* __result,
+           _Compare __comp) {
+          return __pstl::__utils::__set_difference_construct(
+              __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
+        });
+
+  // use serial algorithm
+  return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+//------------------------------------------------------------------------
+// set_symmetric_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
+_OutputIterator __brick_set_symmetric_difference(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp,
+    /*__is_vector=*/std::false_type) noexcept {
+  return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
+_RandomAccessIterator3 __brick_set_symmetric_difference(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp,
+    /*__is_vector=*/std::true_type) noexcept {
+  // TODO: vectorize
+  return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _OutputIterator,
+          class _Compare>
+_OutputIterator __pattern_set_symmetric_difference(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _OutputIterator __result,
+    _Compare __comp) noexcept {
+  return __internal::__brick_set_symmetric_difference(
+      __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _RandomAccessIterator3,
+          class _Compare>
+_RandomAccessIterator3 __pattern_set_symmetric_difference(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _RandomAccessIterator3 __result,
+    _Compare __comp) {
+  const auto __n1 = __last1 - __first1;
+  const auto __n2 = __last2 - __first2;
+
+  // use serial algorithm
+  if (__n1 + __n2 <= __set_algo_cut_off)
+    return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
+
+  typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
+  return __internal::__parallel_set_union_op(
+      __tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first1,
+      __last1,
+      __first2,
+      __last2,
+      __result,
+      __comp,
+      [](_RandomAccessIterator1 __first1,
+         _RandomAccessIterator1 __last1,
+         _RandomAccessIterator2 __first2,
+         _RandomAccessIterator2 __last2,
+         _Tp* __result,
+         _Compare __comp) {
+        return __pstl::__utils::__set_symmetric_difference_construct(
+            __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
+      });
+}
+
+//------------------------------------------------------------------------
+// is_heap_until
+//------------------------------------------------------------------------
+
+template <class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __brick_is_heap_until(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  return std::is_heap_until(__first, __last, __comp);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __brick_is_heap_until(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+  if (__last - __first < 2)
+    return __last;
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
+  return __unseq_backend::__simd_first(
+      __first, _SizeType(0), __last - __first, [&__comp](_RandomAccessIterator __it, _SizeType __i) {
+        return __comp(__it[(__i - 1) / 2], __it[__i]);
+      });
+}
+
+template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __pattern_is_heap_until(
+    _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept {
+  return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
+_RandomAccessIterator __is_heap_until_local(
+    _RandomAccessIterator __first,
+    _DifferenceType __begin,
+    _DifferenceType __end,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  _DifferenceType __i = __begin;
+  for (; __i < __end; ++__i) {
+    if (__comp(__first[(__i - 1) / 2], __first[__i])) {
+      break;
+    }
+  }
+  return __first + __i;
+}
+
+template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
+_RandomAccessIterator __is_heap_until_local(
+    _RandomAccessIterator __first,
+    _DifferenceType __begin,
+    _DifferenceType __end,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+  return __unseq_backend::__simd_first(
+      __first, __begin, __end, [&__comp](_RandomAccessIterator __it, _DifferenceType __i) {
+        return __comp(__it[(__i - 1) / 2], __it[__i]);
+      });
+}
+
+template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator __pattern_is_heap_until(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__last - __first < 2)
+    return __last;
+
+  return __internal::__except_handler([&]() {
+    return __parallel_find(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first,
+        __last,
+        [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) {
+          return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, _IsVector{});
+        },
+        std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(),
+        /*is_first=*/true);
+  });
+}
+
+//------------------------------------------------------------------------
+// min_element
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _Compare>
+_ForwardIterator __brick_min_element(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  return std::min_element(__first, __last, __comp);
+}
+
+template <typename _RandomAccessIterator, typename _Compare>
+_RandomAccessIterator __brick_min_element(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+#if defined(_PSTL_UDR_PRESENT)
+  return __unseq_backend::__simd_min_element(__first, __last - __first, __comp);
+#else
+  return std::min_element(__first, __last, __comp);
+#endif
+}
+
+template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
+_ForwardIterator __pattern_min_element(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept {
+  return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{});
+}
+
+template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
+_RandomAccessIterator __pattern_min_element(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp) {
+  if (__first == __last)
+    return __last;
+
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    return __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first + 1,
+        __last,
+        __first,
+        [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __init)
+            -> _RandomAccessIterator {
+          const _RandomAccessIterator subresult = __internal::__brick_min_element(__begin, __end, __comp, _IsVector{});
+          return __internal::__cmp_iterators_by_values(__init, subresult, __comp);
+        },
+        [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator {
+          return __internal::__cmp_iterators_by_values(__it1, __it2, __comp);
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// minmax_element
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _Compare>
+std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  return std::minmax_element(__first, __last, __comp);
+}
+
+template <typename _RandomAccessIterator, typename _Compare>
+std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+#if defined(_PSTL_UDR_PRESENT)
+  return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp);
+#else
+  return std::minmax_element(__first, __last, __comp);
+#endif
+}
+
+template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
+std::pair<_ForwardIterator, _ForwardIterator> __pattern_minmax_element(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept {
+  return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{});
+}
+
+template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
+std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _Compare __comp) {
+  if (__first == __last)
+    return std::make_pair(__first, __first);
+
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result;
+
+    return __par_backend::__parallel_reduce(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first + 1,
+        __last,
+        std::make_pair(__first, __first),
+        [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result {
+          const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{});
+          return std::make_pair(
+              __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
+              __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp)));
+        },
+        [=](_Result __p1, _Result __p2) -> _Result {
+          return std::make_pair(__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp),
+                                __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp)));
+        });
+  });
+}
+
+//------------------------------------------------------------------------
+// mismatch
+//------------------------------------------------------------------------
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+std::pair<_ForwardIterator1, _ForwardIterator2> __mismatch_serial(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _BinaryPredicate __pred) {
+  return std::mismatch(__first1, __last1, __first2, __last2, __pred);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Predicate __pred,
+    /* __is_vector = */ std::false_type) noexcept {
+  return __mismatch_serial(__first1, __last1, __first2, __last2, __pred);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate>
+std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _Predicate __pred,
+    /* __is_vector = */ std::true_type) noexcept {
+  auto __n = std::min(__last1 - __first1, __last2 - __first2);
+  return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred));
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Predicate __pred) noexcept {
+  return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Predicate>
+std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _Predicate __pred) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  return __internal::__except_handler([&]() {
+    auto __n      = std::min(__last1 - __first1, __last2 - __first2);
+    auto __result = __internal::__parallel_find(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __first1 + __n,
+        [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          return __internal::__brick_mismatch(
+                     __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __pred, _IsVector{})
+              .first;
+        },
+        std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
+        /*is_first=*/true);
+    return std::make_pair(__result, __first2 + (__result - __first1));
+  });
+}
+
+//------------------------------------------------------------------------
+// lexicographical_compare
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __brick_lexicographical_compare(
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Compare __comp,
+    /* __is_vector = */ std::false_type) noexcept {
+  return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare>
+bool __brick_lexicographical_compare(
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _Compare __comp,
+    /* __is_vector = */ std::true_type) noexcept {
+  if (__first2 == __last2) { // if second sequence is empty
+    return false;
+  } else if (__first1 == __last1) { // if first sequence is empty
+    return true;
+  } else {
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2;
+    --__last1;
+    --__last2;
+    auto __n = std::min(__last1 - __first1, __last2 - __first2);
+    std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first(
+        __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable {
+          return __comp(__x, __y) || __comp(__y, __x);
+        });
+
+    if (__result.first == __last1 && __result.second != __last2) { // if first sequence shorter than second
+      return !__comp(*__result.second, *__result.first);
+    } else { // if second sequence shorter than first or both have the same number of elements
+      return __comp(*__result.first, *__result.second);
+    }
+  }
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+bool __pattern_lexicographical_compare(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Compare __comp) noexcept {
+  return __internal::__brick_lexicographical_compare(
+      __first1, __last1, __first2, __last2, __comp, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _Compare>
+bool __pattern_lexicographical_compare(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first1,
+    _RandomAccessIterator1 __last1,
+    _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2,
+    _Compare __comp) noexcept {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  if (__first2 == __last2) { // if second sequence is empty
+    return false;
+  } else if (__first1 == __last1) { // if first sequence is empty
+    return true;
+  } else {
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2;
+    --__last1;
+    --__last2;
+    auto __n      = std::min(__last1 - __first1, __last2 - __first2);
+    auto __result = __internal::__parallel_find(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __first1,
+        __first1 + __n,
+        [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
+          return __internal::__brick_mismatch(
+                     __i,
+                     __j,
+                     __first2 + (__i - __first1),
+                     __first2 + (__j - __first1),
+                     [&__comp](const _RefType1 __x, const _RefType2 __y) {
+                       return !__comp(__x, __y) && !__comp(__y, __x);
+                     },
+                     _IsVector{})
+              .first;
+        },
+        std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
+        /*is_first=*/true);
+
+    if (__result == __last1 && __first2 + (__result - __first1) != __last2) { // if first sequence shorter than second
+      return !__comp(*(__first2 + (__result - __first1)), *__result);
+    } else { // if second sequence shorter than first or both have the same number of elements
+      return __comp(*__result, *(__first2 + (__result - __first1)));
+    }
+  }
+}
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif /* _PSTL_ALGORITHM_IMPL_H */
lib/libcxx/include/__pstl/internal/execution_defs.h
@@ -0,0 +1,76 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_EXECUTION_POLICY_DEFS_H
+#define _PSTL_EXECUTION_POLICY_DEFS_H
+
+#include <__config>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+namespace __pstl {
+namespace execution {
+inline namespace v1 {
+
+// 2.4, Sequential execution policy
+class sequenced_policy {};
+
+// 2.5, Parallel execution policy
+class parallel_policy {};
+
+// 2.6, Parallel+Vector execution policy
+class parallel_unsequenced_policy {};
+
+class unsequenced_policy {};
+
+// 2.8, Execution policy objects
+constexpr sequenced_policy seq{};
+constexpr parallel_policy par{};
+constexpr parallel_unsequenced_policy par_unseq{};
+constexpr unsequenced_policy unseq{};
+
+// 2.3, Execution policy type trait
+template <class>
+struct is_execution_policy : std::false_type {};
+
+template <>
+struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type {};
+template <>
+struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type {};
+template <>
+struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type {};
+template <>
+struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type {};
+
+template <class _Tp>
+constexpr bool is_execution_policy_v = __pstl::execution::is_execution_policy<_Tp>::value;
+} // namespace v1
+} // namespace execution
+
+namespace __internal {
+template <class _ExecPolicy, class _Tp>
+using __enable_if_execution_policy =
+    typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<_ExecPolicy>::type>::value,
+                            _Tp>::type;
+
+template <class _IsVector>
+struct __serial_tag;
+template <class _IsVector>
+struct __parallel_tag;
+
+} // namespace __internal
+
+} // namespace __pstl
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif /* _PSTL_EXECUTION_POLICY_DEFS_H */
lib/libcxx/include/__pstl/internal/execution_impl.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_EXECUTION_IMPL_H
+#define _PSTL_EXECUTION_IMPL_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_base_of.h>
+
+#include <__pstl/internal/execution_defs.h>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+namespace __pstl {
+namespace __internal {
+
+template <typename _IteratorTag, typename... _IteratorTypes>
+using __are_iterators_of = std::conjunction<
+    std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
+
+template <typename... _IteratorTypes>
+using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
+
+struct __serial_backend_tag {};
+struct __tbb_backend_tag {};
+struct __openmp_backend_tag {};
+
+#  if defined(_PSTL_PAR_BACKEND_TBB)
+using __par_backend_tag = __tbb_backend_tag;
+#  elif defined(_PSTL_PAR_BACKEND_OPENMP)
+using __par_backend_tag = __openmp_backend_tag;
+#  elif defined(_PSTL_PAR_BACKEND_SERIAL)
+using __par_backend_tag = __serial_backend_tag;
+#  else
+#    error "A parallel backend must be specified";
+#  endif
+
+template <class _IsVector>
+struct __serial_tag {
+  using __is_vector = _IsVector;
+};
+
+template <class _IsVector>
+struct __parallel_tag {
+  using __is_vector = _IsVector;
+  // backend tag can be change depending on
+  // TBB availability in the environment
+  using __backend_tag = __par_backend_tag;
+};
+
+template <class _IsVector, class... _IteratorTypes>
+using __tag_type =
+    typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
+                              __parallel_tag<_IsVector>,
+                              __serial_tag<_IsVector>>::type;
+
+template <class... _IteratorTypes>
+_LIBCPP_HIDE_FROM_ABI __serial_tag</*_IsVector = */ std::false_type>
+__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) {
+  return {};
+}
+
+template <class... _IteratorTypes>
+_LIBCPP_HIDE_FROM_ABI __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
+__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) {
+  return {};
+}
+
+template <class... _IteratorTypes>
+_LIBCPP_HIDE_FROM_ABI __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
+__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) {
+  return {};
+}
+
+template <class... _IteratorTypes>
+_LIBCPP_HIDE_FROM_ABI __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
+__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) {
+  return {};
+}
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif /* _PSTL_EXECUTION_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_algorithm_defs.h
@@ -0,0 +1,655 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_ALGORITHM_DEFS_H
+#define _PSTL_GLUE_ALGORITHM_DEFS_H
+
+#include <__config>
+#include <functional>
+#include <iterator>
+
+#include "execution_defs.h"
+
+namespace std {
+
+// [alg.find.end]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_end(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first,
+         _ForwardIterator1 __last,
+         _ForwardIterator2 __s_first,
+         _ForwardIterator2 __s_last,
+         _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_end(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first,
+         _ForwardIterator1 __last,
+         _ForwardIterator2 __s_first,
+         _ForwardIterator2 __s_last);
+
+// [alg.find_first_of]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_first_of(_ExecutionPolicy&& __exec,
+              _ForwardIterator1 __first,
+              _ForwardIterator1 __last,
+              _ForwardIterator2 __s_first,
+              _ForwardIterator2 __s_last);
+
+// [alg.adjacent_find]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred);
+
+// [alg.count]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
+                                                 typename iterator_traits<_ForwardIterator>::difference_type>
+count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
+                                                 typename iterator_traits<_ForwardIterator>::difference_type>
+count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred);
+
+// [alg.search]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+search(_ExecutionPolicy&& __exec,
+       _ForwardIterator1 __first,
+       _ForwardIterator1 __last,
+       _ForwardIterator2 __s_first,
+       _ForwardIterator2 __s_last,
+       _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+search(_ExecutionPolicy&& __exec,
+       _ForwardIterator1 __first,
+       _ForwardIterator1 __last,
+       _ForwardIterator2 __s_first,
+       _ForwardIterator2 __s_last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+search_n(_ExecutionPolicy&& __exec,
+         _ForwardIterator __first,
+         _ForwardIterator __last,
+         _Size __count,
+         const _Tp& __value,
+         _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n(
+    _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value);
+
+// [alg.copy]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+copy_if(_ExecutionPolicy&& __exec,
+        _ForwardIterator1 __first,
+        _ForwardIterator1 __last,
+        _ForwardIterator2 result,
+        _Predicate __pred);
+
+// [alg.swap]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
+
+// [alg.replace]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+replace_if(_ExecutionPolicy&& __exec,
+           _ForwardIterator __first,
+           _ForwardIterator __last,
+           _UnaryPredicate __pred,
+           const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+replace(_ExecutionPolicy&& __exec,
+        _ForwardIterator __first,
+        _ForwardIterator __last,
+        const _Tp& __old_value,
+        const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy_if(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _UnaryPredicate __pred,
+    const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    const _Tp& __old_value,
+    const _Tp& __new_value);
+
+// [alg.generate]
+template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size count, _Generator __g);
+
+// [alg.remove]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Predicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+remove_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result,
+            const _Tp& __value);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
+
+// [alg.unique]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+unique_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result,
+            _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result);
+
+// [alg.reverse]
+
+template <class _ExecutionPolicy, class _BidirectionalIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last);
+
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+reverse_copy(_ExecutionPolicy&& __exec,
+             _BidirectionalIterator __first,
+             _BidirectionalIterator __last,
+             _ForwardIterator __d_first);
+
+// [alg.rotate]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+rotate_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __middle,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result);
+
+// [alg.partitions]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition(
+    _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred);
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+partition_copy(_ExecutionPolicy&& __exec,
+               _ForwardIterator __first,
+               _ForwardIterator __last,
+               _ForwardIterator1 __out_true,
+               _ForwardIterator2 __out_false,
+               _UnaryPredicate __pred);
+
+// [alg.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
+
+// [stable.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
+
+// [mismatch]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2,
+         _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _BinaryPredicate __pred);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
+
+// [alg.equal]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _BinaryPredicate __p);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2,
+      _BinaryPredicate __p);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2);
+
+// [alg.move]
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first);
+
+// [partial.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+partial_sort(_ExecutionPolicy&& __exec,
+             _RandomAccessIterator __first,
+             _RandomAccessIterator __middle,
+             _RandomAccessIterator __last,
+             _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+partial_sort(_ExecutionPolicy&& __exec,
+             _RandomAccessIterator __first,
+             _RandomAccessIterator __middle,
+             _RandomAccessIterator __last);
+
+// [partial.sort.copy]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _RandomAccessIterator __d_first,
+    _RandomAccessIterator __d_last,
+    _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _RandomAccessIterator __d_first,
+    _RandomAccessIterator __d_last);
+
+// [is.sorted]
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+// [alg.nth.element]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+nth_element(_ExecutionPolicy&& __exec,
+            _RandomAccessIterator __first,
+            _RandomAccessIterator __nth,
+            _RandomAccessIterator __last,
+            _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+nth_element(_ExecutionPolicy&& __exec,
+            _RandomAccessIterator __first,
+            _RandomAccessIterator __nth,
+            _RandomAccessIterator __last);
+
+// [alg.merge]
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+merge(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2,
+      _ForwardIterator __d_first,
+      _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+merge(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2,
+      _ForwardIterator __d_first);
+
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+inplace_merge(_ExecutionPolicy&& __exec,
+              _BidirectionalIterator __first,
+              _BidirectionalIterator __middle,
+              _BidirectionalIterator __last,
+              _Compare __comp);
+
+template <class _ExecutionPolicy, class _BidirectionalIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+inplace_merge(_ExecutionPolicy&& __exec,
+              _BidirectionalIterator __first,
+              _BidirectionalIterator __middle,
+              _BidirectionalIterator __last);
+
+// [includes]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+includes(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2,
+         _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+includes(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2);
+
+// [set.union]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+set_union(_ExecutionPolicy&& __exec,
+          _ForwardIterator1 __first1,
+          _ForwardIterator1 __last1,
+          _ForwardIterator2 __first2,
+          _ForwardIterator2 __last2,
+          _ForwardIterator __result,
+          _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+set_union(_ExecutionPolicy&& __exec,
+          _ForwardIterator1 __first1,
+          _ForwardIterator1 __last1,
+          _ForwardIterator2 __first2,
+          _ForwardIterator2 __last2,
+          _ForwardIterator __result);
+
+// [set.intersection]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result,
+    _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result);
+
+// [set.difference]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result,
+    _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result);
+
+// [set.symmetric.difference]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator result,
+    _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result);
+
+// [is.heap]
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
+is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
+is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
+
+// [alg.min.max]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
+minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
+minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+// [alg.lex.comparison]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Compare __comp);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2);
+
+} // namespace std
+
+#endif /* _PSTL_GLUE_ALGORITHM_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_algorithm_impl.h
@@ -0,0 +1,972 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_ALGORITHM_IMPL_H
+#define _PSTL_GLUE_ALGORITHM_IMPL_H
+
+#include <__config>
+#include <functional>
+
+#include "algorithm_fwd.h"
+#include "execution_defs.h"
+#include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */
+#include "utils.h"
+
+#include "execution_impl.h"
+
+namespace std {
+
+// [alg.find.end]
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_end(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first,
+         _ForwardIterator1 __last,
+         _ForwardIterator2 __s_first,
+         _ForwardIterator2 __s_last,
+         _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
+
+  return __pstl::__internal::__pattern_find_end(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_end(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first,
+         _ForwardIterator1 __last,
+         _ForwardIterator2 __s_first,
+         _ForwardIterator2 __s_last) {
+  return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
+}
+
+// [alg.find_first_of]
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __s_first,
+    _ForwardIterator2 __s_last,
+    _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
+
+  return __pstl::__internal::__pattern_find_first_of(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+find_first_of(_ExecutionPolicy&& __exec,
+              _ForwardIterator1 __first,
+              _ForwardIterator1 __last,
+              _ForwardIterator2 __s_first,
+              _ForwardIterator2 __s_last) {
+  return std::find_first_of(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
+}
+
+// [alg.adjacent_find]
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  return __pstl::__internal::__pattern_adjacent_find(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      std::equal_to<_ValueType>(),
+      /*first_semantic*/ false);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_adjacent_find(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, /*first_semantic*/ false);
+}
+
+// [alg.count]
+
+// Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce
+// so that we do not have to include <numeric>.
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
+                                                 typename iterator_traits<_ForwardIterator>::difference_type>
+count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  return __pstl::__internal::__pattern_count(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](const _ValueType& __x) {
+        return __value == __x;
+      });
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
+                                                 typename iterator_traits<_ForwardIterator>::difference_type>
+count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_count(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+// [alg.search]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+search(_ExecutionPolicy&& __exec,
+       _ForwardIterator1 __first,
+       _ForwardIterator1 __last,
+       _ForwardIterator2 __s_first,
+       _ForwardIterator2 __s_last,
+       _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
+
+  return __pstl::__internal::__pattern_search(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
+search(_ExecutionPolicy&& __exec,
+       _ForwardIterator1 __first,
+       _ForwardIterator1 __last,
+       _ForwardIterator2 __s_first,
+       _ForwardIterator2 __s_last) {
+  return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+search_n(_ExecutionPolicy&& __exec,
+         _ForwardIterator __first,
+         _ForwardIterator __last,
+         _Size __count,
+         const _Tp& __value,
+         _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_search_n(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n(
+    _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
+  return std::search_n(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __count,
+      __value,
+      std::equal_to<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// [alg.copy]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+copy_if(_ExecutionPolicy&& __exec,
+        _ForwardIterator1 __first,
+        _ForwardIterator1 __last,
+        _ForwardIterator2 __result,
+        _Predicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  return __pstl::__internal::__pattern_copy_if(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred);
+}
+
+// [alg.swap]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+  typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
+  typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_walk2(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first1,
+      __last1,
+      __first2,
+      [](_ReferenceType1 __x, _ReferenceType2 __y) {
+        using std::swap;
+        swap(__x, __y);
+      });
+}
+
+// [alg.generate]
+template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __g);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) {
+  if (__count <= 0)
+    return __first;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_generate_n(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __count, __g);
+}
+
+// [alg.remove]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Predicate __pred) {
+  return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred));
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+remove_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result,
+            const _Tp& __value) {
+  return std::copy_if(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __pstl::__internal::__not_equal_value<_Tp>(__value));
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_remove_if(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  return std::remove_if(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__equal_value<_Tp>(__value));
+}
+
+// [alg.unique]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_unique(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+unique_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result,
+            _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  return __pstl::__internal::__pattern_unique_copy(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> unique_copy(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) {
+  return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>());
+}
+
+// [alg.reverse]
+
+template <class _ExecutionPolicy, class _BidirectionalIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last);
+}
+
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+reverse_copy(_ExecutionPolicy&& __exec,
+             _BidirectionalIterator __first,
+             _BidirectionalIterator __last,
+             _ForwardIterator __d_first) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
+
+  return __pstl::__internal::__pattern_reverse_copy(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first);
+}
+
+// [alg.rotate]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_rotate(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+rotate_copy(_ExecutionPolicy&& __exec,
+            _ForwardIterator1 __first,
+            _ForwardIterator1 __middle,
+            _ForwardIterator1 __last,
+            _ForwardIterator2 __result) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  return __pstl::__internal::__pattern_rotate_copy(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result);
+}
+
+// [alg.partitions]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_is_partitioned(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_partition(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition(
+    _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_stable_partition(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _UnaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+partition_copy(_ExecutionPolicy&& __exec,
+               _ForwardIterator __first,
+               _ForwardIterator __last,
+               _ForwardIterator1 __out_true,
+               _ForwardIterator2 __out_false,
+               _UnaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false);
+
+  return __pstl::__internal::__pattern_partition_copy(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred);
+}
+
+// [alg.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  return __pstl::__internal::__pattern_sort(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __comp,
+      typename std::is_move_constructible<_InputType>::type());
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+// [stable.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_stable_sort(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  std::stable_sort(__exec, __first, __last, std::less<_InputType>());
+}
+
+// [mismatch]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2,
+         _BinaryPredicate __pred) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_mismatch(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _BinaryPredicate __pred) {
+  return std::mismatch(
+      __exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)), __pred);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2) {
+  return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
+mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+  // TODO: to get rid of "distance"
+  return std::mismatch(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first1,
+      __last1,
+      __first2,
+      std::next(__first2, std::distance(__first1, __last1)));
+}
+
+// [alg.equal]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _BinaryPredicate __p) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_equal(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+  return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2,
+      _BinaryPredicate __p) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_equal(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+equal(_ExecutionPolicy&& __exec,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _ForwardIterator2 __last2) {
+  return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>());
+}
+
+// [alg.move]
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
+move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__pattern_walk2_brick(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __d_first,
+      [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
+        return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{});
+      });
+}
+
+// [partial.sort]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+partial_sort(_ExecutionPolicy&& __exec,
+             _RandomAccessIterator __first,
+             _RandomAccessIterator __middle,
+             _RandomAccessIterator __last,
+             _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__pattern_partial_sort(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+partial_sort(_ExecutionPolicy&& __exec,
+             _RandomAccessIterator __first,
+             _RandomAccessIterator __middle,
+             _RandomAccessIterator __last) {
+  typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>());
+}
+
+// [partial.sort.copy]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _RandomAccessIterator __d_first,
+    _RandomAccessIterator __d_last,
+    _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
+
+  return __pstl::__internal::__pattern_partial_sort_copy(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _RandomAccessIterator __d_first,
+    _RandomAccessIterator __d_last) {
+  return std::partial_sort_copy(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, std::less<>());
+}
+
+// [is.sorted]
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
+  auto __dispatch_tag          = __pstl::__internal::__select_backend(__exec, __first);
+  const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __pstl::__internal::__reorder_pred<_Compare>(__comp),
+      /*first_semantic*/ false);
+  return __res == __last ? __last : std::next(__res);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
+  return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_adjacent_find(
+             __dispatch_tag,
+             std::forward<_ExecutionPolicy>(__exec),
+             __first,
+             __last,
+             __pstl::__internal::__reorder_pred<_Compare>(__comp),
+             /*or_semantic*/ true) == __last;
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
+  return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+// [alg.merge]
+template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+inplace_merge(_ExecutionPolicy&& __exec,
+              _BidirectionalIterator __first,
+              _BidirectionalIterator __middle,
+              _BidirectionalIterator __last,
+              _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__pattern_inplace_merge(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _BidirectionalIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+inplace_merge(_ExecutionPolicy&& __exec,
+              _BidirectionalIterator __first,
+              _BidirectionalIterator __middle,
+              _BidirectionalIterator __last) {
+  typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType;
+  std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>());
+}
+
+// [includes]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+includes(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2,
+         _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_includes(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+includes(_ExecutionPolicy&& __exec,
+         _ForwardIterator1 __first1,
+         _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2,
+         _ForwardIterator2 __last2) {
+  return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>());
+}
+
+// [set.union]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+set_union(_ExecutionPolicy&& __exec,
+          _ForwardIterator1 __first1,
+          _ForwardIterator1 __last1,
+          _ForwardIterator2 __first2,
+          _ForwardIterator2 __last2,
+          _ForwardIterator __result,
+          _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
+
+  return __pstl::__internal::__pattern_set_union(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+set_union(_ExecutionPolicy&& __exec,
+          _ForwardIterator1 __first1,
+          _ForwardIterator1 __last1,
+          _ForwardIterator2 __first2,
+          _ForwardIterator2 __last2,
+          _ForwardIterator __result) {
+  return std::set_union(
+      std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
+}
+
+// [set.intersection]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result,
+    _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
+
+  return __pstl::__internal::__pattern_set_intersection(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result) {
+  return std::set_intersection(
+      std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
+}
+
+// [set.difference]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result,
+    _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
+
+  return __pstl::__internal::__pattern_set_difference(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result) {
+  return std::set_difference(
+      std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
+}
+
+// [set.symmetric.difference]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _ForwardIterator,
+          class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result,
+    _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
+
+  return __pstl::__internal::__pattern_set_symmetric_difference(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _ForwardIterator __result) {
+  return std::set_symmetric_difference(
+      std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
+}
+
+// [is.heap]
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
+is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__pattern_is_heap_until(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
+is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+  return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last;
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
+is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+// [alg.min.max]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_min_element(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
+  return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
+  return min_element(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp));
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
+  return std::min_element(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __pstl::__internal::__reorder_pred<std::less<_InputType>>(std::less<_InputType>()));
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
+minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+  return __pstl::__internal::__pattern_minmax_element(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
+minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>());
+}
+
+// [alg.nth.element]
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+nth_element(_ExecutionPolicy&& __exec,
+            _RandomAccessIterator __first,
+            _RandomAccessIterator __nth,
+            _RandomAccessIterator __last,
+            _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__pattern_nth_element(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp);
+}
+
+template <class _ExecutionPolicy, class _RandomAccessIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+nth_element(_ExecutionPolicy&& __exec,
+            _RandomAccessIterator __first,
+            _RandomAccessIterator __nth,
+            _RandomAccessIterator __last) {
+  typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
+  std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>());
+}
+
+// [alg.lex.comparison]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2,
+    _Compare __comp) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
+
+  return __pstl::__internal::__pattern_lexicographical_compare(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first1,
+    _ForwardIterator1 __last1,
+    _ForwardIterator2 __first2,
+    _ForwardIterator2 __last2) {
+  return std::lexicographical_compare(
+      std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>());
+}
+
+} // namespace std
+
+#endif /* _PSTL_GLUE_ALGORITHM_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_memory_defs.h
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_MEMORY_DEFS_H
+#define _PSTL_GLUE_MEMORY_DEFS_H
+
+#include <__config>
+
+#include "execution_defs.h"
+
+namespace std {
+
+// [uninitialized.copy]
+
+template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
+
+template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
+
+// [uninitialized.move]
+
+template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
+
+template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
+
+// [uninitialized.fill]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value);
+
+// [specialized.destroy]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
+
+// [uninitialized.construct.default]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
+
+// [uninitialized.construct.value]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
+
+} //  namespace std
+
+#endif /* _PSTL_GLUE_MEMORY_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_memory_impl.h
@@ -0,0 +1,379 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_MEMORY_IMPL_H
+#define _PSTL_GLUE_MEMORY_IMPL_H
+
+#include <__config>
+
+#include "algorithm_fwd.h"
+#include "execution_defs.h"
+#include "utils.h"
+
+#include "execution_impl.h"
+
+namespace std {
+
+// [uninitialized.copy]
+
+template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_copy(
+    _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) {
+  typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
+  typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::integral_constant < bool,
+      std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_brick(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            __result,
+            [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
+              return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk2(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            __result,
+            [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); });
+      });
+}
+
+template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) {
+  typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
+  typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::integral_constant < bool,
+      std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_brick_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            __result,
+            [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
+              return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            __result,
+            [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); });
+      });
+}
+
+// [uninitialized.move]
+
+template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_move(
+    _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) {
+  typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
+  typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::integral_constant < bool,
+      std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_brick(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            __result,
+            [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
+              return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk2(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            __result,
+            [](_ReferenceType1 __val1, _ReferenceType2 __val2) {
+              ::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
+            });
+      });
+}
+
+template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) {
+  typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
+  typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::integral_constant < bool,
+      std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_brick_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            __result,
+            [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
+              return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk2_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            __result,
+            [](_ReferenceType1 __val1, _ReferenceType2 __val2) {
+              ::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
+            });
+      });
+}
+
+// [uninitialized.fill]
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  __pstl::__internal::__invoke_if_else(
+      std::is_arithmetic<_ValueType>(),
+      [&]() {
+        __pstl::__internal::__pattern_walk_brick(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            [&__value](_ForwardIterator __begin, _ForwardIterator __end) {
+              __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{});
+            });
+      },
+      [&]() {
+        __pstl::__internal::__pattern_walk1(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](_ReferenceType __val) {
+              ::new (std::addressof(__val)) _ValueType(__value);
+            });
+      });
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::is_arithmetic<_ValueType>(),
+      [&]() {
+        return __pstl::__internal::__pattern_walk_brick_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            [&__value](_ForwardIterator __begin, _Size __count) {
+              return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk1_n(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [&__value](_ReferenceType __val) {
+              ::new (std::addressof(__val)) _ValueType(__value);
+            });
+      });
+}
+
+// [specialized.destroy]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
+    __pstl::__internal::__pattern_walk1(
+        __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
+          __val.~_ValueType();
+        });
+  });
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__invoke_if_else(
+      std::is_trivially_destructible<_ValueType>(),
+      [&]() { return std::next(__first, __n); },
+      [&]() {
+        return __pstl::__internal::__pattern_walk1_n(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
+              __val.~_ValueType();
+            });
+      });
+}
+
+// [uninitialized.construct.default]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
+    __pstl::__internal::__pattern_walk1(
+        __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
+          ::new (std::addressof(__val)) _ValueType;
+        });
+  });
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  return __pstl::__internal::__invoke_if_else(
+      std::is_trivial<_ValueType>(),
+      [&]() { return std::next(__first, __n); },
+      [&]() {
+        return __pstl::__internal::__pattern_walk1_n(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
+              ::new (std::addressof(__val)) _ValueType;
+            });
+      });
+}
+
+// [uninitialized.construct.value]
+
+template <class _ExecutionPolicy, class _ForwardIterator>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
+uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  __pstl::__internal::__invoke_if_else(
+      std::is_trivial<_ValueType>(),
+      [&]() {
+        __pstl::__internal::__pattern_walk_brick(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __last,
+            [](_ForwardIterator __begin, _ForwardIterator __end) {
+              __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{});
+            });
+      },
+      [&]() {
+        __pstl::__internal::__pattern_walk1(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
+              ::new (std::addressof(__val)) _ValueType();
+            });
+      });
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
+uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
+  typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
+
+  using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
+
+  return __pstl::__internal::__invoke_if_else(
+      std::is_trivial<_ValueType>(),
+      [&]() {
+        return __pstl::__internal::__pattern_walk_brick_n(
+            __dispatch_tag,
+            std::forward<_ExecutionPolicy>(__exec),
+            __first,
+            __n,
+            [](_ForwardIterator __begin, _Size __count) {
+              return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{});
+            });
+      },
+      [&]() {
+        return __pstl::__internal::__pattern_walk1_n(
+            __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
+              ::new (std::addressof(__val)) _ValueType();
+            });
+      });
+}
+
+} // namespace std
+
+#endif /* _PSTL_GLUE_MEMORY_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_numeric_defs.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_NUMERIC_DEFS_H
+#define _PSTL_GLUE_NUMERIC_DEFS_H
+
+#include <__config>
+#include <iterator>
+
+#include "execution_defs.h"
+
+namespace std {
+// [exclusive.scan]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init,
+    _BinaryOperation __binary_op);
+
+// [inclusive.scan]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _Tp __init);
+
+// [transform.exclusive.scan]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _Tp,
+          class _BinaryOperation,
+          class _UnaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op);
+
+// [transform.inclusive.scan]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _BinaryOperation,
+          class _UnaryOperation,
+          class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op,
+    _Tp __init);
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _UnaryOperation,
+          class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op);
+
+// [adjacent.difference]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __d_first,
+    _BinaryOperation op);
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first);
+
+} // namespace std
+
+#endif /* _PSTL_GLUE_NUMERIC_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_numeric_impl.h
@@ -0,0 +1,223 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_GLUE_NUMERIC_IMPL_H
+#define _PSTL_GLUE_NUMERIC_IMPL_H
+
+#include <__config>
+#include <functional>
+
+#include "execution_impl.h"
+#include "numeric_fwd.h"
+#include "utils.h"
+
+namespace std {
+
+// [exclusive.scan]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using namespace __pstl;
+  return __internal::__pattern_transform_scan(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __pstl::__internal::__no_op(),
+      __init,
+      std::plus<_Tp>(),
+      /*inclusive=*/std::false_type());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init,
+    _BinaryOperation __binary_op) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  using namespace __pstl;
+  return __internal::__pattern_transform_scan(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __pstl::__internal::__no_op(),
+      __init,
+      __binary_op,
+      /*inclusive=*/std::false_type());
+}
+
+// [inclusive.scan]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
+  return transform_inclusive_scan(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      std::plus<_InputType>(),
+      __pstl::__internal::__no_op());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op) {
+  return transform_inclusive_scan(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, __pstl::__internal::__no_op());
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _Tp __init) {
+  return transform_inclusive_scan(
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __binary_op,
+      __pstl::__internal::__no_op(),
+      __init);
+}
+
+// [transform.exclusive.scan]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _Tp,
+          class _BinaryOperation,
+          class _UnaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  return __pstl::__internal::__pattern_transform_scan(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __unary_op,
+      __init,
+      __binary_op,
+      /*inclusive=*/std::false_type());
+}
+
+// [transform.inclusive.scan]
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _BinaryOperation,
+          class _UnaryOperation,
+          class _Tp>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op,
+    _Tp __init) {
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
+
+  return __pstl::__internal::__pattern_transform_scan(
+      __dispatch_tag,
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last,
+      __result,
+      __unary_op,
+      __init,
+      __binary_op,
+      /*inclusive=*/std::true_type());
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator1,
+          class _ForwardIterator2,
+          class _UnaryOperation,
+          class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __result,
+    _BinaryOperation __binary_op,
+    _UnaryOperation __unary_op) {
+  if (__first != __last) {
+    auto __tmp = __unary_op(*__first);
+    *__result  = __tmp;
+    return transform_inclusive_scan(
+        std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, __binary_op, __unary_op, __tmp);
+  } else {
+    return __result;
+  }
+}
+
+// [adjacent.difference]
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
+    _ExecutionPolicy&& __exec,
+    _ForwardIterator1 __first,
+    _ForwardIterator1 __last,
+    _ForwardIterator2 __d_first,
+    _BinaryOperation __op) {
+  if (__first == __last)
+    return __d_first;
+
+  auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
+
+  return __pstl::__internal::__pattern_adjacent_difference(
+      __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op);
+}
+
+template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
+__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
+    _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType;
+  return adjacent_difference(
+      std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, std::minus<_ValueType>());
+}
+
+} // namespace std
+
+#endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */
lib/libcxx/include/__pstl/internal/memory_impl.h
@@ -0,0 +1,106 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_MEMORY_IMPL_H
+#define _PSTL_MEMORY_IMPL_H
+
+#include <__config>
+#include <iterator>
+
+#include "unseq_backend_simd.h"
+
+namespace __pstl {
+namespace __internal {
+
+//------------------------------------------------------------------------
+// uninitialized_move
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _OutputIterator>
+_OutputIterator __brick_uninitialized_move(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    /*vector=*/std::false_type) noexcept {
+  using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
+  for (; __first != __last; ++__first, ++__result) {
+    ::new (std::addressof(*__result)) _ValueType(std::move(*__first));
+  }
+  return __result;
+}
+
+template <typename _RandomAccessIterator, typename _OutputIterator>
+_OutputIterator __brick_uninitialized_move(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    /*vector=*/std::true_type) noexcept {
+  using __ValueType     = typename std::iterator_traits<_OutputIterator>::value_type;
+  using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
+  using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
+
+  return __unseq_backend::__simd_walk_2(
+      __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) {
+        ::new (std::addressof(__y)) __ValueType(std::move(__x));
+      });
+}
+
+template <typename _Iterator>
+void __brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept {
+  using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
+
+  for (; __first != __last; ++__first)
+    __first->~_ValueType();
+}
+
+template <typename _RandomAccessIterator>
+void __brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept {
+  using _ValueType     = typename std::iterator_traits<_RandomAccessIterator>::value_type;
+  using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference;
+
+  __unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); });
+}
+
+//------------------------------------------------------------------------
+// uninitialized copy
+//------------------------------------------------------------------------
+
+template <typename _ForwardIterator, typename _OutputIterator>
+_OutputIterator __brick_uninitialized_copy(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    /*vector=*/std::false_type) noexcept {
+  using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
+  for (; __first != __last; ++__first, ++__result) {
+    ::new (std::addressof(*__result)) _ValueType(*__first);
+  }
+  return __result;
+}
+
+template <typename _RandomAccessIterator, typename _OutputIterator>
+_OutputIterator __brick_uninitialized_copy(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    /*vector=*/std::true_type) noexcept {
+  using __ValueType     = typename std::iterator_traits<_OutputIterator>::value_type;
+  using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
+  using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
+
+  return __unseq_backend::__simd_walk_2(
+      __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) {
+        ::new (std::addressof(__y)) __ValueType(__x);
+      });
+}
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif /* _PSTL_MEMORY_IMPL_H */
lib/libcxx/include/__pstl/internal/numeric_fwd.h
@@ -0,0 +1,143 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_NUMERIC_FWD_H
+#define _PSTL_NUMERIC_FWD_H
+
+#include <__config>
+#include <type_traits>
+#include <utility>
+
+namespace __pstl {
+namespace __internal {
+
+//------------------------------------------------------------------------
+// transform_exclusive_scan
+//
+// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
+std::pair<_OutputIterator, _Tp> __brick_transform_scan(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    _UnaryOperation,
+    _Tp,
+    _BinaryOperation,
+    /*Inclusive*/ std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
+std::pair<_OutputIterator, _Tp> __brick_transform_scan(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _UnaryOperation,
+    _Tp,
+    _BinaryOperation,
+    /*Inclusive*/ std::true_type) noexcept;
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+_OutputIterator __pattern_transform_scan(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    _UnaryOperation,
+    _Tp,
+    _BinaryOperation,
+    _Inclusive) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _UnaryOperation,
+    _Tp,
+    _BinaryOperation,
+    _Inclusive);
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _UnaryOperation,
+    _Tp,
+    _BinaryOperation,
+    _Inclusive);
+
+//------------------------------------------------------------------------
+// adjacent_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
+_OutputIterator __brick_adjacent_difference(
+    _ForwardIterator,
+    _ForwardIterator,
+    _OutputIterator,
+    _BinaryOperation,
+    /*is_vector*/ std::false_type) noexcept;
+
+template <class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation>
+_OutputIterator __brick_adjacent_difference(
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _BinaryOperation,
+    /*is_vector*/ std::true_type) noexcept;
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
+_OutputIterator __pattern_adjacent_difference(
+    _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation) noexcept;
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _BinaryOperation>
+_OutputIterator __pattern_adjacent_difference(
+    __parallel_tag<_IsVector>,
+    _ExecutionPolicy&&,
+    _RandomAccessIterator,
+    _RandomAccessIterator,
+    _OutputIterator,
+    _BinaryOperation);
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif /* _PSTL_NUMERIC_FWD_H */
lib/libcxx/include/__pstl/internal/numeric_impl.h
@@ -0,0 +1,364 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_NUMERIC_IMPL_H
+#define _PSTL_NUMERIC_IMPL_H
+
+#include <__assert>
+#include <__config>
+#include <iterator>
+#include <type_traits>
+#include <numeric>
+
+#include "parallel_backend.h"
+#include "execution_impl.h"
+#include "unseq_backend_simd.h"
+#include "algorithm_fwd.h"
+
+namespace __pstl {
+namespace __internal {
+
+//------------------------------------------------------------------------
+// transform_exclusive_scan
+//
+// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
+//------------------------------------------------------------------------
+
+// Exclusive form
+template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
+std::pair<_OutputIterator, _Tp> __brick_transform_scan(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    /*Inclusive*/ std::false_type,
+    /*is_vector=*/std::false_type) noexcept {
+  for (; __first != __last; ++__first, ++__result) {
+    *__result = __init;
+    __init = __binary_op(__init, __unary_op(*__first));
+  }
+  return std::make_pair(__result, __init);
+}
+
+// Inclusive form
+template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
+std::pair<_OutputIterator, _Tp> __brick_transform_scan(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    /*Inclusive*/ std::true_type,
+    /*is_vector=*/std::false_type) noexcept {
+  for (; __first != __last; ++__first, ++__result) {
+    __init    = __binary_op(__init, __unary_op(*__first));
+    *__result = __init;
+  }
+  return std::make_pair(__result, __init);
+}
+
+// type is arithmetic and binary operation is a user defined operation.
+template <typename _Tp, typename _BinaryOperation>
+using is_arithmetic_udop =
+    std::integral_constant<bool,
+                           std::is_arithmetic<_Tp>::value && !std::is_same<_BinaryOperation, std::plus<_Tp>>::value>;
+
+// [restriction] - T shall be DefaultConstructible.
+// [violation] - default ctor of T shall set the identity value for binary_op.
+template <class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<!is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__brick_transform_scan(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _Inclusive,
+    /*is_vector=*/std::true_type) noexcept {
+#if defined(_PSTL_UDS_PRESENT)
+  return __unseq_backend::__simd_scan(
+      __first, __last - __first, __result, __unary_op, __init, __binary_op, _Inclusive());
+#else
+  // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive()
+  // value
+  return __internal::__brick_transform_scan(
+      __first,
+      __last,
+      __result,
+      __unary_op,
+      __init,
+      __binary_op,
+      _Inclusive(),
+      /*is_vector=*/std::false_type());
+#endif
+}
+
+template <class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__brick_transform_scan(
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _Inclusive,
+    /*is_vector=*/std::true_type) noexcept {
+  return __internal::__brick_transform_scan(
+      __first,
+      __last,
+      __result,
+      __unary_op,
+      __init,
+      __binary_op,
+      _Inclusive(),
+      /*is_vector=*/std::false_type());
+}
+
+template <class _Tag,
+          class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+_OutputIterator __pattern_transform_scan(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _Inclusive) noexcept {
+  return __internal::__brick_transform_scan(
+             __first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), typename _Tag::__is_vector{})
+      .first;
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _Inclusive) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
+
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_transform_scan(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __last - __first,
+        [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); },
+        __init,
+        __binary_op,
+        [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
+          // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a
+          // commutative operation for the guarantee of correct scan.
+          return __internal::__brick_transform_reduce(
+              __first + __i,
+              __first + __j,
+              __init,
+              __binary_op,
+              __unary_op,
+              /*__is_vector*/ std::false_type());
+        },
+        [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
+          return __internal::__brick_transform_scan(
+                     __first + __i,
+                     __first + __j,
+                     __result + __i,
+                     __unary_op,
+                     __init,
+                     __binary_op,
+                     _Inclusive(),
+                     _IsVector{})
+              .second;
+        });
+    return __result + (__last - __first);
+  });
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _OutputIterator,
+          class _UnaryOperation,
+          class _Tp,
+          class _BinaryOperation,
+          class _Inclusive>
+typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator __first,
+    _RandomAccessIterator __last,
+    _OutputIterator __result,
+    _UnaryOperation __unary_op,
+    _Tp __init,
+    _BinaryOperation __binary_op,
+    _Inclusive) {
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
+  _DifferenceType __n = __last - __first;
+
+  if (__n <= 0) {
+    return __result;
+  }
+  return __internal::__except_handler([&]() {
+    __par_backend::__parallel_strict_scan(
+        __backend_tag{},
+        std::forward<_ExecutionPolicy>(__exec),
+        __n,
+        __init,
+        [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) {
+          return __internal::__brick_transform_scan(
+                     __first + __i,
+                     __first + (__i + __len),
+                     __result + __i,
+                     __unary_op,
+                     _Tp{},
+                     __binary_op,
+                     _Inclusive(),
+                     _IsVector{})
+              .second;
+        },
+        __binary_op,
+        [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) {
+          return *(std::transform(__result + __i,
+                                  __result + __i + __len,
+                                  __result + __i,
+                                  [&__initial, &__binary_op](const _Tp& __x) {
+                                    return __binary_op(__initial, __x);
+                                  }) -
+                   1);
+        },
+        [](_Tp) {});
+    return __result + (__last - __first);
+  });
+}
+
+//------------------------------------------------------------------------
+// adjacent_difference
+//------------------------------------------------------------------------
+
+template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
+_OutputIterator __brick_adjacent_difference(
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __d_first,
+    _BinaryOperation __op,
+    /*is_vector*/ std::false_type) noexcept {
+  return std::adjacent_difference(__first, __last, __d_first, __op);
+}
+
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class BinaryOperation>
+_RandomAccessIterator2 __brick_adjacent_difference(
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __d_first,
+    BinaryOperation __op,
+    /*is_vector=*/std::true_type) noexcept {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "Range cannot be empty");
+
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
+  typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
+
+  auto __n   = __last - __first;
+  *__d_first = *__first;
+  return __unseq_backend::__simd_walk_3(
+      __first + 1,
+      __n - 1,
+      __first,
+      __d_first + 1,
+      [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); });
+}
+
+template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
+_OutputIterator __pattern_adjacent_difference(
+    _Tag,
+    _ExecutionPolicy&&,
+    _ForwardIterator __first,
+    _ForwardIterator __last,
+    _OutputIterator __d_first,
+    _BinaryOperation __op) noexcept {
+  return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{});
+}
+
+template <class _IsVector,
+          class _ExecutionPolicy,
+          class _RandomAccessIterator1,
+          class _RandomAccessIterator2,
+          class _BinaryOperation>
+_RandomAccessIterator2 __pattern_adjacent_difference(
+    __parallel_tag<_IsVector> __tag,
+    _ExecutionPolicy&& __exec,
+    _RandomAccessIterator1 __first,
+    _RandomAccessIterator1 __last,
+    _RandomAccessIterator2 __d_first,
+    _BinaryOperation __op) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range cannot be empty");
+  typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
+  typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
+
+  using __backend_tag = typename decltype(__tag)::__backend_tag;
+
+  *__d_first = *__first;
+  __par_backend::__parallel_for(
+      __backend_tag{},
+      std::forward<_ExecutionPolicy>(__exec),
+      __first,
+      __last - 1,
+      [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) {
+        _RandomAccessIterator2 __d_b = __d_first + (__b - __first);
+        __internal::__brick_walk3(
+            __b,
+            __e,
+            __b + 1,
+            __d_b + 1,
+            [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); },
+            _IsVector{});
+      });
+  return __d_first + (__last - __first);
+}
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif /* _PSTL_NUMERIC_IMPL_H */
lib/libcxx/include/__pstl/internal/parallel_backend.h
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_PARALLEL_BACKEND_H
+#define _PSTL_PARALLEL_BACKEND_H
+
+#include <__config>
+
+#if defined(_PSTL_PAR_BACKEND_SERIAL)
+#    include "parallel_backend_serial.h"
+#    if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+namespace __pstl
+{
+namespace __par_backend = __serial_backend;
+} // namespace __pstl
+#    endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+#elif defined(_PSTL_PAR_BACKEND_TBB)
+#    include "parallel_backend_tbb.h"
+namespace __pstl
+{
+namespace __par_backend = __tbb_backend;
+}
+#elif defined(_PSTL_PAR_BACKEND_OPENMP)
+#    include "parallel_backend_omp.h"
+namespace __pstl
+{
+namespace __par_backend = __omp_backend;
+}
+#else
+#  error "No backend set"
+#endif
+
+#endif /* _PSTL_PARALLEL_BACKEND_H */
lib/libcxx/include/__pstl/internal/parallel_backend_omp.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+// -*-===----------------------------------------------------------------------===//
+//
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _PSTL_PARALLEL_BACKEND_OMP_H
+#define _PSTL_PARALLEL_BACKEND_OMP_H
+
+//------------------------------------------------------------------------
+// parallel_invoke
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_invoke.h"
+
+//------------------------------------------------------------------------
+// parallel_for
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_for.h"
+
+//------------------------------------------------------------------------
+// parallel_for_each
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_for_each.h"
+
+//------------------------------------------------------------------------
+// parallel_reduce
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_reduce.h"
+#include "./omp/parallel_transform_reduce.h"
+
+//------------------------------------------------------------------------
+// parallel_scan
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_scan.h"
+#include "./omp/parallel_transform_scan.h"
+
+//------------------------------------------------------------------------
+// parallel_stable_sort
+//------------------------------------------------------------------------
+
+#include "./omp/parallel_stable_partial_sort.h"
+#include "./omp/parallel_stable_sort.h"
+
+//------------------------------------------------------------------------
+// parallel_merge
+//------------------------------------------------------------------------
+#include "./omp/parallel_merge.h"
+
+#endif //_PSTL_PARALLEL_BACKEND_OMP_H
lib/libcxx/include/__pstl/internal/parallel_backend_serial.h
@@ -0,0 +1,106 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_PARALLEL_BACKEND_SERIAL_H
+#define _PSTL_PARALLEL_BACKEND_SERIAL_H
+
+#include <__config>
+#include <__memory/allocator.h>
+#include <__pstl/internal/execution_impl.h>
+#include <__utility/forward.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+namespace __pstl
+{
+namespace __serial_backend
+{
+
+template <typename _Tp>
+class __buffer
+{
+    std::allocator<_Tp> __allocator_;
+    _Tp* __ptr_;
+    const std::size_t __buf_size_;
+    __buffer(const __buffer&) = delete;
+    void
+    operator=(const __buffer&) = delete;
+
+  public:
+    _LIBCPP_HIDE_FROM_ABI
+    __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
+
+    _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ptr_ != nullptr; }
+    _LIBCPP_HIDE_FROM_ABI _Tp*
+    get() const
+    {
+        return __ptr_;
+    }
+    _LIBCPP_HIDE_FROM_ABI ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
+};
+
+template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
+_LIBCPP_HIDE_FROM_ABI _Value
+__parallel_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
+                  const _Value& __identity, const _RealBody& __real_body, const _Reduction&)
+{
+    if (__first == __last)
+    {
+        return __identity;
+    }
+    else
+    {
+        return __real_body(__first, __last, __identity);
+    }
+}
+
+template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
+_LIBCPP_HIDE_FROM_ABI void
+__parallel_strict_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
+                       _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
+{
+    _Tp __sum = __initial;
+    if (__n)
+        __sum = __combine(__sum, __reduce(_Index(0), __n));
+    __apex(__sum);
+    if (__n)
+        __scan(_Index(0), __n, __initial);
+}
+
+template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__parallel_transform_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp,
+                          _Tp __init, _BinaryOp, _Reduce, _Scan __scan)
+{
+    return __scan(_Index(0), __n, __init);
+}
+
+template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
+_LIBCPP_HIDE_FROM_ABI void
+__parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
+                       _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0)
+{
+    __leaf_sort(__first, __last, __comp);
+}
+
+template <class _ExecutionPolicy, typename _F1, typename _F2>
+_LIBCPP_HIDE_FROM_ABI void
+__parallel_invoke(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
+{
+    std::forward<_F1>(__f1)();
+    std::forward<_F2>(__f2)();
+}
+
+} // namespace __serial_backend
+} // namespace __pstl
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
lib/libcxx/include/__pstl/internal/parallel_backend_tbb.h
@@ -0,0 +1,1295 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_PARALLEL_BACKEND_TBB_H
+#define _PSTL_PARALLEL_BACKEND_TBB_H
+
+#include <__assert>
+#include <__config>
+#include <algorithm>
+#include <type_traits>
+
+#include "parallel_backend_utils.h"
+
+// Bring in minimal required subset of Intel TBB
+#include <tbb/blocked_range.h>
+#include <tbb/parallel_for.h>
+#include <tbb/parallel_reduce.h>
+#include <tbb/parallel_scan.h>
+#include <tbb/parallel_invoke.h>
+#include <tbb/task_arena.h>
+#include <tbb/tbb_allocator.h>
+#include <tbb/task.h>
+
+#if TBB_INTERFACE_VERSION < 10000
+#    error Intel(R) Threading Building Blocks 2018 is required; older versions are not supported.
+#endif
+
+namespace __pstl
+{
+namespace __tbb_backend
+{
+
+//! Raw memory buffer with automatic freeing and no exceptions.
+/** Some of our algorithms need to start with raw memory buffer,
+not an initialize array, because initialization/destruction
+would make the span be at least O(N). */
+// tbb::allocator can improve performance in some cases.
+template <typename _Tp>
+class __buffer
+{
+    tbb::tbb_allocator<_Tp> _M_allocator;
+    _Tp* _M_ptr;
+    const std::size_t _M_buf_size;
+    __buffer(const __buffer&) = delete;
+    void
+    operator=(const __buffer&) = delete;
+
+  public:
+    //! Try to obtain buffer of given size to store objects of _Tp type
+    __buffer(std::size_t n) : _M_allocator(), _M_ptr(_M_allocator.allocate(n)), _M_buf_size(n) {}
+    //! True if buffer was successfully obtained, zero otherwise.
+    operator bool() const { return _M_ptr != NULL; }
+    //! Return pointer to buffer, or  NULL if buffer could not be obtained.
+    _Tp*
+    get() const
+    {
+        return _M_ptr;
+    }
+    //! Destroy buffer
+    ~__buffer() { _M_allocator.deallocate(_M_ptr, _M_buf_size); }
+};
+
+// Wrapper for tbb::task
+inline void
+__cancel_execution()
+{
+#if TBB_INTERFACE_VERSION <= 12000
+    tbb::task::self().group()->cancel_group_execution();
+#else
+    tbb::task::current_context()->cancel_group_execution();
+#endif
+}
+
+//------------------------------------------------------------------------
+// parallel_for
+//------------------------------------------------------------------------
+
+template <class _Index, class _RealBody>
+class __parallel_for_body
+{
+  public:
+    __parallel_for_body(const _RealBody& __body) : _M_body(__body) {}
+    __parallel_for_body(const __parallel_for_body& __body) : _M_body(__body._M_body) {}
+    void
+    operator()(const tbb::blocked_range<_Index>& __range) const
+    {
+        _M_body(__range.begin(), __range.end());
+    }
+
+  private:
+    _RealBody _M_body;
+};
+
+//! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last)
+// wrapper over tbb::parallel_for
+template <class _ExecutionPolicy, class _Index, class _Fp>
+void
+__parallel_for(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
+{
+    tbb::this_task_arena::isolate([=]() {
+        tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f));
+    });
+}
+
+//! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last)
+// wrapper over tbb::parallel_reduce
+template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
+_Value
+__parallel_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
+                  const _Value& __identity, const _RealBody& __real_body, const _Reduction& __reduction)
+{
+    return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value {
+        return tbb::parallel_reduce(
+            tbb::blocked_range<_Index>(__first, __last), __identity,
+            [__real_body](const tbb::blocked_range<_Index>& __r, const _Value& __value) -> _Value {
+                return __real_body(__r.begin(), __r.end(), __value);
+            },
+            __reduction);
+    });
+}
+
+//------------------------------------------------------------------------
+// parallel_transform_reduce
+//
+// Notation:
+//      r(i,j,init) returns reduction of init with reduction over [i,j)
+//      u(i) returns f(i,i+1,identity) for a hypothetical left identity element of r
+//      c(x,y) combines values x and y that were the result of r or u
+//------------------------------------------------------------------------
+
+template <class _Index, class _Up, class _Tp, class _Cp, class _Rp>
+struct __par_trans_red_body
+{
+    alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true
+    _Rp _M_brick_reduce;                           // Most likely to have non-empty layout
+    _Up _M_u;
+    _Cp _M_combine;
+    bool _M_has_sum; // Put last to minimize size of class
+    _Tp&
+    sum()
+    {
+        __TBB_ASSERT(_M_has_sum, "sum expected");
+        return *(_Tp*)_M_sum_storage;
+    }
+    __par_trans_red_body(_Up __u, _Tp __init, _Cp __c, _Rp __r)
+        : _M_brick_reduce(__r), _M_u(__u), _M_combine(__c), _M_has_sum(true)
+    {
+        new (_M_sum_storage) _Tp(__init);
+    }
+
+    __par_trans_red_body(__par_trans_red_body& __left, tbb::split)
+        : _M_brick_reduce(__left._M_brick_reduce), _M_u(__left._M_u), _M_combine(__left._M_combine), _M_has_sum(false)
+    {
+    }
+
+    ~__par_trans_red_body()
+    {
+        // 17.6.5.12 tells us to not worry about catching exceptions from destructors.
+        if (_M_has_sum)
+            sum().~_Tp();
+    }
+
+    void
+    join(__par_trans_red_body& __rhs)
+    {
+        sum() = _M_combine(sum(), __rhs.sum());
+    }
+
+    void
+    operator()(const tbb::blocked_range<_Index>& __range)
+    {
+        _Index __i = __range.begin();
+        _Index __j = __range.end();
+        if (!_M_has_sum)
+        {
+            __TBB_ASSERT(__range.size() > 1, "there should be at least 2 elements");
+            new (&_M_sum_storage)
+                _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3
+            _M_has_sum = true;
+            std::advance(__i, 2);
+            if (__i == __j)
+                return;
+        }
+        sum() = _M_brick_reduce(__i, __j, sum());
+    }
+};
+
+template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp>
+_Tp
+__parallel_transform_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
+                            _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce)
+{
+    __tbb_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce);
+    // The grain size of 3 is used in order to provide mininum 2 elements for each body
+    tbb::this_task_arena::isolate(
+        [__first, __last, &__body]() { tbb::parallel_reduce(tbb::blocked_range<_Index>(__first, __last, 3), __body); });
+    return __body.sum();
+}
+
+//------------------------------------------------------------------------
+// parallel_scan
+//------------------------------------------------------------------------
+
+template <class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
+class __trans_scan_body
+{
+    alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true
+    _Rp _M_brick_reduce;                           // Most likely to have non-empty layout
+    _Up _M_u;
+    _Cp _M_combine;
+    _Sp _M_scan;
+    bool _M_has_sum; // Put last to minimize size of class
+  public:
+    __trans_scan_body(_Up __u, _Tp __init, _Cp __combine, _Rp __reduce, _Sp __scan)
+        : _M_brick_reduce(__reduce), _M_u(__u), _M_combine(__combine), _M_scan(__scan), _M_has_sum(true)
+    {
+        new (_M_sum_storage) _Tp(__init);
+    }
+
+    __trans_scan_body(__trans_scan_body& __b, tbb::split)
+        : _M_brick_reduce(__b._M_brick_reduce), _M_u(__b._M_u), _M_combine(__b._M_combine), _M_scan(__b._M_scan),
+          _M_has_sum(false)
+    {
+    }
+
+    ~__trans_scan_body()
+    {
+        // 17.6.5.12 tells us to not worry about catching exceptions from destructors.
+        if (_M_has_sum)
+            sum().~_Tp();
+    }
+
+    _Tp&
+    sum() const
+    {
+        __TBB_ASSERT(_M_has_sum, "sum expected");
+        return *const_cast<_Tp*>(reinterpret_cast<_Tp const*>(_M_sum_storage));
+    }
+
+    void
+    operator()(const tbb::blocked_range<_Index>& __range, tbb::pre_scan_tag)
+    {
+        _Index __i = __range.begin();
+        _Index __j = __range.end();
+        if (!_M_has_sum)
+        {
+            new (&_M_sum_storage) _Tp(_M_u(__i));
+            _M_has_sum = true;
+            ++__i;
+            if (__i == __j)
+                return;
+        }
+        sum() = _M_brick_reduce(__i, __j, sum());
+    }
+
+    void
+    operator()(const tbb::blocked_range<_Index>& __range, tbb::final_scan_tag)
+    {
+        sum() = _M_scan(__range.begin(), __range.end(), sum());
+    }
+
+    void
+    reverse_join(__trans_scan_body& __a)
+    {
+        if (_M_has_sum)
+        {
+            sum() = _M_combine(__a.sum(), sum());
+        }
+        else
+        {
+            new (&_M_sum_storage) _Tp(__a.sum());
+            _M_has_sum = true;
+        }
+    }
+
+    void
+    assign(__trans_scan_body& __b)
+    {
+        sum() = __b.sum();
+    }
+};
+
+template <typename _Index>
+_Index
+__split(_Index __m)
+{
+    _Index __k = 1;
+    while (2 * __k < __m)
+        __k *= 2;
+    return __k;
+}
+
+//------------------------------------------------------------------------
+// __parallel_strict_scan
+//------------------------------------------------------------------------
+
+template <typename _Index, typename _Tp, typename _Rp, typename _Cp>
+void
+__upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine)
+{
+    if (__m == 1)
+        __r[0] = __reduce(__i * __tilesize, __lastsize);
+    else
+    {
+        _Index __k = __split(__m);
+        tbb::parallel_invoke(
+            [=] { __tbb_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
+            [=] {
+                __tbb_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine);
+            });
+        if (__m == 2 * __k)
+            __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]);
+    }
+}
+
+template <typename _Index, typename _Tp, typename _Cp, typename _Sp>
+void
+__downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine,
+            _Sp __scan)
+{
+    if (__m == 1)
+        __scan(__i * __tilesize, __lastsize, __initial);
+    else
+    {
+        const _Index __k = __split(__m);
+        tbb::parallel_invoke(
+            [=] { __tbb_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
+            // Assumes that __combine never throws.
+            //TODO: Consider adding a requirement for user functors to be constant.
+            [=, &__combine] {
+                __tbb_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
+                                           __combine(__initial, __r[__k - 1]), __combine, __scan);
+            });
+    }
+}
+
+// Adapted from Intel(R) Cilk(TM) version from cilkpub.
+// Let i:len denote a counted interval of length n starting at i.  s denotes a generalized-sum value.
+// Expected actions of the functors are:
+//     reduce(i,len) -> s  -- return reduction value of i:len.
+//     combine(s1,s2) -> s -- return merged sum
+//     apex(s) -- do any processing necessary between reduce and scan.
+//     scan(i,len,initial) -- perform scan over i:len starting with initial.
+// The initial range 0:n is partitioned into consecutive subranges.
+// reduce and scan are each called exactly once per subrange.
+// Thus callers can rely upon side effects in reduce.
+// combine must not throw an exception.
+// apex is called exactly once, after all calls to reduce and before all calls to scan.
+// For example, it's useful for allocating a __buffer used by scan but whose size is the sum of all reduction values.
+// T must have a trivial constructor and destructor.
+template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
+void
+__parallel_strict_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
+                       _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
+{
+    tbb::this_task_arena::isolate([=, &__combine]() {
+        if (__n > 1)
+        {
+            _Index __p = tbb::this_task_arena::max_concurrency();
+            const _Index __slack = 4;
+            _Index __tilesize = (__n - 1) / (__slack * __p) + 1;
+            _Index __m = (__n - 1) / __tilesize;
+            __buffer<_Tp> __buf(__m + 1);
+            _Tp* __r = __buf.get();
+            __tbb_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce,
+                                     __combine);
+
+            // When __apex is a no-op and __combine has no side effects, a good optimizer
+            // should be able to eliminate all code between here and __apex.
+            // Alternatively, provide a default value for __apex that can be
+            // recognized by metaprogramming that conditionlly executes the following.
+            size_t __k = __m + 1;
+            _Tp __t = __r[__k - 1];
+            while ((__k &= __k - 1))
+                __t = __combine(__r[__k - 1], __t);
+            __apex(__combine(__initial, __t));
+            __tbb_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial,
+                                       __combine, __scan);
+            return;
+        }
+        // Fewer than 2 elements in sequence, or out of memory.  Handle has single block.
+        _Tp __sum = __initial;
+        if (__n)
+            __sum = __combine(__sum, __reduce(_Index(0), __n));
+        __apex(__sum);
+        if (__n)
+            __scan(_Index(0), __n, __initial);
+    });
+}
+
+template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
+_Tp
+__parallel_transform_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init,
+                          _Cp __combine, _Rp __brick_reduce, _Sp __scan)
+{
+    __trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan);
+    auto __range = tbb::blocked_range<_Index>(0, __n);
+    tbb::this_task_arena::isolate([__range, &__body]() { tbb::parallel_scan(__range, __body); });
+    return __body.sum();
+}
+
+//------------------------------------------------------------------------
+// parallel_stable_sort
+//------------------------------------------------------------------------
+
+//------------------------------------------------------------------------
+// stable_sort utilities
+//
+// These are used by parallel implementations but do not depend on them.
+//------------------------------------------------------------------------
+#define _PSTL_MERGE_CUT_OFF 2000
+
+template <typename _Func>
+class __func_task;
+template <typename _Func>
+class __root_task;
+
+#if TBB_INTERFACE_VERSION <= 12000
+class __task : public tbb::task
+{
+  public:
+    template <typename _Fn>
+    __task*
+    make_continuation(_Fn&& __f)
+    {
+        return new (allocate_continuation()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
+    }
+
+    template <typename _Fn>
+    __task*
+    make_child_of(__task* parent, _Fn&& __f)
+    {
+        return new (parent->allocate_child()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
+    }
+
+    template <typename _Fn>
+    __task*
+    make_additional_child_of(tbb::task* parent, _Fn&& __f)
+    {
+        return new (tbb::task::allocate_additional_child_of(*parent))
+            __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
+    }
+
+    inline void
+    recycle_as_continuation()
+    {
+        tbb::task::recycle_as_continuation();
+    }
+
+    inline void
+    recycle_as_child_of(__task* parent)
+    {
+        tbb::task::recycle_as_child_of(*parent);
+    }
+
+    inline void
+    spawn(__task* __t)
+    {
+        tbb::task::spawn(*__t);
+    }
+
+    template <typename _Fn>
+    static inline void
+    spawn_root_and_wait(__root_task<_Fn>& __root)
+    {
+        tbb::task::spawn_root_and_wait(*__root._M_task);
+    }
+};
+
+template <typename _Func>
+class __func_task : public __task
+{
+    _Func _M_func;
+
+    tbb::task*
+    execute()
+    {
+        return _M_func(this);
+    };
+
+  public:
+    template <typename _Fn>
+    __func_task(_Fn&& __f) : _M_func{std::forward<_Fn>(__f)}
+    {
+    }
+
+    _Func&
+    body()
+    {
+        return _M_func;
+    }
+};
+
+template <typename _Func>
+class __root_task
+{
+    tbb::task* _M_task;
+
+  public:
+    template <typename... Args>
+    __root_task(Args&&... args)
+        : _M_task{new (tbb::task::allocate_root()) __func_task<_Func>{_Func(std::forward<Args>(args)...)}}
+    {
+    }
+
+    friend class __task;
+    friend class __func_task<_Func>;
+};
+
+#else  // TBB_INTERFACE_VERSION <= 12000
+class __task : public tbb::detail::d1::task
+{
+  protected:
+    tbb::detail::d1::small_object_allocator _M_allocator{};
+    tbb::detail::d1::execution_data* _M_execute_data{};
+    __task* _M_parent{};
+    std::atomic<int> _M_refcount{};
+    bool _M_recycle{};
+
+    template <typename _Fn>
+    __task*
+    allocate_func_task(_Fn&& __f)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, "");
+        tbb::detail::d1::small_object_allocator __alloc{};
+        auto __t =
+            __alloc.new_object<__func_task<typename std::decay<_Fn>::type>>(*_M_execute_data, std::forward<_Fn>(__f));
+        __t->_M_allocator = __alloc;
+        return __t;
+    }
+
+  public:
+    __task*
+    parent()
+    {
+        return _M_parent;
+    }
+
+    void
+    set_ref_count(int __n)
+    {
+        _M_refcount.store(__n, std::memory_order_release);
+    }
+
+    template <typename _Fn>
+    __task*
+    make_continuation(_Fn&& __f)
+    {
+        auto __t = allocate_func_task(std::forward<_Fn&&>(__f));
+        __t->_M_parent = _M_parent;
+        _M_parent = nullptr;
+        return __t;
+    }
+
+    template <typename _Fn>
+    __task*
+    make_child_of(__task* __parent, _Fn&& __f)
+    {
+        auto __t = allocate_func_task(std::forward<_Fn&&>(__f));
+        __t->_M_parent = __parent;
+        return __t;
+    }
+
+    template <typename _Fn>
+    __task*
+    make_additional_child_of(__task* __parent, _Fn&& __f)
+    {
+        auto __t = make_child_of(__parent, std::forward<_Fn>(__f));
+        _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, "");
+        ++__parent->_M_refcount;
+        return __t;
+    }
+
+    inline void
+    recycle_as_continuation()
+    {
+        _M_recycle = true;
+    }
+
+    inline void
+    recycle_as_child_of(__task* parent)
+    {
+        _M_recycle = true;
+        _M_parent = parent;
+    }
+
+    inline void
+    spawn(__task* __t)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, "");
+        tbb::detail::d1::spawn(*__t, *_M_execute_data->context);
+    }
+
+    template <typename _Fn>
+    static inline void
+    spawn_root_and_wait(__root_task<_Fn>& __root)
+    {
+        tbb::detail::d1::execute_and_wait(*__root._M_func_task, __root._M_context, __root._M_wait_object,
+                                          __root._M_context);
+    }
+
+    template <typename _Func>
+    friend class __func_task;
+};
+
+template <typename _Func>
+class __func_task : public __task
+{
+    _Func _M_func;
+
+    __task*
+    execute(tbb::detail::d1::execution_data& __ed) override
+    {
+        _M_execute_data = &__ed;
+        _M_recycle = false;
+        __task* __next = _M_func(this);
+        return finalize(__next);
+    };
+
+    __task*
+    cancel(tbb::detail::d1::execution_data& __ed) override
+    {
+        return finalize(nullptr);
+    }
+
+    __task*
+    finalize(__task* __next)
+    {
+        bool __recycle = _M_recycle;
+        _M_recycle = false;
+
+        if (__recycle)
+        {
+            return __next;
+        }
+
+        auto __parent = _M_parent;
+        auto __alloc = _M_allocator;
+        auto __ed = _M_execute_data;
+
+        this->~__func_task();
+
+        _LIBCPP_ASSERT_UNCATEGORIZED(__parent != nullptr, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, "");
+        if (--__parent->_M_refcount == 0)
+        {
+            _LIBCPP_ASSERT_UNCATEGORIZED(__next == nullptr, "");
+            __alloc.deallocate(this, *__ed);
+            return __parent;
+        }
+
+        return __next;
+    }
+
+    friend class __root_task<_Func>;
+
+  public:
+    template <typename _Fn>
+    __func_task(_Fn&& __f) : _M_func(std::forward<_Fn>(__f))
+    {
+    }
+
+    _Func&
+    body()
+    {
+        return _M_func;
+    }
+};
+
+template <typename _Func>
+class __root_task : public __task
+{
+    __task*
+    execute(tbb::detail::d1::execution_data& __ed) override
+    {
+        _M_wait_object.release();
+        return nullptr;
+    };
+
+    __task*
+    cancel(tbb::detail::d1::execution_data& __ed) override
+    {
+        _M_wait_object.release();
+        return nullptr;
+    }
+
+    __func_task<_Func>* _M_func_task{};
+    tbb::detail::d1::wait_context _M_wait_object{0};
+    tbb::task_group_context _M_context{};
+
+  public:
+    template <typename... Args>
+    __root_task(Args&&... args) : _M_wait_object{1}
+    {
+        tbb::detail::d1::small_object_allocator __alloc{};
+        _M_func_task = __alloc.new_object<__func_task<_Func>>(_Func(std::forward<Args>(args)...));
+        _M_func_task->_M_allocator = __alloc;
+        _M_func_task->_M_parent = this;
+        _M_refcount.store(1, std::memory_order_relaxed);
+    }
+
+    friend class __task;
+};
+#endif // TBB_INTERFACE_VERSION <= 12000
+
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _Cleanup,
+          typename _LeafMerge>
+class __merge_func
+{
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
+    typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _ValueType;
+
+    _RandomAccessIterator1 _M_x_beg;
+    _RandomAccessIterator2 _M_z_beg;
+
+    _SizeType _M_xs, _M_xe;
+    _SizeType _M_ys, _M_ye;
+    _SizeType _M_zs;
+    _Compare _M_comp;
+    _LeafMerge _M_leaf_merge;
+    _SizeType _M_nsort; //number of elements to be sorted for partial_sort alforithm
+
+    static const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
+
+    bool _root;   //means a task is merging root task
+    bool _x_orig; //"true" means X(or left ) subrange is in the original container; false - in the buffer
+    bool _y_orig; //"true" means Y(or right) subrange is in the original container; false - in the buffer
+    bool _split; //"true" means a merge task is a split task for parallel merging, the execution logic differs
+
+    bool
+    is_partial() const
+    {
+        return _M_nsort > 0;
+    }
+
+    struct __move_value
+    {
+        template <typename Iterator1, typename Iterator2>
+        void
+        operator()(Iterator1 __x, Iterator2 __z)
+        {
+            *__z = std::move(*__x);
+        }
+    };
+
+    struct __move_value_construct
+    {
+        template <typename Iterator1, typename Iterator2>
+        void
+        operator()(Iterator1 __x, Iterator2 __z)
+        {
+            ::new (std::addressof(*__z)) _ValueType(std::move(*__x));
+        }
+    };
+
+    struct __move_range
+    {
+        template <typename Iterator1, typename Iterator2>
+        Iterator2
+        operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2)
+        {
+            if (__last1 - __first1 < __merge_cut_off)
+                return std::move(__first1, __last1, __first2);
+
+            auto __n = __last1 - __first1;
+            tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
+                              [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) {
+                                  std::move(__first1 + __range.begin(), __first1 + __range.end(),
+                                            __first2 + __range.begin());
+                              });
+            return __first2 + __n;
+        }
+    };
+
+    struct __move_range_construct
+    {
+        template <typename Iterator1, typename Iterator2>
+        Iterator2
+        operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2)
+        {
+            if (__last1 - __first1 < __merge_cut_off)
+            {
+                for (; __first1 != __last1; ++__first1, ++__first2)
+                    __move_value_construct()(__first1, __first2);
+                return __first2;
+            }
+
+            auto __n = __last1 - __first1;
+            tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
+                              [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) {
+                                  for (auto i = __range.begin(); i != __range.end(); ++i)
+                                      __move_value_construct()(__first1 + i, __first2 + i);
+                              });
+            return __first2 + __n;
+        }
+    };
+
+    struct __cleanup_range
+    {
+        template <typename Iterator>
+        void
+        operator()(Iterator __first, Iterator __last)
+        {
+            if (__last - __first < __merge_cut_off)
+                _Cleanup()(__first, __last);
+            else
+            {
+                auto __n = __last - __first;
+                tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
+                                  [__first](const tbb::blocked_range<_SizeType>& __range) {
+                                      _Cleanup()(__first + __range.begin(), __first + __range.end());
+                                  });
+            }
+        }
+    };
+
+  public:
+    __merge_func(_SizeType __xs, _SizeType __xe, _SizeType __ys, _SizeType __ye, _SizeType __zs, _Compare __comp,
+                 _Cleanup, _LeafMerge __leaf_merge, _SizeType __nsort, _RandomAccessIterator1 __x_beg,
+                 _RandomAccessIterator2 __z_beg, bool __x_orig, bool __y_orig, bool __root)
+        : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_x_beg(__x_beg), _M_z_beg(__z_beg),
+          _M_comp(__comp), _M_leaf_merge(__leaf_merge), _M_nsort(__nsort), _root(__root),
+          _x_orig(__x_orig), _y_orig(__y_orig), _split(false)
+    {
+    }
+
+    bool
+    is_left(_SizeType __idx) const
+    {
+        return _M_xs == __idx;
+    }
+
+    template <typename IndexType>
+    void
+    set_odd(IndexType __idx, bool __on_off)
+    {
+        if (is_left(__idx))
+            _x_orig = __on_off;
+        else
+            _y_orig = __on_off;
+    }
+
+    __task*
+    operator()(__task* __self);
+
+  private:
+    __merge_func*
+    parent_merge(__task* __self) const
+    {
+        return _root ? nullptr : &static_cast<__func_task<__merge_func>*>(__self->parent())->body();
+    }
+    bool
+    x_less_y()
+    {
+        const auto __nx = (_M_xe - _M_xs);
+        const auto __ny = (_M_ye - _M_ys);
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, "");
+
+        _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(!is_partial(), "");
+
+        if (_x_orig)
+        {
+            _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_comp), "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_comp), "");
+            return !_M_comp(*(_M_x_beg + _M_ys), *(_M_x_beg + _M_xe - 1));
+        }
+
+        _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), "");
+        return !_M_comp(*(_M_z_beg + _M_zs + __nx), *(_M_z_beg + _M_zs + __nx - 1));
+    }
+    void
+    move_x_range()
+    {
+        const auto __nx = (_M_xe - _M_xs);
+        const auto __ny = (_M_ye - _M_ys);
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, "");
+
+        if (_x_orig)
+            __move_range_construct()(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_z_beg + _M_zs);
+        else
+        {
+            __move_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx, _M_x_beg + _M_xs);
+            __cleanup_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx);
+        }
+
+        _x_orig = !_x_orig;
+    }
+    void
+    move_y_range()
+    {
+        const auto __nx = (_M_xe - _M_xs);
+        const auto __ny = (_M_ye - _M_ys);
+
+        if (_y_orig)
+            __move_range_construct()(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs + __nx);
+        else
+        {
+            __move_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny, _M_x_beg + _M_ys);
+            __cleanup_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny);
+        }
+
+        _y_orig = !_y_orig;
+    }
+    __task*
+    merge_ranges(__task* __self)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); // two merged subrange must be lie into the same buffer
+
+        const auto __nx = (_M_xe - _M_xs);
+        const auto __ny = (_M_ye - _M_ys);
+        const auto __n = __nx + __ny;
+
+        // need to merge {x} and {y}
+        if (__n > __merge_cut_off)
+            return split_merging(__self);
+
+        //merge to buffer
+        if (_x_orig)
+        {
+            _M_leaf_merge(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs,
+                          _M_comp, __move_value_construct(), __move_value_construct(), __move_range_construct(),
+                          __move_range_construct());
+            _LIBCPP_ASSERT_UNCATEGORIZED(parent_merge(__self), ""); //not root merging task
+        }
+        //merge to "origin"
+        else
+        {
+            _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
+
+            _LIBCPP_ASSERT_UNCATEGORIZED(
+                is_partial() || std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(
+                is_partial() || std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), "");
+
+            const auto __nx = (_M_xe - _M_xs);
+            const auto __ny = (_M_ye - _M_ys);
+
+            _M_leaf_merge(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_x_beg + _M_zs,
+                          _M_comp, __move_value(), __move_value(), __move_range(), __move_range());
+
+            __cleanup_range()(_M_z_beg + _M_xs, _M_z_beg + _M_xe);
+            __cleanup_range()(_M_z_beg + _M_ys, _M_z_beg + _M_ye);
+        }
+        return nullptr;
+    }
+
+    __task*
+    process_ranges(__task* __self)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(!_split, "");
+
+        auto p = parent_merge(__self);
+
+        if (!p)
+        { //root merging task
+
+            //optimization, just for sort algorithm, //{x} <= {y}
+            if (!is_partial() && x_less_y()) //we have a solution
+            {
+                if (!_x_orig)
+                {                   //we have to move the solution to the origin
+                    move_x_range(); //parallel moving
+                    move_y_range(); //parallel moving
+                }
+                return nullptr;
+            }
+            //else: if we have data in the origin,
+            //we have to move data to the buffer for final merging into the origin.
+            if (_x_orig)
+            {
+                move_x_range(); //parallel moving
+                move_y_range(); //parallel moving
+            }
+            // need to merge {x} and {y}.
+            return merge_ranges(__self);
+        }
+        //else: not root merging task (parent_merge() == NULL)
+        //optimization, just for sort algorithm, //{x} <= {y}
+        if (!is_partial() && x_less_y())
+        {
+            const auto id_range = _M_zs;
+            p->set_odd(id_range, _x_orig);
+            return nullptr;
+        }
+        //else: we have to revert "_x(y)_orig" flag of the parent merging task
+        const auto id_range = _M_zs;
+        p->set_odd(id_range, !_x_orig);
+
+        return merge_ranges(__self);
+    }
+
+    //splitting as merge task into 2 of the same level
+    __task*
+    split_merging(__task* __self)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
+        const auto __nx = (_M_xe - _M_xs);
+        const auto __ny = (_M_ye - _M_ys);
+
+        _SizeType __xm{};
+        _SizeType __ym{};
+        if (__nx < __ny)
+        {
+            __ym = _M_ys + __ny / 2;
+
+            if (_x_orig)
+                __xm = std::upper_bound(_M_x_beg + _M_xs, _M_x_beg + _M_xe, *(_M_x_beg + __ym), _M_comp) - _M_x_beg;
+            else
+                __xm = std::upper_bound(_M_z_beg + _M_xs, _M_z_beg + _M_xe, *(_M_z_beg + __ym), _M_comp) - _M_z_beg;
+        }
+        else
+        {
+            __xm = _M_xs + __nx / 2;
+
+            if (_y_orig)
+                __ym = std::lower_bound(_M_x_beg + _M_ys, _M_x_beg + _M_ye, *(_M_x_beg + __xm), _M_comp) - _M_x_beg;
+            else
+                __ym = std::lower_bound(_M_z_beg + _M_ys, _M_z_beg + _M_ye, *(_M_z_beg + __xm), _M_comp) - _M_z_beg;
+        }
+
+        auto __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys));
+        __merge_func __right_func(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _Cleanup(), _M_leaf_merge, _M_nsort,
+                                  _M_x_beg, _M_z_beg, _x_orig, _y_orig, _root);
+        __right_func._split = true;
+        auto __merge_task = __self->make_additional_child_of(__self->parent(), std::move(__right_func));
+        __self->spawn(__merge_task);
+        __self->recycle_as_continuation();
+
+        _M_xe = __xm;
+        _M_ye = __ym;
+        _split = true;
+
+        return __self;
+    }
+};
+
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename __M_Compare, typename _Cleanup,
+          typename _LeafMerge>
+__task*
+__merge_func<_RandomAccessIterator1, _RandomAccessIterator2, __M_Compare, _Cleanup, _LeafMerge>::
+operator()(__task* __self)
+{
+    //a. split merge task into 2 of the same level; the special logic,
+    //without processing(process_ranges) adjacent sub-ranges x and y
+    if (_split)
+        return merge_ranges(__self);
+
+    //b. General merging of adjacent sub-ranges x and y (with optimization in case of {x} <= {y} )
+
+    //1. x and y are in the even buffer
+    //2. x and y are in the odd buffer
+    if (_x_orig == _y_orig)
+        return process_ranges(__self);
+
+    //3. x is in even buffer, y is in the odd buffer
+    //4. x is in odd buffer, y is in the even buffer
+    if (!parent_merge(__self))
+    { //root merge task
+        if (_x_orig)
+            move_x_range();
+        else
+            move_y_range();
+    }
+    else
+    {
+        const _SizeType __nx = (_M_xe - _M_xs);
+        const _SizeType __ny = (_M_ye - _M_ys);
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, "");
+
+        if (__nx < __ny)
+            move_x_range();
+        else
+            move_y_range();
+    }
+
+    return process_ranges(__self);
+}
+
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort>
+class __stable_sort_func
+{
+  public:
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
+    typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
+
+  private:
+    _RandomAccessIterator1 _M_xs, _M_xe, _M_x_beg;
+    _RandomAccessIterator2 _M_zs, _M_z_beg;
+    _Compare _M_comp;
+    _LeafSort _M_leaf_sort;
+    bool _M_root;
+    _SizeType _M_nsort; //zero or number of elements to be sorted for partial_sort alforithm
+
+  public:
+    __stable_sort_func(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __zs,
+                       bool __root, _Compare __comp, _LeafSort __leaf_sort, _SizeType __nsort,
+                       _RandomAccessIterator1 __x_beg, _RandomAccessIterator2 __z_beg)
+        : _M_xs(__xs), _M_xe(__xe), _M_x_beg(__x_beg), _M_zs(__zs), _M_z_beg(__z_beg), _M_comp(__comp),
+          _M_leaf_sort(__leaf_sort), _M_root(__root), _M_nsort(__nsort)
+    {
+    }
+
+    __task*
+    operator()(__task* __self);
+};
+
+#define _PSTL_STABLE_SORT_CUT_OFF 500
+
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort>
+__task*
+__stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _LeafSort>::operator()(__task* __self)
+{
+    typedef __merge_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, __utils::__serial_destroy,
+                         __utils::__serial_move_merge>
+        _MergeTaskType;
+
+    const _SizeType __n = _M_xe - _M_xs;
+    const _SizeType __nmerge = _M_nsort > 0 ? _M_nsort : __n;
+    const _SizeType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF;
+    if (__n <= __sort_cut_off)
+    {
+        _M_leaf_sort(_M_xs, _M_xe, _M_comp);
+        _LIBCPP_ASSERT_UNCATEGORIZED(!_M_root, "");
+        return nullptr;
+    }
+
+    const _RandomAccessIterator1 __xm = _M_xs + __n / 2;
+    const _RandomAccessIterator2 __zm = _M_zs + (__xm - _M_xs);
+    const _RandomAccessIterator2 __ze = _M_zs + __n;
+    _MergeTaskType __m(_MergeTaskType(_M_xs - _M_x_beg, __xm - _M_x_beg, __xm - _M_x_beg, _M_xe - _M_x_beg,
+                                      _M_zs - _M_z_beg, _M_comp, __utils::__serial_destroy(),
+                                      __utils::__serial_move_merge(__nmerge), _M_nsort, _M_x_beg, _M_z_beg,
+                                      /*x_orig*/ true, /*y_orig*/ true, /*root*/ _M_root));
+    auto __parent = __self->make_continuation(std::move(__m));
+    __parent->set_ref_count(2);
+    auto __right = __self->make_child_of(
+        __parent, __stable_sort_func(__xm, _M_xe, __zm, false, _M_comp, _M_leaf_sort, _M_nsort, _M_x_beg, _M_z_beg));
+    __self->spawn(__right);
+    __self->recycle_as_child_of(__parent);
+    _M_root = false;
+    _M_xe = __xm;
+
+    return __self;
+}
+
+template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
+void
+__parallel_stable_sort(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __xs,
+                       _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0)
+{
+    tbb::this_task_arena::isolate([=, &__nsort]() {
+        //sorting based on task tree and parallel merge
+        typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
+        typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
+        const _DifferenceType __n = __xe - __xs;
+        if (__nsort == __n)
+            __nsort = 0; // 'partial_sort' becames 'sort'
+
+        const _DifferenceType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF;
+        if (__n > __sort_cut_off)
+        {
+            __buffer<_ValueType> __buf(__n);
+            __root_task<__stable_sort_func<_RandomAccessIterator, _ValueType*, _Compare, _LeafSort>> __root{
+                __xs, __xe, __buf.get(), true, __comp, __leaf_sort, __nsort, __xs, __buf.get()};
+            __task::spawn_root_and_wait(__root);
+            return;
+        }
+        //serial sort
+        __leaf_sort(__xs, __xe, __comp);
+    });
+}
+
+//------------------------------------------------------------------------
+// parallel_merge
+//------------------------------------------------------------------------
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
+          typename _Compare, typename _LeafMerge>
+class __merge_func_static
+{
+    _RandomAccessIterator1 _M_xs, _M_xe;
+    _RandomAccessIterator2 _M_ys, _M_ye;
+    _RandomAccessIterator3 _M_zs;
+    _Compare _M_comp;
+    _LeafMerge _M_leaf_merge;
+
+  public:
+    __merge_func_static(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
+                        _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp,
+                        _LeafMerge __leaf_merge)
+        : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_comp(__comp), _M_leaf_merge(__leaf_merge)
+    {
+    }
+
+    __task*
+    operator()(__task* __self);
+};
+
+//TODO: consider usage of parallel_for with a custom blocked_range
+template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
+          typename __M_Compare, typename _LeafMerge>
+__task*
+__merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, __M_Compare, _LeafMerge>::
+operator()(__task* __self)
+{
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
+    typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
+    const _SizeType __n = (_M_xe - _M_xs) + (_M_ye - _M_ys);
+    const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
+    if (__n <= __merge_cut_off)
+    {
+        _M_leaf_merge(_M_xs, _M_xe, _M_ys, _M_ye, _M_zs, _M_comp);
+        return nullptr;
+    }
+
+    _RandomAccessIterator1 __xm;
+    _RandomAccessIterator2 __ym;
+    if (_M_xe - _M_xs < _M_ye - _M_ys)
+    {
+        __ym = _M_ys + (_M_ye - _M_ys) / 2;
+        __xm = std::upper_bound(_M_xs, _M_xe, *__ym, _M_comp);
+    }
+    else
+    {
+        __xm = _M_xs + (_M_xe - _M_xs) / 2;
+        __ym = std::lower_bound(_M_ys, _M_ye, *__xm, _M_comp);
+    }
+    const _RandomAccessIterator3 __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys));
+    auto __right = __self->make_additional_child_of(
+        __self->parent(), __merge_func_static(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _M_leaf_merge));
+    __self->spawn(__right);
+    __self->recycle_as_continuation();
+    _M_xe = __xm;
+    _M_ye = __ym;
+
+    return __self;
+}
+
+template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
+          typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
+void
+__parallel_merge(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs,
+                 _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
+                 _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
+{
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
+    typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
+    const _SizeType __n = (__xe - __xs) + (__ye - __ys);
+    const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
+    if (__n <= __merge_cut_off)
+    {
+        // Fall back on serial merge
+        __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp);
+    }
+    else
+    {
+        tbb::this_task_arena::isolate([=]() {
+            typedef __merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3,
+                                        _Compare, _LeafMerge>
+                _TaskType;
+            __root_task<_TaskType> __root{__xs, __xe, __ys, __ye, __zs, __comp, __leaf_merge};
+            __task::spawn_root_and_wait(__root);
+        });
+    }
+}
+
+//------------------------------------------------------------------------
+// parallel_invoke
+//------------------------------------------------------------------------
+template <class _ExecutionPolicy, typename _F1, typename _F2>
+void
+__parallel_invoke(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
+{
+    //TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future
+    tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); });
+}
+
+} // namespace __tbb_backend
+} // namespace __pstl
+
+#endif /* _PSTL_PARALLEL_BACKEND_TBB_H */
lib/libcxx/include/__pstl/internal/parallel_backend_utils.h
@@ -0,0 +1,260 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_PARALLEL_BACKEND_UTILS_H
+#define _PSTL_PARALLEL_BACKEND_UTILS_H
+
+#include <__assert>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+
+#include "utils.h"
+
+namespace __pstl
+{
+
+namespace __utils
+{
+
+//! Destroy sequence [xs,xe)
+struct __serial_destroy
+{
+    template <typename _RandomAccessIterator>
+    void
+    operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
+    {
+        typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
+        while (__zs != __ze)
+        {
+            --__ze;
+            (*__ze).~_ValueType();
+        }
+    }
+};
+
+//! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
+struct __serial_move_merge
+{
+    const std::size_t _M_nmerge;
+
+    explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
+    template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
+              class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
+    void
+    operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
+               _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
+               _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
+    {
+        constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
+        constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
+
+        auto __n = _M_nmerge;
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n > 0, "");
+
+        auto __nx = __xe - __xs;
+        //auto __ny = __ye - __ys;
+        _RandomAccessIterator3 __zs_beg = __zs;
+
+        if (__xs != __xe)
+        {
+            if (__ys != __ye)
+            {
+                for (;;)
+                {
+                    if (__comp(*__ys, *__xs))
+                    {
+                        const auto __i = __zs - __zs_beg;
+                        if (__i < __nx)
+                            __move_value_x(__ys, __zs);
+                        else
+                            __move_value_y(__ys, __zs);
+                        ++__zs, --__n;
+                        if (++__ys == __ye)
+                        {
+                            break;
+                        }
+                        else if (__n == 0)
+                        {
+                            const auto __j = __zs - __zs_beg;
+                            if (__same_move_seq || __j < __nx)
+                                __zs = __move_sequence_x(__ys, __ye, __zs);
+                            else
+                                __zs = __move_sequence_y(__ys, __ye, __zs);
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        const auto __i = __zs - __zs_beg;
+                        if (__same_move_val || __i < __nx)
+                            __move_value_x(__xs, __zs);
+                        else
+                            __move_value_y(__xs, __zs);
+                        ++__zs, --__n;
+                        if (++__xs == __xe)
+                        {
+                            const auto __j = __zs - __zs_beg;
+                            if (__same_move_seq || __j < __nx)
+                                __move_sequence_x(__ys, __ye, __zs);
+                            else
+                                __move_sequence_y(__ys, __ye, __zs);
+                            return;
+                        }
+                        else if (__n == 0)
+                        {
+                            const auto __j = __zs - __zs_beg;
+                            if (__same_move_seq || __j < __nx)
+                            {
+                                __zs = __move_sequence_x(__xs, __xe, __zs);
+                                __move_sequence_x(__ys, __ye, __zs);
+                            }
+                            else
+                            {
+                                __zs = __move_sequence_y(__xs, __xe, __zs);
+                                __move_sequence_y(__ys, __ye, __zs);
+                            }
+                            return;
+                        }
+                    }
+                }
+            }
+            __ys = __xs;
+            __ye = __xe;
+        }
+        const auto __i = __zs - __zs_beg;
+        if (__same_move_seq || __i < __nx)
+            __move_sequence_x(__ys, __ye, __zs);
+        else
+            __move_sequence_y(__ys, __ye, __zs);
+    }
+};
+
+template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
+          typename _CopyConstructRange>
+_OutputIterator
+__set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+                      _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
+                      _CopyConstructRange __cc_range)
+{
+    using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
+
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+            return __cc_range(__first1, __last1, __result);
+        if (__comp(*__first2, *__first1))
+        {
+            ::new (std::addressof(*__result)) _Tp(*__first2);
+            ++__first2;
+        }
+        else
+        {
+            ::new (std::addressof(*__result)) _Tp(*__first1);
+            if (!__comp(*__first1, *__first2))
+                ++__first2;
+            ++__first1;
+        }
+    }
+    return __cc_range(__first2, __last2, __result);
+}
+
+template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
+_OutputIterator
+__set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+                             _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
+
+    for (; __first1 != __last1 && __first2 != __last2;)
+    {
+        if (__comp(*__first1, *__first2))
+            ++__first1;
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+            {
+                ::new (std::addressof(*__result)) _Tp(*__first1);
+                ++__result;
+                ++__first1;
+            }
+            ++__first2;
+        }
+    }
+    return __result;
+}
+
+template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
+          typename _CopyConstructRange>
+_OutputIterator
+__set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+                           _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
+                           _CopyConstructRange __cc_range)
+{
+    using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
+
+    for (; __first1 != __last1;)
+    {
+        if (__first2 == __last2)
+            return __cc_range(__first1, __last1, __result);
+
+        if (__comp(*__first1, *__first2))
+        {
+            ::new (std::addressof(*__result)) _Tp(*__first1);
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return __result;
+}
+template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
+          typename _CopyConstructRange>
+_OutputIterator
+__set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+                                     _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
+                                     _CopyConstructRange __cc_range)
+{
+    using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
+
+    for (; __first1 != __last1;)
+    {
+        if (__first2 == __last2)
+            return __cc_range(__first1, __last1, __result);
+
+        if (__comp(*__first1, *__first2))
+        {
+            ::new (std::addressof(*__result)) _Tp(*__first1);
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (__comp(*__first2, *__first1))
+            {
+                ::new (std::addressof(*__result)) _Tp(*__first2);
+                ++__result;
+            }
+            else
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return __cc_range(__first2, __last2, __result);
+}
+
+} // namespace __utils
+} // namespace __pstl
+
+#endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
lib/libcxx/include/__pstl/internal/unseq_backend_simd.h
@@ -0,0 +1,697 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_UNSEQ_BACKEND_SIMD_H
+#define _PSTL_UNSEQ_BACKEND_SIMD_H
+
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_same.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <cstddef>
+#include <cstdint>
+
+#include <__pstl/internal/utils.h>
+
+// This header defines the minimum set of vector routines required
+// to support parallel STL.
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+namespace __pstl
+{
+namespace __unseq_backend
+{
+
+// Expect vector width up to 64 (or 512 bit)
+const std::size_t __lane_size = 64;
+
+template <class _Iterator, class _DifferenceType, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator
+__simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept
+{
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+        __f(__first[__i]);
+
+    return __first + __n;
+}
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator2
+__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept
+{
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+        __f(__first1[__i], __first2[__i]);
+    return __first2 + __n;
+}
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator3
+__simd_walk_3(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3,
+              _Function __f) noexcept
+{
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+        __f(__first1[__i], __first2[__i], __first3[__i]);
+    return __first3 + __n;
+}
+
+// TODO: check whether __simd_first() can be used here
+template <class _Index, class _DifferenceType, class _Pred>
+_LIBCPP_HIDE_FROM_ABI bool
+__simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept
+{
+    _DifferenceType __block_size = 4 < __n ? 4 : __n;
+    const _Index __last = __first + __n;
+    while (__last != __first)
+    {
+        int32_t __flag = 1;
+        _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
+        for (_DifferenceType __i = 0; __i < __block_size; ++__i)
+            if (__pred(*(__first + __i)))
+                __flag = 0;
+        if (!__flag)
+            return true;
+
+        __first += __block_size;
+        if (__last - __first >= __block_size << 1)
+        {
+            // Double the block _Size.  Any unnecessary iterations can be amortized against work done so far.
+            __block_size <<= 1;
+        }
+        else
+        {
+            __block_size = __last - __first;
+        }
+    }
+    return false;
+}
+
+template <class _Index1, class _DifferenceType, class _Index2, class _Pred>
+_LIBCPP_HIDE_FROM_ABI std::pair<_Index1, _Index2>
+__simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pred) noexcept
+{
+    const _Index1 __last1 = __first1 + __n;
+    const _Index2 __last2 = __first2 + __n;
+    // Experiments show good block sizes like this
+    const _DifferenceType __block_size = 8;
+    alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
+    while (__last1 - __first1 >= __block_size)
+    {
+        _DifferenceType __found = 0;
+        _DifferenceType __i;
+            _PSTL_PRAGMA_SIMD_REDUCTION(|
+                                        : __found) for (__i = 0; __i < __block_size; ++__i)
+        {
+            const _DifferenceType __t = __pred(__first1[__i], __first2[__i]);
+            __lane[__i] = __t;
+            __found |= __t;
+        }
+        if (__found)
+        {
+            _DifferenceType __i2;
+            // This will vectorize
+            for (__i2 = 0; __i2 < __block_size; ++__i2)
+            {
+                if (__lane[__i2])
+                    break;
+            }
+            return std::make_pair(__first1 + __i2, __first2 + __i2);
+        }
+        __first1 += __block_size;
+        __first2 += __block_size;
+    }
+
+    //Keep remainder scalar
+    for (; __last1 != __first1; ++__first1, ++__first2)
+        if (__pred(*(__first1), *(__first2)))
+            return std::make_pair(__first1, __first2);
+
+    return std::make_pair(__last1, __last2);
+}
+
+template <class _Index, class _DifferenceType, class _Pred>
+_LIBCPP_HIDE_FROM_ABI _DifferenceType
+__simd_count(_Index __index, _DifferenceType __n, _Pred __pred) noexcept
+{
+    _DifferenceType __count = 0;
+    _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+        if (__pred(*(__index + __i)))
+            ++__count;
+
+    return __count;
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _BinaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _OutputIterator
+__simd_unique_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator __result,
+                   _BinaryPredicate __pred) noexcept
+{
+    if (__n == 0)
+        return __result;
+
+    _DifferenceType __cnt = 1;
+    __result[0] = __first[0];
+
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 1; __i < __n; ++__i)
+    {
+        if (!__pred(__first[__i], __first[__i - 1]))
+        {
+            __result[__cnt] = __first[__i];
+            ++__cnt;
+        }
+    }
+    return __result + __cnt;
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner>
+_LIBCPP_HIDE_FROM_ABI _OutputIterator
+__simd_assign(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _Assigner __assigner) noexcept
+{
+    _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+        __assigner(__first + __i, __result + __i);
+    return __result + __n;
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _UnaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _OutputIterator
+__simd_copy_if(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _UnaryPredicate __pred) noexcept
+{
+    _DifferenceType __cnt = 0;
+
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        if (__pred(__first[__i]))
+        {
+            __result[__cnt] = __first[__i];
+            ++__cnt;
+        }
+    }
+    return __result + __cnt;
+}
+
+template <class _InputIterator, class _DifferenceType, class _BinaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _DifferenceType
+__simd_calc_mask_2(_InputIterator __first, _DifferenceType __n, bool* __mask, _BinaryPredicate __pred) noexcept
+{
+    _DifferenceType __count = 0;
+
+    _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        __mask[__i] = !__pred(__first[__i], __first[__i - 1]);
+        __count += __mask[__i];
+    }
+    return __count;
+}
+
+template <class _InputIterator, class _DifferenceType, class _UnaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _DifferenceType
+__simd_calc_mask_1(_InputIterator __first, _DifferenceType __n, bool* __mask, _UnaryPredicate __pred) noexcept
+{
+    _DifferenceType __count = 0;
+
+    _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        __mask[__i] = __pred(__first[__i]);
+        __count += __mask[__i];
+    }
+    return __count;
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner>
+_LIBCPP_HIDE_FROM_ABI void
+__simd_copy_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, bool* __mask,
+                    _Assigner __assigner) noexcept
+{
+    _DifferenceType __cnt = 0;
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        if (__mask[__i])
+        {
+            {
+                __assigner(__first + __i, __result + __cnt);
+                ++__cnt;
+            }
+        }
+    }
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2>
+_LIBCPP_HIDE_FROM_ABI void
+__simd_partition_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true,
+                         _OutputIterator2 __out_false, bool* __mask) noexcept
+{
+    _DifferenceType __cnt_true = 0, __cnt_false = 0;
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        if (__mask[__i])
+        {
+            __out_true[__cnt_true] = __first[__i];
+            ++__cnt_true;
+        }
+        else
+        {
+            __out_false[__cnt_false] = __first[__i];
+            ++__cnt_false;
+        }
+    }
+}
+
+template <class _Index, class _DifferenceType, class _Generator>
+_LIBCPP_HIDE_FROM_ABI _Index
+__simd_generate_n(_Index __first, _DifferenceType __size, _Generator __g) noexcept
+{
+    _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __size; ++__i)
+        __first[__i] = __g();
+    return __first + __size;
+}
+
+template <class _Index, class _BinaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _Index
+__simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, bool __or_semantic) noexcept
+{
+    if (__last - __first < 2)
+        return __last;
+
+    typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
+    _DifferenceType __i = 0;
+
+    // Experiments show good block sizes like this
+    //TODO: to consider tuning block_size for various data types
+    const _DifferenceType __block_size = 8;
+    alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
+    while (__last - __first >= __block_size)
+    {
+        _DifferenceType __found = 0;
+            _PSTL_PRAGMA_SIMD_REDUCTION(|
+                                        : __found) for (__i = 0; __i < __block_size - 1; ++__i)
+        {
+            //TODO: to improve SIMD vectorization
+            const _DifferenceType __t = __pred(*(__first + __i), *(__first + __i + 1));
+            __lane[__i] = __t;
+            __found |= __t;
+        }
+
+        //Process a pair of elements on a boundary of a data block
+        if (__first + __block_size < __last && __pred(*(__first + __i), *(__first + __i + 1)))
+            __lane[__i] = __found = 1;
+
+        if (__found)
+        {
+            if (__or_semantic)
+                return __first;
+
+            // This will vectorize
+            for (__i = 0; __i < __block_size; ++__i)
+                if (__lane[__i])
+                    break;
+            return __first + __i; //As far as found is true a __result (__lane[__i] is true) is guaranteed
+        }
+        __first += __block_size;
+    }
+    //Process the rest elements
+    for (; __last - __first > 1; ++__first)
+        if (__pred(*__first, *(__first + 1)))
+            return __first;
+
+    return __last;
+}
+
+// It was created to reduce the code inside std::enable_if
+template <typename _Tp, typename _BinaryOperation>
+using is_arithmetic_plus = std::integral_constant<bool, std::is_arithmetic<_Tp>::value &&
+                                                            std::is_same<_BinaryOperation, std::plus<_Tp>>::value>;
+
+// Exclusive scan for "+" and arithmetic types
+template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
+          class _BinaryOperation>
+_LIBCPP_HIDE_FROM_ABI
+typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
+            _BinaryOperation, /*Inclusive*/ std::false_type)
+{
+    _PSTL_PRAGMA_SIMD_SCAN(+ : __init)
+    for (_Size __i = 0; __i < __n; ++__i)
+    {
+        __result[__i] = __init;
+        _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__init)
+        __init += __unary_op(__first[__i]);
+    }
+    return std::make_pair(__result + __n, __init);
+}
+
+// As soon as we cannot call __binary_op in "combiner" we create a wrapper over _Tp to encapsulate __binary_op
+template <typename _Tp, typename _BinaryOp>
+struct _Combiner
+{
+    _Tp __value_;
+    _BinaryOp* __bin_op_; // Here is a pointer to function because of default ctor
+
+    _LIBCPP_HIDE_FROM_ABI _Combiner() : __value_{}, __bin_op_(nullptr) {}
+    _LIBCPP_HIDE_FROM_ABI
+    _Combiner(const _Tp& __value, const _BinaryOp* __bin_op)
+        : __value_(__value), __bin_op_(const_cast<_BinaryOp*>(__bin_op)) {}
+    _LIBCPP_HIDE_FROM_ABI _Combiner(const _Combiner& __obj) : __value_{}, __bin_op_(__obj.__bin_op) {}
+
+    _LIBCPP_HIDE_FROM_ABI void
+    operator()(const _Combiner& __obj)
+    {
+        __value_ = (*__bin_op_)(__value_, __obj.__value_);
+    }
+};
+
+// Exclusive scan for other binary operations and types
+template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
+          class _BinaryOperation>
+_LIBCPP_HIDE_FROM_ABI
+typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
+            _BinaryOperation __binary_op, /*Inclusive*/ std::false_type)
+{
+    typedef _Combiner<_Tp, _BinaryOperation> _CombinerType;
+    _CombinerType __combined_init{__init, &__binary_op};
+
+    _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType)
+    _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init)
+    for (_Size __i = 0; __i < __n; ++__i)
+    {
+        __result[__i] = __combined_init.__value_;
+        _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__combined_init)
+        __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i]));
+    }
+    return std::make_pair(__result + __n, __combined_init.__value_);
+}
+
+// Inclusive scan for "+" and arithmetic types
+template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
+          class _BinaryOperation>
+_LIBCPP_HIDE_FROM_ABI
+typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
+            _BinaryOperation, /*Inclusive*/ std::true_type)
+{
+    _PSTL_PRAGMA_SIMD_SCAN(+ : __init)
+    for (_Size __i = 0; __i < __n; ++__i)
+    {
+        __init += __unary_op(__first[__i]);
+        _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__init)
+        __result[__i] = __init;
+    }
+    return std::make_pair(__result + __n, __init);
+}
+
+// Inclusive scan for other binary operations and types
+template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
+          class _BinaryOperation>
+_LIBCPP_HIDE_FROM_ABI
+typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
+__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
+            _BinaryOperation __binary_op, std::true_type)
+{
+    typedef _Combiner<_Tp, _BinaryOperation> _CombinerType;
+    _CombinerType __combined_init{__init, &__binary_op};
+
+    _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType)
+    _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init)
+    for (_Size __i = 0; __i < __n; ++__i)
+    {
+        __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i]));
+        _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__combined_init)
+        __result[__i] = __combined_init.__value_;
+    }
+    return std::make_pair(__result + __n, __combined_init.__value_);
+}
+
+// [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible.
+// complexity [violation] - We will have at most (__n-1 + number_of_lanes) comparisons instead of at most __n-1.
+template <typename _ForwardIterator, typename _Size, typename _Compare>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+__simd_min_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept
+{
+    if (__n == 0)
+    {
+        return __first;
+    }
+
+    typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType;
+    struct _ComplexType
+    {
+        _ValueType __min_val_;
+        _Size __min_ind_;
+        _Compare* __min_comp_;
+
+        _LIBCPP_HIDE_FROM_ABI _ComplexType() : __min_val_{}, __min_ind_{}, __min_comp_(nullptr) {}
+        _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ValueType& __val, const _Compare* __comp)
+            : __min_val_(__val), __min_ind_(0), __min_comp_(const_cast<_Compare*>(__comp))
+        {
+        }
+        _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj)
+            : __min_val_(__obj.__min_val_), __min_ind_(__obj.__min_ind_), __min_comp_(__obj.__min_comp_)
+        {
+        }
+
+        _PSTL_PRAGMA_DECLARE_SIMD
+        _LIBCPP_HIDE_FROM_ABI void
+        operator()(const _ComplexType& __obj)
+        {
+            if (!(*__min_comp_)(__min_val_, __obj.__min_val_) &&
+                ((*__min_comp_)(__obj.__min_val_, __min_val_) || __obj.__min_ind_ - __min_ind_ < 0))
+            {
+                __min_val_ = __obj.__min_val_;
+                __min_ind_ = __obj.__min_ind_;
+            }
+        }
+    };
+
+    _ComplexType __init{*__first, &__comp};
+
+    _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType)
+
+    _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init)
+    for (_Size __i = 1; __i < __n; ++__i)
+    {
+        const _ValueType __min_val = __init.__min_val_;
+        const _ValueType __current = __first[__i];
+        if (__comp(__current, __min_val))
+        {
+            __init.__min_val_ = __current;
+            __init.__min_ind_ = __i;
+        }
+    }
+    return __first + __init.__min_ind_;
+}
+
+// [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible.
+// complexity [violation] - We will have at most (2*(__n-1) + 4*number_of_lanes) comparisons instead of at most [1.5*(__n-1)].
+template <typename _ForwardIterator, typename _Size, typename _Compare>
+_LIBCPP_HIDE_FROM_ABI std::pair<_ForwardIterator, _ForwardIterator>
+__simd_minmax_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept
+{
+    if (__n == 0)
+    {
+        return std::make_pair(__first, __first);
+    }
+    typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType;
+
+    struct _ComplexType
+    {
+        _ValueType __min_val_;
+        _ValueType __max_val_;
+        _Size __min_ind_;
+        _Size __max_ind_;
+        _Compare* __minmax_comp;
+
+        _LIBCPP_HIDE_FROM_ABI _ComplexType()
+            : __min_val_{}, __max_val_{}, __min_ind_{}, __max_ind_{}, __minmax_comp(nullptr) {}
+        _LIBCPP_HIDE_FROM_ABI _ComplexType(
+                const _ValueType& __min_val, const _ValueType& __max_val, const _Compare* __comp)
+            : __min_val_(__min_val), __max_val_(__max_val), __min_ind_(0), __max_ind_(0),
+              __minmax_comp(const_cast<_Compare*>(__comp))
+        {
+        }
+        _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj)
+            : __min_val_(__obj.__min_val_), __max_val_(__obj.__max_val_), __min_ind_(__obj.__min_ind_),
+              __max_ind_(__obj.__max_ind_), __minmax_comp(__obj.__minmax_comp)
+        {
+        }
+
+        _LIBCPP_HIDE_FROM_ABI void
+        operator()(const _ComplexType& __obj)
+        {
+            // min
+            if ((*__minmax_comp)(__obj.__min_val_, __min_val_))
+            {
+                __min_val_ = __obj.__min_val_;
+                __min_ind_ = __obj.__min_ind_;
+            }
+            else if (!(*__minmax_comp)(__min_val_, __obj.__min_val_))
+            {
+                __min_val_ = __obj.__min_val_;
+                __min_ind_ = (__min_ind_ - __obj.__min_ind_ < 0) ? __min_ind_ : __obj.__min_ind_;
+            }
+
+            // max
+            if ((*__minmax_comp)(__max_val_, __obj.__max_val_))
+            {
+                __max_val_ = __obj.__max_val_;
+                __max_ind_ = __obj.__max_ind_;
+            }
+            else if (!(*__minmax_comp)(__obj.__max_val_, __max_val_))
+            {
+                __max_val_ = __obj.__max_val_;
+                __max_ind_ = (__max_ind_ - __obj.__max_ind_ < 0) ? __obj.__max_ind_ : __max_ind_;
+            }
+        }
+    };
+
+    _ComplexType __init{*__first, *__first, &__comp};
+
+    _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType);
+
+    _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init)
+    for (_Size __i = 1; __i < __n; ++__i)
+    {
+        auto __min_val = __init.__min_val_;
+        auto __max_val = __init.__max_val_;
+        auto __current = __first + __i;
+        if (__comp(*__current, __min_val))
+        {
+            __init.__min_val_ = *__current;
+            __init.__min_ind_ = __i;
+        }
+        else if (!__comp(*__current, __max_val))
+        {
+            __init.__max_val_ = *__current;
+            __init.__max_ind_ = __i;
+        }
+    }
+    return std::make_pair(__first + __init.__min_ind_, __first + __init.__max_ind_);
+}
+
+template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2,
+          class _UnaryPredicate>
+_LIBCPP_HIDE_FROM_ABI std::pair<_OutputIterator1, _OutputIterator2>
+__simd_partition_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true,
+                      _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept
+{
+    _DifferenceType __cnt_true = 0, __cnt_false = 0;
+
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 0; __i < __n; ++__i)
+    {
+        if (__pred(__first[__i]))
+        {
+            __out_true[__cnt_true] = __first[__i];
+            ++__cnt_true;
+        }
+        else
+        {
+            __out_false[__cnt_false] = __first[__i];
+            ++__cnt_false;
+        }
+    }
+    return std::make_pair(__out_true + __cnt_true, __out_false + __cnt_false);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator1
+__simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
+                     _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept
+{
+    typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferencType;
+
+    const _DifferencType __n1 = __last - __first;
+    const _DifferencType __n2 = __s_last - __s_first;
+    if (__n1 == 0 || __n2 == 0)
+    {
+        return __last; // according to the standard
+    }
+
+    // Common case
+    // If first sequence larger than second then we'll run simd_first with parameters of first sequence.
+    // Otherwise, vice versa.
+    if (__n1 < __n2)
+    {
+        for (; __first != __last; ++__first)
+        {
+            if (__unseq_backend::__simd_or(
+                    __s_first, __n2,
+                    __internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
+            {
+                return __first;
+            }
+        }
+    }
+    else
+    {
+        for (; __s_first != __s_last; ++__s_first)
+        {
+            const auto __result = __unseq_backend::__simd_first(
+                __first, _DifferencType(0), __n1, [__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
+                    return __pred(__it[__i], *__s_first);
+                });
+            if (__result != __last)
+            {
+                return __result;
+            }
+        }
+    }
+    return __last;
+}
+
+template <class _RandomAccessIterator, class _DifferenceType, class _UnaryPredicate>
+_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
+__simd_remove_if(_RandomAccessIterator __first, _DifferenceType __n, _UnaryPredicate __pred) noexcept
+{
+    // find first element we need to remove
+    auto __current = __unseq_backend::__simd_first(
+        __first, _DifferenceType(0), __n,
+        [&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
+    __n -= __current - __first;
+
+    // if we have in sequence only one element that pred(__current[1]) != false we can exit the function
+    if (__n < 2)
+    {
+        return __current;
+    }
+
+    _DifferenceType __cnt = 0;
+    _PSTL_PRAGMA_SIMD
+    for (_DifferenceType __i = 1; __i < __n; ++__i)
+    {
+        if (!__pred(__current[__i]))
+        {
+            __current[__cnt] = std::move(__current[__i]);
+            ++__cnt;
+        }
+    }
+    return __current + __cnt;
+}
+} // namespace __unseq_backend
+} // namespace __pstl
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif /* _PSTL_UNSEQ_BACKEND_SIMD_H */
lib/libcxx/include/__pstl/internal/utils.h
@@ -0,0 +1,144 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _PSTL_UTILS_H
+#define _PSTL_UTILS_H
+
+#include <__config>
+#include <__exception/terminate.h>
+#include <__utility/forward.h>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+namespace __pstl {
+namespace __internal {
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI auto __except_handler(_Fp __f) -> decltype(__f()) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+    return __f();
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  } catch (const std::bad_alloc&) {
+    throw;            // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions]
+  } catch (...) {
+    std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions]
+  }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+}
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI void __invoke_if(std::true_type, _Fp __f) {
+  __f();
+}
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI void __invoke_if(std::false_type, _Fp) {}
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::false_type, _Fp __f) {
+  __f();
+}
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::true_type, _Fp) {}
+
+template <typename _F1, typename _F2>
+_LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1()) {
+  return __f1();
+}
+
+template <typename _F1, typename _F2>
+_LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2()) {
+  return __f2();
+}
+
+//! Unary operator that returns reference to its argument.
+struct __no_op {
+  template <typename _Tp>
+  _LIBCPP_HIDE_FROM_ABI _Tp&& operator()(_Tp&& __a) const {
+    return std::forward<_Tp>(__a);
+  }
+};
+
+template <typename _Pred>
+class __reorder_pred {
+  _Pred __pred_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit __reorder_pred(_Pred __pred) : __pred_(__pred) {}
+
+  template <typename _FTp, typename _STp>
+  _LIBCPP_HIDE_FROM_ABI bool operator()(_FTp&& __a, _STp&& __b) {
+    return __pred_(std::forward<_STp>(__b), std::forward<_FTp>(__a));
+  }
+};
+
+//! Like a polymorphic lambda for pred(...,value)
+template <typename _Tp, typename _Predicate>
+class __equal_value_by_pred {
+  const _Tp& __value_;
+  _Predicate __pred_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI __equal_value_by_pred(const _Tp& __value, _Predicate __pred)
+      : __value_(__value), __pred_(__pred) {}
+
+  template <typename _Arg>
+  _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) {
+    return __pred_(std::forward<_Arg>(__arg), __value_);
+  }
+};
+
+//! Like a polymorphic lambda for ==value
+template <typename _Tp>
+class __equal_value {
+  const _Tp& __value_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit __equal_value(const _Tp& __value) : __value_(__value) {}
+
+  template <typename _Arg>
+  _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const {
+    return std::forward<_Arg>(__arg) == __value_;
+  }
+};
+
+//! Logical negation of ==value
+template <typename _Tp>
+class __not_equal_value {
+  const _Tp& __value_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit __not_equal_value(const _Tp& __value) : __value_(__value) {}
+
+  template <typename _Arg>
+  _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const {
+    return !(std::forward<_Arg>(__arg) == __value_);
+  }
+};
+
+template <typename _ForwardIterator, typename _Compare>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+__cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp) {
+  if (__a < __b) { // we should return closer iterator
+    return __comp(*__b, *__a) ? __b : __a;
+  } else {
+    return __comp(*__a, *__b) ? __a : __b;
+  }
+}
+
+} // namespace __internal
+} // namespace __pstl
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+#endif /* _PSTL_UTILS_H */
lib/libcxx/include/__random/binomial_distribution.h
@@ -42,7 +42,7 @@ public:
     public:
         typedef binomial_distribution distribution_type;
 
-        explicit param_type(result_type __t = 1, double __p = 0.5);
+        _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __t = 1, double __p = 0.5);
 
         _LIBCPP_INLINE_VISIBILITY
         result_type t() const {return __t_;}
@@ -85,7 +85,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/clamp_to_integral.h
@@ -12,7 +12,6 @@
 #include <__config>
 #include <cmath>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -44,8 +43,8 @@ template <class _IntT, class _RealT>
 _LIBCPP_INLINE_VISIBILITY
 _IntT __clamp_to_integral(_RealT __r) _NOEXCEPT {
   using _Lim = numeric_limits<_IntT>;
-  const _IntT _MaxVal = __max_representable_int_for_float<_IntT, _RealT>();
-  if (__r >= ::nextafter(static_cast<_RealT>(_MaxVal), INFINITY)) {
+  const _IntT __max_val = __max_representable_int_for_float<_IntT, _RealT>();
+  if (__r >= ::nextafter(static_cast<_RealT>(__max_val), INFINITY)) {
     return _Lim::max();
   } else if (__r <= _Lim::lowest()) {
     return _Lim::min();
lib/libcxx/include/__random/discard_block_engine.h
@@ -11,10 +11,12 @@
 
 #include <__config>
 #include <__random/is_seed_sequence.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_convertible.h>
 #include <__utility/move.h>
+#include <cstddef>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -90,7 +92,7 @@ public:
         seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
 
     // generating functions
-    result_type operator()();
+    _LIBCPP_HIDE_FROM_ABI result_type operator()();
     _LIBCPP_INLINE_VISIBILITY
     void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
 
lib/libcxx/include/__random/discrete_distribution.h
@@ -53,10 +53,10 @@ public:
             : __p_(__wl.begin(), __wl.end()) {__init();}
 #endif // _LIBCPP_CXX03_LANG
         template<class _UnaryOperation>
-            param_type(size_t __nw, double __xmin, double __xmax,
+        _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, double __xmin, double __xmax,
                        _UnaryOperation __fw);
 
-        vector<double> probabilities() const;
+        _LIBCPP_HIDE_FROM_ABI vector<double> probabilities() const;
 
         friend _LIBCPP_INLINE_VISIBILITY
             bool operator==(const param_type& __x, const param_type& __y)
@@ -66,7 +66,7 @@ public:
             {return !(__x == __y);}
 
     private:
-        void __init();
+        _LIBCPP_HIDE_FROM_ABI void __init();
 
         friend class discrete_distribution;
 
@@ -115,7 +115,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/exponential_distribution.h
@@ -79,7 +79,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/extreme_value_distribution.h
@@ -84,7 +84,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/fisher_f_distribution.h
@@ -82,7 +82,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/gamma_distribution.h
@@ -85,7 +85,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/generate_canonical.h
@@ -30,20 +30,20 @@ template<class _RealType, size_t __bits, class _URNG>
 _LIBCPP_HIDE_FROM_ABI _RealType
 generate_canonical(_URNG& __g)
 {
-    const size_t _Dt = numeric_limits<_RealType>::digits;
-    const size_t __b = _Dt < __bits ? _Dt : __bits;
+    const size_t __dt = numeric_limits<_RealType>::digits;
+    const size_t __b = __dt < __bits ? __dt : __bits;
 #ifdef _LIBCPP_CXX03_LANG
-    const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
+    const size_t __log_r = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
 #else
-    const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
+    const size_t __log_r = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
 #endif
-    const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0);
-    const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1);
-    _RealType __base = _Rp;
-    _RealType _Sp = __g() - _URNG::min();
-    for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp)
-        _Sp += (__g() - _URNG::min()) * __base;
-    return _Sp / __base;
+    const size_t __k = __b / __log_r + (__b % __log_r != 0) + (__b == 0);
+    const _RealType __rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1);
+    _RealType __base = __rp;
+    _RealType __sp = __g() - _URNG::min();
+    for (size_t __i = 1; __i < __k; ++__i, __base *= __rp)
+        __sp += (__g() - _URNG::min()) * __base;
+    return __sp / __base;
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__random/independent_bits_engine.h
@@ -12,10 +12,13 @@
 #include <__config>
 #include <__random/is_seed_sequence.h>
 #include <__random/log2.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_convertible.h>
 #include <__utility/move.h>
+#include <cstddef>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -161,7 +164,7 @@ public:
 private:
     _LIBCPP_INLINE_VISIBILITY
     result_type __eval(false_type);
-    result_type __eval(true_type);
+    _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type);
 
     template <size_t __count>
         _LIBCPP_INLINE_VISIBILITY
@@ -196,7 +199,7 @@ template<class _Engine, size_t __w, class _UIntType>
 _UIntType
 independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
 {
-    result_type _Sp = 0;
+    result_type __sp = 0;
     for (size_t __k = 0; __k < __n0; ++__k)
     {
         _Engine_result_type __u;
@@ -204,7 +207,7 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y0);
-        _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0));
+        __sp = static_cast<result_type>(__lshift<__w0>(__sp) + (__u & __mask0));
     }
     for (size_t __k = __n0; __k < __n; ++__k)
     {
@@ -213,9 +216,9 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y1);
-        _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1));
+        __sp = static_cast<result_type>(__lshift<__w0+1>(__sp) + (__u & __mask1));
     }
-    return _Sp;
+    return __sp;
 }
 
 template<class _Eng, size_t _Wp, class _UInt>
lib/libcxx/include/__random/is_seed_sequence.h
@@ -10,7 +10,9 @@
 #define _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H
 
 #include <__config>
-#include <type_traits>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__random/is_valid.h
@@ -10,8 +10,12 @@
 #define _LIBCPP___RANDOM_IS_VALID_H
 
 #include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_unsigned.h>
+#include <__utility/declval.h>
 #include <cstdint>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__random/linear_congruential_engine.h
@@ -11,9 +11,11 @@
 
 #include <__config>
 #include <__random/is_seed_sequence.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_unsigned.h>
 #include <cstdint>
 #include <iosfwd>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -294,9 +296,9 @@ private:
     void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}
 
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
 
     template <class _CharT, class _Traits,
               class _Up, _Up _Ap, _Up _Cp, _Up _Np>
lib/libcxx/include/__random/log2.h
@@ -10,8 +10,8 @@
 #define _LIBCPP___RANDOM_LOG2_H
 
 #include <__config>
+#include <__type_traits/conditional.h>
 #include <cstddef>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/__random/lognormal_distribution.h
@@ -24,142 +24,6 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
-
-template<class _RealType = double>
-class _LIBCPP_TEMPLATE_VIS lognormal_distribution
-{
-public:
-    // types
-    typedef _RealType result_type;
-
-    class _LIBCPP_TEMPLATE_VIS param_type
-    {
-        normal_distribution<result_type> __nd_;
-    public:
-        typedef lognormal_distribution distribution_type;
-
-        _LIBCPP_INLINE_VISIBILITY
-        explicit param_type(result_type __m = 0, result_type __s = 1)
-            : __nd_(__m, __s) {}
-
-        _LIBCPP_INLINE_VISIBILITY
-        result_type m() const {return __nd_.mean();}
-        _LIBCPP_INLINE_VISIBILITY
-        result_type s() const {return __nd_.stddev();}
-
-        friend _LIBCPP_INLINE_VISIBILITY
-            bool operator==(const param_type& __x, const param_type& __y)
-            {return __x.__nd_ == __y.__nd_;}
-        friend _LIBCPP_INLINE_VISIBILITY
-            bool operator!=(const param_type& __x, const param_type& __y)
-            {return !(__x == __y);}
-        friend class lognormal_distribution;
-
-        template <class _CharT, class _Traits, class _RT>
-        friend
-        basic_ostream<_CharT, _Traits>&
-        operator<<(basic_ostream<_CharT, _Traits>& __os,
-                   const lognormal_distribution<_RT>& __x);
-
-        template <class _CharT, class _Traits, class _RT>
-        friend
-        basic_istream<_CharT, _Traits>&
-        operator>>(basic_istream<_CharT, _Traits>& __is,
-                   lognormal_distribution<_RT>& __x);
-    };
-
-private:
-    param_type __p_;
-
-public:
-    // constructor and reset functions
-#ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
-    lognormal_distribution() : lognormal_distribution(0) {}
-    _LIBCPP_INLINE_VISIBILITY
-    explicit lognormal_distribution(result_type __m, result_type __s = 1)
-        : __p_(param_type(__m, __s)) {}
-#else
-    _LIBCPP_INLINE_VISIBILITY
-    explicit lognormal_distribution(result_type __m = 0,
-                                    result_type __s = 1)
-        : __p_(param_type(__m, __s)) {}
-#endif
-    _LIBCPP_INLINE_VISIBILITY
-    explicit lognormal_distribution(const param_type& __p)
-        : __p_(__p) {}
-    _LIBCPP_INLINE_VISIBILITY
-    void reset() {__p_.__nd_.reset();}
-
-    // generating functions
-    template<class _URNG>
-        _LIBCPP_INLINE_VISIBILITY
-        result_type operator()(_URNG& __g)
-        {return (*this)(__g, __p_);}
-    template<class _URNG>
-        _LIBCPP_INLINE_VISIBILITY
-        result_type operator()(_URNG& __g, const param_type& __p)
-        {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));}
-
-    // property functions
-    _LIBCPP_INLINE_VISIBILITY
-    result_type m() const {return __p_.m();}
-    _LIBCPP_INLINE_VISIBILITY
-    result_type s() const {return __p_.s();}
-
-    _LIBCPP_INLINE_VISIBILITY
-    param_type param() const {return __p_;}
-    _LIBCPP_INLINE_VISIBILITY
-    void param(const param_type& __p) {__p_ = __p;}
-
-    _LIBCPP_INLINE_VISIBILITY
-    result_type min() const {return 0;}
-    _LIBCPP_INLINE_VISIBILITY
-    result_type max() const {return numeric_limits<result_type>::infinity();}
-
-    friend _LIBCPP_INLINE_VISIBILITY
-        bool operator==(const lognormal_distribution& __x,
-                        const lognormal_distribution& __y)
-        {return __x.__p_ == __y.__p_;}
-    friend _LIBCPP_INLINE_VISIBILITY
-        bool operator!=(const lognormal_distribution& __x,
-                        const lognormal_distribution& __y)
-        {return !(__x == __y);}
-
-    template <class _CharT, class _Traits, class _RT>
-    friend
-    basic_ostream<_CharT, _Traits>&
-    operator<<(basic_ostream<_CharT, _Traits>& __os,
-               const lognormal_distribution<_RT>& __x);
-
-    template <class _CharT, class _Traits, class _RT>
-    friend
-    basic_istream<_CharT, _Traits>&
-    operator>>(basic_istream<_CharT, _Traits>& __is,
-               lognormal_distribution<_RT>& __x);
-};
-
-template <class _CharT, class _Traits, class _RT>
-inline _LIBCPP_INLINE_VISIBILITY
-basic_ostream<_CharT, _Traits>&
-operator<<(basic_ostream<_CharT, _Traits>& __os,
-           const lognormal_distribution<_RT>& __x)
-{
-    return __os << __x.__p_.__nd_;
-}
-
-template <class _CharT, class _Traits, class _RT>
-inline _LIBCPP_INLINE_VISIBILITY
-basic_istream<_CharT, _Traits>&
-operator>>(basic_istream<_CharT, _Traits>& __is,
-           lognormal_distribution<_RT>& __x)
-{
-    return __is >> __x.__p_.__nd_;
-}
-
-#else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
-
 template<class _RealType = double>
 class _LIBCPP_TEMPLATE_VIS lognormal_distribution
 {
@@ -290,8 +154,6 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
     return __is >> __x.__nd_;
 }
 
-#endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
-
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
lib/libcxx/include/__random/mersenne_twister_engine.h
@@ -17,7 +17,6 @@
 #include <cstdint>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -141,7 +140,7 @@ public:
         explicit mersenne_twister_engine(_Sseq& __q,
         typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)
         {seed(__q);}
-    void seed(result_type __sd = default_seed);
+    _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
     template<class _Sseq>
         _LIBCPP_INLINE_VISIBILITY
         typename enable_if
@@ -153,7 +152,7 @@ public:
             {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
 
     // generating functions
-    result_type operator()();
+    _LIBCPP_HIDE_FROM_ABI result_type operator()();
     _LIBCPP_INLINE_VISIBILITY
     void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
 
@@ -199,9 +198,9 @@ public:
 private:
 
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
 
     template <size_t __count>
         _LIBCPP_INLINE_VISIBILITY
@@ -403,9 +402,9 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
     const size_t __j = (__i_ + 1) % __n;
     const result_type __mask = __r == _Dt ? result_type(~0) :
                                        (result_type(1) << __r) - result_type(1);
-    const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
+    const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
     const size_t __k = (__i_ + __m) % __n;
-    __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1));
+    __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
     result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
     __i_ = __j;
     __z ^= __lshift<__s>(__z) & __b;
lib/libcxx/include/__random/negative_binomial_distribution.h
@@ -85,7 +85,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -135,8 +136,9 @@ negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_
             else
                 ++__f;
         }
-        _LIBCPP_ASSERT(__f >= 0, "std::negative_binomial_distribution should never produce negative values. "
-                                 "This is almost certainly a signed integer overflow issue on __f.");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__f >= 0,
+                                     "std::negative_binomial_distribution should never produce negative values. "
+                                     "This is almost certainly a signed integer overflow issue on __f.");
         return __f;
     }
     return poisson_distribution<result_type>(gamma_distribution<double>
lib/libcxx/include/__random/normal_distribution.h
@@ -86,7 +86,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -133,30 +134,30 @@ _RealType
 normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
 {
     static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
-    result_type _Up;
+    result_type __up;
     if (__v_hot_)
     {
         __v_hot_ = false;
-        _Up = __v_;
+        __up = __v_;
     }
     else
     {
-        uniform_real_distribution<result_type> _Uni(-1, 1);
+        uniform_real_distribution<result_type> __uni(-1, 1);
         result_type __u;
         result_type __v;
         result_type __s;
         do
         {
-            __u = _Uni(__g);
-            __v = _Uni(__g);
+            __u = __uni(__g);
+            __v = __uni(__g);
             __s = __u * __u + __v * __v;
         } while (__s > 1 || __s == 0);
-        result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
-        __v_ = __v * _Fp;
+        result_type __fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
+        __v_ = __v * __fp;
         __v_hot_ = true;
-        _Up = __u * _Fp;
+        __up = __u * __fp;
     }
-    return _Up * __p.stddev() + __p.mean();
+    return __up * __p.stddev() + __p.mean();
 }
 
 template <class _CharT, class _Traits, class _RT>
@@ -189,16 +190,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
     __is.flags(_Istream::dec | _Istream::skipws);
     result_type __mean;
     result_type __stddev;
-    result_type _Vp = 0;
-    bool _V_hot = false;
-    __is >> __mean >> __stddev >> _V_hot;
-    if (_V_hot)
-        __is >> _Vp;
+    result_type __vp = 0;
+    bool __v_hot = false;
+    __is >> __mean >> __stddev >> __v_hot;
+    if (__v_hot)
+        __is >> __vp;
     if (!__is.fail())
     {
         __x.param(param_type(__mean, __stddev));
-        __x.__v_hot_ = _V_hot;
-        __x.__v_ = _Vp;
+        __x.__v_hot_ = __v_hot;
+        __x.__v_ = __vp;
     }
     return __is;
 }
lib/libcxx/include/__random/piecewise_constant_distribution.h
@@ -41,19 +41,19 @@ public:
     public:
         typedef piecewise_constant_distribution distribution_type;
 
-        param_type();
+        _LIBCPP_HIDE_FROM_ABI param_type();
         template<class _InputIteratorB, class _InputIteratorW>
-            param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
+        _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
                        _InputIteratorW __f_w);
 #ifndef _LIBCPP_CXX03_LANG
         template<class _UnaryOperation>
-            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
+        _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
 #endif // _LIBCPP_CXX03_LANG
         template<class _UnaryOperation>
-            param_type(size_t __nw, result_type __xmin, result_type __xmax,
+        _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax,
                        _UnaryOperation __fw);
-        param_type(param_type const&) = default;
-        param_type & operator=(const param_type& __rhs);
+        _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default;
+        _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs);
 
         _LIBCPP_INLINE_VISIBILITY
         vector<result_type> intervals() const {return __b_;}
@@ -68,7 +68,7 @@ public:
             {return !(__x == __y);}
 
     private:
-        void __init();
+        _LIBCPP_HIDE_FROM_ABI void __init();
 
         friend class piecewise_constant_distribution;
 
@@ -125,7 +125,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/piecewise_linear_distribution.h
@@ -41,19 +41,19 @@ public:
     public:
         typedef piecewise_linear_distribution distribution_type;
 
-        param_type();
+        _LIBCPP_HIDE_FROM_ABI param_type();
         template<class _InputIteratorB, class _InputIteratorW>
-            param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
+        _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
                        _InputIteratorW __f_w);
 #ifndef _LIBCPP_CXX03_LANG
         template<class _UnaryOperation>
-            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
+        _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
 #endif // _LIBCPP_CXX03_LANG
         template<class _UnaryOperation>
-            param_type(size_t __nw, result_type __xmin, result_type __xmax,
+        _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax,
                        _UnaryOperation __fw);
-        param_type(param_type const&) = default;
-        param_type & operator=(const param_type& __rhs);
+        _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default;
+        _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs);
 
         _LIBCPP_INLINE_VISIBILITY
         vector<result_type> intervals() const {return __b_;}
@@ -68,7 +68,7 @@ public:
             {return !(__x == __y);}
 
     private:
-        void __init();
+        _LIBCPP_HIDE_FROM_ABI void __init();
 
         friend class piecewise_linear_distribution;
 
@@ -125,7 +125,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -188,23 +189,23 @@ void
 piecewise_linear_distribution<_RealType>::param_type::__init()
 {
     __areas_.assign(__densities_.size() - 1, result_type());
-    result_type _Sp = 0;
+    result_type __sp = 0;
     for (size_t __i = 0; __i < __areas_.size(); ++__i)
     {
         __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) *
                         (__b_[__i+1] - __b_[__i]) * .5;
-        _Sp += __areas_[__i];
+        __sp += __areas_[__i];
     }
     for (size_t __i = __areas_.size(); __i > 1;)
     {
         --__i;
-        __areas_[__i] = __areas_[__i-1] / _Sp;
+        __areas_[__i] = __areas_[__i-1] / __sp;
     }
     __areas_[0] = 0;
     for (size_t __i = 1; __i < __areas_.size(); ++__i)
         __areas_[__i] += __areas_[__i-1];
     for (size_t __i = 0; __i < __densities_.size(); ++__i)
-        __densities_[__i] /= _Sp;
+        __densities_[__i] /= __sp;
 }
 
 template<class _RealType>
lib/libcxx/include/__random/poisson_distribution.h
@@ -52,7 +52,7 @@ public:
     public:
         typedef poisson_distribution distribution_type;
 
-        explicit param_type(double __mean = 1.0);
+        _LIBCPP_HIDE_FROM_ABI explicit param_type(double __mean = 1.0);
 
         _LIBCPP_INLINE_VISIBILITY
         double mean() const {return __mean_;}
@@ -93,7 +93,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -144,12 +145,12 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean)
         __d_ = 6 * __mean_ * __mean_;
         __l_ = _VSTD::trunc(__mean_ - 1.1484);
         __omega_ = .3989423 / __s_;
-        double __b1_ = .4166667E-1 / __mean_;
-        double __b2_ = .3 * __b1_ * __b1_;
-        __c3_ = .1428571 * __b1_ * __b2_;
-        __c2_ = __b2_ - 15. * __c3_;
-        __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_;
-        __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_;
+        double __b1 = .4166667E-1 / __mean_;
+        double __b2 = .3 * __b1 * __b1;
+        __c3_ = .1428571 * __b1 * __b2;
+        __c2_ = __b2 - 15. * __c3_;
+        __c1_ = __b1 - 6. * __b2 + 45. * __c3_;
+        __c0_ = 1. - __b1 + 3. * __b2 - 15. * __c3_;
         __c_ = .1069 / __mean_;
     }
 }
lib/libcxx/include/__random/random_device.h
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
 
-class _LIBCPP_TYPE_VIS random_device
+class _LIBCPP_EXPORTED_FROM_ABI random_device
 {
 #ifdef _LIBCPP_USING_DEV_RANDOM
     int __f_;
@@ -58,7 +58,7 @@ public:
 
     // constructors
 #ifndef _LIBCPP_CXX03_LANG
-    random_device() : random_device("/dev/urandom") {}
+    _LIBCPP_HIDE_FROM_ABI random_device() : random_device("/dev/urandom") {}
     explicit random_device(const string& __token);
 #else
     explicit random_device(const string& __token = "/dev/urandom");
lib/libcxx/include/__random/seed_seq.h
@@ -13,6 +13,8 @@
 #include <__algorithm/fill.h>
 #include <__algorithm/max.h>
 #include <__config>
+#include <__iterator/iterator_traits.h>
+#include <cstdint>
 #include <initializer_list>
 #include <vector>
 
@@ -52,7 +54,7 @@ public:
 
     // generating functions
     template<class _RandomAccessIterator>
-        void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
+    _LIBCPP_HIDE_FROM_ABI void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -70,7 +72,7 @@ public:
 
 private:
     template<class _InputIterator>
-    void __init(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI void __init(_InputIterator __first, _InputIterator __last);
 
     vector<result_type> __v_;
 };
lib/libcxx/include/__random/shuffle_order_engine.h
@@ -12,10 +12,13 @@
 #include <__algorithm/equal.h>
 #include <__config>
 #include <__random/is_seed_sequence.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_convertible.h>
 #include <__utility/move.h>
+#include <cstddef>
 #include <cstdint>
 #include <iosfwd>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -201,10 +204,10 @@ private:
         _LIBCPP_INLINE_VISIBILITY
         result_type __evalf()
         {
-            const double _Fp = __d == 0 ?
+            const double __fp = __d == 0 ?
                 __n / (2. * 0x8000000000000000ull) :
                 __n / (double)__d;
-            const size_t __j = static_cast<size_t>(_Fp * (__y_ - _Min));
+            const size_t __j = static_cast<size_t>(__fp * (__y_ - _Min));
             __y_ = __v_[__j];
             __v_[__j] = __e_();
             return __y_;
@@ -262,16 +265,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
     typedef basic_istream<_CharT, _Traits> _Istream;
     __is.flags(_Istream::dec | _Istream::skipws);
     _Eng __e;
-    result_type _Vp[_Kp+1];
+    result_type __vp[_Kp+1];
     __is >> __e;
     for (size_t __i = 0; __i < _Kp+1; ++__i)
-        __is >> _Vp[__i];
+        __is >> __vp[__i];
     if (!__is.fail())
     {
         __x.__e_ = __e;
         for (size_t __i = 0; __i < _Kp; ++__i)
-            __x.__v_[__i] = _Vp[__i];
-        __x.__y_ = _Vp[_Kp];
+            __x.__v_[__i] = __vp[__i];
+        __x.__y_ = __vp[_Kp];
     }
     return __is;
 }
lib/libcxx/include/__random/student_t_distribution.h
@@ -81,7 +81,8 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/subtract_with_carry_engine.h
@@ -18,7 +18,6 @@
 #include <cstdint>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -121,7 +120,7 @@ public:
             {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
 
     // generating functions
-    result_type operator()();
+    _LIBCPP_HIDE_FROM_ABI result_type operator()();
     _LIBCPP_INLINE_VISIBILITY
     void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
 
@@ -155,12 +154,12 @@ public:
 
 private:
 
-    void seed(result_type __sd, integral_constant<unsigned, 1>);
-    void seed(result_type __sd, integral_constant<unsigned, 2>);
+    _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 1>);
+    _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 2>);
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
     template<class _Sseq>
-        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+    _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
 };
 
 template<class _UIntType, size_t __w, size_t __s, size_t __r>
lib/libcxx/include/__random/uniform_int_distribution.h
@@ -9,15 +9,16 @@
 #ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
 #define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
 
+#include <__bit/countl.h>
 #include <__config>
 #include <__random/is_valid.h>
 #include <__random/log2.h>
-#include <bit>
+#include <__type_traits/conditional.h>
+#include <__type_traits/make_unsigned.h>
 #include <cstddef>
 #include <cstdint>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -63,14 +64,14 @@ private:
 
 public:
     // constructors and seeding functions
-    __independent_bits_engine(_Engine& __e, size_t __w);
+    _LIBCPP_HIDE_FROM_ABI __independent_bits_engine(_Engine& __e, size_t __w);
 
     // generating functions
-    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
+    _LIBCPP_HIDE_FROM_ABI result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
 
 private:
-    result_type __eval(false_type);
-    result_type __eval(true_type);
+    _LIBCPP_HIDE_FROM_ABI result_type __eval(false_type);
+    _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type);
 };
 
 template<class _Engine, class _UIntType>
@@ -120,8 +121,8 @@ template<class _Engine, class _UIntType>
 _UIntType
 __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
 {
-    const size_t _WRt = numeric_limits<result_type>::digits;
-    result_type _Sp = 0;
+    const size_t __w_rt = numeric_limits<result_type>::digits;
+    result_type __sp = 0;
     for (size_t __k = 0; __k < __n0_; ++__k)
     {
         _Engine_result_type __u;
@@ -129,11 +130,11 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y0_);
-        if (__w0_ < _WRt)
-            _Sp <<= __w0_;
+        if (__w0_ < __w_rt)
+            __sp <<= __w0_;
         else
-            _Sp = 0;
-        _Sp += __u & __mask0_;
+            __sp = 0;
+        __sp += __u & __mask0_;
     }
     for (size_t __k = __n0_; __k < __n_; ++__k)
     {
@@ -142,13 +143,13 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y1_);
-        if (__w0_ < _WRt - 1)
-            _Sp <<= __w0_ + 1;
+        if (__w0_ < __w_rt - 1)
+            __sp <<= __w0_ + 1;
         else
-            _Sp = 0;
-        _Sp += __u & __mask1_;
+            __sp = 0;
+        __sp += __u & __mask1_;
     }
-    return _Sp;
+    return __sp;
 }
 
 template<class _IntType = int>
@@ -166,12 +167,12 @@ public:
     public:
         typedef uniform_int_distribution distribution_type;
 
-        explicit param_type(result_type __a = 0,
+        _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __a = 0,
                             result_type __b = numeric_limits<result_type>::max())
             : __a_(__a), __b_(__b) {}
 
-        result_type a() const {return __a_;}
-        result_type b() const {return __b_;}
+        _LIBCPP_HIDE_FROM_ABI result_type a() const {return __a_;}
+        _LIBCPP_HIDE_FROM_ABI result_type b() const {return __b_;}
 
         _LIBCPP_HIDE_FROM_ABI
         friend bool operator==(const param_type& __x, const param_type& __y)
@@ -187,8 +188,8 @@ private:
 public:
     // constructors and reset functions
 #ifndef _LIBCPP_CXX03_LANG
-    uniform_int_distribution() : uniform_int_distribution(0) {}
-    explicit uniform_int_distribution(
+    _LIBCPP_HIDE_FROM_ABI uniform_int_distribution() : uniform_int_distribution(0) {}
+    _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(
         result_type __a, result_type __b = numeric_limits<result_type>::max())
         : __p_(param_type(__a, __b)) {}
 #else
@@ -197,23 +198,25 @@ public:
         result_type __b = numeric_limits<result_type>::max())
         : __p_(param_type(__a, __b)) {}
 #endif
-    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
-    void reset() {}
+    _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_HIDE_FROM_ABI void reset() {}
 
     // generating functions
-    template<class _URNG> result_type operator()(_URNG& __g)
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG>
+    _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
-    result_type a() const {return __p_.a();}
-    result_type b() const {return __p_.b();}
+    _LIBCPP_HIDE_FROM_ABI result_type a() const {return __p_.a();}
+    _LIBCPP_HIDE_FROM_ABI result_type b() const {return __p_.b();}
 
-    param_type param() const {return __p_;}
-    void param(const param_type& __p) {__p_ = __p;}
+    _LIBCPP_HIDE_FROM_ABI param_type param() const {return __p_;}
+    _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) {__p_ = __p;}
 
-    result_type min() const {return a();}
-    result_type max() const {return b();}
+    _LIBCPP_HIDE_FROM_ABI result_type min() const {return a();}
+    _LIBCPP_HIDE_FROM_ABI result_type max() const {return b();}
 
     _LIBCPP_HIDE_FROM_ABI
     friend bool operator==(const uniform_int_distribution& __x,
@@ -234,22 +237,22 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
     static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
     typedef __conditional_t<sizeof(result_type) <= sizeof(uint32_t), uint32_t, __make_unsigned_t<result_type> >
         _UIntType;
-    const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
-    if (_Rp == 1)
+    const _UIntType __rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
+    if (__rp == 1)
         return __p.a();
-    const size_t _Dt = numeric_limits<_UIntType>::digits;
+    const size_t __dt = numeric_limits<_UIntType>::digits;
     typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
-    if (_Rp == 0)
-        return static_cast<result_type>(_Eng(__g, _Dt)());
-    size_t __w = _Dt - std::__countl_zero(_Rp) - 1;
-    if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
+    if (__rp == 0)
+        return static_cast<result_type>(_Eng(__g, __dt)());
+    size_t __w = __dt - std::__countl_zero(__rp) - 1;
+    if ((__rp & (numeric_limits<_UIntType>::max() >> (__dt - __w))) != 0)
         ++__w;
     _Eng __e(__g, __w);
     _UIntType __u;
     do
     {
         __u = __e();
-    } while (__u >= _Rp);
+    } while (__u >= __rp);
     return static_cast<result_type>(__u + __p.a());
 }
 
lib/libcxx/include/__random/uniform_random_bit_generator.h
@@ -13,7 +13,8 @@
 #include <__concepts/invocable.h>
 #include <__concepts/same_as.h>
 #include <__config>
-#include <type_traits>
+#include <__functional/invoke.h>
+#include <__type_traits/integral_constant.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,7 +25,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [rand.req.urng]
 template<class _Gen>
@@ -36,7 +37,7 @@ concept uniform_random_bit_generator =
     requires bool_constant<(_Gen::min() < _Gen::max())>::value;
   };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__random/uniform_real_distribution.h
@@ -14,7 +14,6 @@
 #include <__random/is_valid.h>
 #include <iosfwd>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -65,7 +64,7 @@ public:
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     uniform_real_distribution() : uniform_real_distribution(0) {}
-    explicit uniform_real_distribution(result_type __a, result_type __b = 1)
+    _LIBCPP_HIDE_FROM_ABI explicit uniform_real_distribution(result_type __a, result_type __b = 1)
         : __p_(param_type(__a, __b)) {}
 #else
     _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__ranges/access.h
@@ -29,7 +29,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template <class _Tp>
@@ -223,7 +223,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/all.h
@@ -11,6 +11,8 @@
 #define _LIBCPP___RANGES_ALL_H
 
 #include <__config>
+#include <__functional/compose.h>         // TODO(modules): Those should not be required
+#include <__functional/perfect_forward.h> //
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__ranges/access.h>
@@ -18,10 +20,10 @@
 #include <__ranges/owning_view.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/ref_view.h>
+#include <__type_traits/decay.h>
 #include <__utility/auto_cast.h>
 #include <__utility/declval.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -29,7 +31,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges::views {
 
@@ -77,7 +79,7 @@ using all_t = decltype(views::all(std::declval<_Range>()));
 
 } // namespace ranges::views
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/as_rvalue_view.h
@@ -28,6 +28,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 #if _LIBCPP_STD_VER >= 23
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -125,7 +128,7 @@ struct __fn : __range_adaptor_closure<__fn> {
 } // namespace __as_rvalue
 
 inline namespace __cpo {
-constexpr auto as_rvalue = __as_rvalue::__fn{};
+inline constexpr auto as_rvalue = __as_rvalue::__fn{};
 } // namespace __cpo
 } // namespace views
 } // namespace ranges
@@ -134,4 +137,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 23
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___RANGES_AS_RVALUE_H
lib/libcxx/include/__ranges/common_view.h
@@ -24,15 +24,17 @@
 #include <__ranges/view_interface.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -130,8 +132,10 @@ inline namespace __cpo {
 } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___RANGES_COMMON_VIEW_H
lib/libcxx/include/__ranges/concepts.h
@@ -37,7 +37,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -73,6 +73,9 @@ namespace ranges {
   template <range _Rp>
   using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
 
+  template <range _Rp>
+  using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
+
   // [range.sized]
   template <class _Tp>
   concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
@@ -140,7 +143,7 @@ namespace ranges {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/container_compatible_range.h
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_CONTAINER_COMPATIBLE_RANGE_H
+#define _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__ranges/concepts.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Range, class _Tp>
+concept _ContainerCompatibleRange =
+    ranges::input_range<_Range> && convertible_to<ranges::range_reference_t<_Range>, _Tp>;
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H
lib/libcxx/include/__ranges/copyable_box.h
@@ -1,180 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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___RANGES_COPYABLE_BOX_H
-#define _LIBCPP___RANGES_COPYABLE_BOX_H
-
-#include <__concepts/constructible.h>
-#include <__concepts/copyable.h>
-#include <__concepts/movable.h>
-#include <__config>
-#include <__memory/addressof.h>
-#include <__memory/construct_at.h>
-#include <__utility/move.h>
-#include <optional>
-#include <type_traits>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if _LIBCPP_STD_VER > 17
-
-// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
-// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
-// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
-// to handle the case where the copy construction fails after destroying the object.
-//
-// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
-// __copyable_box that does this, see below for the details.
-
-template<class _Tp>
-concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;
-
-namespace ranges {
-  // Primary template - uses std::optional and introduces an empty state in case assignment fails.
-  template<__copy_constructible_object _Tp>
-  class __copyable_box {
-    _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
-
-  public:
-    template<class ..._Args>
-      requires is_constructible_v<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
-      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
-      : __val_(in_place, std::forward<_Args>(__args)...)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
-      requires default_initializable<_Tp>
-      : __val_(in_place)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box const& __other)
-      noexcept(is_nothrow_copy_constructible_v<_Tp>)
-    {
-      if (this != std::addressof(__other)) {
-        if (__other.__has_value()) __val_.emplace(*__other);
-        else                       __val_.reset();
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box&& __other)
-      noexcept(is_nothrow_move_constructible_v<_Tp>)
-    {
-      if (this != std::addressof(__other)) {
-        if (__other.__has_value()) __val_.emplace(std::move(*__other));
-        else                       __val_.reset();
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
-  };
-
-  // This partial specialization implements an optimization for when we know we don't need to store
-  // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
-  //
-  // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
-  //    directly and avoid using std::optional.
-  // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
-  //    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
-  //
-  // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
-  // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
-  // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
-  // operator.
-  template<class _Tp>
-  concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
-
-  template<class _Tp>
-  concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
-
-  template<__copy_constructible_object _Tp>
-    requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
-  class __copyable_box<_Tp> {
-    _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
-
-  public:
-    template<class ..._Args>
-      requires is_constructible_v<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
-      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
-      : __val_(std::forward<_Args>(__args)...)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
-      requires default_initializable<_Tp>
-      : __val_()
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
-
-    // Implementation of assignment operators in case we perform optimization (1)
-    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
-
-    // Implementation of assignment operators in case we perform optimization (2)
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
-      static_assert(is_nothrow_copy_constructible_v<_Tp>);
-      if (this != std::addressof(__other)) {
-        std::destroy_at(std::addressof(__val_));
-        std::construct_at(std::addressof(__val_), __other.__val_);
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
-      static_assert(is_nothrow_move_constructible_v<_Tp>);
-      if (this != std::addressof(__other)) {
-        std::destroy_at(std::addressof(__val_));
-        std::construct_at(std::addressof(__val_), std::move(__other.__val_));
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
-  };
-} // namespace ranges
-
-#endif // _LIBCPP_STD_VER > 17
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
lib/libcxx/include/__ranges/counted.h
@@ -19,10 +19,11 @@
 #include <__iterator/iterator_traits.h>
 #include <__memory/pointer_traits.h>
 #include <__ranges/subrange.h>
+#include <__type_traits/decay.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
+#include <cstddef>
 #include <span>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -30,7 +31,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges::views {
 
@@ -75,7 +76,7 @@ inline namespace __cpo {
 
 } // namespace ranges::views
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/dangling.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 struct dangling {
@@ -35,7 +35,7 @@ using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
 // borrowed_subrange_t defined in <__ranges/subrange.h>
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/data.h
@@ -30,7 +30,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.prim.data]
 
@@ -105,7 +105,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/drop_view.h
@@ -30,13 +30,19 @@
 #include <__ranges/iota_view.h>
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
+#include <__ranges/repeat_view.h>
 #include <__ranges/size.h>
 #include <__ranges/subrange.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/auto_cast.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -47,7 +53,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<view _View>
@@ -66,14 +72,14 @@ namespace ranges {
     _View __base_ = _View();
 
 public:
-    drop_view() requires default_initializable<_View> = default;
+    _LIBCPP_HIDE_FROM_ABI drop_view() requires default_initializable<_View> = default;
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr drop_view(_View __base, range_difference_t<_View> __count)
+    constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_view(_View __base, range_difference_t<_View> __count)
       : __count_(__count)
       , __base_(std::move(__base))
     {
-      _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
+      _LIBCPP_ASSERT_UNCATEGORIZED(__count_ >= 0, "count must be greater than or equal to zero.");
     }
 
     _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
@@ -255,13 +261,39 @@ struct __fn {
     {
       // Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
       // expression used in the `noexcept` clause and the return statement).
-      auto dist = ranges::distance(__rng);
-      auto clamped = std::min<_Dist>(dist, std::forward<_Np>(__n));
+      auto __dist = ranges::distance(__rng);
+      auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n));
       return          _RawRange(
-                              ranges::begin(__rng) + clamped,
+                              ranges::begin(__rng) + __clamped,
                               ranges::end(__rng),
-                              std::__to_unsigned_like(dist - clamped)
+                              std::__to_unsigned_like(__dist - __clamped)
                               );}
+// clang-format off
+#if _LIBCPP_STD_VER >= 23
+  // [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case.
+  template <class _Range,
+            convertible_to<range_difference_t<_Range>> _Np,
+            class _RawRange = remove_cvref_t<_Range>,
+            class _Dist     = range_difference_t<_Range>>
+    requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+    noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
+    -> decltype(      views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
+    { return          views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
+
+  // [range.drop.overview]: the `repeat_view` "otherwise" case.
+  template <class _Range,
+            convertible_to<range_difference_t<_Range>> _Np,
+            class _RawRange = remove_cvref_t<_Range>,
+            class _Dist     = range_difference_t<_Range>>
+    requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
+  constexpr auto operator()(_Range&& __range, _Np&&) const
+    noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
+    -> decltype(      _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
+    { return          _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
+#endif
+// clang-format on
 
   // [range.drop.overview]: the "otherwise" case.
   template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
@@ -269,6 +301,9 @@ struct __fn {
     // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
     // overloads.
     requires (!(__is_empty_view<_RawRange> ||
+#if _LIBCPP_STD_VER >= 23
+                __is_repeat_specialization<_RawRange> ||
+#endif
                (__is_subrange_specialization_with_store_size<_RawRange> &&
                sized_range<_RawRange> &&
                 random_access_range<_RawRange>) ||
@@ -299,7 +334,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/drop_while_view.h
@@ -20,8 +20,8 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/enable_borrowed_range.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
@@ -51,7 +51,7 @@ public:
     requires default_initializable<_View> && default_initializable<_Pred>
   = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr drop_while_view(_View __base, _Pred __pred)
+  _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_while_view(_View __base, _Pred __pred)
       : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
@@ -65,9 +65,10 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
 
   _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
-    _LIBCPP_ASSERT(__pred_.__has_value(),
-                   "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
-                   "assignment to this drop_while_view fail?");
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __pred_.__has_value(),
+        "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
+        "assignment to this drop_while_view fail?");
     if constexpr (_UseCache) {
       if (!__cached_begin_.__has_value()) {
         __cached_begin_.__emplace(ranges::find_if_not(__base_, std::cref(*__pred_)));
@@ -82,7 +83,7 @@ public:
 
 private:
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
   static constexpr bool _UseCache = forward_range<_View>;
   using _Cache                    = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
lib/libcxx/include/__ranges/elements_view.h
@@ -26,9 +26,9 @@
 #include <__ranges/range_adaptor.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_like.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_like.h>
+#include <__tuple/tuple_size.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/maybe_const.h>
 #include <__type_traits/remove_cv.h>
@@ -224,9 +224,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
     requires forward_range<_Base>
   {
-    auto temp = *this;
+    auto __temp = *this;
     ++__current_;
-    return temp;
+    return __temp;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
@@ -239,9 +239,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
     requires bidirectional_range<_Base>
   {
-    auto temp = *this;
+    auto __temp = *this;
     --__current_;
-    return temp;
+    return __temp;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
lib/libcxx/include/__ranges/empty.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.prim.empty]
 
@@ -75,7 +75,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/empty_view.h
@@ -13,7 +13,8 @@
 #include <__config>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/view_interface.h>
-#include <type_traits>
+#include <__type_traits/is_object.h>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -21,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<class _Tp>
@@ -46,7 +47,7 @@ namespace ranges {
   } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/enable_borrowed_range.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -33,7 +33,7 @@ inline constexpr bool enable_borrowed_range = false;
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/enable_view.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -43,7 +43,7 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> ||
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/filter_view.h
@@ -11,12 +11,12 @@
 #define _LIBCPP___RANGES_FILTER_VIEW_H
 
 #include <__algorithm/ranges_find_if.h>
+#include <__assert>
 #include <__concepts/constructible.h>
 #include <__concepts/copyable.h>
 #include <__concepts/derived_from.h>
 #include <__concepts/equality_comparable.h>
 #include <__config>
-#include <__debug>
 #include <__functional/bind_back.h>
 #include <__functional/invoke.h>
 #include <__functional/reference_wrapper.h>
@@ -28,14 +28,17 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -43,14 +46,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
     requires view<_View> && is_object_v<_Pred>
   class filter_view : public view_interface<filter_view<_View, _Pred>> {
     _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-    _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+    _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
     // We cache the result of begin() to allow providing an amortized O(1) begin() whenever
     // the underlying range is at least a forward_range.
@@ -65,10 +68,8 @@ namespace ranges {
     _LIBCPP_HIDE_FROM_ABI
     filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default;
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr filter_view(_View __base, _Pred __pred)
-      : __base_(std::move(__base)), __pred_(in_place, std::move(__pred))
-    { }
+    _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 filter_view(_View __base, _Pred __pred)
+        : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
 
     template<class _Vp = _View>
     _LIBCPP_HIDE_FROM_ABI
@@ -81,7 +82,9 @@ namespace ranges {
 
     _LIBCPP_HIDE_FROM_ABI
     constexpr __iterator begin() {
-      _LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
+      _LIBCPP_ASSERT_UNCATEGORIZED(
+          __pred_.__has_value(),
+          "Trying to call begin() on a filter_view that does not have a valid predicate.");
       if constexpr (_UseCache) {
         if (!__cached_begin_.__has_value()) {
           __cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_)));
@@ -180,9 +183,9 @@ namespace ranges {
     }
     _LIBCPP_HIDE_FROM_ABI
     constexpr __iterator operator--(int) requires bidirectional_range<_View> {
-      auto tmp = *this;
+      auto __tmp = *this;
       --*this;
-      return tmp;
+      return __tmp;
     }
 
     _LIBCPP_HIDE_FROM_ABI
@@ -257,7 +260,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/from_range.h
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_FROM_RANGE_H
+#define _LIBCPP___RANGES_FROM_RANGE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+struct from_range_t {
+  explicit from_range_t() = default;
+};
+
+inline constexpr from_range_t from_range{};
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_FROM_RANGE_H
lib/libcxx/include/__ranges/iota_view.h
@@ -27,12 +27,15 @@
 #include <__iterator/incrementable_traits.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/unreachable_sentinel.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/enable_borrowed_range.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -40,12 +43,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<class _Int>
   struct __get_wider_signed {
-    static auto __call() {
+    consteval static auto __call() {
            if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{};
       else if constexpr (sizeof(_Int) < sizeof(int))   return type_identity<int>{};
       else if constexpr (sizeof(_Int) < sizeof(long))  return type_identity<long>{};
@@ -278,7 +281,8 @@ namespace ranges {
     public:
       _LIBCPP_HIDE_FROM_ABI
       __sentinel() = default;
-      constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
+      _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
+          : __bound_sentinel_(std::move(__bound_sentinel)) {}
 
       _LIBCPP_HIDE_FROM_ABI
       friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
@@ -311,28 +315,28 @@ namespace ranges {
     constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { }
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
+    constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
         : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
       // Validate the precondition if possible.
       if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
-        _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_sentinel_),
-                       "Precondition violated: value is greater than bound.");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ranges::less_equal()(__value_, __bound_sentinel_),
+                                     "Precondition violated: value is greater than bound.");
       }
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr iota_view(__iterator __first, __iterator __last)
+    constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
       requires same_as<_Start, _BoundSentinel>
     : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr iota_view(__iterator __first, _BoundSentinel __last)
+    constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
       requires same_as<_BoundSentinel, unreachable_sentinel_t>
     : iota_view(std::move(__first.__value_), std::move(__last)) {}
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr iota_view(__iterator __first, __sentinel __last)
-      requires(!same_as<_Start, _BoundSentinel> && !same_as<_Start, unreachable_sentinel_t>)
+    constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
+      requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
     : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
 
     _LIBCPP_HIDE_FROM_ABI
@@ -403,7 +407,7 @@ inline namespace __cpo {
 } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/join_view.h
@@ -22,6 +22,7 @@
 #include <__iterator/iterator_traits.h>
 #include <__iterator/iterator_with_data.h>
 #include <__iterator/segmented_iterator.h>
+#include <__memory/addressof.h>
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
@@ -29,10 +30,10 @@
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/common_type.h>
 #include <__type_traits/maybe_const.h>
 #include <__utility/forward.h>
 #include <optional>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -43,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in
 // the pipeline (https://isocpp.org/files/papers/D2770R0.html).
 // TODO: make `join_view` non-experimental once D2770 is implemented.
-#if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
 
 namespace ranges {
   template<class>
@@ -394,8 +395,8 @@ inline namespace __cpo {
 template <class _JoinViewIterator>
   requires(_JoinViewIterator::__is_join_view_iterator &&
            ranges::common_range<typename _JoinViewIterator::_Parent> &&
-           __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Outer>::value &&
-           __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Inner>::value)
+           __has_random_access_iterator_category<typename _JoinViewIterator::_Outer>::value &&
+           __has_random_access_iterator_category<typename _JoinViewIterator::_Inner>::value)
 struct __segmented_iterator_traits<_JoinViewIterator> {
 
   using __segment_iterator =
@@ -435,7 +436,7 @@ struct __segmented_iterator_traits<_JoinViewIterator> {
   }
 };
 
-#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#endif // #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/lazy_split_view.h
@@ -12,6 +12,7 @@
 
 #include <__algorithm/ranges_find.h>
 #include <__algorithm/ranges_mismatch.h>
+#include <__assert>
 #include <__concepts/constructible.h>
 #include <__concepts/convertible_to.h>
 #include <__concepts/derived_from.h>
@@ -34,10 +35,13 @@
 #include <__ranges/single_view.h>
 #include <__ranges/subrange.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -45,7 +49,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -78,14 +82,14 @@ public:
     requires default_initializable<_View> && default_initializable<_Pattern> = default;
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr lazy_split_view(_View __base, _Pattern __pattern)
+  constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_View __base, _Pattern __pattern)
     : __base_(std::move(__base)), __pattern_(std::move(__pattern)) {}
 
   template <input_range _Range>
     requires constructible_from<_View, views::all_t<_Range>> &&
              constructible_from<_Pattern, single_view<range_value_t<_Range>>>
   _LIBCPP_HIDE_FROM_ABI
-  constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
+  constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
     : __base_(views::all(std::forward<_Range>(__r)))
     , __pattern_(views::single(std::move(__e))) {}
 
@@ -276,7 +280,7 @@ private:
 
     _LIBCPP_HIDE_FROM_ABI
     friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
-      _LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
+      _LIBCPP_ASSERT_UNCATEGORIZED(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
       return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_;
     }
   };
@@ -307,7 +311,7 @@ private:
 
     _LIBCPP_HIDE_FROM_ABI
     constexpr bool __is_done() const {
-      _LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
+      _LIBCPP_ASSERT_UNCATEGORIZED(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
 
       auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_};
       auto __end = ranges::end(__i_.__parent_->__base_);
@@ -458,7 +462,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/movable_box.h
@@ -0,0 +1,206 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_MOVABLE_BOX_H
+#define _LIBCPP___RANGES_MOVABLE_BOX_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/copyable.h>
+#include <__concepts/movable.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// __movable_box allows turning a type that is move-constructible (but maybe not move-assignable) into
+// a type that is both move-constructible and move-assignable. It does that by introducing an empty state
+// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
+// to handle the case where the copy construction fails after destroying the object.
+//
+// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
+// __movable_box that does this, see below for the details.
+
+// until C++23, `__movable_box` was named `__copyable_box` and required the stored type to be copy-constructible, not
+// just move-constructible; we preserve the old behavior in pre-C++23 modes.
+template <class _Tp>
+concept __movable_box_object =
+#  if _LIBCPP_STD_VER >= 23
+    move_constructible<_Tp>
+#  else
+    copy_constructible<_Tp>
+#  endif
+    && is_object_v<_Tp>;
+
+namespace ranges {
+// Primary template - uses std::optional and introduces an empty state in case assignment fails.
+template <__movable_box_object _Tp>
+class __movable_box {
+  _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
+
+public:
+  template <class... _Args>
+    requires is_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
+      is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(in_place, std::forward<_Args>(__args)...) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+    requires default_initializable<_Tp>
+      : __val_(in_place) {}
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&)      = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
+  operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>)
+#  if _LIBCPP_STD_VER >= 23
+    requires copy_constructible<_Tp>
+#  endif
+  {
+    if (this != std::addressof(__other)) {
+      if (__other.__has_value())
+        __val_.emplace(*__other);
+      else
+        __val_.reset();
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
+    requires movable<_Tp>
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
+  operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) {
+    if (this != std::addressof(__other)) {
+      if (__other.__has_value())
+        __val_.emplace(std::move(*__other));
+      else
+        __val_.reset();
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return __val_.operator->(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
+};
+
+// This partial specialization implements an optimization for when we know we don't need to store
+// an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
+//
+// 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
+//    directly and avoid using std::optional.
+// 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
+//    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
+//
+// The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
+// nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
+// whenever we can apply any of these optimizations for both the copy assignment and the move assignment
+// operator.
+
+#  if _LIBCPP_STD_VER >= 23
+template <class _Tp>
+concept __doesnt_need_empty_state =
+    (copy_constructible<_Tp>
+         // 1. If copy_constructible<T> is true, movable-box<T> should store only a T if either T models
+         //    copyable, or is_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true.
+         ? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>)
+         // 2. Otherwise, movable-box<T> should store only a T if either T models movable or
+         //    is_nothrow_move_constructible_v<T> is true.
+         : movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
+#  else
+
+template <class _Tp>
+concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __doesnt_need_empty_state = __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>;
+#  endif
+
+template <__movable_box_object _Tp>
+  requires __doesnt_need_empty_state<_Tp>
+class __movable_box<_Tp> {
+  _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
+
+public:
+  template <class... _Args>
+    requires is_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
+      is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(std::forward<_Args>(__args)...) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+    requires default_initializable<_Tp>
+      : __val_() {}
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&)      = default;
+
+  // Implementation of assignment operators in case we perform optimization (1)
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&)
+    requires copyable<_Tp>
+  = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
+    requires movable<_Tp>
+  = default;
+
+  // Implementation of assignment operators in case we perform optimization (2)
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept {
+    static_assert(is_nothrow_copy_constructible_v<_Tp>);
+    if (this != std::addressof(__other)) {
+      std::destroy_at(std::addressof(__val_));
+      std::construct_at(std::addressof(__val_), __other.__val_);
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept {
+    static_assert(is_nothrow_move_constructible_v<_Tp>);
+    if (this != std::addressof(__other)) {
+      std::destroy_at(std::addressof(__val_));
+      std::construct_at(std::addressof(__val_), std::move(__other.__val_));
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__val_); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__val_); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
+};
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_MOVABLE_BOX_H
lib/libcxx/include/__ranges/non_propagating_cache.h
@@ -16,7 +16,6 @@
 #include <__memory/addressof.h>
 #include <__utility/forward.h>
 #include <optional>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   // __non_propagating_cache is a helper type that allows storing an optional value in it,
@@ -44,10 +43,11 @@ namespace ranges {
     // This helper class is needed to perform copy and move elision when
     // constructing the contained type from an iterator.
     struct __wrapper {
-      template<class ..._Args>
-      constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(std::forward<_Args>(__args)...) { }
-      template<class _Fn>
-      constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) { }
+      template <class... _Args>
+      _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__forward_tag, _Args&&... __args)
+          : __t_(std::forward<_Args>(__args)...) {}
+      template <class _Fn>
+      _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) {}
       _Tp __t_;
     };
 
@@ -107,7 +107,7 @@ namespace ranges {
   struct __empty_cache { };
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/owning_view.h
@@ -20,16 +20,19 @@
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<range _Rp>
@@ -38,11 +41,11 @@ namespace ranges {
     _Rp __r_ = _Rp();
 
 public:
-    owning_view() requires default_initializable<_Rp> = default;
+    _LIBCPP_HIDE_FROM_ABI owning_view() requires default_initializable<_Rp> = default;
     _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {}
 
-    owning_view(owning_view&&) = default;
-    owning_view& operator=(owning_view&&) = default;
+    _LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
+    _LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
 
     _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
     _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
@@ -76,8 +79,10 @@ public:
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___RANGES_OWNING_VIEW_H
lib/libcxx/include/__ranges/range_adaptor.h
@@ -18,17 +18,22 @@
 #include <__functional/compose.h>
 #include <__functional/invoke.h>
 #include <__ranges/concepts.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // CRTP base that one can derive from in order to be considered a range adaptor closure
 // by the library. When deriving from this class, a pipe operator will be provided to
@@ -42,7 +47,7 @@ struct __range_adaptor_closure;
 // i.e. something that can be called via the `x | f` notation.
 template <class _Fn>
 struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
-    constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t);
 
@@ -70,8 +75,10 @@ struct __range_adaptor_closure {
     { return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); }
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H
lib/libcxx/include/__ranges/rbegin.h
@@ -17,8 +17,11 @@
 #include <__iterator/readable_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__ranges/access.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/auto_cast.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,7 +29,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [ranges.access.rbegin]
 
@@ -124,7 +127,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/ref_view.h
@@ -24,8 +24,9 @@
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/is_object.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -33,7 +34,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<range _Range>
@@ -81,7 +82,7 @@ public:
   inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/rend.h
@@ -18,8 +18,11 @@
 #include <__iterator/reverse_iterator.h>
 #include <__ranges/access.h>
 #include <__ranges/rbegin.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/auto_cast.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -27,7 +30,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // [range.access.rend]
 
@@ -128,7 +131,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/repeat_view.h
@@ -0,0 +1,260 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_REPEAT_VIEW_H
+#define _LIBCPP___RANGES_REPEAT_VIEW_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/same_as.h>
+#include <__concepts/semiregular.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/unreachable_sentinel.h>
+#include <__memory/addressof.h>
+#include <__ranges/iota_view.h>
+#include <__ranges/movable_box.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/piecewise_construct.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <class _Tp>
+concept __integer_like_with_usable_difference_type =
+    __signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>);
+
+template <class _Tp>
+struct __repeat_view_iterator_difference {
+  using type = _IotaDiffT<_Tp>;
+};
+
+template <__signed_integer_like _Tp>
+struct __repeat_view_iterator_difference<_Tp> {
+  using type = _Tp;
+};
+
+template <class _Tp>
+using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type;
+
+namespace views::__drop {
+struct __fn;
+} // namespace views::__drop
+
+namespace views::__take {
+struct __fn;
+} // namespace views::__take
+
+template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
+  requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
+           (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
+class repeat_view : public view_interface<repeat_view<_Tp, _Bound>> {
+  friend struct views::__take::__fn;
+  friend struct views::__drop::__fn;
+  class __iterator;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI repeat_view()
+    requires default_initializable<_Tp>
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound())
+    requires copy_constructible<_Tp>
+      : __value_(in_place, __value), __bound_(__bound_sentinel) {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound())
+      : __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
+  }
+
+  template <class... _TpArgs, class... _BoundArgs>
+    requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(
+      piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{})
+      : __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))),
+        __bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(
+          __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
+    requires(!same_as<_Bound, unreachable_sentinel_t>)
+  {
+    return __iterator(std::addressof(*__value_), __bound_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+    requires(!same_as<_Bound, unreachable_sentinel_t>)
+  {
+    return std::__to_unsigned_like(__bound_);
+  }
+
+private:
+  __movable_box<_Tp> __value_;
+  _LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound();
+};
+
+template <class _Tp, class _Bound>
+repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
+
+// [range.repeat.iterator]
+template <move_constructible _Tp, semiregular _Bound>
+  requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
+           (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
+class repeat_view<_Tp, _Bound>::__iterator {
+  friend class repeat_view;
+
+  using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT())
+      : __value_(__value), __current_(__bound_sentinel) {}
+
+public:
+  using iterator_concept  = random_access_iterator_tag;
+  using iterator_category = random_access_iterator_tag;
+  using value_type        = _Tp;
+  using difference_type   = __repeat_view_iterator_difference_t<_IndexT>;
+
+  _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+    ++__current_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
+    auto __tmp = *this;
+    ++*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(__current_ > 0, "The value of bound must be greater than or equal to 0");
+    --__current_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) {
+    auto __tmp = *this;
+    --*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0");
+    __current_ += __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) {
+    if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
+      _LIBCPP_ASSERT(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0");
+    __current_ -= __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+    return __x.__current_ == __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) {
+    return __x.__current_ <=> __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
+    __i += __n;
+    return __i;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
+    __i += __n;
+    return __i;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
+    __i -= __n;
+    return __i;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
+    return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
+  }
+
+private:
+  const _Tp* __value_ = nullptr;
+  _IndexT __current_  = _IndexT();
+};
+
+// clang-format off
+namespace views {
+namespace __repeat {
+struct __fn {
+  template <class _Tp>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value) const
+    noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value))))
+    -> decltype(      ranges::repeat_view(std::forward<_Tp>(__value)))
+    { return          ranges::repeat_view(std::forward<_Tp>(__value)); }
+
+
+  template <class _Tp, class _Bound>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) const
+    noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))))
+    -> decltype(      ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))
+    { return          ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); }
+};
+} // namespace __repeat
+// clang-format on
+
+inline namespace __cpo {
+inline constexpr auto repeat = __repeat::__fn{};
+} // namespace __cpo
+} // namespace views
+
+template <class _Tp>
+inline constexpr bool __is_repeat_specialization = false;
+
+template <class _Tp, class _Bound>
+inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_REPEAT_VIEW_H
lib/libcxx/include/__ranges/reverse_view.h
@@ -24,9 +24,10 @@
 #include <__ranges/size.h>
 #include <__ranges/subrange.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -34,7 +35,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<view _View>
@@ -184,7 +185,7 @@ namespace ranges {
   } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/single_view.h
@@ -12,13 +12,15 @@
 
 #include <__concepts/constructible.h>
 #include <__config>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_object.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,51 +28,51 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
-  template<copy_constructible _Tp>
-    requires is_object_v<_Tp>
-  class single_view : public view_interface<single_view<_Tp>> {
-    __copyable_box<_Tp> __value_;
-
-  public:
-    _LIBCPP_HIDE_FROM_ABI
-    single_view() requires default_initializable<_Tp> = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
-
-    template<class... _Args>
-      requires constructible_from<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(in_place_t, _Args&&... __args)
+#  if _LIBCPP_STD_VER >= 23
+template <move_constructible _Tp>
+#  else
+template <copy_constructible _Tp>
+#  endif
+  requires is_object_v<_Tp>
+class single_view : public view_interface<single_view<_Tp>> {
+  __movable_box<_Tp> __value_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI single_view()
+    requires default_initializable<_Tp>
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
+#  if _LIBCPP_STD_VER >= 23
+    requires copy_constructible<_Tp>
+#  endif
+      : __value_(in_place, __t) {
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
+
+  template <class... _Args>
+    requires constructible_from<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
       : __value_{in_place, std::forward<_Args>(__args)...} {}
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* begin() noexcept { return data(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* begin() const noexcept { return data(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* end() noexcept { return data() + 1; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* end() const noexcept { return data() + 1; }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    static constexpr size_t size() noexcept { return 1; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* data() noexcept { return __value_.operator->(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
-  };
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
+};
 
 template<class _Tp>
 single_view(_Tp) -> single_view<_Tp>;
@@ -95,7 +97,7 @@ inline namespace __cpo {
 } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/size.h
@@ -30,7 +30,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<class>
@@ -141,7 +141,7 @@ inline namespace __cpo {
 } // namespace __cpo
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/split_view.h
@@ -75,13 +75,14 @@ public:
     requires default_initializable<_View> && default_initializable<_Pattern>
   = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern)
+  _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 split_view(_View __base, _Pattern __pattern)
       : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {}
 
   template <forward_range _Range>
     requires constructible_from<_View, views::all_t<_Range>> &&
                  constructible_from<_Pattern, single_view<range_value_t<_Range>>>
-  _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem)
+  _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
+  split_view(_Range&& __range, range_value_t<_Range> __elem)
       : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
lib/libcxx/include/__ranges/subrange.h
@@ -29,9 +29,9 @@
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
-#include <__tuple_dir/pair_like.h>
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/pair_like.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_size.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/is_pointer.h>
@@ -46,9 +46,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
   template<class _From, class _To>
@@ -82,7 +85,7 @@ namespace ranges {
 
   private:
     static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics
-    struct _Empty { constexpr _Empty(auto) noexcept { } };
+    struct _Empty { _LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept { } };
     using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>;
     _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter();
     _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent();
@@ -105,7 +108,7 @@ namespace ranges {
       : __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n)
     {
       if constexpr (sized_sentinel_for<_Sent, _Iter>)
-        _LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
+        _LIBCPP_ASSERT_UNCATEGORIZED((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
           "std::ranges::subrange was passed an invalid size hint");
     }
 
@@ -284,8 +287,10 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
   using type = _Sp;
 };
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___RANGES_SUBRANGE_H
lib/libcxx/include/__ranges/take_view.h
@@ -31,14 +31,18 @@
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/iota_view.h>
 #include <__ranges/range_adaptor.h>
+#include <__ranges/repeat_view.h>
 #include <__ranges/size.h>
 #include <__ranges/subrange.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
 #include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/auto_cast.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -49,7 +53,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -64,9 +68,10 @@ public:
   _LIBCPP_HIDE_FROM_ABI
   take_view() requires default_initializable<_View> = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr take_view(_View __base, range_difference_t<_View> __count)
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_view(_View __base, range_difference_t<_View> __count)
       : __base_(std::move(__base)), __count_(__count) {
-    _LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero");
   }
 
   _LIBCPP_HIDE_FROM_ABI
@@ -297,6 +302,31 @@ struct __fn {
                               *ranges::begin(__rng),
                               *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
                               ); }
+// clang-format off
+#if _LIBCPP_STD_VER >= 23
+  // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
+  template <class _Range,
+            convertible_to<range_difference_t<_Range>> _Np,
+            class _RawRange = remove_cvref_t<_Range>,
+            class _Dist     = range_difference_t<_Range>>
+    requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+    noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
+    -> decltype(      views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
+    { return          views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
+
+  // [range.take.overview]: the `repeat_view` "otherwise" case.
+  template <class _Range,
+            convertible_to<range_difference_t<_Range>> _Np,
+            class _RawRange = remove_cvref_t<_Range>,
+            class _Dist     = range_difference_t<_Range>>
+    requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
+    noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n))))
+    -> decltype(      views::repeat(*__range.__value_, static_cast<_Dist>(__n)))
+    { return          views::repeat(*__range.__value_, static_cast<_Dist>(__n)); }
+#endif
+// clang-format on
 
   // [range.take.overview]: the "otherwise" case.
   template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
@@ -304,6 +334,9 @@ struct __fn {
     // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
     // overloads.
     requires (!(__is_empty_view<_RawRange> ||
+#if _LIBCPP_STD_VER >= 23
+                __is_repeat_specialization<_RawRange> ||
+#endif
                (__is_iota_specialization<_RawRange> &&
                 sized_range<_RawRange> &&
                 random_access_range<_RawRange>) ||
@@ -334,7 +367,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/take_while_view.h
@@ -20,7 +20,7 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
 #include <__type_traits/decay.h>
@@ -60,14 +60,14 @@ class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
   class __sentinel;
 
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
 public:
   _LIBCPP_HIDE_FROM_ABI take_while_view()
     requires default_initializable<_View> && default_initializable<_Pred>
   = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr take_while_view(_View __base, _Pred __pred)
+  _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_while_view(_View __base, _Pred __pred)
       : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
lib/libcxx/include/__ranges/to.h
@@ -0,0 +1,247 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_TO_H
+#define _LIBCPP___RANGES_TO_H
+
+#include <__algorithm/ranges_copy.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__iterator/insert_iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/from_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/transform_view.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_volatile.h>
+#include <__type_traits/type_identity.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+// TODO(clang-15): in the Standard, it's a `constexpr bool` variable, not a concept, but constexpr variables don't
+// short-circuit properly on Clang 15 (fixed in later versions), so use a concept as a workaround.
+template <class _Container>
+concept __reservable_container = sized_range<_Container> && requires(_Container& __c, range_size_t<_Container> __n) {
+  __c.reserve(__n);
+  { __c.capacity() } -> same_as<decltype(__n)>;
+  { __c.max_size() } -> same_as<decltype(__n)>;
+};
+
+template <class _Container, class _Ref>
+constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) {
+  requires(
+      requires { __c.push_back(std::forward<_Ref>(__ref)); } ||
+      requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); });
+};
+
+template <class _Ref, class _Container>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) {
+  if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) {
+    return std::back_inserter(__c);
+  } else {
+    return std::inserter(__c, __c.end());
+  }
+}
+
+// Note: making this a concept allows short-circuiting the second condition.
+template <class _Container, class _Range>
+concept __try_non_recursive_conversion =
+    !input_range<_Container> || convertible_to<range_reference_t<_Range>, range_value_t<_Container>>;
+
+template <class _Container, class _Range, class... _Args>
+concept __constructible_from_iter_pair =
+    common_range<_Range> && requires { typename iterator_traits<iterator_t<_Range>>::iterator_category; } &&
+    derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> &&
+    constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>;
+
+template <class>
+concept __always_false = false;
+
+// `ranges::to` base template -- the `_Container` type is a simple type template parameter.
+template <class _Container, input_range _Range, class... _Args>
+  requires(!view<_Container>)
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) {
+  // Mandates: C is a cv-unqualified class type.
+  static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
+  static_assert(
+      !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
+
+  // First see if the non-recursive case applies -- the conversion target is either:
+  // - a range with a convertible value type;
+  // - a non-range type which might support being created from the input argument(s) (e.g. an `optional`).
+  if constexpr (__try_non_recursive_conversion<_Container, _Range>) {
+    // Case 1 -- construct directly from the given range.
+    if constexpr (constructible_from<_Container, _Range, _Args...>) {
+      return _Container(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
+    }
+
+    // Case 2 -- construct using the `from_range_t` tagged constructor.
+    else if constexpr (constructible_from<_Container, from_range_t, _Range, _Args...>) {
+      return _Container(from_range, std::forward<_Range>(__range), std::forward<_Args>(__args)...);
+    }
+
+    // Case 3 -- construct from a begin-end iterator pair.
+    else if constexpr (__constructible_from_iter_pair<_Container, _Range, _Args...>) {
+      return _Container(ranges::begin(__range), ranges::end(__range), std::forward<_Args>(__args)...);
+    }
+
+    // Case 4 -- default-construct (or construct from the extra arguments) and insert, reserving the size if possible.
+    else if constexpr (constructible_from<_Container, _Args...> &&
+                       __container_insertable<_Container, range_reference_t<_Range>>) {
+      _Container __result(std::forward<_Args>(__args)...);
+      if constexpr (sized_range<_Range> && __reservable_container<_Container>) {
+        __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range)));
+      }
+
+      ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result));
+
+      return __result;
+
+    } else {
+      static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
+    }
+
+    // Try the recursive case.
+  } else if constexpr (input_range<range_reference_t<_Range>>) {
+    return ranges::to<_Container>(
+        __range | views::transform([](auto&& __elem) {
+          return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
+        }),
+        std::forward<_Args>(__args)...);
+
+  } else {
+    static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
+  }
+}
+
+template <class _Range>
+struct __minimal_input_iterator {
+  using iterator_category = input_iterator_tag;
+  using value_type        = range_value_t<_Range>;
+  using difference_type   = ptrdiff_t;
+  using pointer           = add_pointer_t<range_reference_t<_Range>>;
+  using reference         = range_reference_t<_Range>;
+
+  reference operator*() const;
+  pointer operator->() const;
+  __minimal_input_iterator& operator++();
+  __minimal_input_iterator operator++(int);
+  bool operator==(const __minimal_input_iterator&) const;
+};
+
+// Deduces the full type of the container from the given template template parameter.
+template <template <class...> class _Container, input_range _Range, class... _Args>
+struct _Deducer {
+  _LIBCPP_HIDE_FROM_ABI static constexpr auto __deduce_func() {
+    using _InputIter = __minimal_input_iterator<_Range>;
+
+    // Case 1 -- can construct directly from the given range.
+    if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) {
+      using _Result = decltype( //
+          _Container(std::declval<_Range>(), std::declval<_Args>()...));
+      return type_identity<_Result>{};
+
+      // Case 2 -- can construct from the given range using the `from_range_t` tagged constructor.
+    } else if constexpr ( //
+        requires { _Container(from_range, std::declval<_Range>(), std::declval<_Args>()...); }) {
+      using _Result = //
+          decltype(_Container(from_range, std::declval<_Range>(), std::declval<_Args>()...));
+      return type_identity<_Result>{};
+
+      // Case 3 -- can construct from a begin-end iterator pair.
+    } else if constexpr ( //
+        requires { _Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...); }) {
+      using _Result =
+          decltype(_Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...));
+      return type_identity<_Result>{};
+
+    } else {
+      static_assert(__always_false<_Range>,
+                    "ranges::to: unable to deduce the container type from the template template argument.");
+    }
+  }
+
+  using type = typename decltype(__deduce_func())::type;
+};
+
+// `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the
+// container element type.
+template <template <class...> class _Container, input_range _Range, class... _Args>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Range&& __range, _Args&&... __args) {
+  using _DeduceExpr = typename _Deducer<_Container, _Range, _Args...>::type;
+  return ranges::to<_DeduceExpr>(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
+}
+
+// Range adaptor closure object 1 -- wrapping the `ranges::to` version where `_Container` is a simple type template
+// parameter.
+template <class _Container, class... _Args>
+  requires(!view<_Container>)
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
+  // Mandates: C is a cv-unqualified class type.
+  static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
+  static_assert(
+      !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
+
+  auto __to_func = []<input_range _Range, class... _Tail>(_Range && __range, _Tail && ... __tail)
+    requires requires { //
+      /**/ ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
+    }
+  {
+    return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
+  };
+
+  return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
+}
+
+// Range adaptor closure object 2 -- wrapping the `ranges::to` version where `_Container` is a template template
+// parameter.
+template <template <class...> class _Container, class... _Args>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
+  // clang-format off
+  auto __to_func = []<input_range _Range, class... _Tail,
+                      class _DeducedExpr = typename _Deducer<_Container, _Range, _Tail...>::type>
+    (_Range&& __range, _Tail&& ... __tail)
+      requires requires { //
+      /**/ ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
+    }
+  {
+    return ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
+  };
+  // clang-format on
+
+  return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
+}
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_TO_H
lib/libcxx/include/__ranges/transform_view.h
@@ -20,22 +20,28 @@
 #include <__config>
 #include <__functional/bind_back.h>
 #include <__functional/invoke.h>
+#include <__functional/perfect_forward.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/empty.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_reference.h>
 #include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -43,7 +49,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -57,13 +63,17 @@ concept __transform_view_constraints =
   regular_invocable<_Fn&, range_reference_t<_View>> &&
   __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
 
-template<input_range _View, copy_constructible _Fn>
+#  if _LIBCPP_STD_VER >= 23
+template <input_range _View, move_constructible _Fn>
+#  else
+template <input_range _View, copy_constructible _Fn>
+#  endif
   requires __transform_view_constraints<_View, _Fn>
 class transform_view : public view_interface<transform_view<_View, _Fn>> {
   template<bool> class __iterator;
   template<bool> class __sentinel;
 
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __func_;
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
 
 public:
@@ -72,7 +82,7 @@ public:
     requires default_initializable<_View> && default_initializable<_Fn> = default;
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr transform_view(_View __base, _Fn __func)
+  constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func)
     : __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
 
   _LIBCPP_HIDE_FROM_ABI
@@ -146,7 +156,7 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
   using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
 
   using iterator_category = conditional_t<
-    is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
+    is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
     conditional_t<
       derived_from<_Cat, contiguous_iterator_tag>,
       random_access_iterator_tag,
@@ -156,11 +166,14 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
   >;
 };
 
-template<input_range _View, copy_constructible _Fn>
+#  if _LIBCPP_STD_VER >= 23
+template <input_range _View, move_constructible _Fn>
+#  else
+template <input_range _View, copy_constructible _Fn>
+#  endif
   requires __transform_view_constraints<_View, _Fn>
-template<bool _Const>
-class transform_view<_View, _Fn>::__iterator
-  : public __transform_view_iterator_category_base<_View, _Fn> {
+template <bool _Const>
+class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn> {
 
   using _Parent = __maybe_const<_Const, transform_view>;
   using _Base = __maybe_const<_Const, _View>;
@@ -352,9 +365,13 @@ public:
   }
 };
 
-template<input_range _View, copy_constructible _Fn>
+#  if _LIBCPP_STD_VER >= 23
+template <input_range _View, move_constructible _Fn>
+#  else
+template <input_range _View, copy_constructible _Fn>
+#  endif
   requires __transform_view_constraints<_View, _Fn>
-template<bool _Const>
+template <bool _Const>
 class transform_view<_View, _Fn>::__sentinel {
   using _Parent = __maybe_const<_Const, transform_view>;
   using _Base = __maybe_const<_Const, _View>;
@@ -435,7 +452,7 @@ inline namespace __cpo {
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/view_interface.h
@@ -31,7 +31,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -118,7 +118,7 @@ public:
   constexpr decltype(auto) front()
     requires forward_range<_D2>
   {
-    _LIBCPP_ASSERT(!empty(),
+    _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
         "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
     return *ranges::begin(__derived());
   }
@@ -128,7 +128,7 @@ public:
   constexpr decltype(auto) front() const
     requires forward_range<const _D2>
   {
-    _LIBCPP_ASSERT(!empty(),
+    _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
         "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
     return *ranges::begin(__derived());
   }
@@ -138,7 +138,7 @@ public:
   constexpr decltype(auto) back()
     requires bidirectional_range<_D2> && common_range<_D2>
   {
-    _LIBCPP_ASSERT(!empty(),
+    _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
         "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
     return *ranges::prev(ranges::end(__derived()));
   }
@@ -148,7 +148,7 @@ public:
   constexpr decltype(auto) back() const
     requires bidirectional_range<const _D2> && common_range<const _D2>
   {
-    _LIBCPP_ASSERT(!empty(),
+    _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
         "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
     return *ranges::prev(ranges::end(__derived()));
   }
@@ -170,7 +170,7 @@ public:
 
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/views.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
 
@@ -28,7 +28,7 @@ namespace views { }
 
 namespace views = ranges::views;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__ranges/zip_view.h
@@ -30,11 +30,13 @@
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/integer_sequence.h>
 #include <__utility/move.h>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -45,7 +47,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 namespace ranges {
 
@@ -77,7 +79,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tu
 template <class _Fun, class _Tuple>
 _LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
   std::apply(
-      [&]<class... _Types>(_Types&&... __elements) { (std::invoke(__f, std::forward<_Types>(__elements)), ...); },
+      [&]<class... _Types>(_Types&&... __elements) {
+        (static_cast<void>(std::invoke(__f, std::forward<_Types>(__elements))), ...);
+      },
       std::forward<_Tuple>(__tuple));
 }
 
@@ -503,7 +507,7 @@ inline namespace __cpo {
 } // namespace views
 } // namespace ranges
 
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__stop_token/atomic_unique_lock.h
@@ -0,0 +1,139 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
+#define _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
+
+#include <__bit/popcount.h>
+#include <__config>
+#include <atomic>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// This class implements an RAII unique_lock without a mutex.
+// It uses std::atomic<State>,
+// where State contains a lock bit and might contain other data,
+// and LockedBit is the value of State when the lock bit is set, e.g  1 << 2
+template <class _State, _State _LockedBit>
+class _LIBCPP_AVAILABILITY_SYNC __atomic_unique_lock {
+  static_assert(std::popcount(_LockedBit) == 1, "LockedBit must be an integer where only one bit is set");
+
+  std::atomic<_State>& __state_;
+  bool __is_locked_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit __atomic_unique_lock(std::atomic<_State>& __state) noexcept
+      : __state_(__state), __is_locked_(true) {
+    __lock();
+  }
+
+  template <class _Pred>
+  _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock(std::atomic<_State>& __state, _Pred&& __give_up_locking) noexcept
+      : __state_(__state), __is_locked_(false) {
+    __is_locked_ = __lock_impl(__give_up_locking, __set_locked_bit, std::memory_order_acquire);
+  }
+
+  template <class _Pred, class _UnaryFunction>
+  _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock(
+      std::atomic<_State>& __state,
+      _Pred&& __give_up_locking,
+      _UnaryFunction&& __state_after_lock,
+      std::memory_order __locked_ordering) noexcept
+      : __state_(__state), __is_locked_(false) {
+    __is_locked_ = __lock_impl(__give_up_locking, __state_after_lock, __locked_ordering);
+  }
+
+  __atomic_unique_lock(const __atomic_unique_lock&)            = delete;
+  __atomic_unique_lock(__atomic_unique_lock&&)                 = delete;
+  __atomic_unique_lock& operator=(const __atomic_unique_lock&) = delete;
+  __atomic_unique_lock& operator=(__atomic_unique_lock&&)      = delete;
+
+  _LIBCPP_HIDE_FROM_ABI ~__atomic_unique_lock() {
+    if (__is_locked_) {
+      __unlock();
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool __owns_lock() const noexcept { return __is_locked_; }
+
+  _LIBCPP_HIDE_FROM_ABI void __lock() noexcept {
+    const auto __never_give_up_locking = [](_State) { return false; };
+    // std::memory_order_acquire because we'd like to make sure that all the read operations after the lock can read the
+    // up-to-date values.
+    __lock_impl(__never_give_up_locking, __set_locked_bit, std::memory_order_acquire);
+    __is_locked_ = true;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void __unlock() noexcept {
+    // unset the _LockedBit. `memory_order_release` because we need to make sure all the write operations before calling
+    // `__unlock` will be made visible to other threads
+    __state_.fetch_and(static_cast<_State>(~_LockedBit), std::memory_order_release);
+    __state_.notify_all();
+    __is_locked_ = false;
+  }
+
+private:
+  template <class _Pred, class _UnaryFunction>
+  _LIBCPP_HIDE_FROM_ABI bool
+  __lock_impl(_Pred&& __give_up_locking, // while trying to lock the state, if the predicate returns true, give up
+                                         // locking and return
+              _UnaryFunction&& __state_after_lock,
+              std::memory_order __locked_ordering) noexcept {
+    // At this stage, until we exit the inner while loop, other than the atomic state, we are not reading any order
+    // dependent values that is written on other threads, or writing anything that needs to be seen on other threads.
+    // Therefore `memory_order_relaxed` is enough.
+    _State __current_state = __state_.load(std::memory_order_relaxed);
+    do {
+      while (true) {
+        if (__give_up_locking(__current_state)) {
+          // user provided early return condition. fail to lock
+          return false;
+        } else if ((__current_state & _LockedBit) != 0) {
+          // another thread has locked the state, we need to wait
+          __state_.wait(__current_state, std::memory_order_relaxed);
+          // when it is woken up by notifyAll or spuriously, the __state_
+          // might have changed. reload the state
+          // Note that the new state's _LockedBit may or may not equal to 0
+          __current_state = __state_.load(std::memory_order_relaxed);
+        } else {
+          // at least for now, it is not locked. we can try `compare_exchange_weak` to lock it.
+          // Note that the variable `__current_state`'s lock bit has to be 0 at this point.
+          break;
+        }
+      }
+    } while (!__state_.compare_exchange_weak(
+        __current_state, // if __state_ has the same value of __current_state, lock bit must be zero before exchange and
+                         // we are good to lock/exchange and return. If _state has a different value, because other
+                         // threads locked it between the `break` statement above and this statement, exchange will fail
+                         // and go back to the inner while loop above.
+        __state_after_lock(__current_state), // state after lock. Usually it should be __current_state | _LockedBit.
+                                             // Some use cases need to set other bits at the same time as an atomic
+                                             // operation therefore we accept a function
+        __locked_ordering,        // sucessful exchange order. Usually it should be std::memory_order_acquire.
+                                  // Some use cases need more strict ordering therefore we accept it as a parameter
+        std::memory_order_relaxed // fail to exchange order. We don't need any ordering as we are going back to the
+                                  // inner while loop
+        ));
+    return true;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static constexpr auto __set_locked_bit = [](_State __state) { return __state | _LockedBit; };
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
lib/libcxx/include/__stop_token/intrusive_list_view.h
@@ -0,0 +1,85 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
+#define _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
+
+#include <__assert>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Derived>
+struct __intrusive_node_base {
+  _Derived* __next_ = nullptr;
+  _Derived* __prev_ = nullptr;
+};
+
+// This class is a view of underlying double-linked list.
+// It does not own the nodes. It provides user-friendly
+// operations on the linked list.
+template <class _Node>
+struct __intrusive_list_view {
+  _LIBCPP_HIDE_FROM_ABI __intrusive_list_view()                                        = default;
+  _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view const&)            = default;
+  _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view&&)                 = default;
+  _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view&&)      = default;
+  _LIBCPP_HIDE_FROM_ABI ~__intrusive_list_view()                                       = default;
+
+  _LIBCPP_HIDE_FROM_ABI bool __empty() const noexcept { return __head_ == nullptr; }
+
+  _LIBCPP_HIDE_FROM_ABI void __push_front(_Node* __node) noexcept {
+    __node->__next_ = __head_;
+    if (__head_) {
+      __head_->__prev_ = __node;
+    }
+    __head_ = __node;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI _Node* __pop_front() noexcept {
+    _Node* __front = __head_;
+    __head_        = __head_->__next_;
+    if (__head_) {
+      __head_->__prev_ = nullptr;
+    }
+    // OK not to set __front->__next_ = nullptr as __front is not part of the list anymore
+    return __front;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void __remove(_Node* __node) noexcept {
+    if (__node->__prev_) {
+      // prev exists, set its next to our next to skip __node
+      __node->__prev_->__next_ = __node->__next_;
+      if (__node->__next_) {
+        __node->__next_->__prev_ = __node->__prev_;
+      }
+    } else {
+      _LIBCPP_ASSERT_INTERNAL(__node == __head_, "Node to be removed has no prev node, so it has to be the head");
+      __pop_front();
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool __is_head(_Node* __node) noexcept { return __node == __head_; }
+
+private:
+  _Node* __head_ = nullptr;
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
lib/libcxx/include/__stop_token/intrusive_shared_ptr.h
@@ -0,0 +1,134 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
+#define _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
+
+#include <__atomic/atomic.h>
+#include <__atomic/memory_order.h>
+#include <__config>
+#include <__type_traits/is_reference.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// For intrusive_shared_ptr to work with a type T, specialize __intrusive_shared_ptr_traits<T> and implement
+// the following function:
+//
+// static std::atomic<U>& __get_atomic_ref_count(T&);
+//
+// where U must be an integral type representing the number of references to the object.
+template <class _Tp>
+struct __intrusive_shared_ptr_traits;
+
+// A reference counting shared_ptr for types whose reference counter
+// is stored inside the class _Tp itself.
+// When the reference count goes to zero, the destructor of _Tp will be called
+template <class _Tp>
+struct __intrusive_shared_ptr {
+  _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr() = default;
+
+  _LIBCPP_HIDE_FROM_ABI explicit __intrusive_shared_ptr(_Tp* __raw_ptr) : __raw_ptr_(__raw_ptr) {
+    if (__raw_ptr_)
+      __increment_ref_count(*__raw_ptr_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(const __intrusive_shared_ptr& __other) noexcept
+      : __raw_ptr_(__other.__raw_ptr_) {
+    if (__raw_ptr_)
+      __increment_ref_count(*__raw_ptr_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(__intrusive_shared_ptr&& __other) noexcept
+      : __raw_ptr_(__other.__raw_ptr_) {
+    __other.__raw_ptr_ = nullptr;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(const __intrusive_shared_ptr& __other) noexcept {
+    if (__other.__raw_ptr_ != __raw_ptr_) {
+      if (__other.__raw_ptr_) {
+        __increment_ref_count(*__other.__raw_ptr_);
+      }
+      if (__raw_ptr_) {
+        __decrement_ref_count(*__raw_ptr_);
+      }
+      __raw_ptr_ = __other.__raw_ptr_;
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(__intrusive_shared_ptr&& __other) noexcept {
+    __intrusive_shared_ptr(std::move(__other)).swap(*this);
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI ~__intrusive_shared_ptr() {
+    if (__raw_ptr_) {
+      __decrement_ref_count(*__raw_ptr_);
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI _Tp* operator->() const noexcept { return __raw_ptr_; }
+  _LIBCPP_HIDE_FROM_ABI _Tp& operator*() const noexcept { return *__raw_ptr_; }
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __raw_ptr_ != nullptr; }
+
+  _LIBCPP_HIDE_FROM_ABI void swap(__intrusive_shared_ptr& __other) { std::swap(__raw_ptr_, __other.__raw_ptr_); }
+
+  _LIBCPP_HIDE_FROM_ABI friend void swap(__intrusive_shared_ptr& __lhs, __intrusive_shared_ptr& __rhs) {
+    __lhs.swap(__rhs);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend bool constexpr
+  operator==(const __intrusive_shared_ptr&, const __intrusive_shared_ptr&) = default;
+
+  _LIBCPP_HIDE_FROM_ABI friend bool constexpr operator==(const __intrusive_shared_ptr& __ptr, std::nullptr_t) {
+    return __ptr.__raw_ptr_ == nullptr;
+  }
+
+private:
+  _Tp* __raw_ptr_ = nullptr;
+
+  // the memory order for increment/decrement the counter is the same for shared_ptr
+  // increment is relaxed and decrement is acq_rel
+  _LIBCPP_HIDE_FROM_ABI static void __increment_ref_count(_Tp& __obj) {
+    __get_atomic_ref_count(__obj).fetch_add(1, std::memory_order_relaxed);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static void __decrement_ref_count(_Tp& __obj) {
+    if (__get_atomic_ref_count(__obj).fetch_sub(1, std::memory_order_acq_rel) == 1) {
+      delete &__obj;
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static decltype(auto) __get_atomic_ref_count(_Tp& __obj) {
+    using __ret_type = decltype(__intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj));
+    static_assert(
+        std::is_reference_v<__ret_type>, "__get_atomic_ref_count should return a reference to the atomic counter");
+    return __intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj);
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
lib/libcxx/include/__stop_token/stop_callback.h
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_STOP_CALLBACK_H
+#define _LIBCPP___STOP_TOKEN_STOP_CALLBACK_H
+
+#include <__availability>
+#include <__concepts/constructible.h>
+#include <__concepts/destructible.h>
+#include <__concepts/invocable.h>
+#include <__config>
+#include <__stop_token/intrusive_shared_ptr.h>
+#include <__stop_token/stop_state.h>
+#include <__stop_token/stop_token.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
+
+template <class _Callback>
+class _LIBCPP_AVAILABILITY_SYNC stop_callback : private __stop_callback_base {
+  static_assert(invocable<_Callback>,
+                "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that "
+                "satisfies invocable.");
+  static_assert(destructible<_Callback>,
+                "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that "
+                "satisfies destructible.");
+
+public:
+  using callback_type = _Callback;
+
+  template <class _Cb>
+    requires constructible_from<_Callback, _Cb>
+  _LIBCPP_HIDE_FROM_ABI explicit stop_callback(const stop_token& __st,
+                                               _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>)
+      : stop_callback(__private_tag{}, __st.__state_, std::forward<_Cb>(__cb)) {}
+
+  template <class _Cb>
+    requires constructible_from<_Callback, _Cb>
+  _LIBCPP_HIDE_FROM_ABI explicit stop_callback(stop_token&& __st,
+                                               _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>)
+      : stop_callback(__private_tag{}, std::move(__st.__state_), std::forward<_Cb>(__cb)) {}
+
+  _LIBCPP_HIDE_FROM_ABI ~stop_callback() {
+    if (__state_) {
+      __state_->__remove_callback(this);
+    }
+  }
+
+  stop_callback(const stop_callback&)            = delete;
+  stop_callback(stop_callback&&)                 = delete;
+  stop_callback& operator=(const stop_callback&) = delete;
+  stop_callback& operator=(stop_callback&&)      = delete;
+
+private:
+  _LIBCPP_NO_UNIQUE_ADDRESS _Callback __callback_;
+  __intrusive_shared_ptr<__stop_state> __state_;
+
+  friend __stop_callback_base;
+
+  struct __private_tag {};
+
+  template <class _StatePtr, class _Cb>
+  _LIBCPP_HIDE_FROM_ABI explicit stop_callback(__private_tag, _StatePtr&& __state, _Cb&& __cb) noexcept(
+      is_nothrow_constructible_v<_Callback, _Cb>)
+      : __stop_callback_base([](__stop_callback_base* __cb_base) noexcept {
+          // stop callback is supposed to only be called once
+          std::forward<_Callback>(static_cast<stop_callback*>(__cb_base)->__callback_)();
+        }),
+        __callback_(std::forward<_Cb>(__cb)),
+        __state_() {
+    if (__state && __state->__add_callback(this)) {
+      // st.stop_requested() was false and this is successfully added to the linked list
+      __state_ = std::forward<_StatePtr>(__state);
+    }
+  }
+};
+
+template <class _Callback>
+_LIBCPP_AVAILABILITY_SYNC stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
lib/libcxx/include/__stop_token/stop_source.h
@@ -0,0 +1,92 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_STOP_SOURCE_H
+#define _LIBCPP___STOP_TOKEN_STOP_SOURCE_H
+
+#include <__availability>
+#include <__config>
+#include <__stop_token/intrusive_shared_ptr.h>
+#include <__stop_token/stop_state.h>
+#include <__stop_token/stop_token.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
+
+struct nostopstate_t {
+  explicit nostopstate_t() = default;
+};
+
+inline constexpr nostopstate_t nostopstate{};
+
+class _LIBCPP_AVAILABILITY_SYNC stop_source {
+public:
+  _LIBCPP_HIDE_FROM_ABI stop_source() : __state_(new __stop_state()) { __state_->__increment_stop_source_counter(); }
+
+  _LIBCPP_HIDE_FROM_ABI explicit stop_source(nostopstate_t) noexcept : __state_(nullptr) {}
+
+  _LIBCPP_HIDE_FROM_ABI stop_source(const stop_source& __other) noexcept : __state_(__other.__state_) {
+    if (__state_) {
+      __state_->__increment_stop_source_counter();
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI stop_source(stop_source&& __other) noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI stop_source& operator=(const stop_source& __other) noexcept {
+    // increment `__other` first so that we don't hit 0 in case of self-assignment
+    if (__other.__state_) {
+      __other.__state_->__increment_stop_source_counter();
+    }
+    if (__state_) {
+      __state_->__decrement_stop_source_counter();
+    }
+    __state_ = __other.__state_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI stop_source& operator=(stop_source&&) noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI ~stop_source() {
+    if (__state_) {
+      __state_->__decrement_stop_source_counter();
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void swap(stop_source& __other) noexcept { __state_.swap(__other.__state_); }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_token get_token() const noexcept { return stop_token(__state_); }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept { return __state_ != nullptr; }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept {
+    return __state_ != nullptr && __state_->__stop_requested();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool request_stop() noexcept { return __state_ && __state_->__request_stop(); }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_source&, const stop_source&) noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI friend void swap(stop_source& __lhs, stop_source& __rhs) noexcept { __lhs.swap(__rhs); }
+
+private:
+  __intrusive_shared_ptr<__stop_state> __state_;
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
lib/libcxx/include/__stop_token/stop_state.h
@@ -0,0 +1,236 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_STOP_STATE_H
+#define _LIBCPP___STOP_TOKEN_STOP_STATE_H
+
+#include <__availability>
+#include <__config>
+#include <__stop_token/atomic_unique_lock.h>
+#include <__stop_token/intrusive_list_view.h>
+#include <atomic>
+#include <cstdint>
+#include <thread>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+struct __stop_callback_base : __intrusive_node_base<__stop_callback_base> {
+  using __callback_fn_t = void(__stop_callback_base*) noexcept;
+  _LIBCPP_HIDE_FROM_ABI explicit __stop_callback_base(__callback_fn_t* __callback_fn) : __callback_fn_(__callback_fn) {}
+
+  _LIBCPP_HIDE_FROM_ABI void __invoke() noexcept { __callback_fn_(this); }
+
+  __callback_fn_t* __callback_fn_;
+  atomic<bool> __completed_ = false;
+  bool* __destroyed_        = nullptr;
+};
+
+class __stop_state {
+  static constexpr uint32_t __stop_requested_bit        = 1;
+  static constexpr uint32_t __callback_list_locked_bit  = 1 << 1;
+  static constexpr uint32_t __stop_source_counter_shift = 2;
+
+  // The "stop_source counter" is not used for lifetime reference counting.
+  // When the number of stop_source reaches 0, the remaining stop_tokens's
+  // stop_possible will return false. We need this counter to track this.
+  //
+  // The "callback list locked" bit implements the atomic_unique_lock to
+  // guard the operations on the callback list
+  //
+  //       31 - 2          |  1                   |    0           |
+  //  stop_source counter  | callback list locked | stop_requested |
+  atomic<uint32_t> __state_ = 0;
+
+  // Reference count for stop_token + stop_callback + stop_source
+  // When the counter reaches zero, the state is destroyed
+  // It is used by __intrusive_shared_ptr, but it is stored here for better layout
+  atomic<uint32_t> __ref_count_ = 0;
+
+  using __state_t            = uint32_t;
+  using __callback_list_lock = __atomic_unique_lock<__state_t, __callback_list_locked_bit>;
+  using __callback_list      = __intrusive_list_view<__stop_callback_base>;
+
+  __callback_list __callback_list_;
+  thread::id __requesting_thread_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI __stop_state() noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI void __increment_stop_source_counter() noexcept {
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __state_.load(std::memory_order_relaxed) <= static_cast<__state_t>(~(1 << __stop_source_counter_shift)),
+        "stop_source's counter reaches the maximum. Incrementing the counter will overflow");
+    __state_.fetch_add(1 << __stop_source_counter_shift, std::memory_order_relaxed);
+  }
+
+  // We are not destroying the object after counter decrements to zero, nor do we have
+  // operations depend on the ordering of decrementing the counter. relaxed is enough.
+  _LIBCPP_HIDE_FROM_ABI void __decrement_stop_source_counter() noexcept {
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __state_.load(std::memory_order_relaxed) >= static_cast<__state_t>(1 << __stop_source_counter_shift),
+        "stop_source's counter is 0. Decrementing the counter will underflow");
+    __state_.fetch_sub(1 << __stop_source_counter_shift, std::memory_order_relaxed);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool __stop_requested() const noexcept {
+    // acquire because [thread.stoptoken.intro] A call to request_stop that returns true
+    // synchronizes with a call to stop_requested on an associated stop_token or stop_source
+    // object that returns true.
+    // request_stop's compare_exchange_weak has release which syncs with this acquire
+    return (__state_.load(std::memory_order_acquire) & __stop_requested_bit) != 0;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool __stop_possible_for_stop_token() const noexcept {
+    // [stoptoken.mem] false if "a stop request was not made and there are no associated stop_source objects"
+    // Todo: Can this be std::memory_order_relaxed as the standard does not say anything except not to introduce data
+    // race?
+    __state_t __curent_state = __state_.load(std::memory_order_acquire);
+    return ((__curent_state & __stop_requested_bit) != 0) || ((__curent_state >> __stop_source_counter_shift) != 0);
+  }
+
+  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __request_stop() noexcept {
+    auto __cb_list_lock = __try_lock_for_request_stop();
+    if (!__cb_list_lock.__owns_lock()) {
+      return false;
+    }
+    __requesting_thread_ = this_thread::get_id();
+
+    while (!__callback_list_.__empty()) {
+      auto __cb = __callback_list_.__pop_front();
+
+      // allow other callbacks to be removed while invoking the current callback
+      __cb_list_lock.__unlock();
+
+      bool __destroyed   = false;
+      __cb->__destroyed_ = &__destroyed;
+
+      __cb->__invoke();
+
+      // __cb's invoke function could potentially delete itself. We need to check before accessing __cb's member
+      if (!__destroyed) {
+        // needs to set __destroyed_ pointer to nullptr, otherwise it points to a local variable
+        // which is to be destroyed at the end of the loop
+        __cb->__destroyed_ = nullptr;
+
+        // [stopcallback.cons] If callback is concurrently executing on another thread, then the return
+        // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed.
+        // this release syncs with the acquire in the remove_callback
+        __cb->__completed_.store(true, std::memory_order_release);
+        __cb->__completed_.notify_all();
+      }
+
+      __cb_list_lock.__lock();
+    }
+
+    return true;
+  }
+
+  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __add_callback(__stop_callback_base* __cb) noexcept {
+    // If it is already stop_requested. Do not try to request it again.
+    const auto __give_up_trying_to_lock_condition = [__cb](__state_t __state) {
+      if ((__state & __stop_requested_bit) != 0) {
+        // already stop requested, synchronously run the callback and no need to lock the list again
+        __cb->__invoke();
+        return true;
+      }
+      // no stop source. no need to lock the list to add the callback as it can never be invoked
+      return (__state >> __stop_source_counter_shift) == 0;
+    };
+
+    __callback_list_lock __cb_list_lock(__state_, __give_up_trying_to_lock_condition);
+
+    if (!__cb_list_lock.__owns_lock()) {
+      return false;
+    }
+
+    __callback_list_.__push_front(__cb);
+
+    return true;
+    // unlock here: [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of
+    // that callback.
+    // Note: this release sync with the acquire in the request_stop' __try_lock_for_request_stop
+  }
+
+  // called by the destructor of stop_callback
+  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __remove_callback(__stop_callback_base* __cb) noexcept {
+    __callback_list_lock __cb_list_lock(__state_);
+
+    // under below condition, the request_stop call just popped __cb from the list and could execute it now
+    bool __potentially_executing_now = __cb->__prev_ == nullptr && !__callback_list_.__is_head(__cb);
+
+    if (__potentially_executing_now) {
+      auto __requested_thread = __requesting_thread_;
+      __cb_list_lock.__unlock();
+
+      if (std::this_thread::get_id() != __requested_thread) {
+        // [stopcallback.cons] If callback is concurrently executing on another thread, then the return
+        // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed.
+        __cb->__completed_.wait(false, std::memory_order_acquire);
+      } else {
+        // The destructor of stop_callback runs on the same thread of the thread that invokes the callback.
+        // The callback is potentially invoking its own destuctor. Set the flag to avoid accessing destroyed
+        // members on the invoking side
+        if (__cb->__destroyed_) {
+          *__cb->__destroyed_ = true;
+        }
+      }
+    } else {
+      __callback_list_.__remove(__cb);
+    }
+  }
+
+private:
+  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __callback_list_lock __try_lock_for_request_stop() noexcept {
+    // If it is already stop_requested, do not try to request stop or lock the list again.
+    const auto __lock_fail_condition = [](__state_t __state) { return (__state & __stop_requested_bit) != 0; };
+
+    // set locked and requested bit at the same time
+    const auto __after_lock_state = [](__state_t __state) {
+      return __state | __callback_list_locked_bit | __stop_requested_bit;
+    };
+
+    // acq because [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of that
+    //     callback. We are going to invoke the callback after getting the lock, acquire so that we can see the
+    //     registration of a callback (and other writes that happens-before the add_callback)
+    //     Note: the rel (unlock) in the add_callback syncs with this acq
+    // rel because [thread.stoptoken.intro] A call to request_stop that returns true synchronizes with a call
+    //     to stop_requested on an associated stop_token or stop_source object that returns true.
+    //     We need to make sure that all writes (including user code) before request_stop will be made visible
+    //     to the threads that waiting for `stop_requested == true`
+    //     Note: this rel syncs with the acq in `stop_requested`
+    const auto __locked_ordering = std::memory_order_acq_rel;
+
+    return __callback_list_lock(__state_, __lock_fail_condition, __after_lock_state, __locked_ordering);
+  }
+
+  template <class _Tp>
+  friend struct __intrusive_shared_ptr_traits;
+};
+
+template <class _Tp>
+struct __intrusive_shared_ptr_traits;
+
+template <>
+struct __intrusive_shared_ptr_traits<__stop_state> {
+  _LIBCPP_HIDE_FROM_ABI static atomic<uint32_t>& __get_atomic_ref_count(__stop_state& __state) {
+    return __state.__ref_count_;
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STOP_TOKEN_STOP_STATE_H
lib/libcxx/include/__stop_token/stop_token.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STOP_TOKEN_STOP_TOKEN_H
+#define _LIBCPP___STOP_TOKEN_STOP_TOKEN_H
+
+#include <__availability>
+#include <__config>
+#include <__stop_token/intrusive_shared_ptr.h>
+#include <__stop_token/stop_state.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
+
+class _LIBCPP_AVAILABILITY_SYNC stop_token {
+public:
+  _LIBCPP_HIDE_FROM_ABI stop_token() noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI stop_token(const stop_token&) noexcept            = default;
+  _LIBCPP_HIDE_FROM_ABI stop_token(stop_token&&) noexcept                 = default;
+  _LIBCPP_HIDE_FROM_ABI stop_token& operator=(const stop_token&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI stop_token& operator=(stop_token&&) noexcept      = default;
+  _LIBCPP_HIDE_FROM_ABI ~stop_token()                                     = default;
+
+  _LIBCPP_HIDE_FROM_ABI void swap(stop_token& __other) noexcept { __state_.swap(__other.__state_); }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept {
+    return __state_ != nullptr && __state_->__stop_requested();
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept {
+    return __state_ != nullptr && __state_->__stop_possible_for_stop_token();
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_token&, const stop_token&) noexcept = default;
+
+  _LIBCPP_HIDE_FROM_ABI friend void swap(stop_token& __lhs, stop_token& __rhs) noexcept { __lhs.swap(__rhs); }
+
+private:
+  __intrusive_shared_ptr<__stop_state> __state_;
+
+  friend class stop_source;
+  template <class _Tp>
+  friend class stop_callback;
+
+  _LIBCPP_HIDE_FROM_ABI explicit stop_token(const __intrusive_shared_ptr<__stop_state>& __state) : __state_(__state) {}
+};
+
+#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STOP_TOKEN_STOP_TOKEN_H
lib/libcxx/include/__string/char_traits.h
@@ -18,11 +18,11 @@
 #include <__config>
 #include <__functional/hash.h>
 #include <__iterator/iterator_traits.h>
+#include <__string/constexpr_c_functions.h>
 #include <__type_traits/is_constant_evaluated.h>
 #include <cstddef>
 #include <cstdint>
 #include <cstdio>
-#include <cstring>
 #include <iosfwd>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -73,7 +73,7 @@ exposition-only to document what members a char_traits specialization should pro
 
 //
 // Temporary extension to provide a base template for std::char_traits.
-// TODO: Remove in LLVM 18.
+// TODO(LLVM-18): Remove this class.
 //
 template <class _CharT>
 struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it.")
@@ -85,14 +85,14 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
     using pos_type   = streampos;
     using state_type = mbstate_t;
 
-    static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI
         assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
-    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
-    static _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     int compare(const char_type* __s1, const char_type* __s2, size_t __n) {
         for (; __n; --__n, ++__s1, ++__s2)
         {
@@ -120,7 +120,7 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
         }
         return nullptr;
     }
-    static _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) {
         if (__n == 0) return __s1;
         char_type* __r = __s1;
@@ -142,7 +142,8 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) {
         if (!__libcpp_is_constant_evaluated()) {
-            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
+                __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
         }
         char_type* __r = __s1;
         for (; __n; --__n, ++__s1, ++__s2)
@@ -158,37 +159,18 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
         return __r;
     }
 
-    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
         {return int_type(EOF);}
 };
 
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
-_CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
-{
-#ifdef _LIBCPP_COMPILER_GCC
-  if (__libcpp_is_constant_evaluated()) {
-    if (__n == 0)
-      return __dest;
-    _CharT* __allocation = new _CharT[__n];
-    std::copy_n(__source, __n, __allocation);
-    std::copy_n(static_cast<const _CharT*>(__allocation), __n, __dest);
-    delete[] __allocation;
-    return __dest;
-  }
-#endif
-  ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT));
-  return __dest;
-}
-
 // char_traits<char>
 
 template <>
@@ -199,62 +181,83 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
     using off_type            = streamoff;
     using pos_type            = streampos;
     using state_type          = mbstate_t;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using comparison_category = strong_ordering;
 #endif
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
-    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+
+    // TODO: Make this _LIBCPP_HIDE_FROM_ABI
+    static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
             {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return (unsigned char)__c1 < (unsigned char)__c2;}
 
-  static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    if (__n == 0)
-      return 0;
-    return std::__constexpr_memcmp(__s1, __s2, __n);
-  }
+    // __constexpr_memcmp requires a trivially lexicographically comparable type, but char is not when char is a signed type
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
+    compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT {
+      if (__libcpp_is_constant_evaluated()) {
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+        return __builtin_memcmp(__lhs, __rhs, __count);
+#else
+        while (__count != 0) {
+          if (lt(*__lhs, *__rhs))
+            return -1;
+          if (lt(*__rhs, *__lhs))
+            return 1;
 
-  static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s)  _NOEXCEPT {
-    return std::__constexpr_strlen(__s);
-  }
+          __count -= sizeof(char_type);
+          ++__lhs;
+          ++__rhs;
+        }
+        return 0;
+#endif // _LIBCPP_COMPILER_CLANG_BASED
+      } else {
+        return __builtin_memcmp(__lhs, __rhs, __count);
+      }
+    }
 
-  static _LIBCPP_CONSTEXPR_SINCE_CXX17
-  const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
-    if (__n == 0)
-        return nullptr;
-    return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n);
-  }
+    static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s)  _NOEXCEPT {
+      return std::__constexpr_strlen(__s);
+    }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
+      if (__n == 0)
+          return nullptr;
+      return std::__constexpr_memchr(__s, __a, __n);
+    }
+
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-        return std::__char_traits_move(__s1, __s2, __n);
+        return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
     }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
         if (!__libcpp_is_constant_evaluated())
-            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
+                __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
         std::copy_n(__s2, __n, __s1);
         return __s1;
     }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
         std::fill_n(__s, __n, __a);
         return __s;
     }
 
-    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type((unsigned char)__c);}
-    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
         {return int_type(EOF);}
 };
 
@@ -269,62 +272,64 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
     using off_type            = streamoff;
     using pos_type            = streampos;
     using state_type          = mbstate_t;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using comparison_category = strong_ordering;
 #endif
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
-    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
-  static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
+  compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     if (__n == 0)
-        return 0;
+      return 0;
     return std::__constexpr_wmemcmp(__s1, __s2, __n);
   }
 
-  static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
     return std::__constexpr_wcslen(__s);
   }
 
-  static _LIBCPP_CONSTEXPR_SINCE_CXX17
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
   const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
     if (__n == 0)
         return nullptr;
     return std::__constexpr_wmemchr(__s, __a, __n);
   }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-        return std::__char_traits_move(__s1, __s2, __n);
+        return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
     }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
         if (!__libcpp_is_constant_evaluated())
-            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
+                __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
         std::copy_n(__s2, __n, __s1);
         return __s1;
     }
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
         std::fill_n(__s, __n, __a);
         return __s;
     }
 
-    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(WEOF);}
 };
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -339,56 +344,57 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
     using off_type            = streamoff;
     using pos_type            = u8streampos;
     using state_type          = mbstate_t;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using comparison_category = strong_ordering;
 #endif
 
-    static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
         {__c1 = __c2;}
-    static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq(char_type __c1, char_type __c2) noexcept
         {return __c1 == __c2;}
-    static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt(char_type __c1, char_type __c2) noexcept
         {return __c1 < __c2;}
 
   static _LIBCPP_HIDE_FROM_ABI constexpr int
   compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-      return std::__constexpr_memcmp(__s1, __s2, __n);
+      return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
   }
 
-    static constexpr
+    static _LIBCPP_HIDE_FROM_ABI constexpr
     size_t           length(const char_type* __s) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY static constexpr
     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
 
-    static _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-        return std::__char_traits_move(__s1, __s2, __n);
+        return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
     }
 
-    static _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
         if (!__libcpp_is_constant_evaluated())
-            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
+                __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
         std::copy_n(__s2, __n, __s1);
         return __s1;
     }
 
-    static _LIBCPP_CONSTEXPR_SINCE_CXX20
+    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
         std::fill_n(__s, __n, __a);
         return __s;
     }
 
-    static inline constexpr int_type  not_eof(int_type __c) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type  not_eof(int_type __c) noexcept
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline constexpr char_type to_char_type(int_type __c) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type(int_type __c) noexcept
         {return char_type(__c);}
-    static inline constexpr int_type to_int_type(char_type __c) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type(char_type __c) noexcept
         {return int_type(__c);}
-    static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
         {return __c1 == __c2;}
-    static inline constexpr int_type eof() noexcept
+    static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof() noexcept
         {return int_type(EOF);}
 };
 
@@ -427,15 +433,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
     using off_type            = streamoff;
     using pos_type            = u16streampos;
     using state_type          = mbstate_t;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using comparison_category = strong_ordering;
 #endif
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
-    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
@@ -447,13 +453,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-        return std::__char_traits_move(__s1, __s2, __n);
+        return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
         if (!__libcpp_is_constant_evaluated())
-            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
+                __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
         std::copy_n(__s2, __n, __s1);
         return __s1;
     }
@@ -464,15 +471,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
         return __s;
     }
 
-    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(0xFFFF);}
 };
 
@@ -521,15 +528,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
     using off_type            = streamoff;
     using pos_type            = u32streampos;
     using state_type          = mbstate_t;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     using comparison_category = strong_ordering;
 #endif
 
-    static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
-    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
@@ -541,7 +548,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-        return std::__char_traits_move(__s1, __s2, __n);
+        return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -556,15 +563,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
         return __s;
     }
 
-    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(0xFFFFFFFF);}
 };
 
lib/libcxx/include/__string/constexpr_c_functions.h
@@ -0,0 +1,219 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___STRING_CONSTEXPR_C_FUNCTIONS_H
+#define _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__type_traits/datasizeof.h>
+#include <__type_traits/is_always_bitcastable.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/is_trivially_lexicographically_comparable.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/is_pointer_in_range.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Type used to encode that a function takes an integer that represents a number
+// of elements as opposed to a number of bytes.
+enum class __element_count : size_t {};
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
+  // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
+  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
+#ifdef _LIBCPP_COMPILER_GCC
+  if (__libcpp_is_constant_evaluated()) {
+    size_t __i = 0;
+    for (; __str[__i] != '\0'; ++__i)
+      ;
+    return __i;
+  }
+#endif
+  return __builtin_strlen(__str);
+}
+
+// Because of __libcpp_is_trivially_lexicographically_comparable we know that comparing the object representations is
+// equivalent to a std::memcmp. Since we have multiple objects contiguously in memory, we can call memcmp once instead
+// of invoking it on every object individually.
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
+__constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
+  static_assert(__libcpp_is_trivially_lexicographically_comparable<_Tp, _Up>::value,
+                "_Tp and _Up have to be trivially lexicographically comparable");
+
+  auto __count = static_cast<size_t>(__n);
+
+  if (__libcpp_is_constant_evaluated()) {
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+    if (sizeof(_Tp) == 1 && !is_same<_Tp, bool>::value)
+      return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
+#endif
+
+    while (__count != 0) {
+      if (*__lhs < *__rhs)
+        return -1;
+      if (*__rhs < *__lhs)
+        return 1;
+
+      --__count;
+      ++__lhs;
+      ++__rhs;
+    }
+    return 0;
+  } else {
+    return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
+  }
+}
+
+// Because of __libcpp_is_trivially_equality_comparable we know that comparing the object representations is equivalent
+// to a std::memcmp(...) == 0. Since we have multiple objects contiguously in memory, we can call memcmp once instead
+// of invoking it on every object individually.
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
+__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
+  static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+                "_Tp and _Up have to be trivially equality comparable");
+
+  auto __count = static_cast<size_t>(__n);
+
+  if (__libcpp_is_constant_evaluated()) {
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+    if (sizeof(_Tp) == 1 && is_integral<_Tp>::value && !is_same<_Tp, bool>::value)
+      return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
+#endif
+    while (__count != 0) {
+      if (*__lhs != *__rhs)
+        return false;
+
+      --__count;
+      ++__lhs;
+      ++__rhs;
+    }
+    return true;
+  } else {
+    return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
+  }
+}
+
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memchr(_Tp* __str, _Up __value, size_t __count) {
+  static_assert(sizeof(_Tp) == 1 && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+                "Calling memchr on non-trivially equality comparable types is unsafe.");
+
+  if (__libcpp_is_constant_evaluated()) {
+// use __builtin_char_memchr to optimize constexpr evaluation if we can
+#if _LIBCPP_STD_VER >= 17 && __has_builtin(__builtin_char_memchr)
+    if constexpr (is_same_v<remove_cv_t<_Tp>, char> && is_same_v<remove_cv_t<_Up>, char>)
+      return __builtin_char_memchr(__str, __value, __count);
+#endif
+
+    for (; __count; --__count) {
+      if (*__str == __value)
+        return __str;
+      ++__str;
+    }
+    return nullptr;
+  } else {
+    char __value_buffer = 0;
+    __builtin_memcpy(&__value_buffer, &__value, sizeof(char));
+    return static_cast<_Tp*>(__builtin_memchr(__str, __value_buffer, __count));
+  }
+}
+
+// This function performs an assignment to an existing, already alive TriviallyCopyable object
+// from another TriviallyCopyable object.
+//
+// It basically works around the fact that TriviallyCopyable objects are not required to be
+// syntactically copy/move constructible or copy/move assignable. Technically, only one of the
+// four operations is required to be syntactically valid -- but at least one definitely has to
+// be valid.
+//
+// This is necessary in order to implement __constexpr_memmove below in a way that mirrors as
+// closely as possible what the compiler's __builtin_memmove is able to do.
+template <class _Tp, class _Up, __enable_if_t<is_assignable<_Tp&, _Up const&>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) {
+  __dest = __src;
+  return __dest;
+}
+
+// clang-format off
+template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
+                                               is_assignable<_Tp&, _Up&&>::value, int> = 0>
+// clang-format on
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) {
+  __dest =
+      static_cast<_Up&&>(__src); // this is safe, we're not actually moving anything since the assignment is trivial
+  return __dest;
+}
+
+// clang-format off
+template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
+                                              !is_assignable<_Tp&, _Up&&>::value &&
+                                               is_constructible<_Tp, _Up const&>::value, int> = 0>
+// clang-format on
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) {
+  // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object
+  // that was there previously
+  std::__construct_at(std::addressof(__dest), __src);
+  return __dest;
+}
+
+// clang-format off
+template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
+                                              !is_assignable<_Tp&, _Up&&>::value &&
+                                              !is_constructible<_Tp, _Up const&>::value &&
+                                               is_constructible<_Tp, _Up&&>::value, int> = 0>
+// clang-format on
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) {
+  // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object
+  // that was there previously
+  std::__construct_at(
+      std::addressof(__dest),
+      static_cast<_Up&&>(__src)); // this is safe, we're not actually moving anything since the constructor is trivial
+  return __dest;
+}
+
+template <class _Tp, class _Up, __enable_if_t<__is_always_bitcastable<_Up, _Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
+__constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) {
+  size_t __count = static_cast<size_t>(__n);
+  if (__libcpp_is_constant_evaluated()) {
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+    if (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) {
+      ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp));
+      return __dest;
+    }
+#endif
+    if (std::__is_pointer_in_range(__src, __src + __count, __dest)) {
+      for (; __count > 0; --__count)
+        std::__assign_trivially_copyable(__dest[__count - 1], __src[__count - 1]);
+    } else {
+      for (size_t __i = 0; __i != __count; ++__i)
+        std::__assign_trivially_copyable(__dest[__i], __src[__i]);
+    }
+  } else if (__count > 0) {
+    ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __libcpp_datasizeof<_Tp>::value);
+  }
+  return __dest;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
lib/libcxx/include/__string/extern_template_lists.h
@@ -28,104 +28,103 @@
 // functions supporting new c++ version / API changes. Typically entries
 // must never be removed from the stable list.
 #define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
-  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
 
 #define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
-  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
+  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
 
 
 #endif // _LIBCPP___STRING_EXTERN_TEMPLATE_LISTS_H
lib/libcxx/include/__support/musl/xlocale.h
@@ -37,7 +37,8 @@ inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_
   return ::wcstoll(__nptr, __endptr, __base);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
   return ::wcstoull(__nptr, __endptr, __base);
 }
 
lib/libcxx/include/__support/solaris/wchar.h
@@ -1,46 +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
-//
-//===----------------------------------------------------------------------===//
-
-#define iswalpha sun_iswalpha
-#define iswupper sun_iswupper
-#define iswlower sun_iswlower
-#define iswdigit sun_iswdigit
-#define iswxdigit sun_iswxdigit
-#define iswalnum sun_iswalnum
-#define iswspace sun_iswspace
-#define iswpunct sun_iswpunct
-#define iswprint sun_iswprint
-#define iswgraph sun_iswgraph
-#define iswcntrl sun_iswcntrl
-#define iswctype sun_iswctype
-#define towlower sun_towlower
-#define towupper sun_towupper
-#define wcswcs sun_wcswcs
-#define wcswidth sun_wcswidth
-#define wcwidth sun_wcwidth
-#define wctype sun_wctype
-#define _WCHAR_T 1
-#include_next "wchar.h"
-#undef iswalpha
-#undef iswupper
-#undef iswlower
-#undef iswdigit
-#undef iswxdigit
-#undef iswalnum
-#undef iswspace
-#undef iswpunct
-#undef iswprint
-#undef iswgraph
-#undef iswcntrl
-#undef iswctype
-#undef towlower
-#undef towupper
-#undef wcswcs
-#undef wcswidth
-#undef wcwidth
-#undef wctype
lib/libcxx/include/__support/solaris/xlocale.h
@@ -1,75 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-////////////////////////////////////////////////////////////////////////////////
-// Minimal xlocale implementation for Solaris.  This implements the subset of
-// the xlocale APIs that libc++ depends on.
-////////////////////////////////////////////////////////////////////////////////
-#ifndef __XLOCALE_H_INCLUDED
-#define __XLOCALE_H_INCLUDED
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);
-int asprintf_l(char **__s, locale_t __l, const char *__format, ...);
-
-int sscanf_l(const char *__s, locale_t __l, const char *__format, ...);
-
-int toupper_l(int __c, locale_t __l);
-int tolower_l(int __c, locale_t __l);
-
-struct lconv *localeconv(void);
-struct lconv *localeconv_l(locale_t __l);
-
-// FIXME: These are quick-and-dirty hacks to make things pretend to work
-inline _LIBCPP_HIDE_FROM_ABI long long
-strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
-  return ::strtoll(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI long
-strtol_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
-  return ::strtol(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t __loc)
-  return ::strtoull(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long
-strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
-  return ::strtoul(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI float
-strtof_l(const char *__nptr, char **__endptr, locale_t __loc) {
-  return ::strtof(__nptr, __endptr);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI double
-strtod_l(const char *__nptr, char **__endptr, locale_t __loc) {
-  return ::strtod(__nptr, __endptr);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI long double
-strtold_l(const char *__nptr, char **__endptr, locale_t __loc) {
-  return ::strtold(__nptr, __endptr);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
lib/libcxx/include/__support/win32/locale_win32.h
@@ -221,8 +221,8 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l );
 #define strtof_l _strtof_l
 #define strtold_l _strtold_l
 #else
-_LIBCPP_FUNC_VIS float strtof_l(const char*, char**, locale_t);
-_LIBCPP_FUNC_VIS long double strtold_l(const char*, char**, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI float strtof_l(const char*, char**, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI long double strtold_l(const char*, char**, locale_t);
 #endif
 inline _LIBCPP_HIDE_FROM_ABI int
 islower_l(int __c, _locale_t __loc)
@@ -256,7 +256,7 @@ isupper_l(int __c, _locale_t __loc)
 #define towupper_l _towupper_l
 #define towlower_l _towlower_l
 #if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
-_LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format,
+_LIBCPP_EXPORTED_FROM_ABI size_t strftime_l(char *ret, size_t n, const char *format,
                                    const struct tm *tm, locale_t loc);
 #else
 #define strftime_l _strftime_l
@@ -265,9 +265,9 @@ _LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format,
 #define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )
 #define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )
 #define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
-_LIBCPP_FUNC_VIS int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...);
-_LIBCPP_FUNC_VIS int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... );
-_LIBCPP_FUNC_VIS int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap );
+_LIBCPP_EXPORTED_FROM_ABI int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...);
+_LIBCPP_EXPORTED_FROM_ABI int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... );
+_LIBCPP_EXPORTED_FROM_ABI int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap );
 
 // not-so-pressing FIXME: use locale to determine blank characters
 inline int isblank_l( int __c, locale_t /*loc*/ )
lib/libcxx/include/__errc → lib/libcxx/include/__system_error/errc.h
File renamed without changes
lib/libcxx/include/__system_error/error_category.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___SYSTEM_ERROR_ERROR_CATEGORY_H
+#define _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H
+
+#include <__compare/ordering.h>
+#include <__config>
+#include <string>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_EXPORTED_FROM_ABI error_condition;
+class _LIBCPP_EXPORTED_FROM_ABI error_code;
+
+class _LIBCPP_HIDDEN __do_message;
+
+class _LIBCPP_EXPORTED_FROM_ABI error_category {
+public:
+  virtual ~error_category() _NOEXCEPT;
+
+#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS)
+  error_category() noexcept;
+#else
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default;
+#endif
+  error_category(const error_category&)            = delete;
+  error_category& operator=(const error_category&) = delete;
+
+  virtual const char* name() const _NOEXCEPT = 0;
+  virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
+  virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
+  virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
+  virtual string message(int __ev) const = 0;
+
+  _LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; }
+
+#if _LIBCPP_STD_VER >= 20
+
+  _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_category& __rhs) const noexcept {
+    return compare_three_way()(this, std::addressof(__rhs));
+  }
+
+#else // _LIBCPP_STD_VER >= 20
+
+  _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_category& __rhs) const _NOEXCEPT { return !(*this == __rhs); }
+
+  _LIBCPP_HIDE_FROM_ABI bool operator<(const error_category& __rhs) const _NOEXCEPT { return this < &__rhs; }
+
+#endif // _LIBCPP_STD_VER >= 20
+
+  friend class _LIBCPP_HIDDEN __do_message;
+};
+
+class _LIBCPP_HIDDEN __do_message : public error_category {
+public:
+  string message(int __ev) const override;
+};
+
+_LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H
lib/libcxx/include/__system_error/error_code.h
@@ -0,0 +1,145 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___SYSTEM_ERROR_ERROR_CODE_H
+#define _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H
+
+#include <__compare/ordering.h>
+#include <__config>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__system_error/errc.h>
+#include <__system_error/error_category.h>
+#include <__system_error/error_condition.h>
+#include <cstddef>
+#include <string>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public false_type {};
+
+#if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value;
+#endif
+
+namespace __adl_only {
+// Those cause ADL to trigger but they are not viable candidates,
+// so they are never actually selected.
+void make_error_code() = delete;
+} // namespace __adl_only
+
+class _LIBCPP_EXPORTED_FROM_ABI error_code {
+  int __val_;
+  const error_category* __cat_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
+
+  _LIBCPP_HIDE_FROM_ABI error_code(int __val, const error_category& __cat) _NOEXCEPT : __val_(__val), __cat_(&__cat) {}
+
+  template <class _Ep>
+  _LIBCPP_HIDE_FROM_ABI
+  error_code(_Ep __e, typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT {
+    using __adl_only::make_error_code;
+    *this = make_error_code(__e);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT {
+    __val_ = __val;
+    __cat_ = &__cat;
+  }
+
+  template <class _Ep>
+  _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_code_enum<_Ep>::value, error_code& >::type
+  operator=(_Ep __e) _NOEXCEPT {
+    using __adl_only::make_error_code;
+    *this = make_error_code(__e);
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
+    __val_ = 0;
+    __cat_ = &system_category();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
+
+  _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
+
+  _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
+    return __cat_->default_error_condition(__val_);
+  }
+
+  string message() const;
+
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
+};
+
+inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
+  return error_code(static_cast<int>(__e), generic_category());
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_code& __y) _NOEXCEPT {
+  return __x.category() == __y.category() && __x.value() == __y.value();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT {
+  return __x.category().equivalent(__x.value(), __y) || __y.category().equivalent(__x, __y.value());
+}
+
+#if _LIBCPP_STD_VER <= 17
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT {
+  return __y == __x;
+}
+#endif
+
+#if _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_code& __x, const error_code& __y) _NOEXCEPT {
+  return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+#else // _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_code& __x, const error_code& __y) noexcept {
+  if (auto __c = __x.category() <=> __y.category(); __c != 0)
+    return __c;
+  return __x.value() <=> __y.value();
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<error_code> : public __unary_function<error_code, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_code& __ec) const _NOEXCEPT {
+    return static_cast<size_t>(__ec.value());
+  }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H
lib/libcxx/include/__system_error/error_condition.h
@@ -0,0 +1,132 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___SYSTEM_ERROR_ERROR_CONDITION_H
+#define _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H
+
+#include <__compare/ordering.h>
+#include <__config>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__system_error/errc.h>
+#include <__system_error/error_category.h>
+#include <cstddef>
+#include <string>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum : public false_type {};
+
+#if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
+#endif
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> : true_type {};
+
+#ifdef _LIBCPP_CXX03_LANG
+template <>
+struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> : true_type {};
+#endif
+
+namespace __adl_only {
+// Those cause ADL to trigger but they are not viable candidates,
+// so they are never actually selected.
+void make_error_condition() = delete;
+} // namespace __adl_only
+
+class _LIBCPP_EXPORTED_FROM_ABI error_condition {
+  int __val_;
+  const error_category* __cat_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
+
+  _LIBCPP_HIDE_FROM_ABI error_condition(int __val, const error_category& __cat) _NOEXCEPT
+      : __val_(__val),
+        __cat_(&__cat) {}
+
+  template <class _Ep>
+  _LIBCPP_HIDE_FROM_ABI
+  error_condition(_Ep __e, typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT {
+    using __adl_only::make_error_condition;
+    *this = make_error_condition(__e);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT {
+    __val_ = __val;
+    __cat_ = &__cat;
+  }
+
+  template <class _Ep>
+  _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_condition_enum<_Ep>::value, error_condition& >::type
+  operator=(_Ep __e) _NOEXCEPT {
+    using __adl_only::make_error_condition;
+    *this = make_error_condition(__e);
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
+    __val_ = 0;
+    __cat_ = &generic_category();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
+
+  _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
+  string message() const;
+
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
+};
+
+inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
+  return error_condition(static_cast<int>(__e), generic_category());
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
+  return __x.category() == __y.category() && __x.value() == __y.value();
+}
+
+#if _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
+  return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+#else // _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI strong_ordering
+operator<=>(const error_condition& __x, const error_condition& __y) noexcept {
+  if (auto __c = __x.category() <=> __y.category(); __c != 0)
+    return __c;
+  return __x.value() <=> __y.value();
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<error_condition> : public __unary_function<error_condition, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_condition& __ec) const _NOEXCEPT {
+    return static_cast<size_t>(__ec.value());
+  }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H
lib/libcxx/include/__system_error/system_error.h
@@ -0,0 +1,48 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___SYSTEM_ERROR_SYSTEM_ERROR_H
+#define _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H
+
+#include <__config>
+#include <__system_error/error_category.h>
+#include <__system_error/error_code.h>
+#include <stdexcept>
+#include <string>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_EXPORTED_FROM_ABI system_error : public runtime_error {
+  error_code __ec_;
+
+public:
+  system_error(error_code __ec, const string& __what_arg);
+  system_error(error_code __ec, const char* __what_arg);
+  system_error(error_code __ec);
+  system_error(int __ev, const error_category& __ecat, const string& __what_arg);
+  system_error(int __ev, const error_category& __ecat, const char* __what_arg);
+  system_error(int __ev, const error_category& __ecat);
+  _LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default;
+  ~system_error() _NOEXCEPT override;
+
+  _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
+
+private:
+  static string __init(const error_code&, string);
+};
+
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_system_error(int __ev, const char* __what_arg);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H
lib/libcxx/include/__thread/formatter.h
@@ -0,0 +1,80 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___THREAD_FORMATTER_H
+#define _LIBCPP___THREAD_FORMATTER_H
+
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/format_parse_context.h>
+#include <__format/formatter.h>
+#include <__format/formatter_integral.h>
+#include <__format/parser_std_format_spec.h>
+#include <__thread/id.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
+  public:
+    template <class _ParseContext>
+    _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+        return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width);
+    }
+
+    template <class _FormatContext>
+    _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const {
+        // In __threading_support __libcpp_thread_id is either a
+        // unsigned long long or a pthread_t.
+        //
+        // The type of pthread_t is left unspecified in POSIX so it can be any
+        // type. The most logical types are an integral or pointer.
+        // On Linux systems pthread_t is an unsigned long long.
+        // On Apple systems pthread_t is a pointer type.
+        //
+        // Note the output should match what the stream operator does. Since
+        // the ostream operator has been shipped years before this formatter
+        // was added to the Standard, this formatter does what the stream
+        // operator does. This may require platform specific changes.
+
+        using _Tp = decltype(__get_underlying_id(__id));
+        using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>;
+        static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report");
+
+        __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+        if constexpr (is_pointer_v<_Tp>) {
+          __specs.__std_.__alternate_form_ = true;
+          __specs.__std_.__type_           = __format_spec::__type::__hexadecimal_lower_case;
+        }
+        return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs);
+    }
+
+    __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
+};
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___THREAD_FORMATTER_H
lib/libcxx/include/__thread/id.h
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___THREAD_ID_H
+#define _LIBCPP___THREAD_ID_H
+
+#include <__compare/ordering.h>
+#include <__config>
+#include <__fwd/hash.h>
+#include <__threading_support>
+#include <iosfwd>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+class _LIBCPP_EXPORTED_FROM_ABI __thread_id;
+
+namespace this_thread {
+
+_LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT;
+
+} // namespace this_thread
+
+template <>
+struct hash<__thread_id>;
+
+class _LIBCPP_TEMPLATE_VIS __thread_id {
+  // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
+  // NULL is the no-thread value on Darwin.  Someone needs to check
+  // on other platforms.  We assume 0 works everywhere for now.
+  __libcpp_thread_id __id_;
+
+  static _LIBCPP_HIDE_FROM_ABI bool
+  __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id
+    if (__x.__id_ == 0)
+      return __y.__id_ != 0;
+    if (__y.__id_ == 0)
+      return false;
+    return __libcpp_thread_id_less(__x.__id_, __y.__id_);
+  }
+
+public:
+  _LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {}
+
+  _LIBCPP_HIDE_FROM_ABI void __reset() { __id_ = 0; }
+
+  friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
+#  if _LIBCPP_STD_VER <= 17
+  friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
+#  else  // _LIBCPP_STD_VER <= 17
+  friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
+#  endif // _LIBCPP_STD_VER <= 17
+
+  template <class _CharT, class _Traits>
+  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+  operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
+
+private:
+  _LIBCPP_HIDE_FROM_ABI __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
+
+  _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }
+
+  friend __thread_id this_thread::get_id() _NOEXCEPT;
+  friend class _LIBCPP_EXPORTED_FROM_ABI thread;
+  friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
+};
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
+  // Don't pass id==0 to underlying routines
+  if (__x.__id_ == 0)
+    return __y.__id_ == 0;
+  if (__y.__id_ == 0)
+    return false;
+  return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
+}
+
+#  if _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); }
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
+  return __thread_id::__lt_impl(__x.__id_, __y.__id_);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
+inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
+inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
+
+#  else // _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
+  if (__x == __y)
+    return strong_ordering::equal;
+  if (__thread_id::__lt_impl(__x, __y))
+    return strong_ordering::less;
+  return strong_ordering::greater;
+}
+
+#  endif // _LIBCPP_STD_VER <= 17
+
+namespace this_thread {
+
+inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); }
+
+} // namespace this_thread
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___THREAD_ID_H
lib/libcxx/include/__thread/this_thread.h
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___THREAD_THIS_THREAD_H
+#define _LIBCPP___THREAD_THIS_THREAD_H
+
+#include <__chrono/steady_clock.h>
+#include <__chrono/time_point.h>
+#include <__condition_variable/condition_variable.h>
+#include <__config>
+#include <__mutex/mutex.h>
+#include <__mutex/unique_lock.h>
+#include <__threading_support>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace this_thread
+{
+
+_LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns);
+
+template <class _Rep, class _Period>
+_LIBCPP_HIDE_FROM_ABI void
+sleep_for(const chrono::duration<_Rep, _Period>& __d)
+{
+    if (__d > chrono::duration<_Rep, _Period>::zero())
+    {
+        // The standard guarantees a 64bit signed integer resolution for nanoseconds,
+        // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
+        // and issues with long double folding on PowerPC with GCC.
+        _LIBCPP_CONSTEXPR chrono::duration<long double> __max =
+            chrono::duration<long double>(9223372036.0L);
+        chrono::nanoseconds __ns;
+        if (__d < __max)
+        {
+            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
+            if (__ns < __d)
+                ++__ns;
+        }
+        else
+            __ns = chrono::nanoseconds::max();
+        this_thread::sleep_for(__ns);
+    }
+}
+
+template <class _Clock, class _Duration>
+_LIBCPP_HIDE_FROM_ABI void
+sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    mutex __mut;
+    condition_variable __cv;
+    unique_lock<mutex> __lk(__mut);
+    while (_Clock::now() < __t)
+        __cv.wait_until(__lk, __t);
+}
+
+template <class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
+{
+    this_thread::sleep_for(__t - chrono::steady_clock::now());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void yield() _NOEXCEPT {__libcpp_thread_yield();}
+
+} // namespace this_thread
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___THREAD_THIS_THREAD_H
lib/libcxx/include/__thread/thread.h
@@ -0,0 +1,297 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___THREAD_THREAD_H
+#define _LIBCPP___THREAD_THREAD_H
+
+#include <__condition_variable/condition_variable.h>
+#include <__config>
+#include <__exception/terminate.h>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__memory/unique_ptr.h>
+#include <__mutex/mutex.h>
+#include <__system_error/system_error.h>
+#include <__thread/id.h>
+#include <__threading_support>
+#include <__utility/forward.h>
+#include <iosfwd>
+#include <tuple>
+
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#  include <locale>
+#  include <sstream>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> class __thread_specific_ptr;
+class _LIBCPP_EXPORTED_FROM_ABI __thread_struct;
+class _LIBCPP_HIDDEN __thread_struct_imp;
+class __assoc_sub_state;
+
+_LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
+
+class _LIBCPP_EXPORTED_FROM_ABI __thread_struct
+{
+    __thread_struct_imp* __p_;
+
+    __thread_struct(const __thread_struct&);
+    __thread_struct& operator=(const __thread_struct&);
+public:
+    __thread_struct();
+    ~__thread_struct();
+
+    void notify_all_at_thread_exit(condition_variable*, mutex*);
+    void __make_ready_at_thread_exit(__assoc_sub_state*);
+};
+
+template <class _Tp>
+class __thread_specific_ptr
+{
+    __libcpp_tls_key __key_;
+
+     // Only __thread_local_data() may construct a __thread_specific_ptr
+     // and only with _Tp == __thread_struct.
+    static_assert((is_same<_Tp, __thread_struct>::value), "");
+    __thread_specific_ptr();
+    friend _LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
+
+    __thread_specific_ptr(const __thread_specific_ptr&);
+    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
+
+    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
+public:
+    typedef _Tp* pointer;
+
+    ~__thread_specific_ptr();
+
+    _LIBCPP_INLINE_VISIBILITY
+    pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator*() const {return *get();}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return get();}
+    void set_pointer(pointer __p);
+};
+
+template <class _Tp>
+void _LIBCPP_TLS_DESTRUCTOR_CC
+__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
+{
+    delete static_cast<pointer>(__p);
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::__thread_specific_ptr()
+{
+  int __ec =
+      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
+{
+    // __thread_specific_ptr is only created with a static storage duration
+    // so this destructor is only invoked during program termination. Invoking
+    // pthread_key_delete(__key_) may prevent other threads from deleting their
+    // thread local data. For this reason we leak the key.
+}
+
+template <class _Tp>
+void
+__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
+{
+    _LIBCPP_ASSERT_UNCATEGORIZED(get() == nullptr,
+                   "Attempting to overwrite thread local data");
+    std::__libcpp_tls_set(__key_, __p);
+}
+
+template<>
+struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
+    : public __unary_function<__thread_id, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(__thread_id __v) const _NOEXCEPT
+    {
+        return hash<__libcpp_thread_id>()(__v.__id_);
+    }
+};
+
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+template <class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
+    // [thread.thread.id]/9
+    //   Effects: Inserts the text representation for charT of id into out.
+    //
+    // [thread.thread.id]/2
+    //   The text representation for the character type charT of an
+    //   object of type thread::id is an unspecified sequence of charT
+    //   such that, for two objects of type thread::id x and y, if
+    //   x == y is true, the thread::id objects have the same text
+    //   representation, and if x != y is true, the thread::id objects
+    //   have distinct text representations.
+    //
+    // Since various flags in the output stream can affect how the
+    // thread id is represented (e.g. numpunct or showbase), we
+    // use a temporary stream instead and just output the thread
+    // id representation as a string.
+
+    basic_ostringstream<_CharT, _Traits> __sstr;
+    __sstr.imbue(locale::classic());
+    __sstr << __id.__id_;
+    return __os << __sstr.str();
+}
+#endif // _LIBCPP_HAS_NO_LOCALIZATION
+
+class _LIBCPP_EXPORTED_FROM_ABI thread
+{
+    __libcpp_thread_t __t_;
+
+    thread(const thread&);
+    thread& operator=(const thread&);
+public:
+    typedef __thread_id id;
+    typedef __libcpp_thread_t native_handle_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Fp, class ..._Args,
+              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+        explicit thread(_Fp&& __f, _Args&&... __args);
+#else  // _LIBCPP_CXX03_LANG
+    template <class _Fp>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    explicit thread(_Fp __f);
+#endif
+    ~thread();
+
+    _LIBCPP_INLINE_VISIBILITY
+    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
+        __t.__t_ = _LIBCPP_NULL_THREAD;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    thread& operator=(thread&& __t) _NOEXCEPT {
+        if (!__libcpp_thread_isnull(&__t_))
+            terminate();
+        __t_ = __t.__t_;
+        __t.__t_ = _LIBCPP_NULL_THREAD;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
+    void join();
+    void detach();
+    _LIBCPP_INLINE_VISIBILITY
+    id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
+    _LIBCPP_INLINE_VISIBILITY
+    native_handle_type native_handle() _NOEXCEPT {return __t_;}
+
+    static unsigned hardware_concurrency() _NOEXCEPT;
+};
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
+{
+    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
+}
+
+template <class _Fp>
+_LIBCPP_INLINE_VISIBILITY
+void* __thread_proxy(void* __vp)
+{
+    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
+    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
+    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
+    _VSTD::__thread_execute(*__p.get(), _Index());
+    return nullptr;
+}
+
+template <class _Fp, class ..._Args,
+          class
+         >
+thread::thread(_Fp&& __f, _Args&&... __args)
+{
+    typedef unique_ptr<__thread_struct> _TSPtr;
+    _TSPtr __tsp(new __thread_struct);
+    typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
+    unique_ptr<_Gp> __p(
+            new _Gp(_VSTD::move(__tsp),
+                    _VSTD::forward<_Fp>(__f),
+                    _VSTD::forward<_Args>(__args)...));
+    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
+    if (__ec == 0)
+        __p.release();
+    else
+        __throw_system_error(__ec, "thread constructor failed");
+}
+
+#else  // _LIBCPP_CXX03_LANG
+
+template <class _Fp>
+struct __thread_invoke_pair {
+    // This type is used to pass memory for thread local storage and a functor
+    // to a newly created thread because std::pair doesn't work with
+    // std::unique_ptr in C++03.
+    _LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
+    unique_ptr<__thread_struct> __tsp_;
+    _Fp __fn_;
+};
+
+template <class _Fp>
+_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
+{
+    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    __thread_local_data().set_pointer(__p->__tsp_.release());
+    (__p->__fn_)();
+    return nullptr;
+}
+
+template <class _Fp>
+thread::thread(_Fp __f)
+{
+
+    typedef __thread_invoke_pair<_Fp> _InvokePair;
+    typedef unique_ptr<_InvokePair> _PairPtr;
+    _PairPtr __pp(new _InvokePair(__f));
+    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
+    if (__ec == 0)
+        __pp.release();
+    else
+        __throw_system_error(__ec, "thread constructor failed");
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___THREAD_THREAD_H
lib/libcxx/include/__tuple_dir/make_tuple_types.h → lib/libcxx/include/__tuple/make_tuple_types.h
@@ -12,11 +12,11 @@
 #include <__config>
 #include <__fwd/array.h>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/apply_cv.h>
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_indices.h>
-#include <__tuple_dir/tuple_size.h>
-#include <__tuple_dir/tuple_types.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_indices.h>
+#include <__tuple/tuple_size.h>
+#include <__tuple/tuple_types.h>
+#include <__type_traits/apply_cv.h>
 #include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_reference.h>
 #include <cstddef>
@@ -40,20 +40,16 @@ struct __make_tuple_types_flat;
 template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx>
 struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
   // Specialization for pair, tuple, and __tuple_types
-  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
-  using __apply_quals _LIBCPP_NODEBUG = __tuple_types<
-      typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>...
-    >;
+  template <class _Tp>
+  using __apply_quals _LIBCPP_NODEBUG = __tuple_types<__apply_cv_t<_Tp, __type_pack_element<_Idx, _Types...>>...>;
 };
 
 template <class _Vt, size_t _Np, size_t ..._Idx>
 struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> {
   template <size_t>
   using __value_type = _Vt;
-  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
-  using __apply_quals = __tuple_types<
-      typename _ApplyFn::template __apply<__value_type<_Idx>>...
-    >;
+  template <class _Tp>
+  using __apply_quals = __tuple_types<__apply_cv_t<_Tp, __value_type<_Idx>>...>;
 };
 
 template <class _Tp, size_t _Ep = tuple_size<__libcpp_remove_reference_t<_Tp> >::value,
lib/libcxx/include/__tuple_dir/pair_like.h → lib/libcxx/include/__tuple/pair_like.h
@@ -10,8 +10,8 @@
 #define _LIBCPP___TUPLE_PAIR_LIKE_H
 
 #include <__config>
-#include <__tuple_dir/tuple_like.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/tuple_like.h>
+#include <__tuple/tuple_size.h>
 #include <__type_traits/remove_cvref.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/__tuple_dir/sfinae_helpers.h → lib/libcxx/include/__tuple/sfinae_helpers.h
@@ -11,11 +11,11 @@
 
 #include <__config>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/make_tuple_types.h>
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_like_ext.h>
-#include <__tuple_dir/tuple_size.h>
-#include <__tuple_dir/tuple_types.h>
+#include <__tuple/make_tuple_types.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_like_ext.h>
+#include <__tuple/tuple_size.h>
+#include <__tuple/tuple_types.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_assignable.h>
@@ -108,33 +108,20 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
     typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
 };
 
-template <bool _IsTuple, class _SizeTrait, size_t _Expected>
-struct __tuple_like_with_size_imp : false_type {};
+struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
 
-template <class _SizeTrait, size_t _Expected>
-struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
-    : integral_constant<bool, _SizeTrait::value == _Expected> {};
-
-template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __libcpp_remove_reference_t<_Tuple> >
-using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
-                                   __tuple_like_ext<_RawTuple>::value,
-                                   tuple_size<_RawTuple>, _ExpectedSize
-                              >;
-
-struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
-
-    static constexpr bool __enable_explicit_default() { return false; }
-    static constexpr bool __enable_implicit_default() { return false; }
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
     template <class ...>
-    static constexpr bool __enable_explicit() { return false; }
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { return false; }
     template <class ...>
-    static constexpr bool __enable_implicit() { return false; }
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { return false; }
     template <class ...>
-    static constexpr bool __enable_assign() { return false; }
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() { return false; }
 };
 #endif // !defined(_LIBCPP_CXX03_LANG)
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <bool _CanCopy, bool _CanMove>
 struct __sfinae_ctor_base {};
@@ -189,7 +176,7 @@ struct __sfinae_assign_base<false, true> {
   __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
   __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
 };
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__tuple_dir/tuple_element.h → lib/libcxx/include/__tuple/tuple_element.h
@@ -10,8 +10,8 @@
 #define _LIBCPP___TUPLE_TUPLE_ELEMENT_H
 
 #include <__config>
-#include <__tuple_dir/tuple_indices.h>
-#include <__tuple_dir/tuple_types.h>
+#include <__tuple/tuple_indices.h>
+#include <__tuple/tuple_types.h>
 #include <__type_traits/add_const.h>
 #include <__type_traits/add_cv.h>
 #include <__type_traits/add_volatile.h>
@@ -81,7 +81,7 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> >
     typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type;
 };
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <size_t _Ip, class ..._Tp>
 using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type;
 #endif
lib/libcxx/include/__tuple_dir/tuple_indices.h → lib/libcxx/include/__tuple/tuple_indices.h
File renamed without changes
lib/libcxx/include/__tuple_dir/tuple_like.h → lib/libcxx/include/__tuple/tuple_like.h
File renamed without changes
lib/libcxx/include/__tuple_dir/tuple_like_ext.h → lib/libcxx/include/__tuple/tuple_like_ext.h
@@ -13,7 +13,7 @@
 #include <__fwd/array.h>
 #include <__fwd/pair.h>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/tuple_types.h>
+#include <__tuple/tuple_types.h>
 #include <__type_traits/integral_constant.h>
 #include <cstddef>
 
lib/libcxx/include/__tuple_dir/tuple_size.h → lib/libcxx/include/__tuple/tuple_size.h
@@ -11,7 +11,7 @@
 
 #include <__config>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/tuple_types.h>
+#include <__tuple/tuple_types.h>
 #include <__type_traits/is_const.h>
 #include <__type_traits/is_volatile.h>
 #include <cstddef>
lib/libcxx/include/__tuple_dir/tuple_types.h → lib/libcxx/include/__tuple/tuple_types.h
File renamed without changes
lib/libcxx/include/__tuple_dir/apply_cv.h
@@ -1,70 +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___TUPLE_APPLY_CV_H
-#define _LIBCPP___TUPLE_APPLY_CV_H
-
-#include <__config>
-#include <__type_traits/is_const.h>
-#include <__type_traits/is_reference.h>
-#include <__type_traits/is_volatile.h>
-#include <__type_traits/remove_reference.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-#ifndef _LIBCPP_CXX03_LANG
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile>
-struct __apply_cv_mf;
-template <>
-struct __apply_cv_mf<false, false, false> {
-  template <class _Tp> using __apply = _Tp;
-};
-template <>
-struct __apply_cv_mf<false, true, false> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp;
-};
-template <>
-struct __apply_cv_mf<false, false, true> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp;
-};
-template <>
-struct __apply_cv_mf<false, true, true> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp;
-};
-template <>
-struct __apply_cv_mf<true, false, false> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = _Tp&;
-};
-template <>
-struct __apply_cv_mf<true, true, false> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp&;
-};
-template <>
-struct __apply_cv_mf<true, false, true> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp&;
-};
-template <>
-struct __apply_cv_mf<true, true, true> {
-  template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp&;
-};
-template <class _Tp, class _RawTp = __libcpp_remove_reference_t<_Tp> >
-using __apply_cv_t _LIBCPP_NODEBUG = __apply_cv_mf<
-    is_lvalue_reference<_Tp>::value,
-    is_const<_RawTp>::value,
-    is_volatile<_RawTp>::value>;
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP_CXX03_LANG
-
-#endif // _LIBCPP___TUPLE_APPLY_CV_H
lib/libcxx/include/__type_traits/add_const.h
@@ -17,12 +17,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const {
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS add_const {
   typedef _LIBCPP_NODEBUG const _Tp type;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using add_const_t = typename add_const<_Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_cv.h
@@ -17,12 +17,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv {
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS add_cv {
   typedef _LIBCPP_NODEBUG const volatile _Tp type;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using add_cv_t = typename add_cv<_Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_lvalue_reference.h
@@ -44,8 +44,9 @@ struct add_lvalue_reference {
   using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_pointer.h
@@ -28,13 +28,14 @@ template <class _Tp>
 using __add_pointer_t = __add_pointer(_Tp);
 
 #else
-template <class _Tp,
-          bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
+template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
 struct __add_pointer_impl {
   typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp>* type;
 };
-template <class _Tp> struct __add_pointer_impl<_Tp, false>
-    {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp>
+struct __add_pointer_impl<_Tp, false> {
+  typedef _LIBCPP_NODEBUG _Tp type;
+};
 
 template <class _Tp>
 using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
@@ -46,8 +47,9 @@ struct add_pointer {
   using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_pointer_t = __add_pointer_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using add_pointer_t = __add_pointer_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_rvalue_reference.h
@@ -44,7 +44,7 @@ struct add_rvalue_reference {
   using type = __add_rvalue_reference_t<_Tp>;
 };
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp>
 using add_rvalue_reference_t = __add_rvalue_reference_t<_Tp>;
 #endif
lib/libcxx/include/__type_traits/add_volatile.h
@@ -17,12 +17,14 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile {
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS add_volatile {
   typedef _LIBCPP_NODEBUG volatile _Tp type;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using add_volatile_t = typename add_volatile<_Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/aligned_storage.h
@@ -23,59 +23,63 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __align_type
-{
-    static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
-    typedef _Tp type;
+struct __align_type {
+  static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
+  typedef _Tp type;
 };
 
-struct __struct_double {long double __lx;};
-struct __struct_double4 {double __lx[4];};
-
-typedef
-    __type_list<__align_type<unsigned char>,
-    __type_list<__align_type<unsigned short>,
-    __type_list<__align_type<unsigned int>,
-    __type_list<__align_type<unsigned long>,
-    __type_list<__align_type<unsigned long long>,
-    __type_list<__align_type<double>,
-    __type_list<__align_type<long double>,
-    __type_list<__align_type<__struct_double>,
-    __type_list<__align_type<__struct_double4>,
-    __type_list<__align_type<int*>,
-    __nat
-    > > > > > > > > > > __all_types;
+struct __struct_double {
+  long double __lx;
+};
+struct __struct_double4 {
+  double __lx[4];
+};
+
+// clang-format off
+typedef __type_list<__align_type<unsigned char>,
+        __type_list<__align_type<unsigned short>,
+        __type_list<__align_type<unsigned int>,
+        __type_list<__align_type<unsigned long>,
+        __type_list<__align_type<unsigned long long>,
+        __type_list<__align_type<double>,
+        __type_list<__align_type<long double>,
+        __type_list<__align_type<__struct_double>,
+        __type_list<__align_type<__struct_double4>,
+        __type_list<__align_type<int*>,
+        __nat
+        > > > > > > > > > > __all_types;
+// clang-format on
 
 template <size_t _Align>
 struct _ALIGNAS(_Align) __fallback_overaligned {};
 
-template <class _TL, size_t _Align> struct __find_pod;
+template <class _TL, size_t _Align>
+struct __find_pod;
 
 template <class _Hp, size_t _Align>
-struct __find_pod<__type_list<_Hp, __nat>, _Align>
-{
-    typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type;
+struct __find_pod<__type_list<_Hp, __nat>, _Align> {
+  typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type;
 };
 
 template <class _Hp, class _Tp, size_t _Align>
-struct __find_pod<__type_list<_Hp, _Tp>, _Align>
-{
-    typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type;
+struct __find_pod<__type_list<_Hp, _Tp>, _Align> {
+  typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type;
 };
 
-template <class _TL, size_t _Len> struct __find_max_align;
+template <class _TL, size_t _Len>
+struct __find_max_align;
 
 template <class _Hp, size_t _Len>
 struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
 
 template <size_t _Len, size_t _A1, size_t _A2>
-struct __select_align
-{
+struct __select_align {
 private:
-    static const size_t __min = _A2 < _A1 ? _A2 : _A1;
-    static const size_t __max = _A1 < _A2 ? _A2 : _A1;
+  static const size_t __min = _A2 < _A1 ? _A2 : _A1;
+  static const size_t __max = _A1 < _A2 ? _A2 : _A1;
+
 public:
-    static const size_t value = _Len < __max ? __min : __max;
+  static const size_t value = _Len < __max ? __min : __max;
 };
 
 template <class _Hp, class _Tp, size_t _Len>
@@ -83,34 +87,30 @@ struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
     : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
 
 template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage
-{
-    typedef typename __find_pod<__all_types, _Align>::type _Aligner;
-    union type
-    {
-        _Aligner __align;
-        unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
-    };
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage {
+  typedef typename __find_pod<__all_types, _Align>::type _Aligner;
+  union type {
+    _Aligner __align;
+    unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
+  };
 };
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
-  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-    using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
-  _LIBCPP_SUPPRESS_DEPRECATED_POP
+using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
 #endif
 
-#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
-template <size_t _Len>\
-struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
-{\
-    struct _ALIGNAS(n) type\
-    {\
-        unsigned char __lx[(_Len + n - 1)/n * n];\
-    };\
-}
+#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n)                                                                      \
+  template <size_t _Len>                                                                                               \
+  struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n> {                                   \
+    struct _ALIGNAS(n) type {                                                                                          \
+      unsigned char __lx[(_Len + n - 1) / n * n];                                                                      \
+    };                                                                                                                 \
+  }
 
 _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
 _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
lib/libcxx/include/__type_traits/aligned_union.h
@@ -20,33 +20,28 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <size_t _I0, size_t ..._In>
+template <size_t _I0, size_t... _In>
 struct __static_max;
 
 template <size_t _I0>
-struct __static_max<_I0>
-{
-    static const size_t value = _I0;
+struct __static_max<_I0> {
+  static const size_t value = _I0;
 };
 
-template <size_t _I0, size_t _I1, size_t ..._In>
-struct __static_max<_I0, _I1, _In...>
-{
-    static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
-                                             __static_max<_I1, _In...>::value;
+template <size_t _I0, size_t _I1, size_t... _In>
+struct __static_max<_I0, _I1, _In...> {
+  static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : __static_max<_I1, _In...>::value;
 };
 
-template <size_t _Len, class _Type0, class ..._Types>
-struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union
-{
-    static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
-                                                       _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
-    static const size_t __len = __static_max<_Len, sizeof(_Type0),
-                                             sizeof(_Types)...>::value;
-    typedef typename aligned_storage<__len, alignment_value>::type type;
+template <size_t _Len, class _Type0, class... _Types>
+struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union {
+  static const size_t alignment_value =
+      __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
+  static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value;
+  typedef typename aligned_storage<__len, alignment_value>::type type;
 };
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <size_t _Len, class... _Types>
 using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type;
 #endif
lib/libcxx/include/__type_traits/alignment_of.h
@@ -19,10 +19,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
-    : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS alignment_of : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp);
 #endif
lib/libcxx/include/__type_traits/apply_cv.h
@@ -13,7 +13,6 @@
 #include <__type_traits/is_const.h>
 #include <__type_traits/is_volatile.h>
 #include <__type_traits/remove_reference.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -21,55 +20,59 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, class _Up, bool = is_const<__libcpp_remove_reference_t<_Tp> >::value,
-                             bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value>
-struct __apply_cv
-{
-    typedef _LIBCPP_NODEBUG _Up type;
+template <class _Tp,
+          bool = is_const<__libcpp_remove_reference_t<_Tp> >::value,
+          bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value>
+struct __apply_cv_impl {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = _Up;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, true, false>
-{
-    typedef _LIBCPP_NODEBUG const _Up type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp, true, false> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = const _Up;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, false, true>
-{
-    typedef volatile _Up type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp, false, true> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = volatile _Up;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, true, true>
-{
-    typedef const volatile _Up type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp, true, true> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = const volatile _Up;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, false, false>
-{
-    typedef _Up& type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp&, false, false> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = _Up&;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, true, false>
-{
-    typedef const _Up& type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp&, true, false> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = const _Up&;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, false, true>
-{
-    typedef volatile _Up& type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp&, false, true> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = volatile _Up&;
 };
 
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, true, true>
-{
-    typedef const volatile _Up& type;
+template <class _Tp>
+struct __apply_cv_impl<_Tp&, true, true> {
+  template <class _Up>
+  using __apply _LIBCPP_NODEBUG = const volatile _Up&;
 };
 
+template <class _Tp, class _Up>
+using __apply_cv_t _LIBCPP_NODEBUG = typename __apply_cv_impl<_Tp>::template __apply<_Up>;
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___TYPE_TRAITS_APPLY_CV_H
lib/libcxx/include/__type_traits/can_extract_key.h
@@ -40,16 +40,13 @@ struct __can_extract_key<_Pair, _Key, pair<_First, _Second> >
 // __can_extract_map_key uses true_type/false_type instead of the tags.
 // It returns true if _Key != _ContainerValueTy (the container is a map not a set)
 // and _ValTy == _Key.
-template <class _ValTy, class _Key, class _ContainerValueTy,
-          class _RawValTy = __remove_const_ref_t<_ValTy> >
-struct __can_extract_map_key
-    : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
+template <class _ValTy, class _Key, class _ContainerValueTy, class _RawValTy = __remove_const_ref_t<_ValTy> >
+struct __can_extract_map_key : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
 
 // This specialization returns __extract_key_fail_tag for non-map containers
 // because _Key == _ContainerValueTy
 template <class _ValTy, class _Key, class _RawValTy>
-struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy>
-    : false_type {};
+struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> : false_type {};
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/common_reference.h
@@ -27,11 +27,10 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // common_reference
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 // Let COND_RES(X, Y) be:
 template <class _Xp, class _Yp>
-using __cond_res =
-    decltype(false ? std::declval<_Xp(&)()>()() : std::declval<_Yp(&)()>()());
+using __cond_res = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()());
 
 // Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
 // with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
@@ -39,47 +38,49 @@ using __cond_res =
 // [Note: `XREF(A)` is `__xref<A>::template __apply`]
 template <class _Tp>
 struct __xref {
-  template<class _Up>
+  template <class _Up>
   using __apply = __copy_cvref_t<_Tp, _Up>;
 };
 
 // Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>,
 // and let COMMON-REF(A, B) be:
-template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
+template <class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
 struct __common_ref;
 
-template<class _Xp, class _Yp>
+template <class _Xp, class _Yp>
 using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type;
 
-template<class _Xp, class _Yp>
+template <class _Xp, class _Yp>
 using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>;
 
-
 //    If A and B are both lvalue reference types, COMMON-REF(A, B) is
 //    COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type.
-template<class _Ap, class _Bp, class _Xp, class _Yp>
-requires requires { typename __cv_cond_res<_Xp, _Yp>; } && is_reference_v<__cv_cond_res<_Xp, _Yp>>
-struct __common_ref<_Ap&, _Bp&, _Xp, _Yp>
-{
-    using __type = __cv_cond_res<_Xp, _Yp>;
+// clang-format off
+template <class _Ap, class _Bp, class _Xp, class _Yp>
+  requires
+    requires { typename __cv_cond_res<_Xp, _Yp>; } &&
+    is_reference_v<__cv_cond_res<_Xp, _Yp>>
+struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> {
+  using __type = __cv_cond_res<_Xp, _Yp>;
 };
+// clang-format on
 
 //    Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ...
 template <class _Xp, class _Yp>
 using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
 
-
 //    .... If A and B are both rvalue reference types, C is well-formed, and
 //    is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C.
-template<class _Ap, class _Bp, class _Xp, class _Yp>
-requires
-  requires { typename __common_ref_C<_Xp, _Yp>; } &&
-  is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
-  is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
-struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp>
-{
-    using __type = __common_ref_C<_Xp, _Yp>;
+// clang-format off
+template <class _Ap, class _Bp, class _Xp, class _Yp>
+  requires
+    requires { typename __common_ref_C<_Xp, _Yp>; } &&
+    is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
+    is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
+struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> {
+  using __type = __common_ref_C<_Xp, _Yp>;
 };
+// clang-format on
 
 //    Otherwise, let D be COMMON-REF(const X&, Y&). ...
 template <class _Tp, class _Up>
@@ -87,21 +88,23 @@ using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
 
 //    ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and
 //    is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D.
-template<class _Ap, class _Bp, class _Xp, class _Yp>
-requires requires { typename __common_ref_D<_Xp, _Yp>; } &&
-         is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
-struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp>
-{
-    using __type = __common_ref_D<_Xp, _Yp>;
+// clang-format off
+template <class _Ap, class _Bp, class _Xp, class _Yp>
+  requires
+    requires { typename __common_ref_D<_Xp, _Yp>; } &&
+    is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
+struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> {
+  using __type = __common_ref_D<_Xp, _Yp>;
 };
+// clang-format on
 
 //    Otherwise, if A is an lvalue reference and B is an rvalue reference, then
 //    COMMON-REF(A, B) is COMMON-REF(B, A).
-template<class _Ap, class _Bp, class _Xp, class _Yp>
+template <class _Ap, class _Bp, class _Xp, class _Yp>
 struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {};
 
 //    Otherwise, COMMON-REF(A, B) is ill-formed.
-template<class _Ap, class _Bp, class _Xp, class _Yp>
+template <class _Ap, class _Bp, class _Xp, class _Yp>
 struct __common_ref {};
 
 // Note C: For the common_reference trait applied to a parameter pack [...]
@@ -113,75 +116,77 @@ template <class... _Types>
 using common_reference_t = typename common_reference<_Types...>::type;
 
 // bullet 1 - sizeof...(T) == 0
-template<>
+template <>
 struct common_reference<> {};
 
 // bullet 2 - sizeof...(T) == 1
 template <class _Tp>
-struct common_reference<_Tp>
-{
-    using type = _Tp;
+struct common_reference<_Tp> {
+  using type = _Tp;
 };
 
 // bullet 3 - sizeof...(T) == 2
-template <class _Tp, class _Up> struct __common_reference_sub_bullet3;
-template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
-template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
+template <class _Tp, class _Up>
+struct __common_reference_sub_bullet3;
+template <class _Tp, class _Up>
+struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
+template <class _Tp, class _Up>
+struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
 
 // sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
 // the member typedef `type` denotes that type.
-template <class _Tp, class _Up> struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
+template <class _Tp, class _Up>
+struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
 
 template <class _Tp, class _Up>
-requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
-struct __common_reference_sub_bullet1<_Tp, _Up>
-{
-    using type = __common_ref_t<_Tp, _Up>;
+  requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
+struct __common_reference_sub_bullet1<_Tp, _Up> {
+  using type = __common_ref_t<_Tp, _Up>;
 };
 
 // sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type
 // is well-formed, then the member typedef `type` denotes that type.
-template <class, class, template <class> class, template <class> class> struct basic_common_reference {};
+template <class, class, template <class> class, template <class> class>
+struct basic_common_reference {};
 
 template <class _Tp, class _Up>
-using __basic_common_reference_t = typename basic_common_reference<
-    remove_cvref_t<_Tp>, remove_cvref_t<_Up>,
-    __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type;
+using __basic_common_reference_t =
+    typename basic_common_reference<remove_cvref_t<_Tp>,
+                                    remove_cvref_t<_Up>,
+                                    __xref<_Tp>::template __apply,
+                                    __xref<_Up>::template __apply>::type;
 
 template <class _Tp, class _Up>
-requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
-struct __common_reference_sub_bullet2<_Tp, _Up>
-{
-    using type = __basic_common_reference_t<_Tp, _Up>;
+  requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
+struct __common_reference_sub_bullet2<_Tp, _Up> {
+  using type = __basic_common_reference_t<_Tp, _Up>;
 };
 
 // sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed,
 // then the member typedef `type` denotes that type.
 template <class _Tp, class _Up>
-requires requires { typename __cond_res<_Tp, _Up>; }
-struct __common_reference_sub_bullet3<_Tp, _Up>
-{
-    using type = __cond_res<_Tp, _Up>;
+  requires requires { typename __cond_res<_Tp, _Up>; }
+struct __common_reference_sub_bullet3<_Tp, _Up> {
+  using type = __cond_res<_Tp, _Up>;
 };
 
-
 // sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed,
 //                    then the member typedef `type` denotes that type.
 //                  - Otherwise, there shall be no member `type`.
-template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
+template <class _Tp, class _Up>
+struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
 
 // bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if
 //            any, as `common_reference_t<C, Rest...>`.
 template <class _Tp, class _Up, class _Vp, class... _Rest>
-requires requires { typename common_reference_t<_Tp, _Up>; }
-struct common_reference<_Tp, _Up, _Vp, _Rest...>
-    : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...>
-{};
+  requires requires { typename common_reference_t<_Tp, _Up>; }
+struct common_reference<_Tp, _Up, _Vp, _Rest...> : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...> {};
 
 // bullet 5 - Otherwise, there shall be no member `type`.
-template <class...> struct common_reference {};
+template <class...>
+struct common_reference {};
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/common_type.h
@@ -23,7 +23,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 // Let COND_RES(X, Y) be:
 template <class _Tp, class _Up>
 using __cond_type = decltype(false ? std::declval<_Tp>() : std::declval<_Up>());
@@ -33,9 +33,8 @@ struct __common_type3 {};
 
 // sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..."
 template <class _Tp, class _Up>
-struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>>
-{
-    using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
+struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> {
+  using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
 };
 
 template <class _Tp, class _Up, class = void>
@@ -47,50 +46,26 @@ struct __common_type2_imp {};
 
 // sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
 template <class _Tp, class _Up>
-struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> >
-{
-  typedef _LIBCPP_NODEBUG typename decay<decltype(
-                         true ? std::declval<_Tp>() : std::declval<_Up>()
-                         )>::type type;
+struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> > {
+  typedef _LIBCPP_NODEBUG __decay_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> type;
 };
 
 template <class, class = void>
 struct __common_type_impl {};
 
-// Clang provides variadic templates in C++03 as an extension.
-#if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__)
-# define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__
 template <class... _Tp>
 struct __common_types;
 template <class... _Tp>
 struct _LIBCPP_TEMPLATE_VIS common_type;
-#else
-# define _LIBCPP_OPTIONAL_PACK(...)
-struct __no_arg;
-template <class _Tp, class _Up, class = __no_arg>
-struct __common_types;
-template <class _Tp = __no_arg, class _Up = __no_arg, class _Vp = __no_arg,
-          class _Unused = __no_arg>
-struct common_type {
-  static_assert(sizeof(_Unused) == 0,
-                "common_type accepts at most 3 arguments in C++03");
-};
-#endif // _LIBCPP_CXX03_LANG
 
 template <class _Tp, class _Up>
-struct __common_type_impl<
-    __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> >
-{
+struct __common_type_impl< __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> > {
   typedef typename common_type<_Tp, _Up>::type type;
 };
 
-template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
-struct __common_type_impl<
-    __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>,
-    __void_t<typename common_type<_Tp, _Up>::type> >
-    : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type,
-                                        _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {
-};
+template <class _Tp, class _Up, class _Vp, class... _Rest>
+struct __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...>, __void_t<typename common_type<_Tp, _Up>::type> >
+    : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type, _Vp, _Rest...> > {};
 
 // bullet 1 - sizeof...(Tp) == 0
 
@@ -100,33 +75,26 @@ struct _LIBCPP_TEMPLATE_VIS common_type<> {};
 // bullet 2 - sizeof...(Tp) == 1
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
-    : public common_type<_Tp, _Tp> {};
+struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> : public common_type<_Tp, _Tp> {};
 
 // bullet 3 - sizeof...(Tp) == 2
 
 // sub-bullet 1 - "If is_same_v<T1, D1> is false or ..."
 template <class _Tp, class _Up>
 struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>
-    : conditional<
-        _IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value,
-        __common_type2_imp<_Tp, _Up>,
-        common_type<typename decay<_Tp>::type, typename decay<_Up>::type>
-    >::type
-{};
+    : conditional<_IsSame<_Tp, __decay_t<_Tp> >::value && _IsSame<_Up, __decay_t<_Up> >::value,
+                  __common_type2_imp<_Tp, _Up>,
+                  common_type<__decay_t<_Tp>, __decay_t<_Up> > >::type {};
 
 // bullet 4 - sizeof...(Tp) > 2
 
-template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
-struct _LIBCPP_TEMPLATE_VIS
-    common_type<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>
-    : __common_type_impl<
-          __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {};
-
-#undef _LIBCPP_OPTIONAL_PACK
+template <class _Tp, class _Up, class _Vp, class... _Rest>
+struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up, _Vp, _Rest...>
+    : __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...> > {};
 
-#if _LIBCPP_STD_VER > 11
-template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class... _Tp>
+using common_type_t = typename common_type<_Tp...>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/conditional.h
@@ -44,7 +44,7 @@ struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> {
   using type _LIBCPP_NODEBUG = _Then;
 };
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <bool _Bp, class _IfRes, class _ElseRes>
 using conditional_t _LIBCPP_NODEBUG = typename conditional<_Bp, _IfRes, _ElseRes>::type;
 #endif
lib/libcxx/include/__type_traits/conjunction.h
@@ -37,7 +37,7 @@ false_type __and_helper(...);
 template <class... _Pred>
 using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class...>
 struct conjunction : true_type {};
@@ -51,7 +51,7 @@ struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, con
 template <class... _Args>
 inline constexpr bool conjunction_v = conjunction<_Args...>::value;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/copy_cv.h
@@ -23,27 +23,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
 // top-level cv-qualifiers.
 template <class _From, class _To>
-struct __copy_cv
-{
-    using type = _To;
+struct __copy_cv {
+  using type = _To;
 };
 
 template <class _From, class _To>
-struct __copy_cv<const _From, _To>
-{
-    using type = typename add_const<_To>::type;
+struct __copy_cv<const _From, _To> {
+  using type = typename add_const<_To>::type;
 };
 
 template <class _From, class _To>
-struct __copy_cv<volatile _From, _To>
-{
-    using type = typename add_volatile<_To>::type;
+struct __copy_cv<volatile _From, _To> {
+  using type = typename add_volatile<_To>::type;
 };
 
 template <class _From, class _To>
-struct __copy_cv<const volatile _From, _To>
-{
-    using type = typename add_cv<_To>::type;
+struct __copy_cv<const volatile _From, _To> {
+  using type = typename add_cv<_To>::type;
 };
 
 template <class _From, class _To>
lib/libcxx/include/__type_traits/copy_cvref.h
@@ -21,21 +21,18 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _From, class _To>
-struct __copy_cvref
-{
-    using type = __copy_cv_t<_From, _To>;
+struct __copy_cvref {
+  using type = __copy_cv_t<_From, _To>;
 };
 
 template <class _From, class _To>
-struct __copy_cvref<_From&, _To>
-{
-    using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >;
+struct __copy_cvref<_From&, _To> {
+  using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >;
 };
 
 template <class _From, class _To>
-struct __copy_cvref<_From&&, _To>
-{
-    using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >;
+struct __copy_cvref<_From&&, _To> {
+  using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >;
 };
 
 template <class _From, class _To>
lib/libcxx/include/__type_traits/datasizeof.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_DATASIZEOF_H
+#define _LIBCPP___TYPE_TRAITS_DATASIZEOF_H
+
+#include <__config>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_final.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+// This trait provides the size of a type excluding any tail padding.
+//
+// It is useful in contexts where performing an operation using the full size of the class (including padding) may
+// have unintended side effects, such as overwriting a derived class' member when writing the tail padding of a class
+// through a pointer-to-base.
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __libcpp_datasizeof {
+#if __has_cpp_attribute(__no_unique_address__)
+  template <class = char>
+  struct _FirstPaddingByte {
+    [[__no_unique_address__]] _Tp __v_;
+    char __first_padding_byte_;
+  };
+#else
+  template <bool = __libcpp_is_final<_Tp>::value || !is_class<_Tp>::value>
+  struct _FirstPaddingByte : _Tp {
+    char __first_padding_byte_;
+  };
+
+  template <>
+  struct _FirstPaddingByte<true> {
+    _Tp __v_;
+    char __first_padding_byte_;
+  };
+#endif
+
+  static const size_t value = offsetof(_FirstPaddingByte<>, __first_padding_byte_);
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_DATASIZEOF_H
lib/libcxx/include/__type_traits/decay.h
@@ -26,44 +26,46 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__decay)
+template <class _Tp>
+using __decay_t _LIBCPP_NODEBUG = __decay(_Tp);
+
 template <class _Tp>
 struct decay {
-  using type _LIBCPP_NODEBUG = __decay(_Tp);
+  using type _LIBCPP_NODEBUG = __decay_t<_Tp>;
 };
+
 #else
 template <class _Up, bool>
 struct __decay {
-    typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type;
+  typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type;
 };
 
 template <class _Up>
 struct __decay<_Up, true> {
 public:
-    typedef _LIBCPP_NODEBUG typename conditional
-                     <
-                         is_array<_Up>::value,
-                         __add_pointer_t<__remove_extent_t<_Up> >,
-                         typename conditional
-                         <
-                              is_function<_Up>::value,
-                              typename add_pointer<_Up>::type,
-                              __remove_cv_t<_Up>
-                         >::type
-                     >::type type;
+  typedef _LIBCPP_NODEBUG typename conditional<
+      is_array<_Up>::value,
+      __add_pointer_t<__remove_extent_t<_Up> >,
+      typename conditional<is_function<_Up>::value, typename add_pointer<_Up>::type, __remove_cv_t<_Up> >::type >::type
+      type;
 };
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS decay
-{
+struct _LIBCPP_TEMPLATE_VIS decay {
 private:
-    typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
+  typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
+
 public:
   typedef _LIBCPP_NODEBUG typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type type;
 };
+
+template <class _Tp>
+using __decay_t = typename decay<_Tp>::type;
 #endif // __has_builtin(__decay)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using decay_t = typename decay<_Tp>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using decay_t = __decay_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/disjunction.h
@@ -43,7 +43,7 @@ struct _OrImpl<false> {
 template <class... _Args>
 using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class... _Args>
 struct disjunction : _Or<_Args...> {};
@@ -51,7 +51,7 @@ struct disjunction : _Or<_Args...> {};
 template <class... _Args>
 inline constexpr bool disjunction_v = _Or<_Args...>::value;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/enable_if.h
@@ -17,13 +17,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};
-
-template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
-
-#if _LIBCPP_STD_VER > 11
-template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
+template <bool, class _Tp = void>
+struct _LIBCPP_TEMPLATE_VIS enable_if {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {
+  typedef _Tp type;
+};
+
+template <bool _Bp, class _Tp = void>
+using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
+
+#if _LIBCPP_STD_VER >= 14
+template <bool _Bp, class _Tp = void>
+using enable_if_t = typename enable_if<_Bp, _Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/extent.h
@@ -21,32 +21,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__array_extent)
 
-template<class _Tp, size_t _Dim = 0>
-struct _LIBCPP_TEMPLATE_VIS extent
-    : integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
+template <class _Tp, size_t _Dim = 0>
+struct _LIBCPP_TEMPLATE_VIS extent : integral_constant<size_t, __array_extent(_Tp, _Dim)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp, unsigned _Ip = 0>
 inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
-#endif
+#  endif
 
 #else // __has_builtin(__array_extent)
 
-template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
-    : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
-    : public integral_constant<size_t, 0> {};
-template <class _Tp, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip>
-    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0>
-    : public integral_constant<size_t, _Np> {};
-template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip>
-    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
-
-#if _LIBCPP_STD_VER > 14
+template <class _Tp, unsigned _Ip = 0>
+struct _LIBCPP_TEMPLATE_VIS extent : public integral_constant<size_t, 0> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> : public integral_constant<size_t, 0> {};
+template <class _Tp, unsigned _Ip>
+struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0> : public integral_constant<size_t, _Np> {};
+template <class _Tp, size_t _Np, unsigned _Ip>
+struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {};
+
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp, unsigned _Ip = 0>
 inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__array_extent)
 
lib/libcxx/include/__type_traits/has_unique_object_representation.h
@@ -20,11 +20,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
-    : public integral_constant<bool,
-       __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
+    : public integral_constant<bool, __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
 
 template <class _Tp>
 inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value;
lib/libcxx/include/__type_traits/has_virtual_destructor.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
-    : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
 #endif
lib/libcxx/include/__type_traits/integral_constant.h
@@ -18,29 +18,26 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, _Tp __v>
-struct _LIBCPP_TEMPLATE_VIS integral_constant
-{
-  static _LIBCPP_CONSTEXPR const _Tp      value = __v;
-  typedef _Tp               value_type;
+struct _LIBCPP_TEMPLATE_VIS integral_constant {
+  static _LIBCPP_CONSTEXPR const _Tp value = __v;
+  typedef _Tp value_type;
   typedef integral_constant type;
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}
-#if _LIBCPP_STD_VER > 11
-  _LIBCPP_INLINE_VISIBILITY
-  constexpr value_type operator ()() const _NOEXCEPT {return value;}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT { return value; }
+#if _LIBCPP_STD_VER >= 14
+  _LIBCPP_INLINE_VISIBILITY constexpr value_type operator()() const _NOEXCEPT { return value; }
 #endif
 };
 
 template <class _Tp, _Tp __v>
 _LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
 
-typedef integral_constant<bool, true>  true_type;
+typedef integral_constant<bool, true> true_type;
 typedef integral_constant<bool, false> false_type;
 
 template <bool _Val>
 using _BoolConstant _LIBCPP_NODEBUG = integral_constant<bool, _Val>;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <bool __b>
 using bool_constant = integral_constant<bool, __b>;
 #endif
lib/libcxx/include/__type_traits/invoke.h
@@ -0,0 +1,461 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_INVOKE_H
+#define _LIBCPP___TYPE_TRAITS_INVOKE_H
+
+#include <__config>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/apply_cv.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_core_convertible.h>
+#include <__type_traits/is_member_function_pointer.h>
+#include <__type_traits/is_member_object_pointer.h>
+#include <__type_traits/is_reference_wrapper.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/nat.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __any {
+  __any(...);
+};
+
+template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
+struct __member_pointer_traits_imp {};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> {
+  typedef _Class _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> {
+  typedef _Class _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> {
+  typedef _Class const _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> {
+  typedef _Class const _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> {
+  typedef _Class volatile _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> {
+  typedef _Class volatile _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> {
+  typedef _Class const volatile _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> {
+  typedef _Class const volatile _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&, true, false> {
+  typedef _Class& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&, true, false> {
+  typedef _Class& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> {
+  typedef _Class const& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> {
+  typedef _Class const& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> {
+  typedef _Class volatile& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> {
+  typedef _Class volatile& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> {
+  typedef _Class const volatile& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> {
+  typedef _Class const volatile& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&&, true, false> {
+  typedef _Class&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&&, true, false> {
+  typedef _Class&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> {
+  typedef _Class const&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> {
+  typedef _Class const&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> {
+  typedef _Class volatile&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> {
+  typedef _Class volatile&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> {
+  typedef _Class const volatile&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param...);
+};
+
+template <class _Rp, class _Class, class... _Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> {
+  typedef _Class const volatile&& _ClassType;
+  typedef _Rp _ReturnType;
+  typedef _Rp(_FnType)(_Param..., ...);
+};
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp _Class::*, false, true> {
+  typedef _Class _ClassType;
+  typedef _Rp _ReturnType;
+};
+
+template <class _MP>
+struct __member_pointer_traits
+    : public __member_pointer_traits_imp<__remove_cv_t<_MP>,
+                                         is_member_function_pointer<_MP>::value,
+                                         is_member_object_pointer<_MP>::value> {
+  //     typedef ... _ClassType;
+  //     typedef ... _ReturnType;
+  //     typedef ... _FnType;
+};
+
+template <class _DecayedFp>
+struct __member_pointer_class_type {};
+
+template <class _Ret, class _ClassType>
+struct __member_pointer_class_type<_Ret _ClassType::*> {
+  typedef _ClassType type;
+};
+
+template <class _Fp,
+          class _A0,
+          class _DecayFp = __decay_t<_Fp>,
+          class _DecayA0 = __decay_t<_A0>,
+          class _ClassT  = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet1 =
+    typename enable_if<is_member_function_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type;
+
+template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> >
+using __enable_if_bullet2 =
+    typename enable_if<is_member_function_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type;
+
+template <class _Fp,
+          class _A0,
+          class _DecayFp = __decay_t<_Fp>,
+          class _DecayA0 = __decay_t<_A0>,
+          class _ClassT  = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet3 =
+    typename enable_if<is_member_function_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value &&
+                       !__is_reference_wrapper<_DecayA0>::value >::type;
+
+template <class _Fp,
+          class _A0,
+          class _DecayFp = __decay_t<_Fp>,
+          class _DecayA0 = __decay_t<_A0>,
+          class _ClassT  = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet4 =
+    typename enable_if<is_member_object_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type;
+
+template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> >
+using __enable_if_bullet5 =
+    typename enable_if<is_member_object_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type;
+
+template <class _Fp,
+          class _A0,
+          class _DecayFp = __decay_t<_Fp>,
+          class _DecayA0 = __decay_t<_A0>,
+          class _ClassT  = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet6 =
+    typename enable_if<is_member_object_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value &&
+                       !__is_reference_wrapper<_DecayA0>::value >::type;
+
+// __invoke forward declarations
+
+// fall back - none of the bullets
+
+template <class... _Args>
+__nat __invoke(__any, _Args&&... __args);
+
+// bullets 1, 2 and 3
+
+// clang-format off
+template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet1<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
+    _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
+               { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
+
+template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet2<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
+    _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
+               { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
+
+template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet3<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
+    _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
+               { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
+
+// bullets 4, 5 and 6
+
+template <class _Fp, class _A0, class = __enable_if_bullet4<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype(std::declval<_A0>().*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+    _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
+               { return static_cast<_A0&&>(__a0).*__f; }
+
+template <class _Fp, class _A0, class = __enable_if_bullet5<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype(std::declval<_A0>().get().*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+    _NOEXCEPT_(noexcept(__a0.get().*__f))
+               { return __a0.get().*__f; }
+
+template <class _Fp, class _A0, class = __enable_if_bullet6<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype((*std::declval<_A0>()).*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+    _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
+               { return (*static_cast<_A0&&>(__a0)).*__f; }
+
+// bullet 7
+
+template <class _Fp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype(std::declval<_Fp>()(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _Args&&... __args)
+    _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
+               { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
+// clang-format on
+
+// __invokable
+template <class _Ret, class _Fp, class... _Args>
+struct __invokable_r {
+  template <class _XFp, class... _XArgs>
+  static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int);
+  template <class _XFp, class... _XArgs>
+  static __nat __try_call(...);
+
+  // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
+  // or incomplete array types as required by the standard.
+  using _Result = decltype(__try_call<_Fp, _Args...>(0));
+
+  using type              = __conditional_t<_IsNotSame<_Result, __nat>::value,
+                               __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >,
+                               false_type>;
+  static const bool value = type::value;
+};
+template <class _Fp, class... _Args>
+using __invokable = __invokable_r<void, _Fp, _Args...>;
+
+template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class... _Args>
+struct __nothrow_invokable_r_imp {
+  static const bool value = false;
+};
+
+template <class _Ret, class _Fp, class... _Args>
+struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> {
+  typedef __nothrow_invokable_r_imp _ThisT;
+
+  template <class _Tp>
+  static void __test_noexcept(_Tp) _NOEXCEPT;
+
+#ifdef _LIBCPP_CXX03_LANG
+  static const bool value = false;
+#else
+  static const bool value =
+      noexcept(_ThisT::__test_noexcept<_Ret>(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)));
+#endif
+};
+
+template <class _Ret, class _Fp, class... _Args>
+struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> {
+#ifdef _LIBCPP_CXX03_LANG
+  static const bool value = false;
+#else
+  static const bool value = noexcept(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...));
+#endif
+};
+
+template <class _Ret, class _Fp, class... _Args>
+using __nothrow_invokable_r =
+    __nothrow_invokable_r_imp<__invokable_r<_Ret, _Fp, _Args...>::value, is_void<_Ret>::value, _Ret, _Fp, _Args...>;
+
+template <class _Fp, class... _Args>
+using __nothrow_invokable = __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>;
+
+template <class _Fp, class... _Args>
+struct __invoke_of
+    : public enable_if<__invokable<_Fp, _Args...>::value, typename __invokable_r<void, _Fp, _Args...>::_Result> {};
+
+template <class _Ret, bool = is_void<_Ret>::value>
+struct __invoke_void_return_wrapper {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) {
+    return std::__invoke(std::forward<_Args>(__args)...);
+  }
+};
+
+template <class _Ret>
+struct __invoke_void_return_wrapper<_Ret, true> {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) {
+    std::__invoke(std::forward<_Args>(__args)...);
+  }
+};
+
+#if _LIBCPP_STD_VER >= 17
+
+// is_invocable
+
+template <class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
+
+template <class _Ret, class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
+
+template <class _Fn, class... _Args>
+inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+
+template <class _Ret, class _Fn, class... _Args>
+inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
+
+// is_nothrow_invocable
+
+template <class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {
+};
+
+template <class _Ret, class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
+    : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
+
+template <class _Fn, class... _Args>
+inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
+
+template <class _Ret, class _Fn, class... _Args>
+inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
+
+template <class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {};
+
+template <class _Fn, class... _Args>
+using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
+
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_INVOKE_H
lib/libcxx/include/__type_traits/is_abstract.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract
-    : public integral_constant<bool, __is_abstract(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_abstract : public integral_constant<bool, __is_abstract(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_abstract_v = __is_abstract(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_aggregate.h
@@ -18,15 +18,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
 
 template <class _Tp>
 inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_allocator.h
@@ -21,15 +21,13 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<typename _Alloc, typename = void, typename = void>
+template <typename _Alloc, typename = void, typename = void>
 struct __is_allocator : false_type {};
 
-template<typename _Alloc>
+template <typename _Alloc>
 struct __is_allocator<_Alloc,
-       __void_t<typename _Alloc::value_type>,
-       __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))>
-     >
-   : true_type {};
+                      __void_t<typename _Alloc::value_type>,
+                      __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))> > : true_type {};
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_always_bitcastable.h
@@ -32,49 +32,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _From, class _To>
 struct __is_always_bitcastable {
   using _UnqualFrom = __remove_cv_t<_From>;
-  using _UnqualTo = __remove_cv_t<_To>;
+  using _UnqualTo   = __remove_cv_t<_To>;
 
+  // clang-format off
   static const bool value =
-    // First, the simple case -- `From` and `To` are the same object type.
-    (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
+      // First, the simple case -- `From` and `To` are the same object type.
+      (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
 
-    // Beyond the simple case, we say that one type is "always bit-castable" to another if:
-    // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
-    //   a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of
-    //   values of `From`);
-    // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed
-    //   integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed
-    //   integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be produced
-    //   by the built-in assignment (if it were defined for the two types, to which there are minor exceptions, e.g.
-    //   built-in arrays).
-    //
-    // In practice, that means:
-    // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and
-    //   unsigned...
-    // - as well as arrays of such types...
-    // - ...that have the same size.
-    //
-    // Other trivially-copyable types can't be validly bit-cast outside of their own type:
-    // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails #1);
-    // - integral types and floating-point types use different representations, so for example bit-casting an integral
-    //   `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0`
-    //   (fails #2);
-    // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean
-    //   will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2).
-    //   Bit-casting from a boolean into an integer, however, is valid;
-    // - enumeration types may have different ranges of possible values (fails #1);
-    // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent
-    //   addresses, and the conversion results are explicitly unspecified for types with different alignments
-    //   (fails #1);
-    // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of
-    //   the other (fails #1);
-    // - there is no need to consider `nullptr_t` for practical purposes.
-    (
-      sizeof(_From) == sizeof(_To) &&
-      is_integral<_From>::value &&
-      is_integral<_To>::value &&
-      !is_same<_UnqualTo, bool>::value
-    );
+      // Beyond the simple case, we say that one type is "always bit-castable" to another if:
+      // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
+      //   a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of
+      //   values of `From`);
+      // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed
+      //   integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed
+      //   integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be
+      //   produced by the built-in assignment (if it were defined for the two types, to which there are minor
+      //   exceptions, e.g. built-in arrays).
+      //
+      // In practice, that means:
+      // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and
+      //   unsigned...
+      // - as well as arrays of such types...
+      // - ...that have the same size.
+      //
+      // Other trivially-copyable types can't be validly bit-cast outside of their own type:
+      // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails
+      // #1);
+      // - integral types and floating-point types use different representations, so for example bit-casting an integral
+      //   `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0`
+      //   (fails #2);
+      // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean
+      //   will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2).
+      //   Bit-casting from a boolean into an integer, however, is valid;
+      // - enumeration types may have different ranges of possible values (fails #1);
+      // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent
+      //   addresses, and the conversion results are explicitly unspecified for types with different alignments
+      //   (fails #1);
+      // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of
+      //   the other (fails #1);
+      // - there is no need to consider `nullptr_t` for practical purposes.
+      (
+        sizeof(_From) == sizeof(_To) &&
+        is_integral<_From>::value &&
+        is_integral<_To>::value &&
+        !is_same<_UnqualTo, bool>::value
+      );
+  // clang-format on
 };
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_arithmetic.h
@@ -20,11 +20,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
-    : public integral_constant<bool, is_integral<_Tp>::value      ||
-                                     is_floating_point<_Tp>::value> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_arithmetic
+    : public integral_constant<bool, is_integral<_Tp>::value || is_floating_point<_Tp>::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_array.h
@@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_array) && 0
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
+struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_array_v = __is_array(_Tp);
-#endif
+#  endif
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
-    : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
-    : public true_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]>
-    : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_array : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> : public true_type {};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> : public true_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_array_v = is_array<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_array)
 
lib/libcxx/include/__type_traits/is_assignable.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
 #endif
lib/libcxx/include/__type_traits/is_base_of.h
@@ -19,10 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Bp, class _Dp>
-struct _LIBCPP_TEMPLATE_VIS is_base_of
-    : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
+struct _LIBCPP_TEMPLATE_VIS is_base_of : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Bp, class _Dp>
 inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
 #endif
lib/libcxx/include/__type_traits/is_bounded_array.h
@@ -19,17 +19,20 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class>                 struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array           : false_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
+template <class>
+struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
-template <class>                 struct _LIBCPP_TEMPLATE_VIS is_bounded_array           : false_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
+template <class>
+struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
 
 template <class _Tp>
-inline constexpr
-bool is_bounded_array_v  = is_bounded_array<_Tp>::value;
+inline constexpr bool is_bounded_array_v = is_bounded_array<_Tp>::value;
 
 #endif
 
lib/libcxx/include/__type_traits/is_callable.h
@@ -19,12 +19,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))>
+template <class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))>
 true_type __is_callable_helper(int);
-template<class...>
+template <class...>
 false_type __is_callable_helper(...);
 
-template<class _Func, class... _Args>
+template <class _Func, class... _Args>
 struct __is_callable : decltype(std::__is_callable_helper<_Func, _Args...>(0)) {};
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_class.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
-    : public integral_constant<bool, __is_class(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_class : public integral_constant<bool, __is_class(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_class_v = __is_class(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_compound.h
@@ -21,23 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_compound)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_compound_v = __is_compound(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_compound)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
-    : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_compound : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_compound_v = is_compound<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_compound)
 
lib/libcxx/include/__type_traits/is_const.h
@@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_const)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
+struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_const_v = __is_const(_Tp);
-#endif
+#  endif
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const            : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_const_v = is_const<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_const)
 
lib/libcxx/include/__type_traits/is_constant_evaluated.h
@@ -17,15 +17,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
-_LIBCPP_INLINE_VISIBILITY
-inline constexpr bool is_constant_evaluated() noexcept {
+#if _LIBCPP_STD_VER >= 20
+_LIBCPP_INLINE_VISIBILITY inline constexpr bool is_constant_evaluated() noexcept {
   return __builtin_is_constant_evaluated();
 }
 #endif
 
-_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR
-bool __libcpp_is_constant_evaluated() _NOEXCEPT { return __builtin_is_constant_evaluated(); }
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR bool __libcpp_is_constant_evaluated() _NOEXCEPT {
+  return __builtin_is_constant_evaluated();
+}
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_constructible.h
@@ -18,13 +18,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_constructible
-    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
-{ };
+template <class _Tp, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_constructible : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {};
 
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class ..._Args>
+#if _LIBCPP_STD_VER >= 17
+template <class _Tp, class... _Args>
 inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
 #endif
 
lib/libcxx/include/__type_traits/is_convertible.h
@@ -24,81 +24,87 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+#if __has_builtin(__is_convertible) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
 
-template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
-    : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible(_T1, _T2)> {};
 
-#else  // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+#elif __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
 
-namespace __is_convertible_imp
-{
-template <class _Tp> void  __test_convert(_Tp);
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
+
+// TODO: Remove this fallback when GCC < 13 support is no longer required.
+// GCC 13 has the __is_convertible built-in.
+#else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+
+namespace __is_convertible_imp {
+template <class _Tp>
+void __test_convert(_Tp);
 
 template <class _From, class _To, class = void>
 struct __is_convertible_test : public false_type {};
 
 template <class _From, class _To>
-struct __is_convertible_test<_From, _To,
-    decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> : public true_type
-{};
-
-template <class _Tp, bool _IsArray =    is_array<_Tp>::value,
-                     bool _IsFunction = is_function<_Tp>::value,
-                     bool _IsVoid =     is_void<_Tp>::value>
-                     struct __is_array_function_or_void                          {enum {value = 0};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};
-}
+struct __is_convertible_test<_From, _To, decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))>
+    : public true_type {};
+
+// clang-format off
+template <class _Tp,
+          bool _IsArray    = is_array<_Tp>::value,
+          bool _IsFunction = is_function<_Tp>::value,
+          bool _IsVoid     = is_void<_Tp>::value>
+                     struct __is_array_function_or_void                          { enum { value = 0 }; };
+template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> { enum { value = 1 }; };
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> { enum { value = 2 }; };
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> { enum { value = 3 }; };
+// clang-format on
+} // namespace __is_convertible_imp
 
 template <class _Tp,
-    unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value>
-struct __is_convertible_check
-{
-    static const size_t __v = 0;
+          unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value>
+struct __is_convertible_check {
+  static const size_t __v = 0;
 };
 
 template <class _Tp>
-struct __is_convertible_check<_Tp, 0>
-{
-    static const size_t __v = sizeof(_Tp);
+struct __is_convertible_check<_Tp, 0> {
+  static const size_t __v = sizeof(_Tp);
 };
 
-template <class _T1, class _T2,
-    unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
-    unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
+template <class _T1,
+          class _T2,
+          unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
+          unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
 struct __is_convertible
-    : public integral_constant<bool,
-        __is_convertible_imp::__is_convertible_test<_T1, _T2>::value
-    >
-{};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
-
-template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
-    : public __is_convertible<_T1, _T2>
-{
-    static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
-    static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
+    : public integral_constant<bool, __is_convertible_imp::__is_convertible_test<_T1, _T2>::value >{};
+
+// clang-format off
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type{};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type{};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type{};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type{};
+// clang-format on
+
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS is_convertible : public __is_convertible<_T1, _T2> {
+  static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
+  static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
 };
 
 #endif // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _From, class _To>
 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
 #endif
lib/libcxx/include/__type_traits/is_copy_assignable.h
@@ -24,10 +24,9 @@ template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
     : public integral_constant<
           bool,
-          __is_assignable(__add_lvalue_reference_t<_Tp>,
-                          __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
+          __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_copy_constructible.h
@@ -22,11 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_copy_constructible
-    : public integral_constant<
-          bool,
-          __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
+    : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {
+};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_core_convertible.h
@@ -27,9 +27,8 @@ template <class _Tp, class _Up, class = void>
 struct __is_core_convertible : public false_type {};
 
 template <class _Tp, class _Up>
-struct __is_core_convertible<_Tp, _Up, decltype(
-    static_cast<void(*)(_Up)>(0) ( static_cast<_Tp(*)()>(0)() )
-)> : public true_type {};
+struct __is_core_convertible<_Tp, _Up, decltype(static_cast<void (*)(_Up)>(0)(static_cast<_Tp (*)()>(0)()))>
+    : public true_type {};
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_default_constructible.h
@@ -19,11 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_default_constructible
-    : public integral_constant<bool, __is_constructible(_Tp)>
-    {};
+struct _LIBCPP_TEMPLATE_VIS is_default_constructible : public integral_constant<bool, __is_constructible(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_destructible.h
@@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_destructible)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_destructible_v = __is_destructible(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_destructible)
 
@@ -42,19 +42,19 @@ inline constexpr bool is_destructible_v = __is_destructible(_Tp);
 //    where _Up is remove_all_extents<_Tp>::type
 
 template <class>
-struct __is_destructible_apply { typedef int type; };
+struct __is_destructible_apply {
+  typedef int type;
+};
 
 template <typename _Tp>
 struct __is_destructor_wellformed {
-    template <typename _Tp1>
-    static true_type  __test (
-        typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type
-    );
+  template <typename _Tp1>
+  static true_type __test(typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type);
 
-    template <typename _Tp1>
-    static false_type __test (...);
+  template <typename _Tp1>
+  static false_type __test(...);
 
-    static const bool value = decltype(__test<_Tp>(12))::value;
+  static const bool value = decltype(__test<_Tp>(12))::value;
 };
 
 template <class _Tp, bool>
@@ -62,12 +62,10 @@ struct __destructible_imp;
 
 template <class _Tp>
 struct __destructible_imp<_Tp, false>
-   : public integral_constant<bool,
-        __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {};
+    : public integral_constant<bool, __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {};
 
 template <class _Tp>
-struct __destructible_imp<_Tp, true>
-    : public true_type {};
+struct __destructible_imp<_Tp, true> : public true_type {};
 
 template <class _Tp, bool>
 struct __destructible_false;
@@ -79,21 +77,18 @@ template <class _Tp>
 struct __destructible_false<_Tp, true> : public false_type {};
 
 template <class _Tp>
-struct is_destructible
-    : public __destructible_false<_Tp, is_function<_Tp>::value> {};
+struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {};
 
 template <class _Tp>
-struct is_destructible<_Tp[]>
-    : public false_type {};
+struct is_destructible<_Tp[]> : public false_type {};
 
 template <>
-struct is_destructible<void>
-    : public false_type {};
+struct is_destructible<void> : public false_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_destructible)
 
lib/libcxx/include/__type_traits/is_empty.h
@@ -19,10 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_empty
-    : public integral_constant<bool, __is_empty(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS is_empty : public integral_constant<bool, __is_empty(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_empty_v = __is_empty(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_enum.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
-    : public integral_constant<bool, __is_enum(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_enum : public integral_constant<bool, __is_enum(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_enum_v = __is_enum(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_equality_comparable.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Up, class = void>
+struct __is_equality_comparable : false_type {};
+
+template <class _Tp, class _Up>
+struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > : true_type {
+};
+
+// A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))`
+// (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use
+// __is_trivially_equality_comparable. We have special-casing for pointers which point to the same type ignoring
+// cv-qualifications and comparing to void-pointers.
+//
+// The following types are not trivially equality comparable:
+// floating-point types: different bit-patterns can compare equal. (e.g 0.0 and -0.0)
+// enums: The user is allowed to specialize operator== for enums
+// pointers that don't have the same type (ignoring cv-qualifiers): pointers to virtual bases are equality comparable,
+//   but don't have the same bit-pattern. An exception to this is comparing to a void-pointer. There the bit-pattern is
+//   always compared.
+
+template <class _Tp, class _Up>
+struct __libcpp_is_trivially_equality_comparable_impl : false_type {};
+
+template <class _Tp>
+struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp>
+#if __has_builtin(__is_trivially_equality_comparable)
+    : integral_constant<bool, __is_trivially_equality_comparable(_Tp) && __is_equality_comparable<_Tp, _Tp>::value> {
+};
+#else
+    : is_integral<_Tp> {
+};
+#endif // __has_builtin(__is_trivially_equality_comparable)
+
+template <class _Tp>
+struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {};
+
+// TODO: Use is_pointer_inverconvertible_base_of
+template <class _Tp, class _Up>
+struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*>
+    : integral_constant<
+          bool,
+          __is_equality_comparable<_Tp*, _Up*>::value &&
+              (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> {
+};
+
+template <class _Tp, class _Up>
+using __libcpp_is_trivially_equality_comparable =
+    __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
lib/libcxx/include/__type_traits/is_execution_policy.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
+#define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
+
+#include <__config>
+#include <__type_traits/remove_cvref.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+inline constexpr bool is_execution_policy_v = false;
+
+template <class>
+inline constexpr bool __is_unsequenced_execution_policy_impl = false;
+
+template <class _Tp>
+inline constexpr bool __is_unsequenced_execution_policy_v =
+    __is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>;
+
+template <class>
+inline constexpr bool __is_parallel_execution_policy_impl = false;
+
+template <class _Tp>
+inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>;
+
+namespace execution {
+struct __disable_user_instantiations_tag {
+  explicit __disable_user_instantiations_tag() = default;
+};
+} // namespace execution
+
+// TODO: Remove default argument once algorithms are using the new backend dispatching
+template <class _ExecutionPolicy>
+_LIBCPP_HIDE_FROM_ABI auto
+__remove_parallel_policy(const _ExecutionPolicy& = _ExecutionPolicy{execution::__disable_user_instantiations_tag{}});
+
+// Removes the "parallel" part of an execution policy.
+// For example, turns par_unseq into unseq, and par into seq.
+template <class _ExecutionPolicy>
+using __remove_parallel_policy_t = decltype(std::__remove_parallel_policy<_ExecutionPolicy>());
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
lib/libcxx/include/__type_traits/is_final.h
@@ -18,15 +18,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS __libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-is_final : public integral_constant<bool, __is_final(_Tp)> {};
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_final : public integral_constant<bool, __is_final(_Tp)> {};
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_final_v = __is_final(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_floating_point.h
@@ -19,15 +19,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+// clang-format off
 template <class _Tp> struct __libcpp_is_floating_point              : public false_type {};
 template <>          struct __libcpp_is_floating_point<float>       : public true_type {};
 template <>          struct __libcpp_is_floating_point<double>      : public true_type {};
 template <>          struct __libcpp_is_floating_point<long double> : public true_type {};
+// clang-format on
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point
-    : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_function.h
@@ -33,7 +33,7 @@ struct _LIBCPP_TEMPLATE_VIS is_function
 
 #endif // __has_builtin(__is_function)
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_function_v = is_function<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_fundamental.h
@@ -22,25 +22,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_fundamental)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_fundamental)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
-    : public integral_constant<bool, is_void<_Tp>::value        ||
-                                     __is_nullptr_t<_Tp>::value ||
-                                     is_arithmetic<_Tp>::value> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_fundamental
+    : public integral_constant<bool, is_void<_Tp>::value || __is_nullptr_t<_Tp>::value || is_arithmetic<_Tp>::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_fundamental)
 
lib/libcxx/include/__type_traits/is_implicitly_default_constructible.h
@@ -28,19 +28,17 @@ template <class _Tp>
 void __test_implicit_default_constructible(_Tp);
 
 template <class _Tp, class = void, class = typename is_default_constructible<_Tp>::type>
-struct __is_implicitly_default_constructible
-    : false_type
-{ };
+struct __is_implicitly_default_constructible : false_type {};
 
 template <class _Tp>
-struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), true_type>
-    : true_type
-{ };
+struct __is_implicitly_default_constructible<_Tp,
+                                             decltype(std::__test_implicit_default_constructible<_Tp const&>({})),
+                                             true_type> : true_type {};
 
 template <class _Tp>
-struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), false_type>
-    : false_type
-{ };
+struct __is_implicitly_default_constructible<_Tp,
+                                             decltype(std::__test_implicit_default_constructible<_Tp const&>({})),
+                                             false_type> : false_type {};
 #endif // !C++03
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_integral.h
@@ -19,6 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+// clang-format off
 template <class _Tp> struct __libcpp_is_integral                     { enum { value = 0 }; };
 template <>          struct __libcpp_is_integral<bool>               { enum { value = 1 }; };
 template <>          struct __libcpp_is_integral<char>               { enum { value = 1 }; };
@@ -44,26 +45,27 @@ template <>          struct __libcpp_is_integral<unsigned long long> { enum { va
 template <>          struct __libcpp_is_integral<__int128_t>         { enum { value = 1 }; };
 template <>          struct __libcpp_is_integral<__uint128_t>        { enum { value = 1 }; };
 #endif
+// clang-format on
 
 #if __has_builtin(__is_integral)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
+struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_integral_v = __is_integral(_Tp);
-#endif
+#  endif
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
-    : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_integral_v = is_integral<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_integral)
 
lib/libcxx/include/__type_traits/is_literal_type.h
@@ -19,15 +19,15 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
-    : public integral_constant<bool, __is_literal_type(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
+    : public integral_constant<bool, __is_literal_type(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 _LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
-#endif // _LIBCPP_STD_VER > 14
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+#  endif // _LIBCPP_STD_VER >= 17
+#endif   // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_member_function_pointer.h
@@ -21,41 +21,39 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct __libcpp_is_member_pointer {
-  enum {
-    __is_member = false,
-    __is_func = false,
-    __is_obj = false
-  };
+template <class _Tp>
+struct __libcpp_is_member_pointer {
+  enum { __is_member = false, __is_func = false, __is_obj = false };
 };
-template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
+template <class _Tp, class _Up>
+struct __libcpp_is_member_pointer<_Tp _Up::*> {
   enum {
     __is_member = true,
-    __is_func = is_function<_Tp>::value,
-    __is_obj = !__is_func,
+    __is_func   = is_function<_Tp>::value,
+    __is_obj    = !__is_func,
   };
 };
 
 #if __has_builtin(__is_member_function_pointer)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
-    : _BoolConstant<__is_member_function_pointer(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_member_function_pointer)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
-    : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
+    : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_member_function_pointer)
 
lib/libcxx/include/__type_traits/is_member_object_pointer.h
@@ -20,24 +20,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_member_object_pointer)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
-    : _BoolConstant<__is_member_object_pointer(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_member_object_pointer)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
-    : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj >  {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
+    : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_member_object_pointer)
 
lib/libcxx/include/__type_traits/is_member_pointer.h
@@ -21,23 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_member_pointer)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_member_pointer)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
- : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_pointer
+    : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_member_pointer)
 
lib/libcxx/include/__type_traits/is_move_assignable.h
@@ -22,11 +22,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_move_assignable
-    : public integral_constant<
-          bool,
-          __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
+    : public integral_constant<bool, __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_move_constructible.h
@@ -21,10 +21,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_move_constructible
-    : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)>
-    {};
+    : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_nothrow_assignable.h
@@ -19,10 +19,10 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Arg>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
-    : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {
+};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
 inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg);
 #endif
lib/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -24,52 +24,44 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_nothrow_constructible)
 
-template <
-    class _Tp, class... _Args>
+template < class _Tp, class... _Args>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
     : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
 #else
 
-template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
+template <bool, bool, class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible;
 
 template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
-    : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))>
-{
-};
+struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ false, _Tp, _Args...>
+    : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))> {};
 
 template <class _Tp>
-void __implicit_conversion_to(_Tp) noexcept { }
+void __implicit_conversion_to(_Tp) noexcept {}
 
 template <class _Tp, class _Arg>
-struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
-    : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))>
-{
-};
+struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ true, _Tp, _Arg>
+    : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))> {};
 
 template <class _Tp, bool _IsReference, class... _Args>
-struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
-    : public false_type
-{
+struct __libcpp_is_nothrow_constructible</*is constructible*/ false, _IsReference, _Tp, _Args...> : public false_type {
 };
 
 template <class _Tp, class... _Args>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
-{
-};
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value,
+                                        is_reference<_Tp>::value,
+                                        _Tp,
+                                        _Args...> {};
 
 template <class _Tp, size_t _Ns>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
-{
-};
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> {};
 
 #endif // __has_builtin(__is_nothrow_constructible)
 
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class ..._Args>
+#if _LIBCPP_STD_VER >= 17
+template <class _Tp, class... _Args>
 inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
 #endif
 
lib/libcxx/include/__type_traits/is_nothrow_convertible.h
@@ -24,29 +24,26 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <typename _Tp>
-static void __test_noexcept(_Tp) noexcept;
+void __test_noexcept(_Tp) noexcept;
 
-template<typename _Fm, typename _To>
-static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))>
-__is_nothrow_convertible_test();
+template <typename _Fm, typename _To>
+bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))> __is_nothrow_convertible_test();
 
 template <typename _Fm, typename _To>
-struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>())
-{ };
+struct __is_nothrow_convertible_helper : decltype(__is_nothrow_convertible_test<_Fm, _To>()) {};
 
 template <typename _Fm, typename _To>
-struct is_nothrow_convertible : _Or<
-    _And<is_void<_To>, is_void<_Fm>>,
-    _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
->::type { };
+struct is_nothrow_convertible
+    : _Or<_And<is_void<_To>, is_void<_Fm>>,
+          _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To> > >::type {};
 
 template <typename _Fm, typename _To>
 inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_nothrow_copy_assignable.h
@@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable
-    : public integral_constant<
-          bool,
-          __is_nothrow_assignable(
-              __add_lvalue_reference_t<_Tp>,
-              __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
+    : public integral_constant<bool,
+                               __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>,
+                                                       __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_nothrow_copy_constructible.h
@@ -24,9 +24,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
 #ifdef _LIBCPP_COMPILER_GCC
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
-    : public is_nothrow_constructible<_Tp,
-                  __add_lvalue_reference_t<typename add_const<_Tp>::type> > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
+    : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type> > {};
 
 #else // _LIBCPP_COMPILER_GCC
 
@@ -38,7 +38,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
 
 #endif // _LIBCPP_COMPILER_GCC
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_nothrow_default_constructible.h
@@ -18,11 +18,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
-    : public integral_constant<bool, __is_nothrow_constructible(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
+    : public integral_constant<bool, __is_nothrow_constructible(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_nothrow_destructible.h
@@ -26,60 +26,45 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !defined(_LIBCPP_CXX03_LANG)
 
-template <bool, class _Tp> struct __libcpp_is_nothrow_destructible;
+template <bool, class _Tp>
+struct __libcpp_is_nothrow_destructible;
 
 template <class _Tp>
-struct __libcpp_is_nothrow_destructible<false, _Tp>
-    : public false_type
-{
-};
+struct __libcpp_is_nothrow_destructible<false, _Tp> : public false_type {};
 
 template <class _Tp>
 struct __libcpp_is_nothrow_destructible<true, _Tp>
-    : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) >
-{
-};
+    : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) > {};
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
-    : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
-{
-};
+    : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp> {};
 
 template <class _Tp, size_t _Ns>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]>
-    : public is_nothrow_destructible<_Tp>
-{
-};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]> : public is_nothrow_destructible<_Tp> {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&>
-    : public true_type
-{
-};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&> : public true_type {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&>
-    : public true_type
-{
-};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> : public true_type {};
 
 #else
 
-template <class _Tp> struct __libcpp_nothrow_destructor
-    : public integral_constant<bool, is_scalar<_Tp>::value ||
-                                     is_reference<_Tp>::value> {};
+template <class _Tp>
+struct __libcpp_nothrow_destructor : public integral_constant<bool, is_scalar<_Tp>::value || is_reference<_Tp>::value> {
+};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
-    : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > {
+};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]>
-    : public false_type {};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]> : public false_type {};
 
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_nothrow_move_assignable.h
@@ -22,12 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable
-    : public integral_constant<
-          bool,
-          __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {
+    : public integral_constant<bool,
+                               __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_nothrow_move_constructible.h
@@ -23,19 +23,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
 #ifndef _LIBCPP_COMPILER_GCC
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
-    : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
+    : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
 #else // _LIBCPP_COMPILER_GCC
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
-    : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> >
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
+    : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> > {};
 
 #endif // _LIBCPP_COMPILER_GCC
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_null_pointer.h
@@ -20,21 +20,23 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct __is_nullptr_t_impl       : public false_type {};
-template <>          struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
+template <class _Tp>
+struct __is_nullptr_t_impl : public false_type {};
+template <>
+struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t
-    : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_null_pointer
-    : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_null_pointer : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
-#endif
-#endif // _LIBCPP_STD_VER > 11
+#  endif
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_object.h
@@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_object)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_object_v = __is_object(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_object)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
-    : public integral_constant<bool, is_scalar<_Tp>::value ||
-                                     is_array<_Tp>::value  ||
-                                     is_union<_Tp>::value  ||
-                                     is_class<_Tp>::value  > {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_object
+    : public integral_constant<bool,
+                               is_scalar<_Tp>::value || is_array<_Tp>::value || is_union<_Tp>::value ||
+                                   is_class<_Tp>::value > {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_object_v = is_object<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_object)
 
lib/libcxx/include/__type_traits/is_pod.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
-    : public integral_constant<bool, __is_pod(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_pod : public integral_constant<bool, __is_pod(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_pod_v = __is_pod(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_pointer.h
@@ -21,34 +21,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_pointer)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_pointer_v = __is_pointer(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_pointer)
 
-template <class _Tp> struct __libcpp_is_pointer       : public false_type {};
-template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
+template <class _Tp>
+struct __libcpp_is_pointer : public false_type {};
+template <class _Tp>
+struct __libcpp_is_pointer<_Tp*> : public true_type {};
 
-template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; };
-#if defined(_LIBCPP_HAS_OBJC_ARC)
+template <class _Tp>
+struct __libcpp_remove_objc_qualifiers {
+  typedef _Tp type;
+};
+#  if defined(_LIBCPP_HAS_OBJC_ARC)
+// clang-format off
 template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; };
 template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; };
 template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; };
 template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
-#endif
+// clang-format on
+#  endif
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_pointer
     : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<__remove_cv_t<_Tp> >::type> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_pointer)
 
lib/libcxx/include/__type_traits/is_polymorphic.h
@@ -19,10 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_polymorphic
-    : public integral_constant<bool, __is_polymorphic(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_primary_template.h
@@ -21,13 +21,10 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-using __test_for_primary_template = __enable_if_t<
-    _IsSame<_Tp, typename _Tp::__primary_template>::value
-  >;
+using __test_for_primary_template = __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>;
+
 template <class _Tp>
-using __is_primary_template = _IsValidExpansion<
-    __test_for_primary_template, _Tp
-  >;
+using __is_primary_template = _IsValidExpansion<__test_for_primary_template, _Tp>;
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_reference.h
@@ -18,41 +18,46 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_builtin(__is_lvalue_reference) && \
-    __has_builtin(__is_rvalue_reference) && \
-    __has_builtin(__is_reference)
+#if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference) && __has_builtin(__is_reference)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {};
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {};
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_reference_v = __is_reference(_Tp);
 template <class _Tp>
 inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
 template <class _Tp>
 inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_lvalue_reference) && etc...
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference       : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference        : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference        : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&>  : public true_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_reference_v = is_reference<_Tp>::value;
 
@@ -61,7 +66,7 @@ inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
 
 template <class _Tp>
 inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_lvalue_reference) && etc...
 
lib/libcxx/include/__type_traits/is_reference_wrapper.h
@@ -19,12 +19,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS reference_wrapper;
-
-template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
-template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
-template <class _Tp> struct __is_reference_wrapper
-    : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {};
+template <class _Tp>
+class _LIBCPP_TEMPLATE_VIS reference_wrapper;
+
+template <class _Tp>
+struct __is_reference_wrapper_impl : public false_type {};
+template <class _Tp>
+struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
+template <class _Tp>
+struct __is_reference_wrapper : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {};
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_same.h
@@ -19,9 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
+struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Up>
 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
 #endif
lib/libcxx/include/__type_traits/is_scalar.h
@@ -25,35 +25,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_scalar)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_scalar_v = __is_scalar(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_scalar)
 
-template <class _Tp> struct __is_block : false_type {};
-#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
-template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
-#endif
+template <class _Tp>
+struct __is_block : false_type {};
+#  if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
+template <class _Rp, class... _Args>
+struct __is_block<_Rp (^)(_Args...)> : true_type {};
+#  endif
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar
-    : public integral_constant<bool, is_arithmetic<_Tp>::value     ||
-                                     is_member_pointer<_Tp>::value ||
-                                     is_pointer<_Tp>::value        ||
-                                     __is_nullptr_t<_Tp>::value    ||
-                                     __is_block<_Tp>::value        ||
-                                     is_enum<_Tp>::value           > {};
+// clang-format off
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_scalar
+    : public integral_constant<
+          bool, is_arithmetic<_Tp>::value ||
+                is_member_pointer<_Tp>::value ||
+                is_pointer<_Tp>::value ||
+                __is_nullptr_t<_Tp>::value ||
+                __is_block<_Tp>::value ||
+                is_enum<_Tp>::value> {};
+// clang-format on
 
-template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
+template <>
+struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_scalar)
 
lib/libcxx/include/__type_traits/is_scoped_enum.h
@@ -21,17 +21,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _Tp, bool = is_enum_v<_Tp> >
 struct __is_scoped_enum_helper : false_type {};
 
 template <class _Tp>
-struct __is_scoped_enum_helper<_Tp, true>
-    : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
+struct __is_scoped_enum_helper<_Tp, true> : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scoped_enum
-    : public __is_scoped_enum_helper<_Tp> {};
+struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : public __is_scoped_enum_helper<_Tp> {};
 
 template <class _Tp>
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
lib/libcxx/include/__type_traits/is_signed.h
@@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_signed)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_signed_v = __is_signed(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_signed)
 
@@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value>
 struct __libcpp_is_signed_impl : public _BoolConstant<(_Tp(-1) < _Tp(0))> {};
 
 template <class _Tp>
-struct __libcpp_is_signed_impl<_Tp, false> : public true_type {};  // floating point
+struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point
 
 template <class _Tp, bool = is_arithmetic<_Tp>::value>
 struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};
 
-template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};
+template <class _Tp>
+struct __libcpp_is_signed<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_signed_v = is_signed<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_signed)
 
lib/libcxx/include/__type_traits/is_signed_integer.h
@@ -18,15 +18,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
-template <> struct __libcpp_is_signed_integer<signed char>      : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed short>     : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed int>       : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed long>      : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
+// clang-format off
+template <class _Tp> struct __libcpp_is_signed_integer                   : public false_type {};
+template <>          struct __libcpp_is_signed_integer<signed char>      : public true_type {};
+template <>          struct __libcpp_is_signed_integer<signed short>     : public true_type {};
+template <>          struct __libcpp_is_signed_integer<signed int>       : public true_type {};
+template <>          struct __libcpp_is_signed_integer<signed long>      : public true_type {};
+template <>          struct __libcpp_is_signed_integer<signed long long> : public true_type {};
 #ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __libcpp_is_signed_integer<__int128_t>       : public true_type {};
+template <>          struct __libcpp_is_signed_integer<__int128_t>       : public true_type {};
 #endif
+// clang-format on
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_specialization.h
@@ -30,7 +30,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Tp, template <class...> class _Template>
 inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template
@@ -38,7 +38,7 @@ inline constexpr bool __is_specialization_v = false; // true if and only if _Tp
 template <template <class...> class _Template, class... _Args>
 inline constexpr bool __is_specialization_v<_Template<_Args...>, _Template> = true;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_standard_layout.h
@@ -18,11 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout
-    : public integral_constant<bool, __is_standard_layout(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_swappable.h
@@ -30,9 +30,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct __is_swappable;
-template <class _Tp> struct __is_nothrow_swappable;
-
+template <class _Tp>
+struct __is_swappable;
+template <class _Tp>
+struct __is_nothrow_swappable;
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Tp>
@@ -43,49 +44,40 @@ using __swap_result_t = void;
 #endif
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp>
-swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
-                                    is_nothrow_move_assignable<_Tp>::value);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y)
+    _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value);
 
-template<class _Tp, size_t _Np>
+template <class _Tp, size_t _Np>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-typename enable_if<
-    __is_swappable<_Tp>::value
->::type
-swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
+    typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np])
+        _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
 
-namespace __detail
-{
+namespace __detail {
 // ALL generic swap overloads MUST already have a declaration available at this point.
 
-template <class _Tp, class _Up = _Tp,
-          bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value>
-struct __swappable_with
-{
-    template <class _LHS, class _RHS>
-    static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>()))
-    __test_swap(int);
-    template <class, class>
-    static __nat __test_swap(long);
-
-    // Extra parens are needed for the C++03 definition of decltype.
-    typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1;
-    typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2;
-
-    static const bool value = _IsNotSame<__swap1, __nat>::value
-                           && _IsNotSame<__swap2, __nat>::value;
+template <class _Tp, class _Up = _Tp, bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value>
+struct __swappable_with {
+  template <class _LHS, class _RHS>
+  static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>())) __test_swap(int);
+  template <class, class>
+  static __nat __test_swap(long);
+
+  // Extra parens are needed for the C++03 definition of decltype.
+  typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1;
+  typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2;
+
+  static const bool value = _IsNotSame<__swap1, __nat>::value && _IsNotSame<__swap2, __nat>::value;
 };
 
 template <class _Tp, class _Up>
-struct __swappable_with<_Tp, _Up,  false> : false_type {};
+struct __swappable_with<_Tp, _Up, false> : false_type {};
 
 template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value>
 struct __nothrow_swappable_with {
   static const bool value =
 #ifndef _LIBCPP_HAS_NO_NOEXCEPT
-      noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
-  &&  noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()));
+      noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))&& noexcept(
+          swap(std::declval<_Up>(), std::declval<_Tp>()));
 #else
       false;
 #endif
@@ -97,54 +89,32 @@ struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {};
 } // namespace __detail
 
 template <class _Tp>
-struct __is_swappable
-    : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value>
-{
-};
+struct __is_swappable : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> {};
 
 template <class _Tp>
-struct __is_nothrow_swappable
-    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value>
-{
-};
+struct __is_nothrow_swappable : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 template <class _Tp, class _Up>
 struct _LIBCPP_TEMPLATE_VIS is_swappable_with
-    : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value>
-{
-};
+    : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> {};
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_swappable
-    : public __conditional_t<
-        __libcpp_is_referenceable<_Tp>::value,
-        is_swappable_with<
-            __add_lvalue_reference_t<_Tp>,
-            __add_lvalue_reference_t<_Tp> >,
-        false_type
-    >
-{
-};
+    : public __conditional_t<__libcpp_is_referenceable<_Tp>::value,
+                             is_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >,
+                             false_type> {};
 
 template <class _Tp, class _Up>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with
-    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value>
-{
-};
+    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> {};
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable
-    : public __conditional_t<
-        __libcpp_is_referenceable<_Tp>::value,
-        is_nothrow_swappable_with<
-            __add_lvalue_reference_t<_Tp>,
-            __add_lvalue_reference_t<_Tp> >,
-        false_type
-    >
-{
-};
+    : public __conditional_t<__libcpp_is_referenceable<_Tp>::value,
+                             is_nothrow_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >,
+                             false_type> {};
 
 template <class _Tp, class _Up>
 inline constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value;
@@ -158,7 +128,7 @@ inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_T
 template <class _Tp>
 inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_trivial.h
@@ -18,11 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivial
-    : public integral_constant<bool, __is_trivial(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivial_v = __is_trivial(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_trivially_assignable.h
@@ -19,11 +19,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Arg>
-struct is_trivially_assignable
-    : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
-{ };
+struct is_trivially_assignable : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
 inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Arg);
 #endif
lib/libcxx/include/__type_traits/is_trivially_constructible.h
@@ -20,11 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class... _Args>
 struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
-    : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
-{
-};
+    : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class... _Args>
 inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _Args...);
 #endif
lib/libcxx/include/__type_traits/is_trivially_copy_assignable.h
@@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable
-    : public integral_constant<
-          bool,
-          __is_trivially_assignable(
-              __add_lvalue_reference_t<_Tp>,
-              __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
+    : public integral_constant<bool,
+                               __is_trivially_assignable(__add_lvalue_reference_t<_Tp>,
+                                                         __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_trivially_copy_constructible.h
@@ -19,11 +19,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
-    : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
+    : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_trivially_copyable.h
@@ -11,6 +11,7 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
+#include <cstdint>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -18,15 +19,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable
-    : public integral_constant<bool, __is_trivially_copyable(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
 #endif
 
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp>
+inline constexpr bool __is_cheap_to_copy = is_trivially_copyable_v<_Tp> && sizeof(_Tp) <= sizeof(std::intmax_t);
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
lib/libcxx/include/__type_traits/is_trivially_default_constructible.h
@@ -18,11 +18,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
-    : public integral_constant<bool, __is_trivially_constructible(_Tp)>
-    {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
+    : public integral_constant<bool, __is_trivially_constructible(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_trivially_destructible.h
@@ -21,21 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_trivially_destructible)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
     : public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
 
 #elif __has_builtin(__has_trivial_destructor)
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
-    : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+    : public integral_constant<bool, is_destructible<_Tp>::value&& __has_trivial_destructor(_Tp)> {};
 
 #else
 
-#error is_trivially_destructible is not implemented
+#  error is_trivially_destructible is not implemented
 
 #endif // __has_builtin(__is_trivially_destructible)
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_unsigned.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// A type is_trivially_lexicographically_comparable if the expression `a <=> b` (or their pre-C++20 equivalents) is
+// equivalent to `std::memcmp(&a, &b, sizeof(T))` (with `a` and `b` being of type `T`). There is currently no builtin to
+// tell us whether that's the case for arbitrary types, so we can only do this for known types. Specifically, these are
+// currently unsigned integer types with a sizeof(T) == 1.
+//
+// bool is trivially lexicographically comparable, because e.g. false <=> true is valid code. Furthermore, the standard
+// says that [basic.fundamental] "Type bool is a distinct type that has the same object representation, value
+// representation, and alignment requirements as an implementation-defined unsigned integer type. The values of type
+// bool are true and false."
+// This means that bool has to be unsigned and has exactly two values. This means that having anything other than the
+// `true` or `false` value representations in a bool is UB.
+//
+// The following types are not trivially lexicographically comparable:
+// signed integer types: `char(-1) < char(1)`, but memcmp compares `unsigned char`s
+// unsigned integer types with sizeof(T) > 1: depending on the endianness, the LSB might be the first byte to be
+//                                            compared. This means that when comparing unsigned(129) and unsigned(2)
+//                                            using memcmp(), the result would be that 2 > 129.
+//                                            TODO: Do we want to enable this on big-endian systems?
+
+template <class _Tp, class _Up>
+struct __libcpp_is_trivially_lexicographically_comparable
+    : integral_constant<bool,
+                        is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value && sizeof(_Tp) == 1 &&
+                            is_unsigned<_Tp>::value> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
lib/libcxx/include/__type_traits/is_trivially_move_assignable.h
@@ -26,7 +26,7 @@ struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable
           bool,
           __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_trivially_move_constructible.h
@@ -23,7 +23,7 @@ template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible
     : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/is_unbounded_array.h
@@ -18,17 +18,20 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class>     struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array        : false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
+template <class>
+struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
-template <class>     struct _LIBCPP_TEMPLATE_VIS is_unbounded_array        : false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
+template <class>
+struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
 
 template <class _Tp>
-inline constexpr
-bool is_unbounded_array_v  = is_unbounded_array<_Tp>::value;
+inline constexpr bool is_unbounded_array_v = is_unbounded_array<_Tp>::value;
 
 #endif
 
lib/libcxx/include/__type_traits/is_union.h
@@ -18,10 +18,10 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
-    : public integral_constant<bool, __is_union(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_union : public integral_constant<bool, __is_union(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_union_v = __is_union(_Tp);
 #endif
lib/libcxx/include/__type_traits/is_unsigned.h
@@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__is_unsigned)
 
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
-#endif
+#  endif
 
 #else // __has_builtin(__is_unsigned)
 
@@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value>
 struct __libcpp_is_unsigned_impl : public _BoolConstant<(_Tp(0) < _Tp(-1))> {};
 
 template <class _Tp>
-struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {};  // floating point
+struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point
 
 template <class _Tp, bool = is_arithmetic<_Tp>::value>
 struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
 
-template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
+template <class _Tp>
+struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_unsigned)
 
lib/libcxx/include/__type_traits/is_unsigned_integer.h
@@ -18,15 +18,17 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned char>      : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned short>     : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned int>       : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned long>      : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
+// clang-format off
+template <class _Tp> struct __libcpp_is_unsigned_integer                     : public false_type {};
+template <>          struct __libcpp_is_unsigned_integer<unsigned char>      : public true_type {};
+template <>          struct __libcpp_is_unsigned_integer<unsigned short>     : public true_type {};
+template <>          struct __libcpp_is_unsigned_integer<unsigned int>       : public true_type {};
+template <>          struct __libcpp_is_unsigned_integer<unsigned long>      : public true_type {};
+template <>          struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
 #ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __libcpp_is_unsigned_integer<__uint128_t>        : public true_type {};
+template <>          struct __libcpp_is_unsigned_integer<__uint128_t>        : public true_type {};
 #endif
+// clang-format on
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/is_valid_expansion.h
@@ -18,12 +18,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> >
+template <template <class...> class _Templ, class... _Args, class = _Templ<_Args...> >
 true_type __sfinae_test_impl(int);
-template <template <class...> class, class ...>
+template <template <class...> class, class...>
 false_type __sfinae_test_impl(...);
 
-template <template <class ...> class _Templ, class ..._Args>
+template <template <class...> class _Templ, class... _Args>
 using _IsValidExpansion _LIBCPP_NODEBUG = decltype(std::__sfinae_test_impl<_Templ, _Args...>(0));
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_void.h
@@ -23,22 +23,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_void)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
+struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_void_v = __is_void(_Tp);
-#endif
+#  endif
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
-    : public is_same<__remove_cv_t<_Tp>, void> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_void : public is_same<__remove_cv_t<_Tp>, void> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_void_v = is_void<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_void)
 
lib/libcxx/include/__type_traits/is_volatile.h
@@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_volatile)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
+struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_volatile_v = __is_volatile(_Tp);
-#endif
+#  endif
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile               : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
 
-#if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
-#endif
+#  endif
 
 #endif // __has_builtin(__is_volatile)
 
lib/libcxx/include/__type_traits/lazy.h
@@ -17,7 +17,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <template <class...> class _Func, class ..._Args>
+template <template <class...> class _Func, class... _Args>
 struct _Lazy : _Func<_Args...> {};
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_32_64_or_128_bit.h
@@ -27,21 +27,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 ///
 /// The restriction is the same as the integral version of to_char.
 template <class _Tp>
-#if _LIBCPP_STD_VER > 17
-  requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
+#if _LIBCPP_STD_VER >= 20
+  requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
 #endif
+// clang-format off
 using __make_32_64_or_128_bit_t =
-  __copy_unsigned_t<_Tp,
-    __conditional_t<sizeof(_Tp) <= sizeof(int32_t),    int32_t,
-    __conditional_t<sizeof(_Tp) <= sizeof(int64_t),    int64_t,
+    __copy_unsigned_t<_Tp,
+        __conditional_t<sizeof(_Tp) <= sizeof(int32_t),    int32_t,
+        __conditional_t<sizeof(_Tp) <= sizeof(int64_t),    int64_t,
 #ifndef _LIBCPP_HAS_NO_INT128
-    __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
-    /* else */                                         void>
+        __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
+        /* else */                                         void>
 #else
-    /* else */                                         void
+        /* else */                                         void
 #endif
-    > >
-  >;
+    > > >;
+// clang-format on
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/make_const_lvalue_ref.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Tp>
+template <class _Tp>
 using __make_const_lvalue_ref = const __libcpp_remove_reference_t<_Tp>&;
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_signed.h
@@ -29,30 +29,31 @@ template <class _Tp>
 using __make_signed_t = __make_signed(_Tp);
 
 #else
-typedef
-    __type_list<signed char,
-    __type_list<signed short,
-    __type_list<signed int,
-    __type_list<signed long,
-    __type_list<signed long long,
+// clang-format off
+typedef __type_list<signed char,
+        __type_list<signed short,
+        __type_list<signed int,
+        __type_list<signed long,
+        __type_list<signed long long,
 #  ifndef _LIBCPP_HAS_NO_INT128
-    __type_list<__int128_t,
+        __type_list<__int128_t,
 #  endif
-    __nat
+        __nat
 #  ifndef _LIBCPP_HAS_NO_INT128
-    >
+        >
 #  endif
-    > > > > > __signed_types;
+        > > > > > __signed_types;
+// clang-format on
 
 template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
-struct __make_signed {};
+struct __make_signed{};
 
 template <class _Tp>
-struct __make_signed<_Tp, true>
-{
-    typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
+struct __make_signed<_Tp, true> {
+  typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
 };
 
+// clang-format off
 template <> struct __make_signed<bool,               true> {};
 template <> struct __make_signed<  signed short,     true> {typedef short     type;};
 template <> struct __make_signed<unsigned short,     true> {typedef short     type;};
@@ -66,9 +67,10 @@ template <> struct __make_signed<unsigned long long, true> {typedef long long ty
 template <> struct __make_signed<__int128_t,         true> {typedef __int128_t type;};
 template <> struct __make_signed<__uint128_t,        true> {typedef __int128_t type;};
 #  endif
+// clang-format on
 
 template <class _Tp>
-using __make_signed_t = typename __apply_cv<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>::type;
+using __make_signed_t = __apply_cv_t<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>;
 
 #endif // __has_builtin(__make_signed)
 
@@ -77,8 +79,9 @@ struct make_signed {
   using type _LIBCPP_NODEBUG = __make_signed_t<_Tp>;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using make_signed_t = __make_signed_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using make_signed_t = __make_signed_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_unsigned.h
@@ -31,30 +31,31 @@ template <class _Tp>
 using __make_unsigned_t = __make_unsigned(_Tp);
 
 #else
-typedef
-    __type_list<unsigned char,
-    __type_list<unsigned short,
-    __type_list<unsigned int,
-    __type_list<unsigned long,
-    __type_list<unsigned long long,
+// clang-format off
+typedef __type_list<unsigned char,
+        __type_list<unsigned short,
+        __type_list<unsigned int,
+        __type_list<unsigned long,
+        __type_list<unsigned long long,
 #  ifndef _LIBCPP_HAS_NO_INT128
-    __type_list<__uint128_t,
+        __type_list<__uint128_t,
 #  endif
-    __nat
+        __nat
 #  ifndef _LIBCPP_HAS_NO_INT128
-    >
+        >
 #  endif
-    > > > > > __unsigned_types;
+        > > > > > __unsigned_types;
+// clang-format on
 
 template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
-struct __make_unsigned {};
+struct __make_unsigned{};
 
 template <class _Tp>
-struct __make_unsigned<_Tp, true>
-{
-    typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
+struct __make_unsigned<_Tp, true> {
+  typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
 };
 
+// clang-format off
 template <> struct __make_unsigned<bool,               true> {};
 template <> struct __make_unsigned<  signed short,     true> {typedef unsigned short     type;};
 template <> struct __make_unsigned<unsigned short,     true> {typedef unsigned short     type;};
@@ -68,9 +69,10 @@ template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned l
 template <> struct __make_unsigned<__int128_t,         true> {typedef __uint128_t        type;};
 template <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_t        type;};
 #  endif
+// clang-format on
 
 template <class _Tp>
-using __make_unsigned_t = typename __apply_cv<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>::type;
+using __make_unsigned_t = __apply_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>;
 
 #endif // __has_builtin(__make_unsigned)
 
@@ -79,15 +81,15 @@ struct make_unsigned {
   using type _LIBCPP_NODEBUG = __make_unsigned_t<_Tp>;
 };
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using make_unsigned_t = __make_unsigned_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using make_unsigned_t = __make_unsigned_t<_Tp>;
 #endif
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr
-__make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept {
-    return static_cast<__make_unsigned_t<_Tp> >(__x);
+_LIBCPP_HIDE_FROM_ABI constexpr __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept {
+  return static_cast<__make_unsigned_t<_Tp> >(__x);
 }
 #endif
 
lib/libcxx/include/__type_traits/maybe_const.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<bool _Const, class _Tp>
+template <bool _Const, class _Tp>
 using __maybe_const = __conditional_t<_Const, const _Tp, _Tp>;
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/nat.h
@@ -17,13 +17,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-struct __nat
-{
+struct __nat {
 #ifndef _LIBCPP_CXX03_LANG
-    __nat() = delete;
-    __nat(const __nat&) = delete;
-    __nat& operator=(const __nat&) = delete;
-    ~__nat() = delete;
+  __nat()                        = delete;
+  __nat(const __nat&)            = delete;
+  __nat& operator=(const __nat&) = delete;
+  ~__nat()                       = delete;
 #endif
 };
 
lib/libcxx/include/__type_traits/negation.h
@@ -21,12 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Pred>
 struct _Not : _BoolConstant<!_Pred::value> {};
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 struct negation : _Not<_Tp> {};
-template<class _Tp>
+template <class _Tp>
 inline constexpr bool negation_v = !_Tp::value;
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/noexcept_move_assign_container.h
@@ -20,15 +20,17 @@
 
 _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 > 14
-        || _Traits::is_always_equal::value
+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
+                                   && is_nothrow_move_assignable<_Alloc>::value
 #endif
-    > {};
+                               > {
+};
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/operation_traits.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_OPERATION_TRAITS_H
+#define _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Pred, class _Lhs, class _Rhs>
+struct __is_trivial_plus_operation : false_type {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
lib/libcxx/include/__type_traits/predicate_traits.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TYPE_TRAITS_PREDICATE_TRAITS
+#define _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Pred, class _Lhs, class _Rhs>
+struct __is_trivial_equality_predicate : false_type {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
lib/libcxx/include/__type_traits/promote.h
@@ -13,7 +13,6 @@
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_same.h>
 #include <__utility/declval.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,73 +21,69 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __numeric_type
-{
-   static void __test(...);
-   static float __test(float);
-   static double __test(char);
-   static double __test(int);
-   static double __test(unsigned);
-   static double __test(long);
-   static double __test(unsigned long);
-   static double __test(long long);
-   static double __test(unsigned long long);
+struct __numeric_type {
+  static void __test(...);
+  static float __test(float);
+  static double __test(char);
+  static double __test(int);
+  static double __test(unsigned);
+  static double __test(long);
+  static double __test(unsigned long);
+  static double __test(long long);
+  static double __test(unsigned long long);
 #ifndef _LIBCPP_HAS_NO_INT128
-   static double __test(__int128_t);
-   static double __test(__uint128_t);
+  static double __test(__int128_t);
+  static double __test(__uint128_t);
 #endif
-   static double __test(double);
-   static long double __test(long double);
+  static double __test(double);
+  static long double __test(long double);
 
-   typedef decltype(__test(std::declval<_Tp>())) type;
-   static const bool value = _IsNotSame<type, void>::value;
+  typedef decltype(__test(std::declval<_Tp>())) type;
+  static const bool value = _IsNotSame<type, void>::value;
 };
 
 template <>
-struct __numeric_type<void>
-{
-   static const bool value = true;
+struct __numeric_type<void> {
+  static const bool value = true;
 };
 
-template <class _A1, class _A2 = void, class _A3 = void,
-          bool = __numeric_type<_A1>::value &&
-                 __numeric_type<_A2>::value &&
-                 __numeric_type<_A3>::value>
-class __promote_imp
-{
+template <class _A1,
+          class _A2 = void,
+          class _A3 = void,
+          bool      = __numeric_type<_A1>::value&& __numeric_type<_A2>::value&& __numeric_type<_A3>::value>
+class __promote_imp {
 public:
-    static const bool value = false;
+  static const bool value = false;
 };
 
 template <class _A1, class _A2, class _A3>
-class __promote_imp<_A1, _A2, _A3, true>
-{
+class __promote_imp<_A1, _A2, _A3, true> {
 private:
-    typedef typename __promote_imp<_A1>::type __type1;
-    typedef typename __promote_imp<_A2>::type __type2;
-    typedef typename __promote_imp<_A3>::type __type3;
+  typedef typename __promote_imp<_A1>::type __type1;
+  typedef typename __promote_imp<_A2>::type __type2;
+  typedef typename __promote_imp<_A3>::type __type3;
+
 public:
-    typedef decltype(__type1() + __type2() + __type3()) type;
-    static const bool value = true;
+  typedef decltype(__type1() + __type2() + __type3()) type;
+  static const bool value = true;
 };
 
 template <class _A1, class _A2>
-class __promote_imp<_A1, _A2, void, true>
-{
+class __promote_imp<_A1, _A2, void, true> {
 private:
-    typedef typename __promote_imp<_A1>::type __type1;
-    typedef typename __promote_imp<_A2>::type __type2;
+  typedef typename __promote_imp<_A1>::type __type1;
+  typedef typename __promote_imp<_A2>::type __type2;
+
 public:
-    typedef decltype(__type1() + __type2()) type;
-    static const bool value = true;
+  typedef decltype(__type1() + __type2()) type;
+  static const bool value = true;
 };
 
 template <class _A1>
-class __promote_imp<_A1, void, void, true>
-{
+class __promote_imp<_A1, void, void, true> {
 public:
-    typedef typename __numeric_type<_A1>::type type;
-    static const bool value = true;
+  typedef typename __numeric_type<_A1>::type type;
+  static const bool value = true;
 };
 
 template <class _A1, class _A2 = void, class _A3 = void>
lib/libcxx/include/__type_traits/rank.h
@@ -27,16 +27,16 @@ struct rank : integral_constant<size_t, __array_rank(_Tp)> {};
 
 #else
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
-    : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]>
-    : public integral_constant<size_t, rank<_Tp>::value + 1> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]>
-    : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS rank : public integral_constant<size_t, 0> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]> : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> : public integral_constant<size_t, rank<_Tp>::value + 1> {};
 
 #endif // __has_builtin(__array_rank)
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr size_t rank_v = rank<_Tp>::value;
 #endif
lib/libcxx/include/__type_traits/remove_all_extents.h
@@ -27,19 +27,26 @@ struct remove_all_extents {
 template <class _Tp>
 using __remove_all_extents_t = __remove_all_extents(_Tp);
 #else
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents
-    {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]>
-    {typedef typename remove_all_extents<_Tp>::type type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]>
-    {typedef typename remove_all_extents<_Tp>::type type;};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_all_extents {
+  typedef _Tp type;
+};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]> {
+  typedef typename remove_all_extents<_Tp>::type type;
+};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]> {
+  typedef typename remove_all_extents<_Tp>::type type;
+};
 
 template <class _Tp>
 using __remove_all_extents_t = typename remove_all_extents<_Tp>::type;
 #endif // __has_builtin(__remove_all_extents)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_all_extents_t = __remove_all_extents_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_all_extents_t = __remove_all_extents_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_const.h
@@ -26,15 +26,22 @@ struct remove_const {
 template <class _Tp>
 using __remove_const_t = __remove_const(_Tp);
 #else
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const            {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_const {
+  typedef _Tp type;
+};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {
+  typedef _Tp type;
+};
 
 template <class _Tp>
 using __remove_const_t = typename remove_const<_Tp>::type;
 #endif // __has_builtin(__remove_const)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_const_t = __remove_const_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_const_t = __remove_const_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_cv.h
@@ -19,7 +19,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_builtin(__remove_cv)
+#if __has_builtin(__remove_cv) && !defined(_LIBCPP_COMPILER_GCC)
 template <class _Tp>
 struct remove_cv {
   using type _LIBCPP_NODEBUG = __remove_cv(_Tp);
@@ -28,15 +28,18 @@ struct remove_cv {
 template <class _Tp>
 using __remove_cv_t = __remove_cv(_Tp);
 #else
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
-{typedef __remove_volatile_t<__remove_const_t<_Tp> > type;};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_cv {
+  typedef __remove_volatile_t<__remove_const_t<_Tp> > type;
+};
 
 template <class _Tp>
 using __remove_cv_t = __remove_volatile_t<__remove_const_t<_Tp> >;
 #endif // __has_builtin(__remove_cv)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_cv_t = __remove_cv_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_cv_t = __remove_cv_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_cvref.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_builtin(__remove_cvref)
+#if __has_builtin(__remove_cvref) && !defined(_LIBCPP_COMPILER_GCC)
 template <class _Tp>
 using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cvref(_Tp);
 #else
@@ -31,13 +31,14 @@ using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cv_t<__libcpp_remove_reference
 template <class _Tp, class _Up>
 struct __is_same_uncvref : _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> > {};
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp>
 struct remove_cvref {
-    using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>;
+  using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>;
 };
 
-template <class _Tp> using remove_cvref_t = __remove_cvref_t<_Tp>;
+template <class _Tp>
+using remove_cvref_t = __remove_cvref_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_extent.h
@@ -27,19 +27,26 @@ struct remove_extent {
 template <class _Tp>
 using __remove_extent_t = __remove_extent(_Tp);
 #else
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
-    {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]>
-    {typedef _Tp type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]>
-    {typedef _Tp type;};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_extent {
+  typedef _Tp type;
+};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]> {
+  typedef _Tp type;
+};
+template <class _Tp, size_t _Np>
+struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]> {
+  typedef _Tp type;
+};
 
 template <class _Tp>
 using __remove_extent_t = typename remove_extent<_Tp>::type;
 #endif // __has_builtin(__remove_extent)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_extent_t = __remove_extent_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_extent_t = __remove_extent_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_pointer.h
@@ -26,18 +26,21 @@ struct remove_pointer {
 template <class _Tp>
 using __remove_pointer_t = __remove_pointer(_Tp);
 #else
+// clang-format off
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer                      {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*>                {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const>          {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile>       {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
+// clang-format on
 
 template <class _Tp>
 using __remove_pointer_t = typename remove_pointer<_Tp>::type;
 #endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_pointer_t = __remove_pointer_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_reference.h
@@ -27,16 +27,19 @@ struct remove_reference {
 template <class _Tp>
 using __libcpp_remove_reference_t = __remove_reference_t(_Tp);
 #else
+// clang-format off
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference        {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&>  {typedef _LIBCPP_NODEBUG _Tp type;};
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG _Tp type;};
+// clang-format on
 
 template <class _Tp>
 using __libcpp_remove_reference_t = typename remove_reference<_Tp>::type;
 #endif // __has_builtin(__remove_reference_t)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_reference_t = __libcpp_remove_reference_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_reference_t = __libcpp_remove_reference_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_volatile.h
@@ -26,15 +26,22 @@ struct remove_volatile {
 template <class _Tp>
 using __remove_volatile_t = __remove_volatile(_Tp);
 #else
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile               {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_volatile {
+  typedef _Tp type;
+};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {
+  typedef _Tp type;
+};
 
 template <class _Tp>
 using __remove_volatile_t = typename remove_volatile<_Tp>::type;
 #endif // __has_builtin(__remove_volatile)
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_volatile_t = __remove_volatile_t<_Tp>;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using remove_volatile_t = __remove_volatile_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/result_of.h
@@ -21,18 +21,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // result_of
 
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
-template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
-
-template <class _Fp, class ..._Args>
-class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)>
-    : public __invoke_of<_Fp, _Args...>
-{
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
-#endif // _LIBCPP_STD_VER > 11
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+template <class _Callable>
+class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
+
+template <class _Fp, class... _Args>
+class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> {};
+
+#  if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
+#  endif // _LIBCPP_STD_VER >= 14
+#endif   // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/strip_signature.h
@@ -19,23 +19,24 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Fp>
+template <class _Fp>
 struct __strip_signature;
 
 #  if defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
 
 template <class _Rp, class... _Args>
-struct __strip_signature<_Rp(*)(_Args...)> {
+struct __strip_signature<_Rp (*)(_Args...)> {
   using type = _Rp(_Args...);
 };
 
 template <class _Rp, class... _Args>
-struct __strip_signature<_Rp(*)(_Args...) noexcept> {
+struct __strip_signature<_Rp (*)(_Args...) noexcept> {
   using type = _Rp(_Args...);
 };
 
 #  endif // defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
 
+// clang-format off
 template<class _Rp, class _Gp, class ..._Ap>
 struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
 template<class _Rp, class _Gp, class ..._Ap>
@@ -71,6 +72,7 @@ template<class _Rp, class _Gp, class ..._Ap>
 struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
 template<class _Rp, class _Gp, class ..._Ap>
 struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
+// clang-format on
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__type_traits/type_identity.h
@@ -18,14 +18,20 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __type_identity { typedef _Tp type; };
+struct __type_identity {
+  typedef _Tp type;
+};
 
 template <class _Tp>
 using __type_identity_t _LIBCPP_NODEBUG = typename __type_identity<_Tp>::type;
 
-#if _LIBCPP_STD_VER > 17
-template<class _Tp> struct type_identity { typedef _Tp type; };
-template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
+#if _LIBCPP_STD_VER >= 20
+template <class _Tp>
+struct type_identity {
+  typedef _Tp type;
+};
+template <class _Tp>
+using type_identity_t = typename type_identity<_Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/type_list.h
@@ -19,24 +19,22 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Hp, class _Tp>
-struct __type_list
-{
-    typedef _Hp _Head;
-    typedef _Tp _Tail;
+struct __type_list {
+  typedef _Hp _Head;
+  typedef _Tp _Tail;
 };
 
-template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;
+template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)>
+struct __find_first;
 
 template <class _Hp, class _Tp, size_t _Size>
-struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
-{
-    typedef _LIBCPP_NODEBUG _Hp type;
+struct __find_first<__type_list<_Hp, _Tp>, _Size, true> {
+  typedef _LIBCPP_NODEBUG _Hp type;
 };
 
 template <class _Hp, class _Tp, size_t _Size>
-struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
-{
-    typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
+struct __find_first<__type_list<_Hp, _Tp>, _Size, false> {
+  typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
 };
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/underlying_type.h
@@ -18,22 +18,23 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, bool = is_enum<_Tp>::value> struct __underlying_type_impl;
+template <class _Tp, bool = is_enum<_Tp>::value>
+struct __underlying_type_impl;
 
 template <class _Tp>
 struct __underlying_type_impl<_Tp, false> {};
 
 template <class _Tp>
-struct __underlying_type_impl<_Tp, true>
-{
-    typedef __underlying_type(_Tp) type;
+struct __underlying_type_impl<_Tp, true> {
+  typedef __underlying_type(_Tp) type;
 };
 
 template <class _Tp>
 struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
 
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
+#if _LIBCPP_STD_VER >= 14
+template <class _Tp>
+using underlying_type_t = typename underlying_type<_Tp>::type;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__functional/unwrap_ref.h → lib/libcxx/include/__type_traits/unwrap_ref.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
-#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
+#ifndef _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
+#define _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
 
 #include <__config>
 #include <__type_traits/decay.h>
@@ -19,40 +19,45 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; };
+struct __unwrap_reference {
+  typedef _LIBCPP_NODEBUG _Tp type;
+};
 
 template <class _Tp>
 class reference_wrapper;
 
 template <class _Tp>
-struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG _Tp& type; };
+struct __unwrap_reference<reference_wrapper<_Tp> > {
+  typedef _LIBCPP_NODEBUG _Tp& type;
+};
 
 template <class _Tp>
 struct decay;
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp>
-struct unwrap_reference : __unwrap_reference<_Tp> { };
+struct unwrap_reference : __unwrap_reference<_Tp> {};
 
 template <class _Tp>
 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
 
 template <class _Tp>
-struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
+struct unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {};
 
 template <class _Tp>
 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
-#endif // > C++17
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _Tp>
 struct __unwrap_ref_decay
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     : unwrap_ref_decay<_Tp>
 #else
-    : __unwrap_reference<typename decay<_Tp>::type>
+    : __unwrap_reference<__decay_t<_Tp> >
 #endif
-{ };
+{
+};
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
+#endif // _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
lib/libcxx/include/__type_traits/void_t.h
@@ -17,8 +17,9 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
-template <class...> using void_t = void;
+#if _LIBCPP_STD_VER >= 17
+template <class...>
+using void_t = void;
 #endif
 
 template <class...>
lib/libcxx/include/__utility/as_const.h
@@ -20,7 +20,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
 
lib/libcxx/include/__utility/auto_cast.h
@@ -17,6 +17,6 @@
 #  pragma GCC system_header
 #endif
 
-#define _LIBCPP_AUTO_CAST(expr) static_cast<typename decay<decltype((expr))>::type>(expr)
+#define _LIBCPP_AUTO_CAST(expr) static_cast<::std::__decay_t<decltype((expr))> >(expr)
 
 #endif // _LIBCPP___UTILITY_AUTO_CAST_H
lib/libcxx/include/__utility/cmp.h
@@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template<class _Tp, class... _Up>
 struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {};
 
@@ -102,7 +102,7 @@ bool in_range(_Up __u) noexcept
   return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
          _VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__utility/exception_guard.h
@@ -19,6 +19,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // __exception_guard is a helper class for writing code with the strong exception guarantee.
@@ -41,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // less common, especially one that tries to catch an exception through -fno-exceptions code.
 //
 // __exception_guard can help greatly simplify code that would normally be cluttered by
-// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
+// `#if _LIBCPP_HAS_NO_EXCEPTIONS`. For example:
 //
 //    template <class Iterator, class Size, class OutputIterator>
 //    Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
@@ -58,7 +61,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 //    }
 //
 
-#ifndef _LIBCPP_NO_EXCEPTIONS
 template <class _Rollback>
 struct __exception_guard_exceptions {
   __exception_guard_exceptions() = delete;
@@ -91,9 +93,6 @@ private:
 
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_exceptions);
 
-template <class _Rollback>
-using __exception_guard = __exception_guard_exceptions<_Rollback>;
-#else  // _LIBCPP_NO_EXCEPTIONS
 template <class _Rollback>
 struct __exception_guard_noexceptions {
   __exception_guard_noexceptions() = delete;
@@ -116,7 +115,7 @@ struct __exception_guard_noexceptions {
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG ~__exception_guard_noexceptions() {
-    _LIBCPP_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__completed_, "__exception_guard not completed with exceptions disabled");
   }
 
 private:
@@ -125,9 +124,13 @@ private:
 
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions);
 
+#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
 template <class _Rollback>
 using __exception_guard = __exception_guard_noexceptions<_Rollback>;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#else
+template <class _Rollback>
+using __exception_guard = __exception_guard_exceptions<_Rollback>;
+#endif
 
 template <class _Rollback>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback) {
@@ -136,4 +139,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exce
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___UTILITY_TRANSACTION_H
lib/libcxx/include/__utility/exchange.h
@@ -19,9 +19,12 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template<class _T1, class _T2 = _T1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 _T1 exchange(_T1& __obj, _T2&& __new_value)
@@ -31,8 +34,10 @@ _T1 exchange(_T1& __obj, _T2&& __new_value)
     __obj = _VSTD::forward<_T2>(__new_value);
     return __old_value;
 }
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___UTILITY_EXCHANGE_H
lib/libcxx/include/__utility/forward_like.h
@@ -22,7 +22,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 template <class _Ap, class _Bp>
 using _CopyConst = _If<is_const_v<_Ap>, const _Bp, _Bp>;
@@ -39,7 +39,7 @@ template <class _Tp, class _Up>
   return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
 }
 
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__utility/in_place.h
@@ -19,23 +19,23 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
-struct _LIBCPP_TYPE_VIS in_place_t {
-    explicit in_place_t() = default;
+struct _LIBCPP_EXPORTED_FROM_ABI in_place_t {
+  explicit in_place_t() = default;
 };
 inline constexpr in_place_t in_place{};
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
-    explicit in_place_type_t() = default;
+  _LIBCPP_HIDE_FROM_ABI explicit in_place_type_t() = default;
 };
 template <class _Tp>
 inline constexpr in_place_type_t<_Tp> in_place_type{};
 
 template <size_t _Idx>
 struct _LIBCPP_TEMPLATE_VIS in_place_index_t {
-    explicit in_place_index_t() = default;
+  _LIBCPP_HIDE_FROM_ABI explicit in_place_index_t() = default;
 };
 template <size_t _Idx>
 inline constexpr in_place_index_t<_Idx> in_place_index{};
@@ -52,7 +52,7 @@ template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : t
 template <class _Tp>
 using __is_inplace_index = __is_inplace_index_imp<__remove_cvref_t<_Tp>>;
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__utility/integer_sequence.h
@@ -85,7 +85,7 @@ using __make_indices_imp =
 
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template<class _Tp, _Tp... _Ip>
 struct _LIBCPP_TEMPLATE_VIS integer_sequence
@@ -138,15 +138,15 @@ template<size_t _Np>
 template<class... _Tp>
     using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 // Executes __func for every element in an index_sequence.
 template <size_t... _Index, class _Function>
 _LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) {
     (__func.template operator()<_Index>(), ...);
 }
-#  endif // _LIBCPP_STD_VER > 17
+#  endif // _LIBCPP_STD_VER >= 20
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/__utility/is_pointer_in_range.h
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
+#define _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
+
+#include <__algorithm/comp.h>
+#include <__assert>
+#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Up, class = void>
+struct __is_less_than_comparable : false_type {};
+
+template <class _Tp, class _Up>
+struct __is_less_than_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() < std::declval<_Up>())> > : true_type {
+};
+
+template <class _Tp, class _Up, __enable_if_t<__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range(
+    const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
+  if (__libcpp_is_constant_evaluated()) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__builtin_constant_p(__begin <= __end), "__begin and __end do not form a range");
+
+    // If this is not a constant during constant evaluation we know that __ptr is not part of the allocation where
+    // [__begin, __end) is.
+    if (!__builtin_constant_p(__begin <= __ptr && __ptr < __end))
+      return false;
+  }
+
+  // Checking this for unrelated pointers is technically UB, but no compiler optimizes based on it (currently).
+  return !__less<>()(__ptr, __begin) && __less<>()(__ptr, __end);
+}
+
+template <class _Tp, class _Up, __enable_if_t<!__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0>
+_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range(
+    const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
+  if (__libcpp_is_constant_evaluated())
+    return false;
+
+  return reinterpret_cast<const char*>(__begin) <= reinterpret_cast<const char*>(__ptr) &&
+         reinterpret_cast<const char*>(__ptr) < reinterpret_cast<const char*>(__end);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
lib/libcxx/include/__utility/move.h
@@ -20,6 +20,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
@@ -41,4 +44,6 @@ move_if_noexcept(_LIBCPP_LIFETIMEBOUND _Tp& __x) _NOEXCEPT {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___UTILITY_MOVE_H
lib/libcxx/include/__utility/pair.h
@@ -11,17 +11,23 @@
 
 #include <__compare/common_comparison_category.h>
 #include <__compare/synth_three_way.h>
+#include <__concepts/different_from.h>
 #include <__config>
-#include <__functional/unwrap_ref.h>
+#include <__fwd/array.h>
 #include <__fwd/get.h>
+#include <__fwd/pair.h>
+#include <__fwd/subrange.h>
 #include <__fwd/tuple.h>
-#include <__tuple_dir/sfinae_helpers.h>
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_indices.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/pair_like.h>
+#include <__tuple/sfinae_helpers.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_indices.h>
+#include <__tuple/tuple_size.h>
 #include <__type_traits/common_reference.h>
 #include <__type_traits/common_type.h>
 #include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_assignable.h>
 #include <__type_traits/is_constructible.h>
 #include <__type_traits/is_convertible.h>
@@ -38,6 +44,9 @@
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_swappable.h>
 #include <__type_traits/nat.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/unwrap_ref.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/piecewise_construct.h>
@@ -47,16 +56,25 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
 template <class, class>
 struct __non_trivially_copyable_base {
-  _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
   __non_trivially_copyable_base() _NOEXCEPT {}
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
 };
+
+#if _LIBCPP_STD_VER >= 23
+template <class _Tp>
+struct __is_specialization_of_subrange : false_type {};
+
+template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
+struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
 #endif
 
 template <class _T1, class _T2>
@@ -65,66 +83,80 @@ struct _LIBCPP_TEMPLATE_VIS pair
 : private __non_trivially_copyable_base<_T1, _T2>
 #endif
 {
-    typedef _T1 first_type;
-    typedef _T2 second_type;
+    using first_type = _T1;
+    using second_type = _T2;
 
     _T1 first;
     _T2 second;
 
-    pair(pair const&) = default;
-    pair(pair&&) = default;
+    _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
+    _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
 
 #ifdef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     pair() : first(), second() {}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
 
     template <class _U1, class _U2>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI
     pair& operator=(pair const& __p) {
         first = __p.first;
         second = __p.second;
         return *this;
     }
+
+    // Extension: This is provided in C++03 because it allows properly handling the
+    //            assignment to a pair containing references, which would be a hard
+    //            error otherwise.
+    template <class _U1, class _U2, class = __enable_if_t<
+        is_assignable<first_type&, _U1 const&>::value &&
+        is_assignable<second_type&, _U2 const&>::value
+    > >
+    _LIBCPP_HIDE_FROM_ABI
+    pair& operator=(pair<_U1, _U2> const& __p) {
+        first = __p.first;
+        second = __p.second;
+        return *this;
+    }
 #else
     struct _CheckArgs {
       template <int&...>
-      static constexpr bool __enable_explicit_default() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() {
           return is_default_constructible<_T1>::value
               && is_default_constructible<_T2>::value
               && !__enable_implicit_default<>();
       }
 
       template <int&...>
-      static constexpr bool __enable_implicit_default() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
           return __is_implicitly_default_constructible<_T1>::value
               && __is_implicitly_default_constructible<_T2>::value;
       }
 
       template <class _U1, class _U2>
-      static constexpr bool __is_pair_constructible() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
           return is_constructible<first_type, _U1>::value
               && is_constructible<second_type, _U2>::value;
       }
 
       template <class _U1, class _U2>
-      static constexpr bool __is_implicit() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
           return is_convertible<_U1, first_type>::value
               && is_convertible<_U2, second_type>::value;
       }
 
       template <class _U1, class _U2>
-      static constexpr bool __enable_explicit() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
           return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
       }
 
       template <class _U1, class _U2>
-      static constexpr bool __enable_implicit() {
+      static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
           return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
       }
     };
@@ -133,36 +165,10 @@ struct _LIBCPP_TEMPLATE_VIS pair
     using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
       _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
 
-    struct _CheckTupleLikeConstructor {
-        template <class _Tuple>
-        static constexpr bool __enable_implicit() {
-            return __tuple_convertible<_Tuple, pair>::value;
-        }
-
-        template <class _Tuple>
-        static constexpr bool __enable_explicit() {
-            return __tuple_constructible<_Tuple, pair>::value
-               && !__tuple_convertible<_Tuple, pair>::value;
-        }
-
-        template <class _Tuple>
-        static constexpr bool __enable_assign() {
-            return __tuple_assignable<_Tuple, pair>::value;
-        }
-    };
-
-    template <class _Tuple>
-    using _CheckTLC _LIBCPP_NODEBUG = __conditional_t<
-        __tuple_like_with_size<_Tuple, 2>::value
-            && !is_same<typename decay<_Tuple>::type, pair>::value,
-        _CheckTupleLikeConstructor,
-        __check_tuple_constructor_fail
-    >;
-
     template<bool _Dummy = true, typename enable_if<
             _CheckArgsDep<_Dummy>::__enable_explicit_default()
     >::type* = nullptr>
-    explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
                       is_nothrow_default_constructible<second_type>::value)
         : first(), second() {}
@@ -170,7 +176,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template<bool _Dummy = true, typename enable_if<
             _CheckArgsDep<_Dummy>::__enable_implicit_default()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
                       is_nothrow_default_constructible<second_type>::value)
         : first(), second() {}
@@ -178,7 +184,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template <bool _Dummy = true, typename enable_if<
              _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     explicit pair(_T1 const& __t1, _T2 const& __t2)
         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
                    is_nothrow_copy_constructible<second_type>::value)
@@ -187,41 +193,41 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template<bool _Dummy = true, typename enable_if<
             _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     pair(_T1 const& __t1, _T2 const& __t2)
         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
                    is_nothrow_copy_constructible<second_type>::value)
         : first(__t1), second(__t2) {}
 
     template <
-#if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
+#if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
         class _U1 = _T1, class _U2 = _T2,
 #else
         class _U1, class _U2,
 #endif
         typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr
     >
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     explicit pair(_U1&& __u1, _U2&& __u2)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
                     is_nothrow_constructible<second_type, _U2>::value))
-        : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
+        : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
 
     template <
-#if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
+#if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
         class _U1 = _T1, class _U2 = _T2,
 #else
         class _U1, class _U2,
 #endif
         typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr
     >
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     pair(_U1&& __u1, _U2&& __u2)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
                     is_nothrow_constructible<second_type, _U2>::value))
-        : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
+        : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template<class _U1, class _U2, __enable_if_t<
             _CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
     >* = nullptr>
@@ -235,7 +241,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template<class _U1, class _U2, typename enable_if<
             _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     explicit pair(pair<_U1, _U2> const& __p)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
                     is_nothrow_constructible<second_type, _U2 const&>::value))
@@ -244,7 +250,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template<class _U1, class _U2, typename enable_if<
             _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     pair(pair<_U1, _U2> const& __p)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
                     is_nothrow_constructible<second_type, _U2 const&>::value))
@@ -253,22 +259,22 @@ struct _LIBCPP_TEMPLATE_VIS pair
     template<class _U1, class _U2, typename enable_if<
             _CheckArgs::template __enable_explicit<_U1, _U2>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     explicit pair(pair<_U1, _U2>&&__p)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
                     is_nothrow_constructible<second_type, _U2&&>::value))
-        : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
+        : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
 
     template<class _U1, class _U2, typename enable_if<
             _CheckArgs::template __enable_implicit<_U1, _U2>()
     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     pair(pair<_U1, _U2>&& __p)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
                     is_nothrow_constructible<second_type, _U2&&>::value))
-        : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
+        : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template<class _U1, class _U2, __enable_if_t<
             _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
     >* = nullptr>
@@ -280,24 +286,27 @@ struct _LIBCPP_TEMPLATE_VIS pair
         : first(std::move(__p.first)), second(std::move(__p.second)) {}
 #endif
 
-    template<class _Tuple, typename enable_if<
-            _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
-    >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    explicit pair(_Tuple&& __p)
-        : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
-          second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
+#  if _LIBCPP_STD_VER >= 23
+    // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
+    template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2>
+    _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
+        if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) {
+            return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
+                   !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
+        }
+        return false;
+    }
 
-    template<class _Tuple, typename enable_if<
-            _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
-    >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
-    pair(_Tuple&& __p)
-        : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
-          second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
+    template <__pair_like _PairLike>
+      requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> &&
+               is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>)
+    _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>())
+        pair(_PairLike&& __p)
+        : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
+#  endif
 
     template <class... _Args1, class... _Args2>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     pair(piecewise_construct_t __pc,
          tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
         _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
@@ -306,7 +315,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
                 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
                 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     pair& operator=(__conditional_t<
                         is_copy_assignable<first_type>::value &&
                         is_copy_assignable<second_type>::value,
@@ -319,7 +328,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
         return *this;
     }
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     pair& operator=(__conditional_t<
                         is_move_assignable<first_type>::value &&
                         is_move_assignable<second_type>::value,
@@ -327,12 +336,34 @@ struct _LIBCPP_TEMPLATE_VIS pair
         _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
                    is_nothrow_move_assignable<second_type>::value)
     {
-        first = _VSTD::forward<first_type>(__p.first);
-        second = _VSTD::forward<second_type>(__p.second);
+        first = std::forward<first_type>(__p.first);
+        second = std::forward<second_type>(__p.second);
         return *this;
     }
 
-#if _LIBCPP_STD_VER > 20
+    template <class _U1, class _U2, __enable_if_t<
+        is_assignable<first_type&, _U1 const&>::value &&
+        is_assignable<second_type&, _U2 const&>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    pair& operator=(pair<_U1, _U2> const& __p) {
+        first = __p.first;
+        second = __p.second;
+        return *this;
+    }
+
+    template <class _U1, class _U2, __enable_if_t<
+        is_assignable<first_type&, _U1>::value &&
+        is_assignable<second_type&, _U2>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    pair& operator=(pair<_U1, _U2>&& __p) {
+        first = std::forward<_U1>(__p.first);
+        second = std::forward<_U2>(__p.second);
+        return *this;
+    }
+
+#  if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr
     const pair& operator=(pair const& __p) const
       noexcept(is_nothrow_copy_assignable_v<const first_type> &&
@@ -374,30 +405,178 @@ struct _LIBCPP_TEMPLATE_VIS pair
         second = std::forward<_U2>(__p.second);
         return *this;
     }
-#endif // _LIBCPP_STD_VER > 20
-
-    template <class _Tuple, typename enable_if<
-            _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
-     >::type* = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-    pair& operator=(_Tuple&& __p) {
-        first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
-        second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
+
+    template <__pair_like _PairLike>
+      requires(__different_from<_PairLike, pair> &&
+               !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
+               is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
+               is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
+    _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
+        first  = std::get<0>(std::forward<_PairLike>(__p));
+        second = std::get<1>(std::forward<_PairLike>(__p));
         return *this;
     }
-#endif
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+    template <__pair_like _PairLike>
+      requires(__different_from<_PairLike, pair> &&
+               !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
+               is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
+               is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
+    _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
+        first  = std::get<0>(std::forward<_PairLike>(__p));
+        second = std::get<1>(std::forward<_PairLike>(__p));
+        return *this;
+    }
+#  endif // _LIBCPP_STD_VER >= 23
+
+    // Prior to C++23, we provide an approximation of constructors and assignment operators from
+    // pair-like types. This was historically provided as an extension.
+#if _LIBCPP_STD_VER < 23
+    // from std::tuple
+    template<class _U1, class _U2, __enable_if_t<
+        is_convertible<_U1 const&, _T1>::value &&
+        is_convertible<_U2 const&, _T2>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair(tuple<_U1, _U2> const& __p)
+        : first(std::get<0>(__p)),
+          second(std::get<1>(__p)) {}
+
+    template<class _U1, class _U2, __enable_if_t<
+        is_constructible<_T1, _U1 const&>::value &&
+        is_constructible<_T2, _U2 const&>::value &&
+        !(is_convertible<_U1 const&, _T1>::value &&
+          is_convertible<_U2 const&, _T2>::value)
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    explicit
+    pair(tuple<_U1, _U2> const& __p)
+        : first(std::get<0>(__p)),
+          second(std::get<1>(__p)) {}
+
+    template<class _U1, class _U2, __enable_if_t<
+        is_convertible<_U1, _T1>::value &&
+        is_convertible<_U2, _T2>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair(tuple<_U1, _U2>&& __p)
+        : first(std::get<0>(std::move(__p))),
+          second(std::get<1>(std::move(__p))) {}
+
+    template<class _U1, class _U2, __enable_if_t<
+        is_constructible<_T1, _U1>::value &&
+        is_constructible<_T2, _U2>::value &&
+        !(is_convertible<_U1, _T1>::value &&
+          is_convertible<_U2, _T2>::value)
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    explicit
+    pair(tuple<_U1, _U2>&& __p)
+        : first(std::get<0>(std::move(__p))),
+          second(std::get<1>(std::move(__p))) {}
+
+
+    template<class _U1, class _U2, __enable_if_t<
+        is_assignable<_T1&, _U1 const&>::value &&
+        is_assignable<_T2&, _U2 const&>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair& operator=(tuple<_U1, _U2> const& __p) {
+        first = std::get<0>(__p);
+        second = std::get<1>(__p);
+        return *this;
+    }
+
+    template<class _U1, class _U2, __enable_if_t<
+        is_assignable<_T1&, _U1&&>::value &&
+        is_assignable<_T2&, _U2&&>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair& operator=(tuple<_U1, _U2>&& __p) {
+        first = std::get<0>(std::move(__p));
+        second = std::get<1>(std::move(__p));
+        return *this;
+    }
+
+    // from std::array
+    template<class _Up, __enable_if_t<
+        is_convertible<_Up const&, _T1>::value &&
+        is_convertible<_Up const&, _T2>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair(array<_Up, 2> const& __p)
+        : first(__p[0]),
+          second(__p[1]) {}
+
+    template<class _Up, __enable_if_t<
+        is_constructible<_T1, _Up const&>::value &&
+        is_constructible<_T2, _Up const&>::value &&
+        !(is_convertible<_Up const&, _T1>::value &&
+          is_convertible<_Up const&, _T2>::value)
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    explicit
+    pair(array<_Up, 2> const& __p)
+        : first(__p[0]),
+          second(__p[1]) {}
+
+    template<class _Up, __enable_if_t<
+        is_convertible<_Up, _T1>::value &&
+        is_convertible<_Up, _T2>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair(array<_Up, 2>&& __p)
+        : first(std::move(__p)[0]),
+          second(std::move(__p)[1]) {}
+
+    template<class _Up, __enable_if_t<
+        is_constructible<_T1, _Up>::value &&
+        is_constructible<_T2, _Up>::value &&
+        !(is_convertible<_Up, _T1>::value &&
+          is_convertible<_Up, _T2>::value)
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    explicit
+    pair(array<_Up, 2>&& __p)
+        : first(std::move(__p)[0]),
+          second(std::move(__p)[1]) {}
+
+
+    template<class _Up, __enable_if_t<
+        is_assignable<_T1&, _Up const&>::value &&
+        is_assignable<_T2&, _Up const&>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair& operator=(array<_Up, 2> const& __p) {
+        first = std::get<0>(__p);
+        second = std::get<1>(__p);
+        return *this;
+    }
+
+    template<class _Up, __enable_if_t<
+        is_assignable<_T1&, _Up>::value &&
+        is_assignable<_T2&, _Up>::value
+    >* = nullptr>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+    pair& operator=(array<_Up, 2>&& __p) {
+        first = std::get<0>(std::move(__p));
+        second = std::get<1>(std::move(__p));
+        return *this;
+    }
+#endif // _LIBCPP_STD_VER < 23
+#endif // _LIBCPP_CXX03_LANG
+
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     void
     swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
                                __is_nothrow_swappable<second_type>::value)
     {
-        using _VSTD::swap;
+        using std::swap;
         swap(first,  __p.first);
         swap(second, __p.second);
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr
     void swap(const pair& __p) const
         noexcept(__is_nothrow_swappable<const first_type>::value &&
@@ -412,88 +591,88 @@ private:
 
 #ifndef _LIBCPP_CXX03_LANG
     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     pair(piecewise_construct_t,
          tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
          __tuple_indices<_I1...>, __tuple_indices<_I2...>);
 #endif
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _T1, class _T2>
 pair(_T1, _T2) -> pair<_T1, _T2>;
 #endif
 
 // [pairs.spec], specialized algorithms
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return __x.first == __y.first && __x.second == __y.second;
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
-template <class _T1, class _T2>
+template <class _T1, class _T2, class _U1, class _U2>
 _LIBCPP_HIDE_FROM_ABI constexpr
 common_comparison_category_t<
-        __synth_three_way_result<_T1>,
-        __synth_three_way_result<_T2> >
-operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+        __synth_three_way_result<_T1, _U1>,
+        __synth_three_way_result<_T2, _U2> >
+operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
-    if (auto __c = _VSTD::__synth_three_way(__x.first, __y.first); __c != 0) {
+    if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
       return __c;
     }
-    return _VSTD::__synth_three_way(__x.second, __y.second);
+    return std::__synth_three_way(__x.second, __y.second);
 }
 
-#else // _LIBCPP_STD_VER > 17
+#else // _LIBCPP_STD_VER >= 20
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return !(__x == __y);
 }
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
 }
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return __y < __x;
 }
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return !(__x < __y);
 }
 
-template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+template <class _T1, class _T2, class _U1, class _U2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
-operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
 {
     return !(__y < __x);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
     requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
                                       common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
@@ -507,10 +686,10 @@ template <class _T1, class _T2, class _U1, class _U2>
 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
     using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
 };
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
     __is_swappable<_T1>::value &&
@@ -524,7 +703,7 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _T1, class _T2>
   requires (__is_swappable<const _T1>::value &&
             __is_swappable<const _T2>::value)
@@ -537,12 +716,12 @@ void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
 #endif
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
 make_pair(_T1&& __t1, _T2&& __t2)
 {
     return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
-               (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
+               (std::forward<_T1>(__t1), std::forward<_T2>(__t2));
 }
 
 template <class _T1, class _T2>
@@ -558,13 +737,13 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
 template <class _T1, class _T2>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
 {
-    typedef _LIBCPP_NODEBUG _T1 type;
+    using type _LIBCPP_NODEBUG = _T1;
 };
 
 template <class _T1, class _T2>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
 {
-    typedef _LIBCPP_NODEBUG _T2 type;
+    using type _LIBCPP_NODEBUG = _T2;
 };
 
 template <size_t _Ip> struct __get_pair;
@@ -574,27 +753,27 @@ struct __get_pair<0>
 {
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     _T1&
     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     const _T1&
     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     _T1&&
-    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
+    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     const _T1&&
-    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
+    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);}
 };
 
 template <>
@@ -602,31 +781,31 @@ struct __get_pair<1>
 {
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     _T2&
     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     const _T2&
     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     _T2&&
-    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
+    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
     const _T2&&
-    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
+    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);}
 };
 
 template <size_t _Ip, class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(pair<_T1, _T2>& __p) _NOEXCEPT
 {
@@ -634,7 +813,7 @@ get(pair<_T1, _T2>& __p) _NOEXCEPT
 }
 
 template <size_t _Ip, class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(const pair<_T1, _T2>& __p) _NOEXCEPT
 {
@@ -642,80 +821,82 @@ get(const pair<_T1, _T2>& __p) _NOEXCEPT
 }
 
 template <size_t _Ip, class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(pair<_T1, _T2>&& __p) _NOEXCEPT
 {
-    return __get_pair<_Ip>::get(_VSTD::move(__p));
+    return __get_pair<_Ip>::get(std::move(__p));
 }
 
 template <size_t _Ip, class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(const pair<_T1, _T2>&& __p) _NOEXCEPT
 {
-    return __get_pair<_Ip>::get(_VSTD::move(__p));
+    return __get_pair<_Ip>::get(std::move(__p));
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
 {
     return __get_pair<0>::get(__p);
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
 {
     return __get_pair<0>::get(__p);
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
 {
-    return __get_pair<0>::get(_VSTD::move(__p));
+    return __get_pair<0>::get(std::move(__p));
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
 {
-    return __get_pair<0>::get(_VSTD::move(__p));
+    return __get_pair<0>::get(std::move(__p));
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
 {
     return __get_pair<1>::get(__p);
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
 {
     return __get_pair<1>::get(__p);
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
 {
-    return __get_pair<1>::get(_VSTD::move(__p));
+    return __get_pair<1>::get(std::move(__p));
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
 constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
 {
-    return __get_pair<1>::get(_VSTD::move(__p));
+    return __get_pair<1>::get(std::move(__p));
 }
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___UTILITY_PAIR_H
lib/libcxx/include/__utility/piecewise_construct.h
@@ -18,10 +18,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
-#else
-/* inline */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+
+#if _LIBCPP_STD_VER >= 17
+inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+#elif !defined(_LIBCPP_CXX03_LANG)
+constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__utility/swap.h
@@ -23,6 +23,9 @@
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -51,4 +54,6 @@ swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::v
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___UTILITY_SWAP_H
lib/libcxx/include/__utility/terminate_on_exception.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___UTILITY_TERMINATE_ON_EXCEPTION_H
+#define _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
+
+#include <__config>
+#include <__exception/terminate.h>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+
+template <class _Func>
+_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
+  try {
+    return __func();
+  } catch (...) {
+    std::terminate();
+  }
+}
+
+#  else // _LIBCPP_HAS_NO_EXCEPTIONS
+
+template <class _Func>
+_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
+  return __func();
+}
+
+#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
lib/libcxx/include/__utility/to_underlying.h
@@ -27,7 +27,7 @@ __to_underlying(_Tp __val) noexcept {
 }
 #endif // !_LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _Tp>
 _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY constexpr underlying_type_t<_Tp>
 to_underlying(_Tp __val) noexcept {
lib/libcxx/include/__utility/unreachable.h
@@ -19,11 +19,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() {
-    _LIBCPP_ASSERT(false, "std::unreachable() was reached");
+    _LIBCPP_ASSERT_UNCATEGORIZED(false, "std::unreachable() was reached");
     __builtin_unreachable();
 }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 
 [[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); }
 
lib/libcxx/include/__variant/monostate.h
@@ -21,19 +21,19 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 struct _LIBCPP_TEMPLATE_VIS monostate {};
 
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(monostate, monostate) noexcept { return true; }
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(monostate, monostate) noexcept {
   return strong_ordering::equal;
 }
 
-#  else // _LIBCPP_STD_VER > 17
+#  else // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(monostate, monostate) noexcept { return false; }
 
@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(monostate, monostate) noexcept {
 
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(monostate, monostate) noexcept { return true; }
 
-#  endif // _LIBCPP_STD_VER > 17
+#  endif // _LIBCPP_STD_VER >= 20
 
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
@@ -57,7 +57,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
   }
 };
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/experimental/__config
@@ -32,18 +32,6 @@
 #define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
 #define _VSTD_LFTS_PMR _VSTD_LFTS::pmr
 
-#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
-#define _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
-#endif
-
-#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES \
-  _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace coroutines_v1 {
-
-#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES \
-  } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
-
-#define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1
-
 #define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \
     _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 {
 
lib/libcxx/include/experimental/__memory
@@ -12,9 +12,12 @@
 
 #include <__memory/allocator_arg_t.h>
 #include <__memory/uses_allocator.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_same.h>
 #include <experimental/__config>
 #include <experimental/utility> // for erased_type
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -90,7 +93,7 @@ template <class _Tp, class _Allocator, class... _Args>
 inline _LIBCPP_INLINE_VISIBILITY
 void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
 {
-    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
+    new (__storage) _Tp (allocator_arg_t(), __a, _VSTD::forward<_Args>(__args)...);
 }
 
 // FIXME: This should have a version which takes a non-const alloc.
lib/libcxx/include/experimental/algorithm
@@ -1,53 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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_EXPERIMENTAL_ALGORITHM
-#define _LIBCPP_EXPERIMENTAL_ALGORITHM
-
-/*
-   experimental/algorithm synopsis
-
-#include <algorithm>
-
-namespace std {
-namespace experimental {
-inline namespace fundamentals_v1 {
-
-template <class ForwardIterator, class Searcher>
-ForwardIterator search(ForwardIterator first, ForwardIterator last,
-                       const Searcher &searcher);
-
-// sample removed because it's now part of C++17
-
-} // namespace fundamentals_v1
-} // namespace experimental
-} // namespace std
-
-*/
-
-#include <__assert> // all public C++ headers provide the assertion handler
-#include <__debug>
-#include <algorithm>
-#include <experimental/__config>
-#include <type_traits>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_LFTS
-
-template <class _ForwardIterator, class _Searcher>
-_LIBCPP_INLINE_VISIBILITY
-_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)
-{ return __s(__f, __l).first; }
-
-_LIBCPP_END_NAMESPACE_LFTS
-
-#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */
lib/libcxx/include/experimental/coroutine
@@ -1,344 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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_EXPERIMENTAL_COROUTINE
-#define _LIBCPP_EXPERIMENTAL_COROUTINE
-
-/**
-    experimental/coroutine synopsis
-
-// C++next
-
-namespace std {
-namespace experimental {
-inline namespace coroutines_v1 {
-
-  // 18.11.1 coroutine traits
-template <typename R, typename... ArgTypes>
-class coroutine_traits;
-// 18.11.2 coroutine handle
-template <typename Promise = void>
-class coroutine_handle;
-// 18.11.2.7 comparison operators:
-bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
-// 18.11.3 trivial awaitables
-struct suspend_never;
-struct suspend_always;
-// 18.11.2.8 hash support:
-template <class T> struct hash;
-template <class P> struct hash<coroutine_handle<P>>;
-
-} // namespace coroutines_v1
-} // namespace experimental
-} // namespace std
-
- */
-
-#include <__assert> // all public C++ headers provide the assertion handler
-#include <__functional/hash.h>
-#include <__functional/operations.h>
-#include <cstddef>
-#include <experimental/__config>
-#include <new>
-#include <type_traits>
-
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
-#  include <atomic>
-#  include <climits>
-#  include <cmath>
-#  include <compare>
-#  include <concepts>
-#  include <ctime>
-#  include <initializer_list>
-#  include <iosfwd>
-#  include <iterator>
-#  include <memory>
-#  include <ratio>
-#  include <stdexcept>
-#  include <tuple>
-#  include <typeinfo>
-#  include <utility>
-#  include <variant>
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
-
-_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES
-
-template <class _Tp, class = void>
-struct __coroutine_traits_sfinae {};
-
-template <class _Tp>
-struct __coroutine_traits_sfinae<_Tp, __void_t<typename _Tp::promise_type> >
-{
-  using promise_type = typename _Tp::promise_type;
-};
-
-template <typename _Ret, typename... _Args>
-struct coroutine_traits
-    : public __coroutine_traits_sfinae<_Ret>
-{
-};
-
-template <typename _Promise = void>
-class _LIBCPP_TEMPLATE_VIS coroutine_handle;
-
-template <>
-class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
-        __handle_ = nullptr;
-        return *this;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void operator()() { resume(); }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void resume() {
-      _LIBCPP_ASSERT(__is_suspended(),
-                     "resume() can only be called on suspended coroutines");
-      _LIBCPP_ASSERT(!done(),
-                "resume() has undefined behavior when the coroutine is done");
-      __builtin_coro_resume(__handle_);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void destroy() {
-      _LIBCPP_ASSERT(__is_suspended(),
-                     "destroy() can only be called on suspended coroutines");
-      __builtin_coro_destroy(__handle_);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool done() const {
-      _LIBCPP_ASSERT(__is_suspended(),
-                     "done() can only be called on suspended coroutines");
-      return __builtin_coro_done(__handle_);
-    }
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    static coroutine_handle from_address(void* __addr) _NOEXCEPT {
-        coroutine_handle __tmp;
-        __tmp.__handle_ = __addr;
-        return __tmp;
-    }
-
-    // FIXME: Should from_address(nullptr) be allowed?
-    _LIBCPP_INLINE_VISIBILITY
-    static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
-      return coroutine_handle(nullptr);
-    }
-
-    template <class _Tp, bool _CallIsValid = false>
-    static coroutine_handle from_address(_Tp*) {
-      static_assert(_CallIsValid,
-       "coroutine_handle<void>::from_address cannot be called with "
-        "non-void pointers");
-    }
-
-private:
-  bool __is_suspended() const _NOEXCEPT  {
-    // FIXME actually implement a check for if the coro is suspended.
-    return __handle_;
-  }
-
-  template <class _PromiseT> friend class coroutine_handle;
-  void* __handle_;
-};
-
-// 18.11.2.7 comparison operators:
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return __x.address() == __y.address();
-}
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return !(__x == __y);
-}
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return less<void*>()(__x.address(), __y.address());
-}
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return __y < __x;
-}
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return !(__x > __y);
-}
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
-    return !(__x < __y);
-}
-
-template <typename _Promise>
-class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> {
-    using _Base = coroutine_handle<>;
-public:
-#ifndef _LIBCPP_CXX03_LANG
-    // 18.11.2.1 construct/reset
-    using coroutine_handle<>::coroutine_handle;
-#else
-    _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {}
-    _LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {}
-#endif
-    _LIBCPP_INLINE_VISIBILITY
-    coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
-        _Base::operator=(nullptr);
-        return *this;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Promise& promise() const {
-        return *static_cast<_Promise*>(
-            __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
-    }
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    static coroutine_handle from_address(void* __addr) _NOEXCEPT {
-        coroutine_handle __tmp;
-        __tmp.__handle_ = __addr;
-        return __tmp;
-    }
-
-    // NOTE: this overload isn't required by the standard but is needed so
-    // the deleted _Promise* overload doesn't make from_address(nullptr)
-    // ambiguous.
-    // FIXME: should from_address work with nullptr?
-    _LIBCPP_INLINE_VISIBILITY
-    static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
-      return coroutine_handle(nullptr);
-    }
-
-    template <class _Tp, bool _CallIsValid = false>
-    static coroutine_handle from_address(_Tp*) {
-      static_assert(_CallIsValid,
-       "coroutine_handle<promise_type>::from_address cannot be called with "
-        "non-void pointers");
-    }
-
-    template <bool _CallIsValid = false>
-    static coroutine_handle from_address(_Promise*) {
-      static_assert(_CallIsValid,
-       "coroutine_handle<promise_type>::from_address cannot be used with "
-        "pointers to the coroutine's promise type; use 'from_promise' instead");
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
-        typedef __remove_cv_t<_Promise> _RawPromise;
-        coroutine_handle __tmp;
-        __tmp.__handle_ = __builtin_coro_promise(
-            _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
-             _LIBCPP_ALIGNOF(_Promise), true);
-        return __tmp;
-    }
-};
-
-#if __has_builtin(__builtin_coro_noop)
-struct noop_coroutine_promise {};
-
-template <>
-class _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise>
-    : public coroutine_handle<> {
-  using _Base = coroutine_handle<>;
-  using _Promise = noop_coroutine_promise;
-public:
-
-  _LIBCPP_INLINE_VISIBILITY
-  _Promise& promise() const {
-    return *static_cast<_Promise*>(
-      __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
-  }
-
-  _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
-  _LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; }
-
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() const _NOEXCEPT {}
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 void resume() const _NOEXCEPT {}
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy() const _NOEXCEPT {}
-
-private:
-  _LIBCPP_INLINE_VISIBILITY
-  friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT;
-
-  _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT {
-    this->__handle_ = __builtin_coro_noop();
-  }
-};
-
-using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
-
-inline _LIBCPP_INLINE_VISIBILITY
-noop_coroutine_handle noop_coroutine() _NOEXCEPT {
-  return noop_coroutine_handle();
-}
-#endif // __has_builtin(__builtin_coro_noop)
-
-struct suspend_never {
-  _LIBCPP_INLINE_VISIBILITY
-  bool await_ready() const _NOEXCEPT { return true; }
-  _LIBCPP_INLINE_VISIBILITY
-  void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
-  _LIBCPP_INLINE_VISIBILITY
-  void await_resume() const _NOEXCEPT {}
-};
-
-struct suspend_always {
-  _LIBCPP_INLINE_VISIBILITY
-  bool await_ready() const _NOEXCEPT { return false; }
-  _LIBCPP_INLINE_VISIBILITY
-  void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
-  _LIBCPP_INLINE_VISIBILITY
-  void await_resume() const _NOEXCEPT {}
-};
-
-_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-struct hash<_VSTD_CORO::coroutine_handle<_Tp> > {
-    using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>;
-    _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(__arg_type const& __v) const _NOEXCEPT
-    {return hash<void*>()(__v.address());}
-};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-
-#endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */
lib/libcxx/include/experimental/functional
@@ -1,436 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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_EXPERIMENTAL_FUNCTIONAL
-#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL
-
-/*
-   experimental/functional synopsis
-
-#include <algorithm>
-
-namespace std {
-namespace experimental {
-inline namespace fundamentals_v1 {
-    // 4.3, Searchers
-    template<class ForwardIterator, class BinaryPredicate = equal_to<>>
-      class default_searcher;
-
-    template<class RandomAccessIterator,
-             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
-             class BinaryPredicate = equal_to<>>
-      class boyer_moore_searcher;
-
-    template<class RandomAccessIterator,
-             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
-             class BinaryPredicate = equal_to<>>
-      class boyer_moore_horspool_searcher;
-
-    template<class ForwardIterator, class BinaryPredicate = equal_to<>>
-    default_searcher<ForwardIterator, BinaryPredicate>
-    make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
-                          BinaryPredicate pred = BinaryPredicate());
-
-    template<class RandomAccessIterator,
-             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
-             class BinaryPredicate = equal_to<>>
-    boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
-    make_boyer_moore_searcher(
-        RandomAccessIterator pat_first, RandomAccessIterator pat_last,
-        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
-
-    template<class RandomAccessIterator,
-             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
-             class BinaryPredicate = equal_to<>>
-    boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
-    make_boyer_moore_horspool_searcher(
-        RandomAccessIterator pat_first, RandomAccessIterator pat_last,
-        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
-
-  } // namespace fundamentals_v1
-  } // namespace experimental
-
-} // namespace std
-
-*/
-
-#include <__assert> // all public C++ headers provide the assertion handler
-#include <__debug>
-#include <__functional/identity.h>
-#include <__memory/uses_allocator.h>
-#include <array>
-#include <experimental/__config>
-#include <functional>
-#include <type_traits>
-#include <unordered_map>
-#include <vector>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_LFTS
-
-#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
-#  define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER
-#  define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER
-#  define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER
-#else
-#  define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead")
-#  define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead")
-#  define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead")
-#endif
-
-#if _LIBCPP_STD_VER > 11
-// default searcher
-template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
-class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher {
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    default_searcher(_ForwardIterator __f, _ForwardIterator __l,
-                       _BinaryPredicate __p = _BinaryPredicate())
-        : __first_(__f), __last_(__l), __pred_(__p) {}
-
-    template <typename _ForwardIterator2>
-    _LIBCPP_INLINE_VISIBILITY
-    pair<_ForwardIterator2, _ForwardIterator2>
-    operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
-    {
-        auto __proj = __identity();
-        return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj);
-    }
-
-private:
-    _ForwardIterator __first_;
-    _ForwardIterator __last_;
-    _BinaryPredicate __pred_;
-    };
-
-template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
-_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY
-default_searcher<_ForwardIterator, _BinaryPredicate>
-make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
-{
-    return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
-}
-
-template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable;
-
-//  General case for BM data searching; use a map
-template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
-class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
-    typedef _Value value_type;
-    typedef _Key   key_type;
-
-    const _Value __default_value_;
-    std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
-        : __default_value_(__default), __table_(__sz, __hf, __pred) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    void insert(const key_type &__key, value_type __val)
-    {
-        __table_ [__key] = __val;    // Would skip_.insert (val) be better here?
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    value_type operator [](const key_type & __key) const
-    {
-        auto __it = __table_.find (__key);
-        return __it == __table_.end() ? __default_value_ : __it->second;
-    }
-};
-
-
-//  Special case small numeric values; use an array
-template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
-class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
-private:
-    typedef _Value value_type;
-    typedef _Key   key_type;
-
-    typedef __make_unsigned_t<key_type> unsigned_key_type;
-    typedef std::array<value_type, 256> skip_map;
-    skip_map __table_;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
-    {
-        std::fill_n(__table_.begin(), __table_.size(), __default);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void insert(key_type __key, value_type __val)
-    {
-        __table_[static_cast<unsigned_key_type>(__key)] = __val;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    value_type operator [](key_type __key) const
-    {
-        return __table_[static_cast<unsigned_key_type>(__key)];
-    }
-};
-
-
-template <class _RandomAccessIterator1,
-          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
-          class _BinaryPredicate = equal_to<>>
-class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
-private:
-    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
-    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
-    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
-                    is_integral<value_type>::value && // what about enums?
-                    sizeof(value_type) == 1 &&
-                    is_same<_Hash, hash<value_type>>::value &&
-                    is_same<_BinaryPredicate, equal_to<>>::value
-            > skip_table_type;
-
-public:
-    boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
-                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
-            : __first_(__f), __last_(__l), __pred_(__pred),
-              __pattern_length_(_VSTD::distance(__first_, __last_)),
-              __skip_{std::make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)},
-              __suffix_{std::make_shared<vector<difference_type>>(__pattern_length_ + 1)}
-        {
-    //  build the skip table
-        for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
-            __skip_->insert(*__f, __i);
-
-        this->__build_suffix_table ( __first_, __last_, __pred_ );
-        }
-
-    template <typename _RandomAccessIterator2>
-    pair<_RandomAccessIterator2, _RandomAccessIterator2>
-    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
-    {
-        static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
-                                        typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
-                      "Corpus and Pattern iterators must point to the same type");
-
-        if (__f      == __l )    return std::make_pair(__l, __l); // empty corpus
-        if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern
-
-    //  If the pattern is larger than the corpus, we can't find it!
-        if ( __pattern_length_ > _VSTD::distance(__f, __l))
-            return std::make_pair(__l, __l);
-
-    //  Do the search
-        return this->__search(__f, __l);
-    }
-
-private:
-    _RandomAccessIterator1               __first_;
-    _RandomAccessIterator1               __last_;
-    _BinaryPredicate                     __pred_;
-    difference_type                      __pattern_length_;
-    shared_ptr<skip_table_type>          __skip_;
-    shared_ptr<vector<difference_type>>  __suffix_;
-
-    template <typename _RandomAccessIterator2>
-    pair<_RandomAccessIterator2, _RandomAccessIterator2>
-    __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
-    {
-        _RandomAccessIterator2 __cur = __f;
-        const _RandomAccessIterator2 __last = __l - __pattern_length_;
-        const skip_table_type &         __skip   = *__skip_.get();
-        const vector<difference_type> & __suffix = *__suffix_.get();
-
-        while (__cur <= __last)
-        {
-
-        //  Do we match right where we are?
-            difference_type __j = __pattern_length_;
-            while (__pred_(__first_ [__j-1], __cur [__j-1])) {
-                __j--;
-            //  We matched - we're done!
-                if ( __j == 0 )
-                    return std::make_pair(__cur, __cur + __pattern_length_);
-                }
-
-        //  Since we didn't match, figure out how far to skip forward
-            difference_type __k = __skip[__cur [ __j - 1 ]];
-            difference_type __m = __j - __k - 1;
-            if (__k < __j && __m > __suffix[ __j ])
-                __cur += __m;
-            else
-                __cur += __suffix[ __j ];
-        }
-
-        return std::make_pair(__l, __l);     // We didn't find anything
-    }
-
-
-    template<typename _Iterator, typename _Container>
-    void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
-    {
-        const size_t __count = _VSTD::distance(__f, __l);
-
-        __prefix[0] = 0;
-        size_t __k = 0;
-        for ( size_t __i = 1; __i < __count; ++__i )
-        {
-            while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
-                __k = __prefix [ __k - 1 ];
-
-            if ( __pred ( __f[__k], __f[__i] ))
-                __k++;
-            __prefix [ __i ] = __k;
-        }
-    }
-
-    void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
-                                                    _BinaryPredicate __pred)
-    {
-        const size_t __count = _VSTD::distance(__f, __l);
-        vector<difference_type> & __suffix = *__suffix_.get();
-        if (__count > 0)
-        {
-            vector<difference_type> __scratch(__count);
-
-            __compute_bm_prefix(__f, __l, __pred, __scratch);
-            for ( size_t __i = 0; __i <= __count; __i++ )
-                __suffix[__i] = __count - __scratch[__count-1];
-
-            typedef reverse_iterator<_RandomAccessIterator1> _RevIter;
-            __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
-
-            for ( size_t __i = 0; __i < __count; __i++ )
-            {
-                const size_t     __j = __count - __scratch[__i];
-                const difference_type __k = __i     - __scratch[__i] + 1;
-
-                if (__suffix[__j] > __k)
-                    __suffix[__j] = __k;
-            }
-        }
-    }
-
-};
-
-template<class _RandomAccessIterator,
-         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
-         class _BinaryPredicate = equal_to<>>
-_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY
-boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
-make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
-                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
-{
-    return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
-}
-
-// boyer-moore-horspool
-template <class _RandomAccessIterator1,
-          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
-          class _BinaryPredicate = equal_to<>>
-class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
-private:
-    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
-    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
-    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
-                    is_integral<value_type>::value && // what about enums?
-                    sizeof(value_type) == 1 &&
-                    is_same<_Hash, hash<value_type>>::value &&
-                    is_same<_BinaryPredicate, equal_to<>>::value
-            > skip_table_type;
-
-public:
-    boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
-                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
-            : __first_(__f), __last_(__l), __pred_(__pred),
-              __pattern_length_(_VSTD::distance(__first_, __last_)),
-              __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)}
-        {
-    //  build the skip table
-            if ( __f != __l )
-            {
-                __l = __l - 1;
-                for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
-                    __skip_->insert(*__f, __pattern_length_ - 1 - __i);
-            }
-        }
-
-    template <typename _RandomAccessIterator2>
-    pair<_RandomAccessIterator2, _RandomAccessIterator2>
-    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
-    {
-        static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
-                                        typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
-                      "Corpus and Pattern iterators must point to the same type");
-
-        if (__f      == __l )    return std::make_pair(__l, __l); // empty corpus
-        if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern
-
-    //  If the pattern is larger than the corpus, we can't find it!
-        if ( __pattern_length_ > _VSTD::distance(__f, __l))
-            return std::make_pair(__l, __l);
-
-    //  Do the search
-        return this->__search(__f, __l);
-    }
-
-private:
-    _RandomAccessIterator1      __first_;
-    _RandomAccessIterator1      __last_;
-    _BinaryPredicate            __pred_;
-    difference_type             __pattern_length_;
-    shared_ptr<skip_table_type> __skip_;
-
-    template <typename _RandomAccessIterator2>
-    pair<_RandomAccessIterator2, _RandomAccessIterator2>
-    __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const {
-        _RandomAccessIterator2 __cur = __f;
-        const _RandomAccessIterator2 __last = __l - __pattern_length_;
-        const skip_table_type & __skip = *__skip_.get();
-
-        while (__cur <= __last)
-        {
-        //  Do we match right where we are?
-            difference_type __j = __pattern_length_;
-            while (__pred_(__first_[__j-1], __cur[__j-1]))
-            {
-                __j--;
-            //  We matched - we're done!
-                if ( __j == 0 )
-                    return std::make_pair(__cur, __cur + __pattern_length_);
-            }
-            __cur += __skip[__cur[__pattern_length_-1]];
-        }
-
-        return std::make_pair(__l, __l);
-    }
-};
-
-template<class _RandomAccessIterator,
-         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
-         class _BinaryPredicate = equal_to<>>
-_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY
-boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
-make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
-                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
-{
-    return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
-}
-
-#endif // _LIBCPP_STD_VER > 11
-
-_LIBCPP_END_NAMESPACE_LFTS
-
-_LIBCPP_POP_MACROS
-
-#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */
lib/libcxx/include/experimental/iterator
@@ -65,7 +65,7 @@ namespace std {
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 _LIBCPP_BEGIN_NAMESPACE_LFTS
 
@@ -82,15 +82,15 @@ public:
     typedef void                                 pointer;
     typedef void                                 reference;
 
-    ostream_joiner(ostream_type& __os, _Delim&& __d)
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d)
         : __output_iter_(_VSTD::addressof(__os)), __delim_(_VSTD::move(__d)), __first_(true) {}
 
-    ostream_joiner(ostream_type& __os, const _Delim& __d)
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d)
         : __output_iter_(_VSTD::addressof(__os)), __delim_(__d), __first_(true) {}
 
 
     template<typename _Tp>
-    ostream_joiner& operator=(const _Tp& __v)
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v)
     {
         if (!__first_)
             *__output_iter_ << __delim_;
@@ -99,9 +99,9 @@ public:
         return *this;
     }
 
-    ostream_joiner& operator*()     _NOEXCEPT { return *this; }
-    ostream_joiner& operator++()    _NOEXCEPT { return *this; }
-    ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*()     _NOEXCEPT { return *this; }
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++()    _NOEXCEPT { return *this; }
+    _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
 
 private:
     ostream_type*   __output_iter_;
@@ -111,13 +111,13 @@ private:
 
 
 template <class _CharT, class _Traits, class _Delim>
-_LIBCPP_HIDE_FROM_ABI ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>
+_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>
 make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d)
-{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
+{ return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
 
 _LIBCPP_END_NAMESPACE_LFTS
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <type_traits>
lib/libcxx/include/experimental/memory_resource
@@ -66,16 +66,15 @@ namespace pmr {
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__memory/allocator_traits.h>
+#include <__type_traits/aligned_storage.h>
 #include <__utility/move.h>
 #include <cstddef>
-#include <cstdlib>
 #include <experimental/__config>
 #include <experimental/__memory>
 #include <limits>
 #include <new>
 #include <stdexcept>
 #include <tuple>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -96,18 +95,18 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
 inline _LIBCPP_INLINE_VISIBILITY
 size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s + __a > __s, "aligned allocation size overflows");
     return (__s + __a - 1) & ~(__a - 1);
 }
 
 // 8.5, memory.resource
-class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_TYPE_VIS memory_resource
+class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_EXPORTED_FROM_ABI memory_resource
 {
     static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
 
 // 8.5.2, memory.resource.public
 public:
-    virtual ~memory_resource() = default;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~memory_resource() = default;
 
     _LIBCPP_INLINE_VISIBILITY
     void* allocate(size_t __bytes, size_t __align = __max_align)
@@ -143,16 +142,16 @@ bool operator!=(memory_resource const & __lhs,
     return !(__lhs == __rhs);
 }
 
-_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_FUNC_VIS
+_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_EXPORTED_FROM_ABI
 memory_resource * new_delete_resource() _NOEXCEPT;
 
-_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_FUNC_VIS
+_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_EXPORTED_FROM_ABI
 memory_resource * null_memory_resource() _NOEXCEPT;
 
-_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_FUNC_VIS
+_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_EXPORTED_FROM_ABI
 memory_resource * get_default_resource() _NOEXCEPT;
 
-_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_FUNC_VIS
+_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_EXPORTED_FROM_ABI
 memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT;
 
 // 8.6, memory.polymorphic.allocator.class
@@ -175,7 +174,7 @@ public:
       : __res_(__r)
     {}
 
-    polymorphic_allocator(polymorphic_allocator const &) = default;
+    _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(polymorphic_allocator const &) = default;
 
     template <class _Tp>
     _LIBCPP_INLINE_VISIBILITY
@@ -198,8 +197,8 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY
     void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
-        _LIBCPP_ASSERT(__n <= __max_size(),
-                       "deallocate called for size which exceeds max_size()");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(),
+                                     "deallocate called for size which exceeds max_size()");
         __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
     }
 
@@ -363,9 +362,9 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
 public:
     typedef _CharAlloc allocator_type;
 
-    __resource_adaptor_imp() = default;
-    __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
-    __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
+    _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp() = default;
+    _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
+    _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
 
     // 8.7.2, memory.resource.adaptor.ctor
 
@@ -379,7 +378,7 @@ public:
       : __alloc_(_VSTD::move(__a))
     {}
 
-    __resource_adaptor_imp &
+    _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp &
     operator=(__resource_adaptor_imp const &) = default;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -388,7 +387,7 @@ public:
 
 // 8.7.3, memory.resource.adaptor.mem
 private:
-    void * do_allocate(size_t __bytes, size_t) override
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void * do_allocate(size_t __bytes, size_t) override
     {
         if (__bytes > __max_size())
             __throw_bad_array_new_length();
@@ -396,15 +395,15 @@ private:
         return __alloc_.allocate(__s);
     }
 
-    void do_deallocate(void * __p, size_t __bytes, size_t) override
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void * __p, size_t __bytes, size_t) override
     {
-        _LIBCPP_ASSERT(__bytes <= __max_size(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__bytes <= __max_size(),
             "do_deallocate called for size which exceeds the maximum allocation size");
         size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
         __alloc_.deallocate((_ValueType*)__p, __s);
     }
 
-    bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
         __resource_adaptor_imp const * __p
           = dynamic_cast<__resource_adaptor_imp const *>(&__other);
         return __p  ? __alloc_ == __p->__alloc_ : false;
@@ -432,11 +431,13 @@ _LIBCPP_POP_MACROS
 #  include <atomic>
 #  include <climits>
 #  include <concepts>
+#  include <cstdlib>
 #  include <cstring>
 #  include <ctime>
 #  include <iterator>
 #  include <memory>
 #  include <ratio>
+#  include <type_traits>
 #  include <variant>
 #endif
 
lib/libcxx/include/experimental/propagate_const
@@ -110,17 +110,35 @@
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__functional/operations.h>
 #include <__fwd/hash.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
+#include <cstddef>
 #include <experimental/__config>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 11
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 14
 
 _LIBCPP_BEGIN_NAMESPACE_LFTS_V2
 
@@ -152,25 +170,25 @@ public:
 
 private:
   template <class _Up>
-  static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
   {
     return __u;
   }
 
   template <class _Up>
-  static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
   {
     return __get_pointer(__u.get());
   }
 
   template <class _Up>
-  static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
   {
     return __u;
   }
 
   template <class _Up>
-  static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
   {
     return __get_pointer(__u.get());
   }
@@ -192,22 +210,22 @@ public:
   template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
   template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
 
-  _LIBCPP_CONSTEXPR propagate_const() = default;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default;
 
   propagate_const(const propagate_const&) = delete;
 
-  _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
 
   template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
                                  is_constructible<_Tp, _Up&&>::value,bool> = true>
-  explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
+  explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
       : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
   {
   }
 
   template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
                                  is_constructible<_Tp, _Up&&>::value,bool> = false>
-  _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
       : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
   {
   }
@@ -215,7 +233,7 @@ public:
   template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
                                  is_constructible<_Tp, _Up&&>::value &&
                                  !__is_propagate_const<decay_t<_Up>>::value,bool> = true>
-  explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
+  explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
       : __t_(std::forward<_Up>(__u))
   {
   }
@@ -223,78 +241,78 @@ public:
   template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
                                  is_constructible<_Tp, _Up&&>::value &&
                                  !__is_propagate_const<decay_t<_Up>>::value,bool> = false>
-  _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
       : __t_(std::forward<_Up>(__u))
   {
   }
 
   propagate_const& operator=(const propagate_const&) = delete;
 
-  _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
 
   template <class _Up>
-  _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
   {
     __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
     return *this;
   }
 
   template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
-  _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
   {
     __t_ = std::forward<_Up>(__u);
     return *this;
   }
 
-  _LIBCPP_CONSTEXPR const element_type* get() const
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const
   {
     return __get_pointer(__t_);
   }
 
-  _LIBCPP_CONSTEXPR element_type* get()
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get()
   {
     return __get_pointer(__t_);
   }
 
-  explicit _LIBCPP_CONSTEXPR operator bool() const
+  _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const
   {
     return get() != nullptr;
   }
 
-  _LIBCPP_CONSTEXPR const element_type* operator->() const
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const
   {
     return get();
   }
 
-  template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible<
-                                  const _Tp_, const element_type *>::value>>
-  _LIBCPP_CONSTEXPR operator const element_type *() const {
+  template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible<
+                                  const _Dummy, const element_type *>::value>>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const {
     return get();
   }
 
-  _LIBCPP_CONSTEXPR const element_type& operator*() const
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const
   {
     return *get();
   }
 
-  _LIBCPP_CONSTEXPR element_type* operator->()
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->()
   {
     return get();
   }
 
-  template <class _Tp_ = _Tp, class _Up = enable_if_t<
-                                  is_convertible<_Tp_, element_type *>::value>>
-  _LIBCPP_CONSTEXPR operator element_type *() {
+  template <class _Dummy = _Tp, class _Up = enable_if_t<
+                                  is_convertible<_Dummy, element_type *>::value>>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() {
     return get();
   }
 
-  _LIBCPP_CONSTEXPR element_type& operator*()
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*()
   {
     return *get();
   }
 
-  _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
-  {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt)
+      _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
     using _VSTD::swap;
     swap(__t_, __pt.__t_);
   }
@@ -491,7 +509,7 @@ struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef size_t result_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
 
-  size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
   {
     return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
   }
@@ -503,7 +521,7 @@ struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -516,7 +534,7 @@ struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -529,7 +547,7 @@ struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -542,7 +560,7 @@ struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -555,7 +573,7 @@ struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -568,7 +586,7 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
 
-  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
   {
     return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
@@ -577,5 +595,12 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
+
+_LIBCPP_POP_MACROS
+
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <type_traits>
+#endif
+
 #endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
lib/libcxx/include/experimental/simd
@@ -691,8 +691,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
   friend struct simd_mask;
 
 public:
-  _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
-  void __set(size_t __index, _Tp __val) noexcept {
+  _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
+  _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
     __storage_[__index] = __val;
   }
 };
@@ -708,8 +708,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
   friend struct simd_mask;
 
 public:
-  _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }
-  void __set(size_t __index, _Tp __val) noexcept {
+  _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }
+  _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
     (&__storage_)[__index] = __val;
   }
 };
@@ -810,8 +810,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
   friend struct simd_mask;
 
 public:
-  _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
-  void __set(size_t __index, _Tp __val) noexcept {
+  _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
+  _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
     __storage_[__index] = __val;
   }
 };
@@ -831,79 +831,79 @@ class __simd_reference {
   __simd_storage<_Tp, _Abi>* __ptr_;
   size_t __index_;
 
-  __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
+  _LIBCPP_HIDE_FROM_ABI __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
       : __ptr_(__ptr), __index_(__index) {}
 
-  __simd_reference(const __simd_reference&) = default;
+  _LIBCPP_HIDE_FROM_ABI __simd_reference(const __simd_reference&) = default;
 
 public:
   __simd_reference() = delete;
   __simd_reference& operator=(const __simd_reference&) = delete;
 
-  operator _Vp() const { return __ptr_->__get(__index_); }
+  _LIBCPP_HIDE_FROM_ABI operator _Vp() const { return __ptr_->__get(__index_); }
 
-  __simd_reference operator=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Vp __value) && {
     __ptr_->__set(__index_, __value);
     return *this;
   }
 
-  __simd_reference operator++() && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator++() && {
     return std::move(*this) = __ptr_->__get(__index_) + 1;
   }
 
-  _Vp operator++(int) && {
+  _LIBCPP_HIDE_FROM_ABI _Vp operator++(int) && {
     auto __val = __ptr_->__get(__index_);
     __ptr_->__set(__index_, __val + 1);
     return __val;
   }
 
-  __simd_reference operator--() && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator--() && {
     return std::move(*this) = __ptr_->__get(__index_) - 1;
   }
 
-  _Vp operator--(int) && {
+  _LIBCPP_HIDE_FROM_ABI _Vp operator--(int) && {
     auto __val = __ptr_->__get(__index_);
     __ptr_->__set(__index_, __val - 1);
     return __val;
   }
 
-  __simd_reference operator+=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator+=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) + __value;
   }
 
-  __simd_reference operator-=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator-=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) - __value;
   }
 
-  __simd_reference operator*=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator*=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) * __value;
   }
 
-  __simd_reference operator/=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator/=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) / __value;
   }
 
-  __simd_reference operator%=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator%=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) % __value;
   }
 
-  __simd_reference operator>>=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator>>=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) >> __value;
   }
 
-  __simd_reference operator<<=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator<<=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) << __value;
   }
 
-  __simd_reference operator&=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator&=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) & __value;
   }
 
-  __simd_reference operator|=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator|=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) | __value;
   }
 
-  __simd_reference operator^=(_Vp __value) && {
+  _LIBCPP_HIDE_FROM_ABI __simd_reference operator^=(_Vp __value) && {
     return std::move(*this) = __ptr_->__get(__index_) ^ __value;
   }
 };
@@ -1350,11 +1350,11 @@ public:
   using mask_type = simd_mask<_Tp, _Abi>;
   using abi_type = _Abi;
 
-  simd() = default;
-  simd(const simd&) = default;
-  simd& operator=(const simd&) = default;
+  _LIBCPP_HIDE_FROM_ABI simd() = default;
+  _LIBCPP_HIDE_FROM_ABI simd(const simd&) = default;
+  _LIBCPP_HIDE_FROM_ABI simd& operator=(const simd&) = default;
 
-  static constexpr size_t size() noexcept {
+  static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept {
     return simd_size<_Tp, _Abi>::value;
   }
 
@@ -1362,7 +1362,7 @@ private:
   __simd_storage<_Tp, _Abi> __s_;
 
   template <class _Up>
-  static constexpr bool __can_broadcast() {
+  static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_broadcast() {
     return (std::is_arithmetic<_Up>::value &&
             __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) ||
            (!std::is_arithmetic<_Up>::value &&
@@ -1374,7 +1374,7 @@ private:
   }
 
   template <class _Generator, size_t... __indicies>
-  static constexpr decltype(
+  static _LIBCPP_HIDE_FROM_ABI constexpr decltype(
       std::forward_as_tuple(std::declval<_Generator>()(
           std::integral_constant<size_t, __indicies>())...),
       bool())
@@ -1385,12 +1385,12 @@ private:
   }
 
   template <class _Generator>
-  static bool __can_generate(...) {
+  static _LIBCPP_HIDE_FROM_ABI bool __can_generate(...) {
     return false;
   }
 
   template <class _Generator, size_t... __indicies>
-  void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
+  _LIBCPP_HIDE_FROM_ABI void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
     int __not_used[]{((*this)[__indicies] =
                           __g(std::integral_constant<size_t, __indicies>()),
                       0)...};
@@ -1403,7 +1403,7 @@ public:
             class = typename std::enable_if<
                 std::is_same<_Abi, simd_abi::fixed_size<size()>>::value &&
                 __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type>
-  simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
+  _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
     for (size_t __i = 0; __i < size(); __i++) {
       (*this)[__i] = static_cast<_Tp>(__v[__i]);
     }
@@ -1412,7 +1412,7 @@ public:
   // implicit broadcast constructor
   template <class _Up,
             class = typename std::enable_if<__can_broadcast<_Up>()>::type>
-  simd(_Up&& __rv) {
+  _LIBCPP_HIDE_FROM_ABI simd(_Up&& __rv) {
     auto __v = static_cast<_Tp>(__rv);
     for (size_t __i = 0; __i < size(); __i++) {
       (*this)[__i] = __v;
@@ -1424,7 +1424,7 @@ public:
             int = typename std::enable_if<
                 __can_generate<_Generator>(std::make_index_sequence<size()>()),
                 int>::type()>
-  explicit simd(_Generator&& __g) {
+  explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) {
     __generator_init(std::forward<_Generator>(__g),
                      std::make_index_sequence<size()>());
   }
@@ -1434,7 +1434,7 @@ public:
       class _Up, class _Flags,
       class = typename std::enable_if<__vectorizable<_Up>()>::type,
       class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
-  simd(const _Up* __buffer, _Flags) {
+  _LIBCPP_HIDE_FROM_ABI simd(const _Up* __buffer, _Flags) {
     // TODO: optimize for overaligned flags
     for (size_t __i = 0; __i < size(); __i++) {
       (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
@@ -1445,7 +1445,7 @@ public:
   template <class _Up, class _Flags>
   typename std::enable_if<__vectorizable<_Up>() &&
                           is_simd_flag_type<_Flags>::value>::type
-  copy_from(const _Up* __buffer, _Flags) {
+  _LIBCPP_HIDE_FROM_ABI copy_from(const _Up* __buffer, _Flags) {
     *this = simd(__buffer, _Flags());
   }
 
@@ -1453,7 +1453,7 @@ public:
   template <class _Up, class _Flags>
   typename std::enable_if<__vectorizable<_Up>() &&
                           is_simd_flag_type<_Flags>::value>::type
-  copy_to(_Up* __buffer, _Flags) const {
+  _LIBCPP_HIDE_FROM_ABI copy_to(_Up* __buffer, _Flags) const {
     // TODO: optimize for overaligned flags
     for (size_t __i = 0; __i < size(); __i++) {
       __buffer[__i] = static_cast<_Up>((*this)[__i]);
@@ -1461,9 +1461,9 @@ public:
   }
 
   // scalar access [simd.subscr]
-  reference operator[](size_t __i) { return reference(&__s_, __i); }
+  _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) { return reference(&__s_, __i); }
 
-  value_type operator[](size_t __i) const { return __s_.__get(__i); }
+  _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const { return __s_.__get(__i); }
 
   // unary operators [simd.unary]
   simd& operator++();
@@ -1526,7 +1526,7 @@ public:
   using simd_type = simd<_Tp, _Abi>;
   using abi_type = _Abi;
   static constexpr size_t size() noexcept;
-  simd_mask() = default;
+  _LIBCPP_HIDE_FROM_ABI simd_mask() = default;
 
   // broadcast constructor
   explicit simd_mask(value_type) noexcept;
lib/libcxx/include/experimental/type_traits
@@ -71,7 +71,7 @@ inline namespace fundamentals_v1 {
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 #include <initializer_list>
 #include <type_traits>
@@ -132,24 +132,24 @@ template <template<class...> class _Op, class... _Args>
 template <template<class...> class _Op, class... _Args>
   _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value;
 
-template <class Default, template<class...> class _Op, class... _Args>
-  using detected_or = _DETECTOR<Default, void, _Op, _Args...>;
-template <class Default, template<class...> class _Op, class... _Args>
-  using detected_or_t = typename detected_or<Default, _Op, _Args...>::type;
+template <class _Default, template<class...> class _Op, class... _Args>
+  using detected_or = _DETECTOR<_Default, void, _Op, _Args...>;
+template <class _Default, template<class...> class _Op, class... _Args>
+  using detected_or_t = typename detected_or<_Default, _Op, _Args...>::type;
 
-template <class Expected, template<class...> class _Op, class... _Args>
-  using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>;
-template <class Expected, template<class...> class _Op, class... _Args>
-  _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value;
+template <class _Expected, template<class...> class _Op, class... _Args>
+  using is_detected_exact = is_same<_Expected, detected_t<_Op, _Args...>>;
+template <class _Expected, template<class...> class _Op, class... _Args>
+  _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<_Expected, _Op, _Args...>::value;
 
-template <class To, template<class...> class _Op, class... _Args>
-  using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>;
-template <class To, template<class...> class _Op, class... _Args>
-  _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value;
+template <class _To, template<class...> class _Op, class... _Args>
+  using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, _To>;
+template <class _To, template<class...> class _Op, class... _Args>
+  _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<_To, _Op, _Args...>::value;
 
 
 _LIBCPP_END_NAMESPACE_LFTS
 
-#endif /* _LIBCPP_STD_VER > 11 */
+#endif /* _LIBCPP_STD_VER >= 14 */
 
 #endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */
lib/libcxx/include/ext/hash_map
@@ -208,7 +208,6 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 #include <ext/__hash>
 #include <functional>
 #include <stdexcept>
-#include <type_traits>
 
 #if defined(__DEPRECATED) && __DEPRECATED
 #if defined(_LIBCPP_WARNING)
@@ -324,7 +323,7 @@ public:
     bool __first_constructed;
     bool __second_constructed;
 
-    __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
+    _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
     __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -508,23 +507,23 @@ public:
     typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
 
     _LIBCPP_INLINE_VISIBILITY hash_map() { }
-    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
-    hash_map(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf,
                   const key_equal& __eql,
                   const allocator_type& __a);
     template <class _InputIterator>
-        hash_map(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        hash_map(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        hash_map(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf,
                       const key_equal& __eql,
                       const allocator_type& __a);
-    hash_map(const hash_map& __u);
+    _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const
@@ -588,7 +587,7 @@ public:
     std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
         {return __table_.__equal_range_unique(__k);}
 
-    mapped_type& operator[](const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
 
     _LIBCPP_INLINE_VISIBILITY
     size_type bucket_count() const {return __table_.bucket_count();}
@@ -603,7 +602,7 @@ public:
     void resize(size_type __n) {__table_.__rehash_unique(__n);}
 
 private:
-    __node_holder __construct_node(const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k);
 };
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -780,23 +779,23 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY
     hash_multimap() { }
-    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
-    hash_multimap(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf,
                                 const key_equal& __eql,
                                 const allocator_type& __a);
     template <class _InputIterator>
-        hash_multimap(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        hash_multimap(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        hash_multimap(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf,
                       const key_equal& __eql,
                       const allocator_type& __a);
-    hash_multimap(const hash_multimap& __u);
+    _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const
@@ -985,6 +984,7 @@ operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_HASH_MAP
lib/libcxx/include/ext/hash_set
@@ -244,21 +244,21 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY
     hash_set() { }
-    explicit hash_set(size_type __n, const hasher& __hf = hasher(),
+    _LIBCPP_HIDE_FROM_ABI explicit hash_set(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
-    hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+    _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
     template <class _InputIterator>
-        hash_set(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        hash_set(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        hash_set(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf, const key_equal& __eql,
                       const allocator_type& __a);
-    hash_set(const hash_set& __u);
+    _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const
@@ -465,21 +465,21 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY
     hash_multiset() { }
-    explicit hash_multiset(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
-    hash_multiset(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf,
                        const key_equal& __eql, const allocator_type& __a);
     template <class _InputIterator>
-        hash_multiset(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        hash_multiset(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        hash_multiset(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
                       size_type __n , const hasher& __hf,
                       const key_equal& __eql, const allocator_type& __a);
-    hash_multiset(const hash_multiset& __u);
+    _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const
@@ -665,6 +665,7 @@ operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_HASH_SET
lib/libcxx/include/__assert
@@ -17,39 +17,21 @@
 #  pragma GCC system_header
 #endif
 
-// TODO: Remove in LLVM 17.
-#if defined(_LIBCPP_DEBUG)
-#   error "Defining _LIBCPP_DEBUG is not supported anymore. Please use _LIBCPP_ENABLE_DEBUG_MODE instead."
-#endif
-
-// Automatically enable assertions when the debug mode is enabled.
-#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
-# ifndef _LIBCPP_ENABLE_ASSERTIONS
-#   define _LIBCPP_ENABLE_ASSERTIONS 1
-# endif
-#endif
-
-#ifndef _LIBCPP_ENABLE_ASSERTIONS
-# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
-#endif
-
-#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
-# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
-#endif
-
-#if _LIBCPP_ENABLE_ASSERTIONS
-# define _LIBCPP_ASSERT(expression, message)                                        \
-    (__builtin_expect(static_cast<bool>(expression), 1) ?                           \
-      (void)0 :                                                                     \
-      _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
-#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
-# define _LIBCPP_ASSERT(expression, message)                                        \
-    (_LIBCPP_DIAGNOSTIC_PUSH                                                        \
-    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume")                                    \
-    __builtin_assume(static_cast<bool>(expression))                                 \
-    _LIBCPP_DIAGNOSTIC_POP)
+#define _LIBCPP_ASSERT(expression, message)                                                                            \
+  (__builtin_expect(static_cast<bool>(expression), 1)                                                                  \
+       ? (void)0                                                                                                       \
+       : _LIBCPP_VERBOSE_ABORT(                                                                                        \
+             "%s:%d: assertion %s failed: %s\n", __builtin_FILE(), __builtin_LINE(), #expression, message))
+
+// TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add
+//       assumptions without a clear optimization intent, disable that to avoid worsening the code generation.
+//       See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion.
+#if 0 && __has_builtin(__builtin_assume)
+#  define _LIBCPP_ASSUME(expression)                                                                                   \
+    (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume")                                              \
+         __builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP)
 #else
-# define _LIBCPP_ASSERT(expression, message) ((void)0)
+#  define _LIBCPP_ASSUME(expression) ((void)0)
 #endif
 
 #endif // _LIBCPP___ASSERT
lib/libcxx/include/__availability
@@ -39,17 +39,23 @@
 //
 // This mechanism is general in nature, and any vendor can add their markup to
 // the library (see below). Whenever a new feature is added that requires support
-// in the shared library, a macro should be added below to mark this feature
-// as unavailable. When vendors decide to ship the feature as part of their
-// shared library, they can update the markup appropriately.
+// in the shared library, two macros are added below to allow marking the feature
+// as unavailable:
+// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` which must be defined
+//    exactly when compiling for a target that doesn't support the feature.
+// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must always be defined
+//    and must expand to the proper availability attribute for the platform.
+//
+// When vendors decide to ship the feature as part of their shared library, they
+// can update these macros appropriately for their platform, and the library will
+// use those to provide an optimal user experience.
 //
 // Furthermore, many features in the standard library have corresponding
-// feature-test macros. When a feature is made unavailable on some deployment
-// target, a macro should be defined to signal that it is unavailable. That
-// macro can then be picked up when feature-test macros are generated (see
-// generate_feature_test_macro_components.py) to make sure that feature-test
-// macros don't announce a feature as being implemented if it has been marked
-// as unavailable.
+// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` macros
+// are checked by the corresponding feature-test macros generated by
+// generate_feature_test_macro_components.py to ensure that the library
+// doesn't announce a feature as being implemented if it is unavailable on
+// the deployment target.
 //
 // Note that this mechanism is disabled by default in the "upstream" libc++.
 // Availability annotations are only meaningful when shipping libc++ inside
@@ -83,9 +89,8 @@
 
     // This controls the availability of std::shared_mutex and std::shared_timed_mutex,
     // which were added to the dylib later.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX
 #   define _LIBCPP_AVAILABILITY_SHARED_MUTEX
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
 
     // These macros control the availability of std::bad_optional_access and
     // other exception types. These were put in the shared library to prevent
@@ -95,16 +100,23 @@
     // Note that when exceptions are disabled, the methods that normally throw
     // these exceptions can be used even on older deployment targets, but those
     // methods will abort instead of throwing.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS
 #   define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS
 #   define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
+
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST
 #   define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
 
     // This controls the availability of std::uncaught_exceptions().
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS
 #   define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
 
     // This controls the availability of the sized version of ::operator delete,
     // ::operator delete[], and their align_val_t variants, which were all added
     // in C++17, and hence not present in early dylibs.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE
 #   define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
 
     // This controls the availability of the std::future_error exception.
@@ -112,73 +124,83 @@
     // Note that when exceptions are disabled, the methods that normally throw
     // std::future_error can be used even on older deployment targets, but those
     // methods will abort instead of throwing.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR
 #   define _LIBCPP_AVAILABILITY_FUTURE_ERROR
 
     // This controls the availability of std::type_info's vtable.
     // I can't imagine how using std::type_info can work at all if
     // this isn't supported.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE
 #   define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
 
     // This controls the availability of std::locale::category members
     // (e.g. std::locale::collate), which are defined in the dylib.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY
 #   define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
 
     // This controls the availability of atomic operations on std::shared_ptr
     // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared
     // lock table located in the dylib.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR
 #   define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
 
     // These macros control the availability of all parts of <filesystem> that
     // depend on something in the dylib.
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
 
     // This controls the availability of floating-point std::to_chars functions.
     // These overloads were added later than the integer overloads.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
 #   define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
 
     // This controls the availability of the C++20 synchronization library,
     // which requires shared library support for various operations
     // (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
     // <semaphore>, and notification functions on std::atomic.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_SYNC
 #   define _LIBCPP_AVAILABILITY_SYNC
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
-
-    // This controls the availability of the C++20 format library.
-    // The library is in development and not ABI stable yet. P2216 is
-    // retroactively accepted in C++20. This paper contains ABI breaking
-    // changes.
-#   define _LIBCPP_AVAILABILITY_FORMAT
-// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
 
     // This controls whether the library claims to provide a default verbose
     // termination function, and consequently whether the headers will try
     // to use it when the mechanism isn't overriden at compile-time.
-// #   define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
+#   define _LIBCPP_AVAILABILITY_VERBOSE_ABORT
+
+    // This controls the availability of the C++17 std::pmr library,
+    // which is implemented in large part in the built library.
+// #   define _LIBCPP_AVAILABILITY_HAS_NO_PMR
+#   define _LIBCPP_AVAILABILITY_PMR
 
 #elif defined(__APPLE__)
 
-#   define _LIBCPP_AVAILABILITY_SHARED_MUTEX                                    \
-        __attribute__((availability(macos,strict,introduced=10.12)))            \
-        __attribute__((availability(ios,strict,introduced=10.0)))               \
-        __attribute__((availability(tvos,strict,introduced=10.0)))              \
-        __attribute__((availability(watchos,strict,introduced=3.0)))
+    // shared_mutex and shared_timed_mutex
 #   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) ||    \
         (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
         (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) ||         \
         (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
+#       define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX
 #   endif
+#   define _LIBCPP_AVAILABILITY_SHARED_MUTEX                                    \
+        __attribute__((availability(macos,strict,introduced=10.12)))            \
+        __attribute__((availability(ios,strict,introduced=10.0)))               \
+        __attribute__((availability(tvos,strict,introduced=10.0)))              \
+        __attribute__((availability(watchos,strict,introduced=3.0)))
 
+        // bad_optional_access, bad_variant_access and bad_any_cast
         // Note: bad_optional_access & friends were not introduced in the matching
         // macOS and iOS versions, so the version mismatch between macOS and others
         // is intended.
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS
+#       define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS
+#       define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST
+#   endif
 #   define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS                             \
         __attribute__((availability(macos,strict,introduced=10.13)))            \
         __attribute__((availability(ios,strict,introduced=12.0)))               \
@@ -189,78 +211,142 @@
 #   define _LIBCPP_AVAILABILITY_BAD_ANY_CAST                                    \
         _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
 
+    // uncaught_exceptions
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS
+#   endif
 #   define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS                             \
         __attribute__((availability(macos,strict,introduced=10.12)))            \
         __attribute__((availability(ios,strict,introduced=10.0)))               \
         __attribute__((availability(tvos,strict,introduced=10.0)))              \
         __attribute__((availability(watchos,strict,introduced=3.0)))
 
+    // sized operator new and sized operator delete
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE
+#   endif
 #   define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE                                \
         __attribute__((availability(macos,strict,introduced=10.12)))            \
         __attribute__((availability(ios,strict,introduced=10.0)))               \
         __attribute__((availability(tvos,strict,introduced=10.0)))              \
         __attribute__((availability(watchos,strict,introduced=3.0)))
 
+    // future_error
+#   if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 60000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR
+#   endif
 #   define _LIBCPP_AVAILABILITY_FUTURE_ERROR                                    \
         __attribute__((availability(ios,strict,introduced=6.0)))
 
+    // type_info's vtable
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE
+#   endif
 #   define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE                                 \
         __attribute__((availability(macos,strict,introduced=10.9)))             \
         __attribute__((availability(ios,strict,introduced=7.0)))
 
+    // locale::category
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY
+#   endif
 #   define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY                                 \
         __attribute__((availability(macos,strict,introduced=10.9)))             \
         __attribute__((availability(ios,strict,introduced=7.0)))
 
+    // atomic operations on shared_ptr
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR
+#   endif
 #   define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR                               \
         __attribute__((availability(macos,strict,introduced=10.9)))             \
         __attribute__((availability(ios,strict,introduced=7.0)))
 
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM                                      \
+    // <filesystem>
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY
+#   endif
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY                              \
         __attribute__((availability(macos,strict,introduced=10.15)))            \
         __attribute__((availability(ios,strict,introduced=13.0)))               \
         __attribute__((availability(tvos,strict,introduced=13.0)))              \
         __attribute__((availability(watchos,strict,introduced=6.0)))
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH                                 \
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH                                 \
         _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
         _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))")    \
         _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))")   \
         _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
-#   define _LIBCPP_AVAILABILITY_FILESYSTEM_POP                                  \
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP                                  \
         _Pragma("clang attribute pop")                                          \
         _Pragma("clang attribute pop")                                          \
         _Pragma("clang attribute pop")                                          \
         _Pragma("clang attribute pop")
-#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) ||    \
-        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
-        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) ||         \
-        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
-#   endif
 
+    // std::to_chars(floating-point)
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
+#   endif
 #   define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT                         \
-        __attribute__((unavailable))
+        __attribute__((availability(macos,strict,introduced=13.3)))             \
+        __attribute__((availability(ios,strict,introduced=16.3)))               \
+        __attribute__((availability(tvos,strict,introduced=16.3)))              \
+        __attribute__((availability(watchos,strict,introduced=9.3)))
 
-#   define _LIBCPP_AVAILABILITY_SYNC                                            \
-        __attribute__((availability(macos,strict,introduced=11.0)))             \
-        __attribute__((availability(ios,strict,introduced=14.0)))               \
-        __attribute__((availability(tvos,strict,introduced=14.0)))              \
-        __attribute__((availability(watchos,strict,introduced=7.0)))
+    // c++20 synchronization library
 #   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) ||    \
         (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
         (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) ||         \
         (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
-#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
+#       define _LIBCPP_AVAILABILITY_HAS_NO_SYNC
 #   endif
+#   define _LIBCPP_AVAILABILITY_SYNC                                            \
+        __attribute__((availability(macos,strict,introduced=11.0)))             \
+        __attribute__((availability(ios,strict,introduced=14.0)))               \
+        __attribute__((availability(tvos,strict,introduced=14.0)))              \
+        __attribute__((availability(watchos,strict,introduced=7.0)))
 
-#   define _LIBCPP_AVAILABILITY_FORMAT                                          \
+    // __libcpp_verbose_abort
+#   if 1 // TODO: Update once this is released
+#       define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
+#   endif
+#   define _LIBCPP_AVAILABILITY_VERBOSE_ABORT                                   \
         __attribute__((unavailable))
-#   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
 
-#   define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+    // std::pmr
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000)
+#       define _LIBCPP_AVAILABILITY_HAS_NO_PMR
+#   endif
+// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed
+//       Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
+//       it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
+//       use availability annotations until that bug has been fixed.
+#  if 0
+#    define _LIBCPP_AVAILABILITY_PMR                                                                                   \
+      __attribute__((availability(macos, strict, introduced = 14.0)))                                                  \
+      __attribute__((availability(ios, strict, introduced = 17.0)))                                                    \
+      __attribute__((availability(tvos, strict, introduced = 17.0)))                                                   \
+      __attribute__((availability(watchos, strict, introduced = 10.0)))
+#  else
+#    define _LIBCPP_AVAILABILITY_PMR
+#  endif
 
 #else
 
@@ -270,10 +356,10 @@
 
 #endif
 
-// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS.
+// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS.
 // Those are defined in terms of the availability attributes above, and
 // should not be vendor-specific.
-#if defined(_LIBCPP_NO_EXCEPTIONS)
+#if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
 #   define _LIBCPP_AVAILABILITY_FUTURE
 #   define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
 #   define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
lib/libcxx/include/__bit_reference
@@ -19,8 +19,9 @@
 #include <__iterator/iterator_traits.h>
 #include <__memory/construct_at.h>
 #include <__memory/pointer_traits.h>
+#include <__type_traits/conditional.h>
+#include <__utility/swap.h>
 #include <cstring>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -75,7 +76,7 @@ public:
         return *this;
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
         if (__x)
             *__seg_ |= __mask_;
@@ -155,6 +156,8 @@ class __bit_const_reference
     friend typename _Cp::__self;
     friend class __bit_iterator<_Cp, true>;
 public:
+    using __container = typename _Cp::__self;
+
     _LIBCPP_INLINE_VISIBILITY
     __bit_const_reference(const __bit_const_reference&) = default;
 
@@ -728,12 +731,12 @@ move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCons
 
 // swap_ranges
 
-template <class __C1, class __C2>
-_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
-__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
-                      __bit_iterator<__C2, false> __result)
+template <class _Cl, class _Cr>
+_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false>
+__swap_ranges_aligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last,
+                      __bit_iterator<_Cr, false> __result)
 {
-    typedef __bit_iterator<__C1, false> _I1;
+    typedef __bit_iterator<_Cl, false> _I1;
     typedef  typename _I1::difference_type difference_type;
     typedef typename _I1::__storage_type __storage_type;
     const int __bits_per_word = _I1::__bits_per_word;
@@ -778,12 +781,12 @@ __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1,
     return __result;
 }
 
-template <class __C1, class __C2>
-_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
-__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
-                        __bit_iterator<__C2, false> __result)
+template <class _Cl, class _Cr>
+_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false>
+__swap_ranges_unaligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last,
+                        __bit_iterator<_Cr, false> __result)
 {
-    typedef __bit_iterator<__C1, false> _I1;
+    typedef __bit_iterator<_Cl, false> _I1;
     typedef  typename _I1::difference_type difference_type;
     typedef typename _I1::__storage_type __storage_type;
     const int __bits_per_word = _I1::__bits_per_word;
@@ -878,11 +881,11 @@ __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1
     return __result;
 }
 
-template <class __C1, class __C2>
+template <class _Cl, class _Cr>
 inline _LIBCPP_INLINE_VISIBILITY
-__bit_iterator<__C2, false>
-swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
-            __bit_iterator<__C2, false> __first2)
+__bit_iterator<_Cr, false>
+swap_ranges(__bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1,
+            __bit_iterator<_Cr, false> __first2)
 {
     if (__first1.__ctz_ == __first2.__ctz_)
         return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2);
@@ -1135,7 +1138,7 @@ private:
 
 public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     : __seg_(nullptr), __ctz_(0)
 #endif
     {}
@@ -1311,15 +1314,15 @@ private:
     friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
                                                     __bit_iterator<_Dp, _IC> __last,
                                                     __bit_iterator<_Dp, false> __result);
-    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
-                                                                                           __bit_iterator<__C1, false>,
-                                                                                           __bit_iterator<__C2, false>);
-    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
-                                                                                             __bit_iterator<__C1, false>,
-                                                                                             __bit_iterator<__C2, false>);
-    template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
-                                                                                 __bit_iterator<__C1, false>,
-                                                                                 __bit_iterator<__C2, false>);
+    template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_aligned(__bit_iterator<_Cl, false>,
+                                                                                           __bit_iterator<_Cl, false>,
+                                                                                           __bit_iterator<_Cr, false>);
+    template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_unaligned(__bit_iterator<_Cl, false>,
+                                                                                             __bit_iterator<_Cl, false>,
+                                                                                             __bit_iterator<_Cr, false>);
+    template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> swap_ranges(__bit_iterator<_Cl, false>,
+                                                                                 __bit_iterator<_Cl, false>,
+                                                                                 __bit_iterator<_Cr, false>);
     template <class _Dp>
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
lib/libcxx/include/__config
@@ -35,10 +35,12 @@
 
 #ifdef __cplusplus
 
+// The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html
+
 // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
-// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is
+// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
 // defined to XXYYZZ.
-#  define _LIBCPP_VERSION 160001
+#  define _LIBCPP_VERSION 170000
 
 #  define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
 #  define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
@@ -51,6 +53,7 @@
 #    define _LIBCPP_FREESTANDING
 #  endif
 
+// NOLINTBEGIN(libcpp-cpp-version-check)
 #  ifndef _LIBCPP_STD_VER
 #    if __cplusplus <= 201103L
 #      define _LIBCPP_STD_VER 11
@@ -60,11 +63,14 @@
 #      define _LIBCPP_STD_VER 17
 #    elif __cplusplus <= 202002L
 #      define _LIBCPP_STD_VER 20
+#    elif __cplusplus <= 202302L
+#      define _LIBCPP_STD_VER 23
 #    else
 // Expected release year of the next C++ standard
-#      define _LIBCPP_STD_VER 23
+#      define _LIBCPP_STD_VER 26
 #    endif
 #  endif // _LIBCPP_STD_VER
+// NOLINTEND(libcpp-cpp-version-check)
 
 #  if defined(__ELF__)
 #    define _LIBCPP_OBJECT_FORMAT_ELF 1
@@ -80,6 +86,8 @@
 // ... add new file formats here ...
 #  endif
 
+// ABI {
+
 #  if _LIBCPP_ABI_VERSION >= 2
 // Change short string representation so that string data starts at offset 0,
 // improving its alignment in some cases.
@@ -165,6 +173,12 @@
 #    if defined(__FreeBSD__)
 #      define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
 #    endif
+// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol
+// in user code (like you get with -fvisibility-inlines-hidden) and then a strong def
+// in the library, so we need to always rely on the library version.
+#    if defined(_AIX)
+#      define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+#    endif
 #  endif
 
 #  if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2
@@ -179,9 +193,137 @@
 #    define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
 #  endif
 
+// Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's
+// within the bounds of the original container and asserts it on every dereference.
+//
+// ABI impact: changes the iterator type of the relevant containers.
+//
+// Supported containers:
+// - `span`;
+// - `string_view`;
+// - `array`.
+// #define _LIBCPP_ABI_BOUNDED_ITERATORS
+
+// } ABI
+
+// HARDENING {
+
+// TODO(hardening): remove this in LLVM 18.
+// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes)
+// equivalent to setting the hardened mode.
+#  ifdef _LIBCPP_ENABLE_ASSERTIONS
+#    warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_HARDENED_MODE instead."
+#    if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
+#      error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
+#    endif
+#    if _LIBCPP_ENABLE_ASSERTIONS
+#      define _LIBCPP_ENABLE_HARDENED_MODE 1
+#    endif
+#  endif
+
+// Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes
+// security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with
+// `_LIBCPP_ENABLE_DEBUG_MODE`.
+//
+// #define _LIBCPP_ENABLE_HARDENED_MODE 1
+
+// Enables the debug mode which contains all the checks from the hardened mode and additionally more expensive checks
+// that may affect the complexity of algorithms. The debug mode is intended to be used for testing, not in production.
+// Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE`.
+//
+// #define _LIBCPP_ENABLE_DEBUG_MODE 1
+
+// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
+// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
+//
+// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
+//   a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
+//   - the sentinel is reachable from the begin iterator;
+//   - TODO(hardening): both iterators refer to the same container.
+//
+// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
+//   the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
+//   a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
+//   `optional` and `function` are considered one-element containers for the purposes of this check.
+//
+// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
+//   given ranges do not overlap.
+//
+// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
+//   the containers have compatible allocators.
+//
+// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
+//   user input.
+//
+// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
+
+#  ifndef _LIBCPP_ENABLE_HARDENED_MODE
+#    define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
+#  endif
+#  if _LIBCPP_ENABLE_HARDENED_MODE != 0 && _LIBCPP_ENABLE_HARDENED_MODE != 1
+#    error "_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1."
+#  endif
+
+#  ifndef _LIBCPP_ENABLE_DEBUG_MODE
+#    define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT
+#  endif
+#  if _LIBCPP_ENABLE_DEBUG_MODE != 0 && _LIBCPP_ENABLE_DEBUG_MODE != 1
+#    error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1."
+#  endif
+
+#  if _LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE
+#    error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled."
+#  endif
+
+// Hardened mode checks.
+
+// clang-format off
+#  if _LIBCPP_ENABLE_HARDENED_MODE
+
+// Enabled checks.
+#    define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message)        _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message)     _LIBCPP_ASSERT(expression, message)
+// Disabled checks.
+// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
+// vulnerability.
+#    define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message)   _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message)     _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_INTERNAL(expression, message)                 _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)            _LIBCPP_ASSUME(expression)
+
+// Debug mode checks.
+
+#  elif _LIBCPP_ENABLE_DEBUG_MODE
+
+// All checks enabled.
+#    define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message)         _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message)      _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message)    _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message)      _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSERT(expression, message)
+#    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSERT(expression, message)
+
+// Disable all checks if hardening is not enabled.
+
+#  else
+
+// All checks disabled.
+#    define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message)         _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message)      _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message)    _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message)      _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSUME(expression)
+#    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSUME(expression)
+
+#  endif // _LIBCPP_ENABLE_HARDENED_MODE
+// clang-format on
+
+// } HARDENING
+
 #  define _LIBCPP_TOSTRING2(x) #x
 #  define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
 
+// NOLINTNEXTLINE(libcpp-cpp-version-check)
 #  if __cplusplus < 201103L
 #    define _LIBCPP_CXX03_LANG
 #  endif
@@ -262,7 +404,11 @@
 // Incomplete features get their own specific disabling flags. This makes it
 // easier to grep for target specific flags once the feature is complete.
 #  if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
-#    define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT
+#    define _LIBCPP_HAS_NO_INCOMPLETE_PSTL
+#  endif
+
+#  if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
+#    define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
 #  endif
 
 // Need to detect which libc we're using if we're on Linux.
@@ -300,8 +446,8 @@
 #  endif   // __BYTE_ORDER__
 
 #  ifdef __FreeBSD__
-#    include <sys/endian.h>
 #    include <osreldate.h>
+#    include <sys/endian.h>
 #    if _BYTE_ORDER == _LITTLE_ENDIAN
 #      define _LIBCPP_LITTLE_ENDIAN
 #    else // _BYTE_ORDER == _LITTLE_ENDIAN
@@ -335,15 +481,6 @@
 #    define _LIBCPP_HAS_OPEN_WITH_WCHAR
 #  endif // defined(_WIN32)
 
-#  ifdef __sun__
-#    include <sys/isa_defs.h>
-#    ifdef _LITTLE_ENDIAN
-#      define _LIBCPP_LITTLE_ENDIAN
-#    else
-#      define _LIBCPP_BIG_ENDIAN
-#    endif
-#  endif // __sun__
-
 #  if defined(_AIX) && !defined(__64BIT__)
 // The size of wchar is 2 byte on 32-bit mode on AIX.
 #    define _LIBCPP_SHORT_WCHAR 1
@@ -388,7 +525,7 @@
 //      When this option is used, the token passed to `std::random_device`'s
 //      constructor *must* be "/dev/urandom" -- anything else is an error.
 #  if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||                     \
-      defined(__DragonFly__) || defined(__sun__)
+      defined(__DragonFly__)
 #    define _LIBCPP_USING_ARC4_RANDOM
 #  elif defined(__wasi__) || defined(__EMSCRIPTEN__)
 #    define _LIBCPP_USING_GETENTROPY
@@ -449,15 +586,24 @@ typedef __char32_t char32_t;
 #  endif
 
 #  if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L
-#    define _LIBCPP_NO_EXCEPTIONS
+#    define _LIBCPP_HAS_NO_EXCEPTIONS
 #  endif
 
 #  define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
 
 #  if defined(_LIBCPP_COMPILER_CLANG_BASED)
 
-#    if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
-#      define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+#    if defined(__APPLE__)
+#      if defined(__i386__) || defined(__x86_64__)
+// use old string layout on x86_64 and i386
+#      elif defined(__arm__)
+// use old string layout on arm (which does not include aarch64/arm64), except on watch ABIs
+#        if defined(__ARM_ARCH_7K__) && __ARM_ARCH_7K__ >= 2
+#          define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+#        endif
+#      else
+#        define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+#      endif
 #    endif
 
 // Objective-C++ features (opt-in)
@@ -535,9 +681,6 @@ typedef __char32_t char32_t;
 #      define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
 #    endif
 
-#    define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
-#    define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
-#    define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
 #    define _LIBCPP_HIDDEN
 #    define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
 #    define _LIBCPP_TEMPLATE_VIS
@@ -553,11 +696,8 @@ typedef __char32_t char32_t;
 #    endif
 
 #    define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden")
-#    define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default")
-#    define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default")
 #    define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default")
 #    define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default")
-#    define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default")
 #    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default")
 #    define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
 
@@ -666,7 +806,7 @@ typedef __char32_t char32_t;
 
 _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 
-#  if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 #    define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM                                                                         \
        _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
 #  else
@@ -683,16 +823,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, "")))
 #  endif
 
-#  ifndef __SIZEOF_INT128__
+#  if !defined(__SIZEOF_INT128__) || defined(_MSC_VER)
 #    define _LIBCPP_HAS_NO_INT128
 #  endif
 
-#  ifndef __cpp_consteval
-#    define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR
-#  else
-#    define _LIBCPP_CONSTEVAL consteval
-#  endif
-
 #  if __has_attribute(__malloc__)
 #    define _LIBCPP_NOALIAS __attribute__((__malloc__))
 #  else
@@ -707,7 +841,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 
 #  ifdef _LIBCPP_CXX03_LANG
 #    define _LIBCPP_DECLARE_STRONG_ENUM(x)                                                                             \
-      struct _LIBCPP_TYPE_VIS x {                                                                                      \
+      struct _LIBCPP_EXPORTED_FROM_ABI x {                                                                             \
         enum __lx
 // clang-format off
 #    define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)                                                                      \
@@ -723,8 +857,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
 #  endif // _LIBCPP_CXX03_LANG
 
-#  if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) ||                \
-      defined(__NetBSD__)
+#  if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__NetBSD__)
 #    define _LIBCPP_LOCALE__L_EXTENSIONS 1
 #  endif
 
@@ -764,7 +897,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_HAS_DEFAULTRUNELOCALE
 #  endif
 
-#  if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)
+#  if defined(__APPLE__) || defined(__FreeBSD__)
 #    define _LIBCPP_WCTYPE_IS_MASK
 #  endif
 
@@ -777,10 +910,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 // Deprecations warnings are always enabled, except when users explicitly opt-out
 // by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS.
 #  if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-#    if __has_attribute(deprecated)
-#      define _LIBCPP_DEPRECATED __attribute__((deprecated))
-#      define _LIBCPP_DEPRECATED_(m) __attribute__((deprecated(m)))
-#    elif _LIBCPP_STD_VER > 11
+#    if __has_attribute(__deprecated__)
+#      define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
+#      define _LIBCPP_DEPRECATED_(m) __attribute__((__deprecated__(m)))
+#    elif _LIBCPP_STD_VER >= 14
 #      define _LIBCPP_DEPRECATED [[deprecated]]
 #      define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]]
 #    else
@@ -798,29 +931,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_DEPRECATED_IN_CXX11
 #  endif
 
-#  if _LIBCPP_STD_VER > 11
+#  if _LIBCPP_STD_VER >= 14
 #    define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
 #  else
 #    define _LIBCPP_DEPRECATED_IN_CXX14
 #  endif
 
-#  if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 #    define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
 #  else
 #    define _LIBCPP_DEPRECATED_IN_CXX17
 #  endif
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 #    define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED
 #  else
 #    define _LIBCPP_DEPRECATED_IN_CXX20
 #  endif
 
-#if _LIBCPP_STD_VER >= 23
-#  define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
-#else
-#  define _LIBCPP_DEPRECATED_IN_CXX23
-#endif
+#  if _LIBCPP_STD_VER >= 23
+#    define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
+#  else
+#    define _LIBCPP_DEPRECATED_IN_CXX23
+#  endif
 
 #  if !defined(_LIBCPP_HAS_NO_CHAR8_T)
 #    define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
@@ -840,37 +973,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #  endif
 
 #  if _LIBCPP_STD_VER <= 11
-#    define _LIBCPP_EXPLICIT_AFTER_CXX11
+#    define _LIBCPP_EXPLICIT_SINCE_CXX14
+#  else
+#    define _LIBCPP_EXPLICIT_SINCE_CXX14 explicit
+#  endif
+
+#  if _LIBCPP_STD_VER >= 23
+#    define _LIBCPP_EXPLICIT_SINCE_CXX23 explicit
 #  else
-#    define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
+#    define _LIBCPP_EXPLICIT_SINCE_CXX23
 #  endif
 
-#  if _LIBCPP_STD_VER > 11
+#  if _LIBCPP_STD_VER >= 14
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX14 constexpr
 #  else
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX14
 #  endif
 
-#  if _LIBCPP_STD_VER > 14
+#  if _LIBCPP_STD_VER >= 17
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX17 constexpr
 #  else
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX17
 #  endif
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX20 constexpr
 #  else
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX20
 #  endif
 
-#  if _LIBCPP_STD_VER > 20
+#  if _LIBCPP_STD_VER >= 23
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX23 constexpr
 #  else
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX23
 #  endif
 
 #  if __has_cpp_attribute(nodiscard)
-#    define _LIBCPP_NODISCARD [[nodiscard]]
+#    define _LIBCPP_NODISCARD [[__nodiscard__]]
 #  else
 // We can't use GCC's [[gnu::warn_unused_result]] and
 // __attribute__((warn_unused_result)), because GCC does not silence them via
@@ -886,7 +1025,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_NODISCARD_EXT
 #  endif
 
-#  if _LIBCPP_STD_VER > 17 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
+#  if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
 #    define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
 #  else
 #    define _LIBCPP_NODISCARD_AFTER_CXX17
@@ -899,8 +1038,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #  endif
 
 #  ifndef _LIBCPP_HAS_NO_ASAN
-    extern "C" _LIBCPP_FUNC_VIS void
+    extern "C" _LIBCPP_EXPORTED_FROM_ABI void
     __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
+#    if _LIBCPP_CLANG_VER >= 1600
+extern "C" _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container(
+    const void*, const void*, const void*, const void*, const void*, const void*);
+extern "C" _LIBCPP_EXPORTED_FROM_ABI int
+__sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*);
+#    endif
 #  endif
 
 // Try to find out if RTTI is disabled.
@@ -927,7 +1072,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
         defined(__linux__) ||                                                                                          \
         defined(__GNU__) ||                                                                                            \
         defined(__APPLE__) ||                                                                                          \
-        defined(__sun__) ||                                                                                            \
         defined(__MVS__) ||                                                                                            \
         defined(_AIX) ||                                                                                               \
         defined(__EMSCRIPTEN__)
@@ -1034,6 +1178,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 #  endif
 
+#  if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__)
+#    define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__))
+#  else
+#    define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+#  endif
+
 #  if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS)
 #    if defined(__clang__) && __has_attribute(acquire_capability)
 // Work around the attribute handling in clang.  When both __declspec and
@@ -1052,7 +1202,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
 #  endif
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 #    define _LIBCPP_CONSTINIT constinit
 #  elif __has_attribute(__require_constant_initialization__)
 #    define _LIBCPP_CONSTINIT __attribute__((__require_constant_initialization__))
@@ -1099,6 +1249,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_PREFERRED_NAME(x)
 #  endif
 
+#  if __has_attribute(__no_sanitize__)
+#    define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__)))
+#  else
+#    define _LIBCPP_NO_SANITIZE(...)
+#  endif
+
 // We often repeat things just for handling wide characters in the library.
 // When wide characters are disabled, it can be useful to have a quick way of
 // disabling it without having to resort to #if-#endif, which has a larger
@@ -1132,8 +1288,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
 #  endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
 
-#  define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")")
-#  define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")")
+// clang-format off
+#  define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh()\")") _Pragma("push_macro(\"move(int, int)\")") _Pragma("push_macro(\"erase()\")")
+#  define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh()\")") _Pragma("pop_macro(\"move(int, int)\")") _Pragma("pop_macro(\"erase()\")")
+// clang-format on
 
 #  ifndef _LIBCPP_NO_AUTO_LINK
 #    if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
@@ -1189,7 +1347,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 // [[msvc::no_unique_address]], this should be preferred though.
 #    define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
 #  elif __has_cpp_attribute(no_unique_address)
-#    define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]]
+#    define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]]
 #  else
 #    define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */
 // Note that this can be replaced by #error as soon as clang-cl
@@ -1252,13 +1410,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 // macro is used to mark them as such, which suppresses the
 // '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code
 // with these classes.
-#if _LIBCPP_STD_VER >= 17
-#    define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName)                                                                \
-      template <class ..._Tag>                                                                                         \
-      _ClassName(typename _Tag::__allow_ctad...) -> _ClassName<_Tag...>
-#else
-#  define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
-#endif
+#  if _LIBCPP_STD_VER >= 17
+#    ifdef _LIBCPP_COMPILER_CLANG_BASED
+#      define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName)                                                              \
+        template <class... _Tag>                                                                                       \
+        [[maybe_unused]] _ClassName(typename _Tag::__allow_ctad...)->_ClassName<_Tag...>
+#    else
+#      define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(ClassName)                                                               \
+        template <class... _Tag>                                                                                       \
+        ClassName(typename _Tag::__allow_ctad...)->ClassName<_Tag...>
+#    endif
+#  else
+#    define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
+#  endif
 
 // TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use
 // compiler intrinsics in the Objective-C++ mode.
@@ -1266,6 +1430,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
 #  endif
 
+#  define _PSTL_PRAGMA(x) _Pragma(#x)
+
+// Enable SIMD for compilers that support OpenMP 4.0
+#  if (defined(_OPENMP) && _OPENMP >= 201307)
+
+#    define _PSTL_UDR_PRESENT
+#    define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd)
+#    define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd)
+#    define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM))
+#    define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM))
+#    define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM))
+#    define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM))
+
+// Declaration of reduction functor, where
+// NAME - the name of the functor
+// OP - type of the callable object with the reduction operation
+// omp_in - refers to the local partial result
+// omp_out - refers to the final value of the combiner operator
+// omp_priv - refers to the private copy of the initial value
+// omp_orig - refers to the original variable to be reduced
+#    define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP)                                                                   \
+      _PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
+
+#  else // (defined(_OPENMP) && _OPENMP >= 201307)
+
+#    define _PSTL_PRAGMA_SIMD
+#    define _PSTL_PRAGMA_DECLARE_SIMD
+#    define _PSTL_PRAGMA_SIMD_REDUCTION(PRM)
+#    define _PSTL_PRAGMA_SIMD_SCAN(PRM)
+#    define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM)
+#    define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM)
+#    define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP)
+
+#  endif // (defined(_OPENMP) && _OPENMP >= 201307)
+
+#  define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+
 #endif // __cplusplus
 
 #endif // _LIBCPP___CONFIG
lib/libcxx/include/__debug
@@ -1,266 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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___DEBUG
-#define _LIBCPP___DEBUG
-
-#include <__assert>
-#include <__config>
-#include <__type_traits/is_constant_evaluated.h>
-#include <cstddef>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
-#endif
-
-#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING)
-# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
-#endif
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-#   define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m)
-#else
-#   define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
-#endif
-
-#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-struct _LIBCPP_TYPE_VIS __c_node;
-
-struct _LIBCPP_TYPE_VIS __i_node
-{
-    void* __i_;
-    __i_node* __next_;
-    __c_node* __c_;
-
-    __i_node(const __i_node&) = delete;
-    __i_node& operator=(const __i_node&) = delete;
-
-    _LIBCPP_INLINE_VISIBILITY
-    __i_node(void* __i, __i_node* __next, __c_node* __c)
-        : __i_(__i), __next_(__next), __c_(__c) {}
-    ~__i_node();
-};
-
-struct _LIBCPP_TYPE_VIS __c_node
-{
-    void* __c_;
-    __c_node* __next_;
-    __i_node** beg_;
-    __i_node** end_;
-    __i_node** cap_;
-
-    __c_node(const __c_node&) = delete;
-    __c_node& operator=(const __c_node&) = delete;
-
-    _LIBCPP_INLINE_VISIBILITY
-    explicit __c_node(void* __c, __c_node* __next)
-        : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
-    virtual ~__c_node();
-
-    virtual bool __dereferenceable(const void*) const = 0;
-    virtual bool __decrementable(const void*) const = 0;
-    virtual bool __addable(const void*, ptrdiff_t) const = 0;
-    virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;
-
-    void __add(__i_node* __i);
-    _LIBCPP_HIDDEN void __remove(__i_node* __i);
-};
-
-template <class _Cont>
-struct _C_node
-    : public __c_node
-{
-    explicit _C_node(void* __c, __c_node* __n)
-        : __c_node(__c, __n) {}
-
-    bool __dereferenceable(const void*) const override;
-    bool __decrementable(const void*) const override;
-    bool __addable(const void*, ptrdiff_t) const override;
-    bool __subscriptable(const void*, ptrdiff_t) const override;
-};
-
-template <class _Cont>
-inline bool
-_C_node<_Cont>::__dereferenceable(const void* __i) const
-{
-    typedef typename _Cont::const_iterator iterator;
-    const iterator* __j = static_cast<const iterator*>(__i);
-    _Cont* _Cp = static_cast<_Cont*>(__c_);
-    return _Cp->__dereferenceable(__j);
-}
-
-template <class _Cont>
-inline bool
-_C_node<_Cont>::__decrementable(const void* __i) const
-{
-    typedef typename _Cont::const_iterator iterator;
-    const iterator* __j = static_cast<const iterator*>(__i);
-    _Cont* _Cp = static_cast<_Cont*>(__c_);
-    return _Cp->__decrementable(__j);
-}
-
-template <class _Cont>
-inline bool
-_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
-{
-    typedef typename _Cont::const_iterator iterator;
-    const iterator* __j = static_cast<const iterator*>(__i);
-    _Cont* _Cp = static_cast<_Cont*>(__c_);
-    return _Cp->__addable(__j, __n);
-}
-
-template <class _Cont>
-inline bool
-_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
-{
-    typedef typename _Cont::const_iterator iterator;
-    const iterator* __j = static_cast<const iterator*>(__i);
-    _Cont* _Cp = static_cast<_Cont*>(__c_);
-    return _Cp->__subscriptable(__j, __n);
-}
-
-class _LIBCPP_TYPE_VIS __libcpp_db
-{
-    __c_node** __cbeg_;
-    __c_node** __cend_;
-    size_t   __csz_;
-    __i_node** __ibeg_;
-    __i_node** __iend_;
-    size_t   __isz_;
-
-    explicit __libcpp_db();
-public:
-    __libcpp_db(const __libcpp_db&) = delete;
-    __libcpp_db& operator=(const __libcpp_db&) = delete;
-
-    ~__libcpp_db();
-
-    class __db_c_iterator;
-    class __db_c_const_iterator;
-    class __db_i_iterator;
-    class __db_i_const_iterator;
-
-    __db_c_const_iterator __c_end() const;
-    __db_i_const_iterator __i_end() const;
-
-    typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*);
-
-    template <class _Cont>
-    _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) {
-        return ::new (__mem) _C_node<_Cont>(__c, __next);
-    }
-
-    template <class _Cont>
-    _LIBCPP_INLINE_VISIBILITY
-    void __insert_c(_Cont* __c)
-    {
-        __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>);
-    }
-
-    void __insert_i(void* __i);
-    void __insert_c(void* __c, _InsertConstruct* __fn);
-    void __erase_c(void* __c);
-
-    void __insert_ic(void* __i, const void* __c);
-    void __iterator_copy(void* __i, const void* __i0);
-    void __erase_i(void* __i);
-
-    void* __find_c_from_i(void* __i) const;
-    void __invalidate_all(void* __c);
-    __c_node* __find_c_and_lock(void* __c) const;
-    __c_node* __find_c(void* __c) const;
-    void unlock() const;
-
-    void swap(void* __c1, void* __c2);
-
-
-    bool __dereferenceable(const void* __i) const;
-    bool __decrementable(const void* __i) const;
-    bool __addable(const void* __i, ptrdiff_t __n) const;
-    bool __subscriptable(const void* __i, ptrdiff_t __n) const;
-    bool __less_than_comparable(const void* __i, const void* __j) const;
-private:
-    _LIBCPP_HIDDEN
-    __i_node* __insert_iterator(void* __i);
-    _LIBCPP_HIDDEN
-    __i_node* __find_iterator(const void* __i) const;
-
-    friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db();
-};
-
-_LIBCPP_FUNC_VIS __libcpp_db* __get_db();
-_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated())
-        __get_db()->__insert_c(__c);
-#else
-    (void)(__c);
-#endif
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated())
-        __get_db()->__insert_i(__i);
-#else
-    (void)(__i);
-#endif
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated())
-        __get_db()->__erase_c(__c);
-#else
-    (void)(__c);
-#endif
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated())
-        __get_db()->swap(__lhs, __rhs);
-#else
-    (void)(__lhs);
-    (void)(__rhs);
-#endif
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated())
-        __get_db()->__invalidate_all(__c);
-#else
-    (void)(__c);
-#endif
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___DEBUG
lib/libcxx/include/__hash_table
@@ -15,8 +15,8 @@
 #include <__assert>
 #include <__bit/countl.h>
 #include <__config>
-#include <__debug>
 #include <__functional/hash.h>
+#include <__functional/invoke.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/allocator_traits.h>
@@ -25,6 +25,19 @@
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
 #include <__type_traits/can_extract_key.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cvref.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
@@ -32,7 +45,6 @@
 #include <cmath>
 #include <cstring>
 #include <initializer_list>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -59,8 +71,7 @@ struct __is_hash_value_type : false_type {};
 template <class _One>
 struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {};
 
-_LIBCPP_FUNC_VIS
-size_t __next_prime(size_t __n);
+_LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n);
 
 template <class _NodePtr>
 struct __hash_node_base
@@ -296,53 +307,20 @@ public:
     typedef typename _NodeTypes::__node_value_type_pointer pointer;
 
     _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
-        _VSTD::__debug_db_insert_i(this);
     }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_iterator(const __hash_iterator& __i)
-        : __node_(__i.__node_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__hash_iterator()
-    {
-        __get_db()->__erase_i(this);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_iterator& operator=(const __hash_iterator& __i)
-    {
-        if (this != _VSTD::addressof(__i))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-            __node_ = __i.__node_;
-        }
-        return *this;
-    }
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable unordered container iterator");
         return __node_->__upcast()->__value_;
     }
 
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container iterator");
         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_iterator& operator++() {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment a non-incrementable unordered container iterator");
         __node_ = __node_->__next_;
         return *this;
     }
@@ -366,14 +344,11 @@ public:
 
 private:
     _LIBCPP_INLINE_VISIBILITY
-    explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
+    explicit __hash_iterator(__next_pointer __node) _NOEXCEPT
         : __node_(__node)
         {
-            (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-            __get_db()->__insert_ic(this, __c);
-#endif
         }
+
     template <class, class, class, class> friend class __hash_table;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
@@ -402,61 +377,25 @@ public:
 
 
     _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
-        _VSTD::__debug_db_insert_i(this);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
         : __node_(__x.__node_)
     {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
-#endif
     }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_const_iterator(const __hash_const_iterator& __i)
-        : __node_(__i.__node_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__hash_const_iterator()
-    {
-        __get_db()->__erase_i(this);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
-    {
-        if (this != _VSTD::addressof(__i))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-            __node_ = __i.__node_;
-        }
-        return *this;
-    }
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
         return __node_->__upcast()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator& operator++() {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to increment a non-incrementable unordered container const_iterator");
         __node_ = __node_->__next_;
         return *this;
     }
@@ -480,14 +419,11 @@ public:
 
 private:
     _LIBCPP_INLINE_VISIBILITY
-    explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
+    explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT
         : __node_(__node)
         {
-            (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-            __get_db()->__insert_ic(this, __c);
-#endif
         }
+
     template <class, class, class, class> friend class __hash_table;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
@@ -513,57 +449,20 @@ public:
     typedef typename _NodeTypes::__node_value_type_pointer      pointer;
 
     _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
-        _VSTD::__debug_db_insert_i(this);
-    }
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_local_iterator(const __hash_local_iterator& __i)
-        : __node_(__i.__node_),
-          __bucket_(__i.__bucket_),
-          __bucket_count_(__i.__bucket_count_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__hash_local_iterator()
-    {
-        __get_db()->__erase_i(this);
     }
 
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
-    {
-        if (this != _VSTD::addressof(__i))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-            __node_ = __i.__node_;
-            __bucket_ = __i.__bucket_;
-            __bucket_count_ = __i.__bucket_count_;
-        }
-        return *this;
-    }
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
         return __node_->__upcast()->__value_;
     }
 
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable unordered container local_iterator");
         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_local_iterator& operator++() {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment a non-incrementable unordered container local_iterator");
         __node_ = __node_->__next_;
         if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
             __node_ = nullptr;
@@ -590,18 +489,15 @@ public:
 private:
     _LIBCPP_INLINE_VISIBILITY
     explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
-                                   size_t __bucket_count, const void* __c) _NOEXCEPT
+                                   size_t __bucket_count) _NOEXCEPT
         : __node_(__node),
           __bucket_(__bucket),
           __bucket_count_(__bucket_count)
         {
-            (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-            __get_db()->__insert_ic(this, __c);
-#endif
             if (__node_ != nullptr)
                 __node_ = __node_->__next_;
         }
+
     template <class, class, class, class> friend class __hash_table;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
@@ -635,7 +531,6 @@ public:
 
 
     _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
-        _VSTD::__debug_db_insert_i(this);
     }
 
     _LIBCPP_INLINE_VISIBILITY
@@ -644,59 +539,20 @@ public:
           __bucket_(__x.__bucket_),
           __bucket_count_(__x.__bucket_count_)
     {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
-#endif
     }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
-        : __node_(__i.__node_),
-          __bucket_(__i.__bucket_),
-          __bucket_count_(__i.__bucket_count_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__hash_const_local_iterator()
-    {
-        __get_db()->__erase_i(this);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
-    {
-        if (this != _VSTD::addressof(__i))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
-            __node_ = __i.__node_;
-            __bucket_ = __i.__bucket_;
-            __bucket_count_ = __i.__bucket_count_;
-        }
-        return *this;
-    }
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
         return __node_->__upcast()->__value_;
     }
 
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_local_iterator& operator++() {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment a non-incrementable unordered container const_local_iterator");
         __node_ = __node_->__next_;
         if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
             __node_ = nullptr;
@@ -723,18 +579,15 @@ public:
 private:
     _LIBCPP_INLINE_VISIBILITY
     explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
-                                         size_t __bucket_count, const void* __c) _NOEXCEPT
+                                         size_t __bucket_count) _NOEXCEPT
         : __node_(__node_ptr),
           __bucket_(__bucket),
           __bucket_count_(__bucket_count)
         {
-            (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-            __get_db()->__insert_ic(this, __c);
-#endif
             if (__node_ != nullptr)
                 __node_ = __node_->__next_;
         }
+
     template <class, class, class, class> friend class __hash_table;
     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
 };
@@ -803,8 +656,8 @@ private:
 public:
     bool __value_constructed;
 
-    __hash_node_destructor(__hash_node_destructor const&) = default;
-    __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
+    _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default;
+    _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
 
 
     _LIBCPP_INLINE_VISIBILITY
@@ -826,7 +679,7 @@ public:
     template <class> friend class __hash_map_node_destructor;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _NodeType, class _Alloc>
 struct __generic_container_node_destructor;
 
@@ -976,22 +829,22 @@ public:
             is_nothrow_default_constructible<key_equal>::value);
     _LIBCPP_INLINE_VISIBILITY
     __hash_table(const hasher& __hf, const key_equal& __eql);
-    __hash_table(const hasher& __hf, const key_equal& __eql,
+    _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql,
                  const allocator_type& __a);
-    explicit __hash_table(const allocator_type& __a);
-    __hash_table(const __hash_table& __u);
-    __hash_table(const __hash_table& __u, const allocator_type& __a);
-    __hash_table(__hash_table&& __u)
+    _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u);
+    _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);
-    __hash_table(__hash_table&& __u, const allocator_type& __a);
-    ~__hash_table();
+    _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI ~__hash_table();
 
-    __hash_table& operator=(const __hash_table& __u);
+    _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
     _LIBCPP_INLINE_VISIBILITY
     __hash_table& operator=(__hash_table&& __u)
         _NOEXCEPT_(
@@ -1000,9 +853,9 @@ public:
             is_nothrow_move_assignable<hasher>::value &&
             is_nothrow_move_assignable<key_equal>::value);
     template <class _InputIterator>
-        void __assign_unique(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        void __assign_multi(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
 
     _LIBCPP_INLINE_VISIBILITY
     size_type max_size() const _NOEXCEPT
@@ -1121,7 +974,7 @@ public:
         return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
     }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     template <class _NodeHandle, class _InsertReturnType>
     _LIBCPP_INLINE_VISIBILITY
     _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
@@ -1151,7 +1004,7 @@ public:
     _NodeHandle __node_handle_extract(const_iterator __it);
 #endif
 
-    void clear() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
     _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
     _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
@@ -1182,48 +1035,48 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         size_type bucket(const _Key& __k) const
         {
-            _LIBCPP_ASSERT(bucket_count() > 0,
+            _LIBCPP_ASSERT_UNCATEGORIZED(bucket_count() > 0,
                 "unordered container::bucket(key) called when bucket_count() == 0");
             return std::__constrain_hash(hash_function()(__k), bucket_count());
         }
 
     template <class _Key>
-        iterator       find(const _Key& __x);
+    _LIBCPP_HIDE_FROM_ABI iterator       find(const _Key& __x);
     template <class _Key>
-        const_iterator find(const _Key& __x) const;
+    _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const;
 
     typedef __hash_node_destructor<__node_allocator> _Dp;
     typedef unique_ptr<__node, _Dp> __node_holder;
 
-    iterator erase(const_iterator __p);
-    iterator erase(const_iterator __first, const_iterator __last);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
     template <class _Key>
-        size_type __erase_unique(const _Key& __k);
+    _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
     template <class _Key>
-        size_type __erase_multi(const _Key& __k);
-    __node_holder remove(const_iterator __p) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
+    _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
 
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         size_type __count_unique(const _Key& __k) const;
     template <class _Key>
-        size_type __count_multi(const _Key& __k) const;
+    _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
 
     template <class _Key>
-        pair<iterator, iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
         __equal_range_unique(const _Key& __k);
     template <class _Key>
-        pair<const_iterator, const_iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
         __equal_range_unique(const _Key& __k) const;
 
     template <class _Key>
-        pair<iterator, iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
         __equal_range_multi(const _Key& __k);
     template <class _Key>
-        pair<const_iterator, const_iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
         __equal_range_multi(const _Key& __k) const;
 
-    void swap(__hash_table& __u)
+    _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
 #if _LIBCPP_STD_VER <= 11
         _NOEXCEPT_(
             __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
@@ -1239,7 +1092,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type max_bucket_count() const _NOEXCEPT
         {return max_size(); }
-    size_type bucket_size(size_type __n) const;
+    _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
     _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
     {
         size_type __bc = bucket_count();
@@ -1247,7 +1100,7 @@ public:
     }
     _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__mlf > 0,
+        _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0,
             "unordered container::max_load_factor(lf) called with lf <= 0");
         max_load_factor() = _VSTD::max(__mlf, load_factor());
     }
@@ -1256,68 +1109,61 @@ public:
     local_iterator
     begin(size_type __n)
     {
-        _LIBCPP_ASSERT(__n < bucket_count(),
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
             "unordered container::begin(n) called with n >= bucket_count()");
-        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+        return local_iterator(__bucket_list_[__n], __n, bucket_count());
     }
 
     _LIBCPP_INLINE_VISIBILITY
     local_iterator
     end(size_type __n)
     {
-        _LIBCPP_ASSERT(__n < bucket_count(),
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
             "unordered container::end(n) called with n >= bucket_count()");
-        return local_iterator(nullptr, __n, bucket_count(), this);
+        return local_iterator(nullptr, __n, bucket_count());
     }
 
     _LIBCPP_INLINE_VISIBILITY
     const_local_iterator
     cbegin(size_type __n) const
     {
-        _LIBCPP_ASSERT(__n < bucket_count(),
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
             "unordered container::cbegin(n) called with n >= bucket_count()");
-        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+        return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
     }
 
     _LIBCPP_INLINE_VISIBILITY
     const_local_iterator
     cend(size_type __n) const
     {
-        _LIBCPP_ASSERT(__n < bucket_count(),
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
             "unordered container::cend(n) called with n >= bucket_count()");
-        return const_local_iterator(nullptr, __n, bucket_count(), this);
+        return const_local_iterator(nullptr, __n, bucket_count());
     }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const;
-    bool __decrementable(const const_iterator* __i) const;
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 private:
-    template <bool _UniqueKeys> void __rehash(size_type __n);
-    template <bool _UniqueKeys> void __do_rehash(size_type __n);
+    template <bool _UniqueKeys>
+    _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n);
+    template <bool _UniqueKeys>
+    _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n);
 
     template <class ..._Args>
-    __node_holder __construct_node(_Args&& ...__args);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args);
 
     template <class _First, class ..._Rest>
-    __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
 
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __hash_table& __u)
         {__copy_assign_alloc(__u, integral_constant<bool,
              __node_traits::propagate_on_container_copy_assignment::value>());}
-    void __copy_assign_alloc(const __hash_table& __u, true_type);
+    _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type);
     _LIBCPP_INLINE_VISIBILITY
         void __copy_assign_alloc(const __hash_table&, false_type) {}
 
-    void __move_assign(__hash_table& __u, false_type);
-    void __move_assign(__hash_table& __u, true_type)
+    _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 &&
@@ -1343,8 +1189,8 @@ private:
     _LIBCPP_INLINE_VISIBILITY
         void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
 
-    void __deallocate_node(__next_pointer __np) _NOEXCEPT;
-    __next_pointer __detach() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
 
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
@@ -1476,7 +1322,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
 #endif
 
     __deallocate_node(__p1_.first().__next_);
-    std::__debug_db_erase_c(this);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1518,21 +1363,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
     while (__np != nullptr)
     {
         __next_pointer __next = __np->__next_;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __c_node* __c = __get_db()->__find_c_and_lock(this);
-        for (__i_node** __p = __c->end_; __p != __c->beg_; )
-        {
-            --__p;
-            iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__node_ == __np)
-            {
-                (*__p)->__c_ = nullptr;
-                if (--__c->end_ != __p)
-                    _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-            }
-        }
-        __get_db()->unlock();
-#endif
         __node_pointer __real_np = __np->__upcast();
         __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
         __node_traits::deallocate(__na, __real_np, 1);
@@ -1579,7 +1409,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
         __u.__p1_.first().__next_ = nullptr;
         __u.size() = 0;
     }
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1597,10 +1426,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
         if (bucket_count() != 0)
         {
             __next_pointer __cache = __detach();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             try
             {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
                 const_iterator __i = __u.begin();
                 while (__cache != nullptr && __u.size() != 0)
                 {
@@ -1610,14 +1439,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
                     __node_insert_multi(__cache->__upcast());
                     __cache = __next;
                 }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             }
             catch (...)
             {
                 __deallocate_node(__cache);
                 throw;
             }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             __deallocate_node(__cache);
         }
         const_iterator __i = __u.begin();
@@ -1659,10 +1488,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
     if (bucket_count() != 0)
     {
         __next_pointer __cache = __detach();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (; __cache != nullptr && __first != __last; ++__first)
             {
                 __cache->__upcast()->__value_ = *__first;
@@ -1670,14 +1499,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
                 __node_insert_unique(__cache->__upcast());
                 __cache = __next;
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __deallocate_node(__cache);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __deallocate_node(__cache);
     }
     for (; __first != __last; ++__first)
@@ -1699,10 +1528,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
     if (bucket_count() != 0)
     {
         __next_pointer __cache = __detach();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (; __cache != nullptr && __first != __last; ++__first)
             {
                 __cache->__upcast()->__value_ = *__first;
@@ -1710,14 +1539,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
                 __node_insert_multi(__cache->__upcast());
                 __cache = __next;
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __deallocate_node(__cache);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __deallocate_node(__cache);
     }
     for (; __first != __last; ++__first)
@@ -1729,7 +1558,7 @@ inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
 {
-    return iterator(__p1_.first().__next_, this);
+    return iterator(__p1_.first().__next_);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1737,7 +1566,7 @@ inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
 {
-    return iterator(nullptr, this);
+    return iterator(nullptr);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1745,7 +1574,7 @@ inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
 {
-    return const_iterator(__p1_.first().__next_, this);
+    return const_iterator(__p1_.first().__next_);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1753,7 +1582,7 @@ inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
 {
-    return const_iterator(nullptr, this);
+    return const_iterator(nullptr);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1794,10 +1623,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
         if (__ndptr != nullptr)
         {
             for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
-                                             std::__constrain_hash(__ndptr->__hash(), __bc) == __chash;
+                    (__ndptr->__hash() == __hash ||
+                     std::__constrain_hash(__ndptr->__hash(), __bc) == __chash);
                                                      __ndptr = __ndptr->__next_)
             {
-                if (key_eq()(__ndptr->__upcast()->__value_, __value))
+                if ((__ndptr->__hash() == __hash) &&
+                    key_eq()(__ndptr->__upcast()->__value_, __value))
                     return __ndptr;
             }
         }
@@ -1858,7 +1689,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
         __existing_node = __nd->__ptr();
         __inserted = true;
     }
-    return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
+    return pair<iterator, bool>(iterator(__existing_node), __inserted);
 }
 
 // Prepare the container for an insertion of the value __cp_val with the hash
@@ -1952,7 +1783,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
     __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
     __node_insert_multi_perform(__cp, __pn);
 
-    return iterator(__cp->__ptr(), this);
+    return iterator(__cp->__ptr());
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1960,9 +1791,6 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
         const_iterator __p, __node_pointer __cp)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
-                         " referring to this unordered container");
     if (__p != end() && key_eq()(*__p, __cp->__value_))
     {
         __next_pointer __np = __p.__node_;
@@ -1981,7 +1809,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
         __cp->__next_ = __np;
         __pp->__next_ = static_cast<__next_pointer>(__cp);
         ++size();
-        return iterator(static_cast<__next_pointer>(__cp), this);
+        return iterator(static_cast<__next_pointer>(__cp));
     }
     return __node_insert_multi(__cp);
 }
@@ -2009,7 +1837,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
                 (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
                                                            __nd = __nd->__next_)
             {
-                if (key_eq()(__nd->__upcast()->__value_, __k))
+                if ((__nd->__hash() == __hash) &&
+                    key_eq()(__nd->__upcast()->__value_, __k))
                     goto __done;
             }
         }
@@ -2047,7 +1876,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
         __inserted = true;
     }
 __done:
-    return pair<iterator, bool>(iterator(__nd, this), __inserted);
+    return pair<iterator, bool>(iterator(__nd), __inserted);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2079,16 +1908,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
         const_iterator __p, _Args&&... __args)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
-                         " referring to this unordered container");
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     iterator __r = __node_insert_multi(__p, __h.get());
     __h.release();
     return __r;
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <class _NodeHandle, class _InsertReturnType>
 _LIBCPP_INLINE_VISIBILITY
@@ -2218,7 +2044,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
         __node_insert_multi_perform(__src_ptr, __pn);
     }
 }
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <bool _UniqueKeys>
@@ -2251,7 +2077,6 @@ template <bool _UniqueKeys>
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
 {
-    std::__debug_db_invalidate_all(this);
     __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
     __bucket_list_.reset(__nbc > 0 ?
                       __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
@@ -2323,7 +2148,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
             {
                 if ((__nd->__hash() == __hash)
                     && key_eq()(__nd->__upcast()->__value_, __k))
-                    return iterator(__nd, this);
+                    return iterator(__nd);
             }
         }
     }
@@ -2350,7 +2175,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
             {
                 if ((__nd->__hash() == __hash)
                     && key_eq()(__nd->__upcast()->__value_, __k))
-                    return const_iterator(__nd, this);
+                    return const_iterator(__nd);
             }
         }
 
@@ -2398,12 +2223,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
 {
     __next_pointer __np = __p.__node_;
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "unordered container erase(iterator) called with an iterator not"
-                         " referring to this container");
-    _LIBCPP_ASSERT(__p != end(),
-                   "unordered container erase(iterator) called with a non-dereferenceable iterator");
-    iterator __r(__np, this);
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
+        "unordered container::erase(iterator) called with a non-dereferenceable iterator");
+    iterator __r(__np);
     ++__r;
     remove(__p);
     return __r;
@@ -2414,19 +2236,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
                                                 const_iterator __last)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this,
-                         "unordered container::erase(iterator, iterator) called with an iterator not"
-                         " referring to this container");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this,
-                         "unordered container::erase(iterator, iterator) called with an iterator not"
-                         " referring to this container");
     for (const_iterator __p = __first; __first != __last; __p = __first)
     {
         ++__first;
         erase(__p);
     }
     __next_pointer __np = __last.__node_;
-    return iterator (__np, this);
+    return iterator (__np);
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2493,21 +2309,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
     __pn->__next_ = __cn->__next_;
     __cn->__next_ = nullptr;
     --size();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    __c_node* __c = __get_db()->__find_c_and_lock(this);
-    for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
-    {
-        --__dp;
-        iterator* __i = static_cast<iterator*>((*__dp)->__i_);
-        if (__i->__node_ == __cn)
-        {
-            (*__dp)->__c_ = nullptr;
-            if (--__c->end_ != __dp)
-                _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
-        }
-    }
-    __get_db()->unlock();
-#endif
     return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
 }
 
@@ -2622,10 +2423,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
   _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
 #endif
 {
-    _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
-                   this->__node_alloc() == __u.__node_alloc(),
-                   "list::swap: Either propagate_on_container_swap must be true"
-                   " or the allocators must compare 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 "
+                                        "must be true or the allocators must compare equal");
     {
     __node_pointer_pointer __npp = __bucket_list_.release();
     __bucket_list_.reset(__u.__bucket_list_.release());
@@ -2644,14 +2445,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
     if (__u.size() > 0)
         __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
             __u.__p1_.first().__ptr();
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
 {
-    _LIBCPP_ASSERT(__n < bucket_count(),
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
         "unordered container::bucket_size(n) called with n >= bucket_count()");
     __next_pointer __np = __bucket_list_[__n];
     size_type __bc = bucket_count();
@@ -2676,38 +2476,6 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
     __x.swap(__y);
 }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-bool
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
-{
-    return __i->__node_ != nullptr;
-}
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-bool
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
-{
-    return false;
-}
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-bool
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
-{
-    return false;
-}
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-bool
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
-{
-    return false;
-}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
lib/libcxx/include/__locale
@@ -12,9 +12,12 @@
 
 #include <__availability>
 #include <__config>
+#include <__memory/shared_ptr.h> // __shared_count
+#include <__type_traits/make_unsigned.h>
 #include <cctype>
+#include <clocale>
 #include <cstdint>
-#include <locale.h>
+#include <cstdlib>
 #include <mutex>
 #include <string>
 
@@ -22,15 +25,18 @@
 #include <cstddef>
 #include <cstring>
 
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  include <cwchar>
+#else
+#  include <__std_mbstate_t.h>
+#endif
+
 #if defined(_LIBCPP_MSVCRT_LIKE)
 # include <__support/win32/locale_win32.h>
 #elif defined(_AIX) || defined(__MVS__)
 # include <__support/ibm/xlocale.h>
 #elif defined(__ANDROID__)
 # include <__support/android/locale_bionic.h>
-#elif defined(__sun__)
-# include <__support/solaris/xlocale.h>
-# include <xlocale.h>
 #elif defined(_NEWLIB_VERSION)
 # include <__support/newlib/xlocale.h>
 #elif defined(__OpenBSD__)
@@ -52,64 +58,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
-struct __libcpp_locale_guard {
-  _LIBCPP_INLINE_VISIBILITY
-  __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
-
-  _LIBCPP_INLINE_VISIBILITY
-  ~__libcpp_locale_guard() {
-    if (__old_loc_)
-      uselocale(__old_loc_);
-  }
-
-  locale_t __old_loc_;
-private:
-  __libcpp_locale_guard(__libcpp_locale_guard const&);
-  __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
-};
-#elif defined(_LIBCPP_MSVCRT_LIKE)
-struct __libcpp_locale_guard {
-    __libcpp_locale_guard(locale_t __l) :
-        __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
-      // Setting the locale can be expensive even when the locale given is
-      // already the current locale, so do an explicit check to see if the
-      // current locale is already the one we want.
-      const char* __lc = __setlocale(nullptr);
-      // If every category is the same, the locale string will simply be the
-      // locale name, otherwise it will be a semicolon-separated string listing
-      // each category.  In the second case, we know at least one category won't
-      // be what we want, so we only have to check the first case.
-      if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
-        __locale_all = _strdup(__lc);
-        if (__locale_all == nullptr)
-          __throw_bad_alloc();
-        __setlocale(__l.__get_locale());
-      }
-    }
-    ~__libcpp_locale_guard() {
-      // The CRT documentation doesn't explicitly say, but setlocale() does the
-      // right thing when given a semicolon-separated list of locale settings
-      // for the different categories in the same format as returned by
-      // setlocale(LC_ALL, nullptr).
-      if (__locale_all != nullptr) {
-        __setlocale(__locale_all);
-        free(__locale_all);
-      }
-      _configthreadlocale(__status);
-    }
-    static const char* __setlocale(const char* __locale) {
-      const char* __new_locale = setlocale(LC_ALL, __locale);
-      if (__new_locale == nullptr)
-        __throw_bad_alloc();
-      return __new_locale;
-    }
-    int __status;
-    char* __locale_all = nullptr;
-};
-#endif
-
-class _LIBCPP_TYPE_VIS locale;
+class _LIBCPP_EXPORTED_FROM_ABI locale;
 
 template <class _Facet>
 _LIBCPP_INLINE_VISIBILITY
@@ -121,12 +70,12 @@ _LIBCPP_INLINE_VISIBILITY
 const _Facet&
 use_facet(const locale&);
 
-class _LIBCPP_TYPE_VIS locale
+class _LIBCPP_EXPORTED_FROM_ABI locale
 {
 public:
     // types:
-    class _LIBCPP_TYPE_VIS facet;
-    class _LIBCPP_TYPE_VIS id;
+    class _LIBCPP_EXPORTED_FROM_ABI facet;
+    class _LIBCPP_EXPORTED_FROM_ABI id;
 
     typedef int category;
     _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
@@ -162,7 +111,9 @@ public:
     // locale operations:
     string name() const;
     bool operator==(const locale&) const;
-    bool operator!=(const locale& __y) const {return !(*this == __y);}
+#if _LIBCPP_STD_VER <= 17
+    _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const {return !(*this == __y);}
+#endif
     template <class _CharT, class _Traits, class _Allocator>
       _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
       bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
@@ -185,7 +136,7 @@ private:
     template <class _Facet> friend const _Facet& use_facet(const locale&);
 };
 
-class _LIBCPP_TYPE_VIS locale::facet
+class _LIBCPP_EXPORTED_FROM_ABI locale::facet
     : public __shared_count
 {
 protected:
@@ -201,7 +152,7 @@ private:
     void __on_zero_shared() _NOEXCEPT override;
 };
 
-class _LIBCPP_TYPE_VIS locale::id
+class _LIBCPP_EXPORTED_FROM_ABI locale::id
 {
     once_flag      __flag_;
     int32_t        __id_;
@@ -349,7 +300,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
 template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
 
 template <>
-class _LIBCPP_TYPE_VIS collate_byname<char>
+class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char>
     : public collate<char>
 {
     locale_t __l_;
@@ -369,7 +320,7 @@ protected:
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t>
     : public collate<wchar_t>
 {
     locale_t __l_;
@@ -401,7 +352,7 @@ locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
 
 // template <class charT> class ctype
 
-class _LIBCPP_TYPE_VIS ctype_base
+class _LIBCPP_EXPORTED_FROM_ABI ctype_base
 {
 public:
 #if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE)
@@ -482,7 +433,7 @@ public:
     static const mask blank  = _CTYPE_B;
     static const mask __regex_word = 0x80;
 # endif
-#elif defined(__sun__) || defined(_AIX)
+#elif defined(_AIX)
     typedef unsigned int mask;
     static const mask space  = _ISSPACE;
     static const mask print  = _ISPRINT;
@@ -494,11 +445,7 @@ public:
     static const mask punct  = _ISPUNCT;
     static const mask xdigit = _ISXDIGIT;
     static const mask blank  = _ISBLANK;
-# if defined(_AIX)
     static const mask __regex_word = 0x8000;
-# else
-    static const mask __regex_word = 0x80;
-# endif
 #elif defined(_NEWLIB_VERSION)
     // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
     typedef char mask;
@@ -561,7 +508,7 @@ template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS ctype<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t>
     : public locale::facet,
       public ctype_base
 {
@@ -664,7 +611,7 @@ protected:
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
 template <>
-class _LIBCPP_TYPE_VIS ctype<char>
+class _LIBCPP_EXPORTED_FROM_ABI ctype<char>
     : public locale::facet, public ctype_base
 {
     const mask* __tab_;
@@ -793,7 +740,7 @@ protected:
 template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
 
 template <>
-class _LIBCPP_TYPE_VIS ctype_byname<char>
+class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char>
     : public ctype<char>
 {
     locale_t __l_;
@@ -812,7 +759,7 @@ protected:
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t>
     : public ctype<wchar_t>
 {
     locale_t __l_;
@@ -926,6 +873,11 @@ isgraph(_CharT __c, const locale& __loc)
     return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
 }
 
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) {
+    return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c);
+}
+
 template <class _CharT>
 inline _LIBCPP_INLINE_VISIBILITY
 _CharT
@@ -944,7 +896,7 @@ tolower(_CharT __c, const locale& __loc)
 
 // codecvt_base
 
-class _LIBCPP_TYPE_VIS codecvt_base
+class _LIBCPP_EXPORTED_FROM_ABI codecvt_base
 {
 public:
     _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
@@ -958,7 +910,7 @@ template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_
 // template <> class codecvt<char, char, mbstate_t>
 
 template <>
-class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
+class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1045,7 +997,7 @@ protected:
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
+class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1129,7 +1081,7 @@ protected:
 // template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
 
 template <>
-class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
+class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1217,7 +1169,7 @@ protected:
 // template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
 
 template <>
-class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t>
+class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1305,7 +1257,7 @@ protected:
 // template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
 
 template <>
-class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
+class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1393,7 +1345,7 @@ protected:
 // template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
 
 template <>
-class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t>
+class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1537,7 +1489,7 @@ struct __narrow_to_utf8<8>
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16>
+struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1573,7 +1525,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32>
+struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1631,7 +1583,7 @@ struct __widen_from_utf8<8>
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct _LIBCPP_TYPE_VIS __widen_from_utf8<16>
+struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1667,7 +1619,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct _LIBCPP_TYPE_VIS __widen_from_utf8<32>
+struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1706,7 +1658,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
 
 template <>
-class _LIBCPP_TYPE_VIS numpunct<char>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct<char>
     : public locale::facet
 {
 public:
@@ -1738,7 +1690,7 @@ protected:
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS numpunct<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t>
     : public locale::facet
 {
 public:
@@ -1774,7 +1726,7 @@ protected:
 template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
 
 template <>
-class _LIBCPP_TYPE_VIS numpunct_byname<char>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char>
 : public numpunct<char>
 {
 public:
@@ -1793,7 +1745,7 @@ private:
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t>
 : public numpunct<wchar_t>
 {
 public:
lib/libcxx/include/__mbstate_t.h
@@ -16,29 +16,39 @@
 #  pragma GCC system_header
 #endif
 
-// TODO(ldionne):
-// The goal of this header is to provide mbstate_t without having to pull in
-// <wchar.h> or <uchar.h>. This is necessary because we need that type even
-// when we don't have (or try to provide) support for wchar_t, because several
-// types like std::fpos are defined in terms of mbstate_t.
+// The goal of this header is to provide mbstate_t without requiring all of
+// <uchar.h> or <wchar.h>. It's also used by the libc++ versions of <uchar.h>
+// and <wchar.h> to get mbstate_t when the C library doesn't provide <uchar.h>
+// or <wchar.h>, hence the #include_next of those headers instead of #include.
+// (e.g. if <wchar.h> isn't present in the C library, the libc++ <wchar.h>
+// will include this header. This header needs to not turn around and cyclically
+// include <wchar.h>, but fall through to <uchar.h>.)
 //
-// This is a gruesome hack, but I don't know how to make it cleaner for
-// the time being.
+// This does not define std::mbstate_t -- this only brings in the declaration
+// in the global namespace.
+
+// We define this here to support older versions of glibc <wchar.h> that do
+// not define this for clang. This is also set in libc++'s <wchar.h> header,
+// and we need to do so here too to avoid a different function signature given
+// a different include order.
+#ifdef __cplusplus
+#  define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+#endif
 
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-#   include <wchar.h> // for mbstate_t
+#if defined(_LIBCPP_HAS_MUSL_LIBC)
+#   define __NEED_mbstate_t
+#   include <bits/alltypes.h>
+#   undef __NEED_mbstate_t
 #elif __has_include(<bits/types/mbstate_t.h>)
 #   include <bits/types/mbstate_t.h> // works on most Unixes
 #elif __has_include(<sys/_types/_mbstate_t.h>)
 #   include <sys/_types/_mbstate_t.h> // works on Darwin
+#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next(<wchar.h>)
+#   include_next <wchar.h> // fall back to the C standard provider of mbstate_t
+#elif __has_include_next(<uchar.h>)
+#   include_next <uchar.h> // <uchar.h> is also required to make mbstate_t visible
 #else
-#   error "The library was configured without support for wide-characters, but we don't know how to get the definition of mbstate_t without <wchar.h> on your platform."
+#   error "We don't know how to get the definition of mbstate_t without <wchar.h> on your platform."
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
-
-_LIBCPP_END_NAMESPACE_STD
-
 #endif // _LIBCPP___MBSTATE_T_H
lib/libcxx/include/__mutex_base
@@ -1,523 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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___MUTEX_BASE
-#define _LIBCPP___MUTEX_BASE
-
-#include <__chrono/duration.h>
-#include <__chrono/steady_clock.h>
-#include <__chrono/system_clock.h>
-#include <__chrono/time_point.h>
-#include <__config>
-#include <__threading_support>
-#include <ratio>
-#include <system_error>
-#include <time.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-
-class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
-{
-    __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR mutex() = default;
-
-    mutex(const mutex&) = delete;
-    mutex& operator=(const mutex&) = delete;
-
-#if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
-    ~mutex() = default;
-#else
-    ~mutex() _NOEXCEPT;
-#endif
-
-    void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
-    bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
-    void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
-
-    typedef __libcpp_mutex_t* native_handle_type;
-    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
-};
-
-static_assert(is_nothrow_default_constructible<mutex>::value,
-              "the default constructor for std::mutex must be nothrow");
-
-struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; };
-struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; };
-struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; };
-
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-
-extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t  defer_lock;
-extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
-extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t  adopt_lock;
-
-#else
-
-/* inline */ constexpr defer_lock_t  defer_lock  = defer_lock_t();
-/* inline */ constexpr try_to_lock_t try_to_lock = try_to_lock_t();
-/* inline */ constexpr adopt_lock_t  adopt_lock  = adopt_lock_t();
-
-#endif
-
-template <class _Mutex>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
-lock_guard
-{
-public:
-    typedef _Mutex mutex_type;
-
-private:
-    mutex_type& __m_;
-public:
-
-    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
-    explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
-        : __m_(__m) {__m_.lock();}
-
-    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
-    lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
-        : __m_(__m) {}
-    _LIBCPP_INLINE_VISIBILITY
-    ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
-
-private:
-    lock_guard(lock_guard const&) = delete;
-    lock_guard& operator=(lock_guard const&) = delete;
-};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
-
-template <class _Mutex>
-class _LIBCPP_TEMPLATE_VIS unique_lock
-{
-public:
-    typedef _Mutex mutex_type;
-
-private:
-    mutex_type* __m_;
-    bool __owns_;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
-    _LIBCPP_INLINE_VISIBILITY
-    explicit unique_lock(mutex_type& __m)
-        : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();}
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
-        : __m_(_VSTD::addressof(__m)), __owns_(false) {}
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock(mutex_type& __m, try_to_lock_t)
-        : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {}
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock(mutex_type& __m, adopt_lock_t)
-        : __m_(_VSTD::addressof(__m)), __owns_(true) {}
-    template <class _Clock, class _Duration>
-    _LIBCPP_INLINE_VISIBILITY
-        unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
-            : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
-    template <class _Rep, class _Period>
-    _LIBCPP_INLINE_VISIBILITY
-        unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
-            : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
-    _LIBCPP_INLINE_VISIBILITY
-    ~unique_lock()
-    {
-        if (__owns_)
-            __m_->unlock();
-    }
-
-    unique_lock(unique_lock const&) = delete;
-    unique_lock& operator=(unique_lock const&) = delete;
-
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock(unique_lock&& __u) _NOEXCEPT
-        : __m_(__u.__m_), __owns_(__u.__owns_)
-        {__u.__m_ = nullptr; __u.__owns_ = false;}
-    _LIBCPP_INLINE_VISIBILITY
-    unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
-        {
-            if (__owns_)
-                __m_->unlock();
-            __m_ = __u.__m_;
-            __owns_ = __u.__owns_;
-            __u.__m_ = nullptr;
-            __u.__owns_ = false;
-            return *this;
-        }
-
-    void lock();
-    bool try_lock();
-
-    template <class _Rep, class _Period>
-        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
-    template <class _Clock, class _Duration>
-        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
-
-    void unlock();
-
-    _LIBCPP_INLINE_VISIBILITY
-    void swap(unique_lock& __u) _NOEXCEPT
-    {
-        _VSTD::swap(__m_, __u.__m_);
-        _VSTD::swap(__owns_, __u.__owns_);
-    }
-    _LIBCPP_INLINE_VISIBILITY
-    mutex_type* release() _NOEXCEPT
-    {
-        mutex_type* __m = __m_;
-        __m_ = nullptr;
-        __owns_ = false;
-        return __m;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool owns_lock() const _NOEXCEPT {return __owns_;}
-    _LIBCPP_INLINE_VISIBILITY
-    explicit operator bool() const _NOEXCEPT {return __owns_;}
-    _LIBCPP_INLINE_VISIBILITY
-    mutex_type* mutex() const _NOEXCEPT {return __m_;}
-};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock);
-
-template <class _Mutex>
-void
-unique_lock<_Mutex>::lock()
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
-    __m_->lock();
-    __owns_ = true;
-}
-
-template <class _Mutex>
-bool
-unique_lock<_Mutex>::try_lock()
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
-    __owns_ = __m_->try_lock();
-    return __owns_;
-}
-
-template <class _Mutex>
-template <class _Rep, class _Period>
-bool
-unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
-    __owns_ = __m_->try_lock_for(__d);
-    return __owns_;
-}
-
-template <class _Mutex>
-template <class _Clock, class _Duration>
-bool
-unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
-    __owns_ = __m_->try_lock_until(__t);
-    return __owns_;
-}
-
-template <class _Mutex>
-void
-unique_lock<_Mutex>::unlock()
-{
-    if (!__owns_)
-        __throw_system_error(EPERM, "unique_lock::unlock: not locked");
-    __m_->unlock();
-    __owns_ = false;
-}
-
-template <class _Mutex>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
-    {__x.swap(__y);}
-
-//enum class cv_status
-_LIBCPP_DECLARE_STRONG_ENUM(cv_status)
-{
-    no_timeout,
-    timeout
-};
-_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
-
-class _LIBCPP_TYPE_VIS condition_variable
-{
-    __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
-
-#ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
-    ~condition_variable() = default;
-#else
-    ~condition_variable();
-#endif
-
-    condition_variable(const condition_variable&) = delete;
-    condition_variable& operator=(const condition_variable&) = delete;
-
-    void notify_one() _NOEXCEPT;
-    void notify_all() _NOEXCEPT;
-
-    void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
-    template <class _Predicate>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        void wait(unique_lock<mutex>& __lk, _Predicate __pred);
-
-    template <class _Clock, class _Duration>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        cv_status
-        wait_until(unique_lock<mutex>& __lk,
-                   const chrono::time_point<_Clock, _Duration>& __t);
-
-    template <class _Clock, class _Duration, class _Predicate>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        bool
-        wait_until(unique_lock<mutex>& __lk,
-                   const chrono::time_point<_Clock, _Duration>& __t,
-                   _Predicate __pred);
-
-    template <class _Rep, class _Period>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        cv_status
-        wait_for(unique_lock<mutex>& __lk,
-                 const chrono::duration<_Rep, _Period>& __d);
-
-    template <class _Rep, class _Period, class _Predicate>
-        bool
-        _LIBCPP_INLINE_VISIBILITY
-        wait_for(unique_lock<mutex>& __lk,
-                 const chrono::duration<_Rep, _Period>& __d,
-                 _Predicate __pred);
-
-    typedef __libcpp_condvar_t* native_handle_type;
-    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
-
-private:
-    void __do_timed_wait(unique_lock<mutex>& __lk,
-       chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
-#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
-    void __do_timed_wait(unique_lock<mutex>& __lk,
-       chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
-#endif
-    template <class _Clock>
-    void __do_timed_wait(unique_lock<mutex>& __lk,
-       chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
-};
-#endif // !_LIBCPP_HAS_NO_THREADS
-
-template <class _Rep, class _Period>
-inline _LIBCPP_INLINE_VISIBILITY
-__enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds>
-__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
-{
-    using namespace chrono;
-    using __ratio = ratio_divide<_Period, nano>;
-    using __ns_rep = nanoseconds::rep;
-    _Rep __result_float = __d.count() * __ratio::num / __ratio::den;
-
-    _Rep __result_max = numeric_limits<__ns_rep>::max();
-    if (__result_float >= __result_max) {
-        return nanoseconds::max();
-    }
-
-    _Rep __result_min = numeric_limits<__ns_rep>::min();
-    if (__result_float <= __result_min) {
-        return nanoseconds::min();
-    }
-
-    return nanoseconds(static_cast<__ns_rep>(__result_float));
-}
-
-template <class _Rep, class _Period>
-inline _LIBCPP_INLINE_VISIBILITY
-__enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds>
-__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
-{
-    using namespace chrono;
-    if (__d.count() == 0) {
-        return nanoseconds(0);
-    }
-
-    using __ratio = ratio_divide<_Period, nano>;
-    using __ns_rep = nanoseconds::rep;
-    __ns_rep __result_max = numeric_limits<__ns_rep>::max();
-    if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
-        return nanoseconds::max();
-    }
-
-    __ns_rep __result_min = numeric_limits<__ns_rep>::min();
-    if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
-        return nanoseconds::min();
-    }
-
-    __ns_rep __result = __d.count() * __ratio::num / __ratio::den;
-    if (__result == 0) {
-        return nanoseconds(1);
-    }
-
-    return nanoseconds(__result);
-}
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-template <class _Predicate>
-void
-condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
-{
-    while (!__pred())
-        wait(__lk);
-}
-
-template <class _Clock, class _Duration>
-cv_status
-condition_variable::wait_until(unique_lock<mutex>& __lk,
-                               const chrono::time_point<_Clock, _Duration>& __t)
-{
-    using namespace chrono;
-    using __clock_tp_ns = time_point<_Clock, nanoseconds>;
-
-    typename _Clock::time_point __now = _Clock::now();
-    if (__t <= __now)
-        return cv_status::timeout;
-
-    __clock_tp_ns __t_ns = __clock_tp_ns(_VSTD::__safe_nanosecond_cast(__t.time_since_epoch()));
-
-    __do_timed_wait(__lk, __t_ns);
-    return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
-}
-
-template <class _Clock, class _Duration, class _Predicate>
-bool
-condition_variable::wait_until(unique_lock<mutex>& __lk,
-                   const chrono::time_point<_Clock, _Duration>& __t,
-                   _Predicate __pred)
-{
-    while (!__pred())
-    {
-        if (wait_until(__lk, __t) == cv_status::timeout)
-            return __pred();
-    }
-    return true;
-}
-
-template <class _Rep, class _Period>
-cv_status
-condition_variable::wait_for(unique_lock<mutex>& __lk,
-                             const chrono::duration<_Rep, _Period>& __d)
-{
-    using namespace chrono;
-    if (__d <= __d.zero())
-        return cv_status::timeout;
-    using __ns_rep = nanoseconds::rep;
-    steady_clock::time_point __c_now = steady_clock::now();
-
-#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
-    using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
-    __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
-#else
-    using __clock_tp_ns = time_point<system_clock, nanoseconds>;
-    __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
-#endif
-
-    __ns_rep __d_ns_count = _VSTD::__safe_nanosecond_cast(__d).count();
-
-    if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
-        __do_timed_wait(__lk, __clock_tp_ns::max());
-    } else {
-        __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
-    }
-
-    return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
-                                                 cv_status::timeout;
-}
-
-template <class _Rep, class _Period, class _Predicate>
-inline
-bool
-condition_variable::wait_for(unique_lock<mutex>& __lk,
-                             const chrono::duration<_Rep, _Period>& __d,
-                             _Predicate __pred)
-{
-    return wait_until(__lk, chrono::steady_clock::now() + __d,
-                      _VSTD::move(__pred));
-}
-
-#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
-inline
-void
-condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
-     chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT
-{
-    using namespace chrono;
-    if (!__lk.owns_lock())
-        __throw_system_error(EPERM,
-                            "condition_variable::timed wait: mutex not locked");
-    nanoseconds __d = __tp.time_since_epoch();
-    timespec __ts;
-    seconds __s = duration_cast<seconds>(__d);
-    using __ts_sec = decltype(__ts.tv_sec);
-    const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
-    if (__s.count() < __ts_sec_max)
-    {
-        __ts.tv_sec = static_cast<__ts_sec>(__s.count());
-        __ts.tv_nsec = (__d - __s).count();
-    }
-    else
-    {
-        __ts.tv_sec = __ts_sec_max;
-        __ts.tv_nsec = giga::num - 1;
-    }
-    int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
-    if (__ec != 0 && __ec != ETIMEDOUT)
-        __throw_system_error(__ec, "condition_variable timed_wait failed");
-}
-#endif // _LIBCPP_HAS_COND_CLOCKWAIT
-
-template <class _Clock>
-inline
-void
-condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
-     chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT
-{
-    wait_for(__lk, __tp - _Clock::now());
-}
-
-#endif // !_LIBCPP_HAS_NO_THREADS
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___MUTEX_BASE
lib/libcxx/include/__node_handle
@@ -68,9 +68,12 @@ public:
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 // Specialized in __tree & __hash_table for their _NodeType.
 template <class _NodeType, class _Alloc>
@@ -146,7 +149,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __basic_node_handle& operator=(__basic_node_handle&& __other)
     {
-        _LIBCPP_ASSERT(
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
             __alloc_ == _VSTD::nullopt ||
             __alloc_traits::propagate_on_container_move_assignment::value ||
             __alloc_ == __other.__alloc_,
@@ -247,8 +250,10 @@ struct _LIBCPP_TEMPLATE_VIS __insert_return_type
     _NodeType node;
 };
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif  // _LIBCPP___NODE_HANDLE
lib/libcxx/src/format.cpp → lib/libcxx/include/__pstl_algorithm
@@ -1,3 +1,4 @@
+// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -6,12 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <format>
+#ifndef __PSTL_ALGORITHM
+#define __PSTL_ALGORITHM
 
-_LIBCPP_BEGIN_NAMESPACE_STD
+#include <pstl/internal/glue_algorithm_impl.h>
 
-#ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR
-format_error::~format_error() noexcept = default;
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
+#endif /* __PSTL_ALGORITHM */
lib/libcxx/src/utility.cpp → lib/libcxx/include/__pstl_memory
@@ -1,3 +1,4 @@
+// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -6,10 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <utility>
+#ifndef __PSTL_MEMORY
+#define __PSTL_MEMORY
 
-_LIBCPP_BEGIN_NAMESPACE_STD
+#include <pstl/internal/glue_memory_impl.h>
 
-const piecewise_construct_t piecewise_construct{};
-
-_LIBCPP_END_NAMESPACE_STD
+#endif /* __PSTL_MEMORY */
lib/libcxx/include/__support/solaris/floatingpoint.h → lib/libcxx/include/__pstl_numeric
@@ -1,3 +1,4 @@
+// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -6,8 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define atof sun_atof
-#define strtod sun_strtod
-#include_next "floatingpoint.h"
-#undef atof
-#undef strtod
+#ifndef __PSTL_NUMERIC
+#define __PSTL_NUMERIC
+
+#include <pstl/internal/glue_numeric_impl.h>
+
+#endif /* __PSTL_NUMERIC */
lib/libcxx/include/__split_buffer
@@ -23,9 +23,18 @@
 #include <__memory/compressed_pair.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -44,139 +53,173 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp, class _Allocator = allocator<_Tp> >
 struct __split_buffer
 {
-private:
-    __split_buffer(const __split_buffer&);
-    __split_buffer& operator=(const __split_buffer&);
 public:
-    typedef _Tp                                             value_type;
-    typedef _Allocator                                      allocator_type;
-    typedef __libcpp_remove_reference_t<allocator_type>     __alloc_rr;
-    typedef allocator_traits<__alloc_rr>                    __alloc_traits;
-    typedef value_type&                                     reference;
-    typedef const value_type&                               const_reference;
-    typedef typename __alloc_traits::size_type              size_type;
-    typedef typename __alloc_traits::difference_type        difference_type;
-    typedef typename __alloc_traits::pointer                pointer;
-    typedef typename __alloc_traits::const_pointer          const_pointer;
-    typedef pointer                                         iterator;
-    typedef const_pointer                                   const_iterator;
-
-    pointer                                         __first_;
-    pointer                                         __begin_;
-    pointer                                         __end_;
-    __compressed_pair<pointer, allocator_type> __end_cap_;
-
-    typedef __add_lvalue_reference_t<allocator_type> __alloc_ref;
-    typedef __add_lvalue_reference_t<allocator_type> __alloc_const_ref;
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr&           __alloc() _NOEXCEPT         {return __end_cap_.second();}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr&     __alloc() const _NOEXCEPT   {return __end_cap_.second();}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    __split_buffer()
-        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    explicit __split_buffer(__alloc_rr& __a);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    explicit __split_buffer(const __alloc_rr& __a);
-    _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();
-
-    _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, 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       iterator begin() _NOEXCEPT       {return __begin_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {return __begin_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI       iterator end() _NOEXCEPT         {return __end_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT   {return __end_;}
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    void clear() _NOEXCEPT
-        {__destruct_at_end(__begin_);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty()     const {return __end_ == __begin_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI       reference front()       {return *__begin_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const {return *__begin_;}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI       reference back()        {return *(__end_ - 1);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const  {return *(__end_ - 1);}
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
-    template <class... _Args>
-        _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() {__destruct_at_begin(__begin_+1);}
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() {__destruct_at_end(__end_-1);}
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
-    template <class _InputIter>
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
-        __construct_at_end(_InputIter __first, _InputIter __last);
-    template <class _ForwardIterator>
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
-        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin)
-        {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
-        _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-        void __destruct_at_begin(pointer __new_begin, false_type);
-        _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-        void __destruct_at_begin(pointer __new_begin, true_type);
-
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    void __destruct_at_end(pointer __new_last) _NOEXCEPT
-        {__destruct_at_end(__new_last, false_type());}
-    _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<__alloc_rr>::value);
+  using value_type      = _Tp;
+  using allocator_type  = _Allocator;
+  using __alloc_rr      = __libcpp_remove_reference_t<allocator_type>;
+  using __alloc_traits  = allocator_traits<__alloc_rr>;
+  using reference       = value_type&;
+  using const_reference = const value_type&;
+  using size_type       = typename __alloc_traits::size_type;
+  using difference_type = typename __alloc_traits::difference_type;
+  using pointer         = typename __alloc_traits::pointer;
+  using const_pointer   = typename __alloc_traits::const_pointer;
+  using iterator        = pointer;
+  using const_iterator  = const_pointer;
+
+  pointer __first_;
+  pointer __begin_;
+  pointer __end_;
+  __compressed_pair<pointer, allocator_type> __end_cap_;
+
+  using __alloc_ref       = __add_lvalue_reference_t<allocator_type>;
+  using __alloc_const_ref = __add_lvalue_reference_t<allocator_type>;
+
+  __split_buffer(const __split_buffer&) = delete;
+  __split_buffer& operator=(const __split_buffer&) = delete;
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
+      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a)
+      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a)
+      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
+
+  _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, 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();
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __end_cap_.second(); }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {
+    return __end_cap_.second();
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_.first(); }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {
+    return __end_cap_.first();
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {
+    return static_cast<size_type>(__end_ - __begin_);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
+    return static_cast<size_type>(__end_cap() - __first_);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
+    return static_cast<size_type>(__begin_ - __first_);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
+    return static_cast<size_type>(__end_cap() - __end_);
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
+
+  template <class... _Args>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); }
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
+
+  template <class _InputIter>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+      __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value>
+      __construct_at_end(_InputIter __first, _InputIter __last);
+
+  template <class _ForwardIterator>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+      __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value>
+      __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+
+  template <class _Iterator, class _Sentinel>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  void __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last);
+
+  template <class _Iterator>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  void __construct_at_end_with_size(_Iterator __first, size_type __n);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) {
+    __destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, false_type);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, true_type);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
+    __destruct_at_end(__new_last, false_type());
+  }
+
+  _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 bool __invariants() const;
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
+      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__alloc_rr>::value);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
 
 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)
-        {
-            __alloc() = _VSTD::move(__c.__alloc());
-        }
+  _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) {
+    __alloc() = _VSTD::move(__c.__alloc());
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
+
+  struct _ConstructTransaction {
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(
+        pointer* __p, size_type __n) _NOEXCEPT
+        : __pos_(*__p),
+          __end_(*__p + __n),
+          __dest_(__p) {}
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
-        {}
-
-    struct _ConstructTransaction {
-      _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
-      : __pos_(*__p), __end_(*__p + __n), __dest_(__p) {
-      }
-      _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
-        *__dest_ = __pos_;
-      }
-      pointer __pos_;
-     const pointer __end_;
-    private:
-     pointer *__dest_;
-    };
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; }
+
+    pointer __pos_;
+    const pointer __end_;
+
+  private:
+    pointer* __dest_;
+  };
 };
 
 template <class _Tp, class _Allocator>
@@ -241,9 +284,16 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_referen
 
 template <class _Tp, class _Allocator>
 template <class _InputIter>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value>
 __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
 {
+  __construct_at_end_with_sentinel(__first, __last);
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20
+void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
     __alloc_rr& __a = this->__alloc();
     for (; __first != __last; ++__first)
     {
@@ -261,13 +311,19 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt
         ++this->__end_;
     }
 }
-
 template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value>
 __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
 {
-    _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last));
+  __construct_at_end_with_size(__first, std::distance(__first, __last));
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+_LIBCPP_CONSTEXPR_SINCE_CXX20
+void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
+    _ConstructTransaction __tx(&this->__end_, __n);
     for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void) ++__first) {
         __alloc_traits::construct(this->__alloc(),
             _VSTD::__to_address(__tx.__pos_), *__first);
@@ -328,31 +384,6 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __sta
     __end_cap() = __first_ + __cap;
 }
 
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-inline
-__split_buffer<_Tp, _Allocator>::__split_buffer()
-    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag())
-{
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-inline
-__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
-    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
-{
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-inline
-__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
-    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
-{
-}
-
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 __split_buffer<_Tp, _Allocator>::~__split_buffer()
@@ -463,10 +494,10 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
 {
     if (capacity() > size())
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
             __t.__construct_at_end(move_iterator<pointer>(__begin_),
                                    move_iterator<pointer>(__end_));
@@ -475,12 +506,12 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
             _VSTD::swap(__begin_, __t.__begin_);
             _VSTD::swap(__end_, __t.__end_);
             _VSTD::swap(__end_cap(), __t.__end_cap());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
lib/libcxx/include/__std_mbstate_t.h
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___STD_MBSTATE_T_H
+#define _LIBCPP___STD_MBSTATE_T_H
+
+#include <__config>
+#include <__mbstate_t.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+// The goal of this header is to provide std::mbstate_t without requiring all
+// of <cuchar> or <cwchar>.
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___STD_MBSTATE_T_H
lib/libcxx/include/__threading_support
@@ -13,13 +13,9 @@
 #include <__availability>
 #include <__chrono/convert_to_timespec.h>
 #include <__chrono/duration.h>
-#include <__compare/ordering.h>
 #include <__config>
-#include <__fwd/hash.h>
 #include <__thread/poll_with_backoff.h>
 #include <errno.h>
-#include <iosfwd>
-#include <limits>
 
 #ifdef __MVS__
 # include <__support/ibm/nanosleep.h>
@@ -34,26 +30,26 @@
 #elif !defined(_LIBCPP_HAS_NO_THREADS)
 
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+// Some platforms require <bits/atomic_wide_counter.h> in order for
+// PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
+// in via <pthread.h>, but it's a non-modular header on those platforms,
+// so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
+// module with <math.h> and makes atomic_wide_counter.h invisible.
+// Include <math.h> here to work around that.
+# include <math.h>
+
 # include <pthread.h>
 # include <sched.h>
 #elif defined(_LIBCPP_HAS_THREAD_API_C11)
 # include <threads.h>
 #endif
 
-#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
-    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
-    defined(_LIBCPP_HAS_THREAD_API_WIN32)
-#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
+#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_EXPORTED_FROM_ABI
 #else
 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
 #endif
 
-#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
-#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
-#else
-#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
-#endif
-
 typedef ::timespec __libcpp_timespec_t;
 #endif // !defined(_LIBCPP_HAS_NO_THREADS)
 
@@ -252,28 +248,25 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
 
 #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
 
-#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
-     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
-
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 
 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
 {
-  pthread_mutexattr_t attr;
-  int __ec = pthread_mutexattr_init(&attr);
+  pthread_mutexattr_t __attr;
+  int __ec = pthread_mutexattr_init(&__attr);
   if (__ec)
     return __ec;
-  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+  __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
   if (__ec) {
-    pthread_mutexattr_destroy(&attr);
+    pthread_mutexattr_destroy(&__attr);
     return __ec;
   }
-  __ec = pthread_mutex_init(__m, &attr);
+  __ec = pthread_mutex_init(__m, &__attr);
   if (__ec) {
-    pthread_mutexattr_destroy(&attr);
+    pthread_mutexattr_destroy(&__attr);
     return __ec;
   }
-  __ec = pthread_mutexattr_destroy(&attr);
+  __ec = pthread_mutexattr_destroy(&__attr);
   if (__ec) {
     pthread_mutex_destroy(__m);
     return __ec;
@@ -380,8 +373,8 @@ int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
 
 __libcpp_thread_id __libcpp_thread_get_current_id()
 {
-  const __libcpp_thread_t thread = pthread_self();
-  return __libcpp_thread_get_id(&thread);
+  const __libcpp_thread_t __current_thread = pthread_self();
+  return __libcpp_thread_get_id(&__current_thread);
 }
 
 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
@@ -589,116 +582,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
 
 #endif
 
-
-#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
-
-class _LIBCPP_TYPE_VIS thread;
-class _LIBCPP_TYPE_VIS __thread_id;
-
-namespace this_thread
-{
-
-_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
-
-} // namespace this_thread
-
-template<> struct hash<__thread_id>;
-
-class _LIBCPP_TEMPLATE_VIS __thread_id
-{
-    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
-    // NULL is the no-thread value on Darwin.  Someone needs to check
-    // on other platforms.  We assume 0 works everywhere for now.
-    __libcpp_thread_id __id_;
-
-    static _LIBCPP_HIDE_FROM_ABI
-        bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT
-        { // id==0 is always less than any other thread_id
-        if (__x.__id_ == 0) return __y.__id_ != 0;
-        if (__y.__id_ == 0) return false;
-        return  __libcpp_thread_id_less(__x.__id_, __y.__id_);
-        }
-
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    __thread_id() _NOEXCEPT : __id_(0) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __reset() { __id_ = 0; }
-
-    friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
-#if _LIBCPP_STD_VER <= 17
-    friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
-#else // _LIBCPP_STD_VER <= 17
-    friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
-#endif // _LIBCPP_STD_VER <= 17
-
-    template<class _CharT, class _Traits>
-    friend
-    _LIBCPP_INLINE_VISIBILITY
-    basic_ostream<_CharT, _Traits>&
-    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
-
-private:
-    _LIBCPP_INLINE_VISIBILITY
-    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
-
-    friend __thread_id this_thread::get_id() _NOEXCEPT;
-    friend class _LIBCPP_TYPE_VIS thread;
-    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
-};
-
-inline _LIBCPP_HIDE_FROM_ABI
-bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
-  // Don't pass id==0 to underlying routines
-  if (__x.__id_ == 0)
-    return __y.__id_ == 0;
-  if (__y.__id_ == 0)
-    return false;
-  return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
-}
-
-#if _LIBCPP_STD_VER <= 17
-
-inline _LIBCPP_HIDE_FROM_ABI
-bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
-  return !(__x == __y);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI
-bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
-  return __thread_id::__lt_impl(__x.__id_, __y.__id_);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
-inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
-inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
-
-#else // _LIBCPP_STD_VER <= 17
-
-inline _LIBCPP_HIDE_FROM_ABI
-strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
-  if (__x == __y)
-    return strong_ordering::equal;
-  if (__thread_id::__lt_impl(__x, __y))
-    return strong_ordering::less;
-  return strong_ordering::greater;
-}
-
-#endif // _LIBCPP_STD_VER <= 17
-
-namespace this_thread
-{
-
-inline _LIBCPP_INLINE_VISIBILITY
-__thread_id
-get_id() _NOEXCEPT
-{
-    return __libcpp_thread_get_current_id();
-}
-
-} // namespace this_thread
-
 #endif // !_LIBCPP_HAS_NO_THREADS
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__tree
@@ -13,11 +13,11 @@
 #include <__algorithm/min.h>
 #include <__assert>
 #include <__config>
-#include <__debug>
 #include <__functional/invoke.h>
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
 #include <__memory/pointer_traits.h>
@@ -26,6 +26,7 @@
 #include <__type_traits/can_extract_key.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/is_const.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__type_traits/is_nothrow_copy_constructible.h>
 #include <__type_traits/is_nothrow_default_constructible.h>
 #include <__type_traits/is_nothrow_move_assignable.h>
@@ -167,7 +168,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 _NodePtr
 __tree_min(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
     while (__x->__left_ != nullptr)
         __x = __x->__left_;
     return __x;
@@ -179,7 +180,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 _NodePtr
 __tree_max(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
     while (__x->__right_ != nullptr)
         __x = __x->__right_;
     return __x;
@@ -190,7 +191,7 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI _NodePtr
 __tree_next(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
     if (__x->__right_ != nullptr)
         return _VSTD::__tree_min(__x->__right_);
     while (!_VSTD::__tree_is_left_child(__x))
@@ -203,7 +204,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 _EndNodePtr
 __tree_next_iter(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
     if (__x->__right_ != nullptr)
         return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
     while (!_VSTD::__tree_is_left_child(__x))
@@ -218,7 +219,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 _NodePtr
 __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
     if (__x->__left_ != nullptr)
         return _VSTD::__tree_max(__x->__left_);
     _NodePtr __xx = static_cast<_NodePtr>(__x);
@@ -232,7 +233,7 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI _NodePtr
 __tree_leaf(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
     while (true)
     {
         if (__x->__left_ != nullptr)
@@ -256,8 +257,8 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI void
 __tree_left_rotate(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
-    _LIBCPP_ASSERT(__x->__right_ != nullptr, "node should have a right child");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child");
     _NodePtr __y = __x->__right_;
     __x->__right_ = __y->__left_;
     if (__x->__right_ != nullptr)
@@ -277,8 +278,8 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI void
 __tree_right_rotate(_NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
-    _LIBCPP_ASSERT(__x->__left_ != nullptr, "node should have a left child");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child");
     _NodePtr __y = __x->__left_;
     __x->__left_ = __y->__right_;
     if (__x->__left_ != nullptr)
@@ -303,8 +304,8 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI void
 __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__root != nullptr, "Root of the tree shouldn't be null");
-    _LIBCPP_ASSERT(__x != nullptr, "Can't attach null node to a leaf");
+    _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null");
+    _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf");
     __x->__is_black_ = __x == __root;
     while (__x != __root && !__x->__parent_unsafe()->__is_black_)
     {
@@ -373,9 +374,9 @@ template <class _NodePtr>
 _LIBCPP_HIDE_FROM_ABI void
 __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__root != nullptr, "Root node should not be null");
-    _LIBCPP_ASSERT(__z != nullptr, "The node to remove should not be null");
-    _LIBCPP_DEBUG_ASSERT(__tree_invariant(__root), "The tree invariants should hold");
+    _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null");
+    _LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null");
+    _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold");
     // __z will be removed from the tree.  Client still needs to destruct/deallocate it
     // __y is either __z, or if __z has two children, __tree_next(__z).
     // __y will have at most one child.
@@ -797,7 +798,7 @@ public:
     bool __value_constructed;
 
 
-    __tree_node_destructor(const __tree_node_destructor &) = default;
+    _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor &) = default;
     __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -818,7 +819,7 @@ public:
     template <class> friend class __map_node_destructor;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _NodeType, class _Alloc>
 struct __generic_container_node_destructor;
 template <class _Tp, class _VoidPtr, class _Alloc>
@@ -849,7 +850,7 @@ public:
     typedef typename _NodeTypes::__node_value_type_pointer pointer;
 
     _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     : __ptr_(nullptr)
 #endif
     {}
@@ -922,7 +923,7 @@ public:
     typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
 
     _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     : __ptr_(nullptr)
 #endif
     {}
@@ -1100,36 +1101,36 @@ public:
     __node_pointer __root() const _NOEXCEPT
         {return static_cast<__node_pointer>(__end_node()->__left_);}
 
-    __node_base_pointer* __root_ptr() const _NOEXCEPT {
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT {
         return _VSTD::addressof(__end_node()->__left_);
     }
 
     typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
     typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
 
-    explicit __tree(const value_compare& __comp)
+    _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp)
         _NOEXCEPT_(
             is_nothrow_default_constructible<__node_allocator>::value &&
             is_nothrow_copy_constructible<value_compare>::value);
-    explicit __tree(const allocator_type& __a);
-    __tree(const value_compare& __comp, const allocator_type& __a);
-    __tree(const __tree& __t);
-    __tree& operator=(const __tree& __t);
+    _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
+    _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
     template <class _ForwardIterator>
-        void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
+    _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
     template <class _InputIterator>
-        void __assign_multi(_InputIterator __first, _InputIterator __last);
-    __tree(__tree&& __t)
+    _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);
-    __tree(__tree&& __t, const allocator_type& __a);
-    __tree& operator=(__tree&& __t)
+    _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
         _NOEXCEPT_(
             __node_traits::propagate_on_container_move_assignment::value &&
             is_nothrow_move_assignable<value_compare>::value &&
             is_nothrow_move_assignable<__node_allocator>::value);
-    ~__tree();
+    _LIBCPP_HIDE_FROM_ABI ~__tree();
 
     _LIBCPP_INLINE_VISIBILITY
           iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}
@@ -1146,9 +1147,9 @@ public:
                 __node_traits::max_size(__node_alloc()),
                 numeric_limits<difference_type >::max());}
 
-    void clear() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
 
-    void swap(__tree& __t)
+    _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t)
 #if _LIBCPP_STD_VER <= 11
         _NOEXCEPT_(
             __is_nothrow_swappable<value_compare>::value
@@ -1160,23 +1161,23 @@ public:
 #endif
 
     template <class _Key, class ..._Args>
-    pair<iterator, bool>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, bool>
     __emplace_unique_key_args(_Key const&, _Args&&... __args);
     template <class _Key, class ..._Args>
-    pair<iterator, bool>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, bool>
     __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
 
     template <class... _Args>
-    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
 
     template <class... _Args>
-    iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
 
     template <class... _Args>
-    iterator __emplace_multi(_Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
 
     template <class... _Args>
-    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
 
     template <class _Pp>
     _LIBCPP_INLINE_VISIBILITY
@@ -1331,7 +1332,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY iterator
     __remove_node_pointer(__node_pointer) _NOEXCEPT;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     template <class _NodeHandle, class _InsertReturnType>
     _LIBCPP_INLINE_VISIBILITY
     _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
@@ -1361,33 +1362,33 @@ public:
     _NodeHandle __node_handle_extract(const_iterator);
 #endif
 
-    iterator erase(const_iterator __p);
-    iterator erase(const_iterator __f, const_iterator __l);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
     template <class _Key>
-        size_type __erase_unique(const _Key& __k);
+    _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
     template <class _Key>
-        size_type __erase_multi(const _Key& __k);
+    _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
 
-    void __insert_node_at(__parent_pointer     __parent,
+    _LIBCPP_HIDE_FROM_ABI void __insert_node_at(__parent_pointer     __parent,
                           __node_base_pointer& __child,
                           __node_base_pointer __new_node) _NOEXCEPT;
 
     template <class _Key>
-        iterator find(const _Key& __v);
+    _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
     template <class _Key>
-        const_iterator find(const _Key& __v) const;
+    _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
 
     template <class _Key>
-        size_type __count_unique(const _Key& __k) const;
+    _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
     template <class _Key>
-        size_type __count_multi(const _Key& __k) const;
+    _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
 
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         iterator lower_bound(const _Key& __v)
             {return __lower_bound(__v, __root(), __end_node());}
     template <class _Key>
-        iterator __lower_bound(const _Key& __v,
+    _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v,
                                __node_pointer __root,
                                __iter_pointer __result);
     template <class _Key>
@@ -1395,7 +1396,7 @@ public:
         const_iterator lower_bound(const _Key& __v) const
             {return __lower_bound(__v, __root(), __end_node());}
     template <class _Key>
-        const_iterator __lower_bound(const _Key& __v,
+    _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound(const _Key& __v,
                                      __node_pointer __root,
                                      __iter_pointer __result) const;
     template <class _Key>
@@ -1403,7 +1404,7 @@ public:
         iterator upper_bound(const _Key& __v)
             {return __upper_bound(__v, __root(), __end_node());}
     template <class _Key>
-        iterator __upper_bound(const _Key& __v,
+    _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v,
                                __node_pointer __root,
                                __iter_pointer __result);
     template <class _Key>
@@ -1411,55 +1412,52 @@ public:
         const_iterator upper_bound(const _Key& __v) const
             {return __upper_bound(__v, __root(), __end_node());}
     template <class _Key>
-        const_iterator __upper_bound(const _Key& __v,
+    _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound(const _Key& __v,
                                      __node_pointer __root,
                                      __iter_pointer __result) const;
     template <class _Key>
-        pair<iterator, iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
         __equal_range_unique(const _Key& __k);
     template <class _Key>
-        pair<const_iterator, const_iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
         __equal_range_unique(const _Key& __k) const;
 
     template <class _Key>
-        pair<iterator, iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
         __equal_range_multi(const _Key& __k);
     template <class _Key>
-        pair<const_iterator, const_iterator>
+    _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
         __equal_range_multi(const _Key& __k) const;
 
     typedef __tree_node_destructor<__node_allocator> _Dp;
     typedef unique_ptr<__node, _Dp> __node_holder;
 
-    __node_holder remove(const_iterator __p) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
 private:
-    __node_base_pointer&
-        __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
-    __node_base_pointer&
-        __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
-    __node_base_pointer&
-        __find_leaf(const_iterator __hint,
-                    __parent_pointer& __parent, const key_type& __v);
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
+    __find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v);
     // FIXME: Make this function const qualified. Unfortunately doing so
     // breaks existing code which uses non-const callable comparators.
     template <class _Key>
-    __node_base_pointer&
-        __find_equal(__parent_pointer& __parent, const _Key& __v);
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v);
     template <class _Key>
     _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
     __find_equal(__parent_pointer& __parent, const _Key& __v) const {
       return const_cast<__tree*>(this)->__find_equal(__parent, __v);
     }
     template <class _Key>
-    __node_base_pointer&
+    _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
         __find_equal(const_iterator __hint, __parent_pointer& __parent,
                      __node_base_pointer& __dummy,
                      const _Key& __v);
 
     template <class ..._Args>
-    __node_holder __construct_node(_Args&& ...__args);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args);
 
-    void destroy(__node_pointer __nd) _NOEXCEPT;
+    // TODO: Make this _LIBCPP_HIDE_FROM_ABI
+    _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __tree& __t)
@@ -1476,8 +1474,8 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __tree&, false_type) {}
 
-    void __move_assign(__tree& __t, false_type);
-    void __move_assign(__tree& __t, true_type)
+    _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);
 
@@ -1640,7 +1638,7 @@ __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _Fo
     typedef typename _ITraits::value_type _ItValueType;
     static_assert((is_same<_ItValueType, __container_value_type>::value),
                   "__assign_unique may only be called with the containers value type");
-    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+    static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
                   "__assign_unique requires a forward iterator");
     if (size() != 0)
     {
@@ -2265,7 +2263,7 @@ __tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _
     return __r;
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Compare, class _Allocator>
 template <class _NodeHandle, class _InsertReturnType>
 _LIBCPP_INLINE_VISIBILITY
@@ -2422,7 +2420,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
     }
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
lib/libcxx/include/__undef_macros
@@ -14,3 +14,15 @@
 #ifdef max
 #  undef max
 #endif
+
+#ifdef refresh
+#  undef refresh
+#endif
+
+#ifdef move
+#  undef move
+#endif
+
+#ifdef erase
+#  undef erase
+#endif
lib/libcxx/include/__verbose_abort
@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // This function should never be called directly from the code -- it should only be called through
 // the _LIBCPP_VERBOSE_ABORT macro.
-_LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
+_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
 void __libcpp_verbose_abort(const char *__format, ...);
 
 // _LIBCPP_VERBOSE_ABORT(format, args...)
@@ -40,16 +40,19 @@ void __libcpp_verbose_abort(const char *__format, ...);
 
 // Support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED until LLVM 18, but tell people
 // to move to customizing _LIBCPP_VERBOSE_ABORT instead.
-#  if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
-#    undef _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+#  if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
+#    undef _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
 #    warning _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED is deprecated, please customize _LIBCPP_VERBOSE_ABORT instead
 #  endif
 
-#  if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY)
-#    define _LIBCPP_VERBOSE_ABORT(...) __builtin_abort()
+#  if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT)
+// The decltype is there to suppress -Wunused warnings in this configuration.
+void __use(const char*, ...);
+#    define _LIBCPP_VERBOSE_ABORT(...) (decltype(::std::__use(__VA_ARGS__))(), __builtin_abort())
 #  else
 #    define _LIBCPP_VERBOSE_ABORT(...) ::std::__libcpp_verbose_abort(__VA_ARGS__)
 #  endif
+
 #endif // !defined(_LIBCPP_VERBOSE_ABORT)
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/algorithm
@@ -22,41 +22,41 @@ namespace ranges {
 
   // [algorithms.results], algorithm result types
   template <class I, class F>
-    struct in_fun_result;     // since C++20
+    struct in_fun_result;                // since C++20
 
   template <class I1, class I2>
-    struct in_in_result;      // since C++20
+    struct in_in_result;                 // since C++20
 
   template <class I, class O>
-    struct in_out_result;  // since C++20
+    struct in_out_result;                // since C++20
 
   template <class I1, class I2, class O>
-    struct in_in_out_result;  // since C++20
+    struct in_in_out_result;             // since C++20
 
   template <class I, class O1, class O2>
-    struct in_out_out_result; // since C++20
+    struct in_out_out_result;            // since C++20
 
   template <class I1, class I2>
-    struct min_max_result;    // since C++20
+    struct min_max_result;               // since C++20
 
   template <class I>
-    struct in_found_result;   // since C++20
+    struct in_found_result;              // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
-    indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>             // since C++20
+    indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>                                   // since C++20
   constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {});
 
   template<forward_range R, class Proj = identity,
-    indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20
+    indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>                       // since C++20
   constexpr borrowed_iterator_t<R> min_element(R&& r, Comp comp = {}, Proj proj = {});
 
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
     indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
-  constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {});                        // since C++20
+  constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {});                       // since C++20
 
   template<forward_range R, class Proj = identity,
     indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
-  constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {});             // since C++20
+  constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {});            // since C++20
 
   template<class I1, class I2>
     using mismatch_result = in_in_result<I1, I2>;
@@ -64,86 +64,86 @@ namespace ranges {
   template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2,
           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
     requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
-  constexpr mismatch_result<_I1, _I2>
-  mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
+  constexpr mismatch_result<_I1, _I2>                                                                     // since C++20
+  mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
 
   template <input_range R1, input_range R2,
           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
     requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
   constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
-  mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})                           // since C++20
+  mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})                          // since C++20
 
     requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
-    constexpr I find(I first, S last, const T& value, Proj proj = {});              // since C++20
+    constexpr I find(I first, S last, const T& value, Proj proj = {});                                    // since C++20
 
   template<input_range R, class T, class Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
     constexpr borrowed_iterator_t<R>
-      find(R&& r, const T& value, Proj proj = {});                                  // since C++20
+      find(R&& r, const T& value, Proj proj = {});                                                        // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr I find_if(I first, S last, Pred pred, Proj proj = {});                // since C++20
+    constexpr I find_if(I first, S last, Pred pred, Proj proj = {});                                      // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     constexpr borrowed_iterator_t<R>
-      find_if(R&& r, Pred pred, Proj proj = {});                                    // since C++20
+      find_if(R&& r, Pred pred, Proj proj = {});                                                          // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {});            // since C++20
+    constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {});                                  // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     constexpr borrowed_iterator_t<R>
-      find_if_not(R&& r, Pred pred, Proj proj = {});                                // since C++20
+      find_if_not(R&& r, Pred pred, Proj proj = {});                                                      // since C++20
 
   template<class T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
-    constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
+    constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {});                       // since C++20
 
   template<copyable T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
-    constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {});         // since C++20
+    constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {});                               // since C++20
 
  template<input_range R, class Proj = identity,
           indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
    requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
    constexpr range_value_t<R>
-     min(R&& r, Comp comp = {}, Proj proj = {});                                    // since C++20
+     min(R&& r, Comp comp = {}, Proj proj = {});                                                          // since C++20
 
   template<class T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
-    constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
+    constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {});                       // since C++20
 
   template<copyable T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
-    constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {});         // since C++20
+    constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {});                               // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
     requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
     constexpr range_value_t<R>
-      max(R&& r, Comp comp = {}, Proj proj = {});                                   // since C++20
+      max(R&& r, Comp comp = {}, Proj proj = {});                                                         // since C++20
 
   template<class I, class O>
-    using unary_transform_result = in_out_result<I, O>;                             // since C++20
+    using unary_transform_result = in_out_result<I, O>;                                                   // since C++20
 
   template<class I1, class I2, class O>
-    using binary_transform_result = in_in_out_result<I1, I2, O>;                    // since C++20
+    using binary_transform_result = in_in_out_result<I1, I2, O>;                                          // since C++20
 
   template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
            copy_constructible F, class Proj = identity>
     requires indirectly_writable<O, indirect_result_t<F&, projected<I, Proj>>>
     constexpr ranges::unary_transform_result<I, O>
-      transform(I first1, S last1, O result, F op, Proj proj = {});                 // since C++20
+      transform(I first1, S last1, O result, F op, Proj proj = {});                                       // since C++20
 
   template<input_range R, weakly_incrementable O, copy_constructible F,
            class Proj = identity>
     requires indirectly_writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>>
     constexpr ranges::unary_transform_result<borrowed_iterator_t<R>, O>
-      transform(R&& r, O result, F op, Proj proj = {});                             // since C++20
+      transform(R&& r, O result, F op, Proj proj = {});                                                   // since C++20
 
   template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
            weakly_incrementable O, copy_constructible F, class Proj1 = identity,
@@ -152,7 +152,7 @@ namespace ranges {
                                            projected<I2, Proj2>>>
     constexpr ranges::binary_transform_result<I1, I2, O>
       transform(I1 first1, S1 last1, I2 first2, S2 last2, O result,
-                        F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});           // since C++20
+                        F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});                                 // since C++20
 
   template<input_range R1, input_range R2, weakly_incrementable O,
            copy_constructible F, class Proj1 = identity, class Proj2 = identity>
@@ -160,27 +160,27 @@ namespace ranges {
                                            projected<iterator_t<R2>, Proj2>>>
     constexpr ranges::binary_transform_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
       transform(R1&& r1, R2&& r2, O result,
-                        F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});           // since C++20
+                        F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});                                 // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
     constexpr iter_difference_t<I>
-      count(I first, S last, const T& value, Proj proj = {});                       // since C++20
+      count(I first, S last, const T& value, Proj proj = {});                                             // since C++20
 
   template<input_range R, class T, class Proj = identity>
     requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
     constexpr range_difference_t<R>
-      count(R&& r, const T& value, Proj proj = {});                                 // since C++20
+      count(R&& r, const T& value, Proj proj = {});                                                       // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
     constexpr iter_difference_t<I>
-      count_if(I first, S last, Pred pred, Proj proj = {});                         // since C++20
+      count_if(I first, S last, Pred pred, Proj proj = {});                                               // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     constexpr range_difference_t<R>
-      count_if(R&& r, Pred pred, Proj proj = {});                                   // since C++20
+      count_if(R&& r, Pred pred, Proj proj = {});                                                         // since C++20
 
   template<class T>
   using minmax_result = min_max_result<T>;
@@ -188,18 +188,18 @@ namespace ranges {
   template<class T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_result<const T&>
-      minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {});                     // since C++20
+      minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {});                                     // since C++20
 
   template<copyable T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_result<T>
-      minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {});                      // since C++20
+      minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {});                                      // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
     requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
     constexpr ranges::minmax_result<range_value_t<R>>
-      minmax(R&& r, Comp comp = {}, Proj proj = {});                                      // since C++20
+      minmax(R&& r, Comp comp = {}, Proj proj = {});                                                      // since C++20
 
   template<class I>
   using minmax_element_result = min_max_result<I>;
@@ -207,18 +207,18 @@ namespace ranges {
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_element_result<I>
-      minmax_element(I first, S last, Comp comp = {}, Proj proj = {});                    // since C++20
+      minmax_element(I first, S last, Comp comp = {}, Proj proj = {});                                    // since C++20
 
   template<forward_range R, class Proj = identity,
            indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_element_result<borrowed_iterator_t<R>>
-      minmax_element(R&& r, Comp comp = {}, Proj proj = {});                              // since C++20
+      minmax_element(R&& r, Comp comp = {}, Proj proj = {});                                              // since C++20
 
   template<class I, class O>
-    using copy_result = in_out_result<I, O>;                                              // since C++20
+    using copy_result = in_out_result<I, O>;                                                // since C++20
 
   template<class I, class O>
-    using copy_n_result = in_out_result<I, O>;                                            // since C++20
+    using copy_n_result = in_out_result<I, O>;                                              // since C++20
 
   template<class I, class O>
     using copy_if_result = in_out_result<I, O>;                                             // since C++20
@@ -333,20 +333,20 @@ namespace ranges {
 
   template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
-    constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {});                // Since C++20
+    constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {});                // since C++20
 
   template<random_access_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
-    constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {});                          // Since C++20
+    constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {});                          // since C++20
 
   template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
-    constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {});             // Since C++20
+    constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {});             // since C++20
 
   template<random_access_range R, class Proj = identity,
            indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
     constexpr borrowed_iterator_t<R>
-      is_heap_until(R&& r, Comp comp = {}, Proj proj = {});                                 // Since C++20
+      is_heap_until(R&& r, Comp comp = {}, Proj proj = {});                                 // since C++20
 
   template<bidirectional_iterator I, sentinel_for<I> S>
     requires permutable<I>
@@ -399,15 +399,24 @@ namespace ranges {
 
   template<input_or_output_iterator O, sentinel_for<O> S, copy_constructible F>
     requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
-    constexpr O generate(O first, S last, F gen);                                           // Since C++20
+    constexpr O generate(O first, S last, F gen);                                           // since C++20
+
+  template<class ExecutionPolicy, class ForwardIterator, class Generator>
+    void generate(ExecutionPolicy&& exec,
+                  ForwardIterator first, ForwardIterator last,
+                  Generator gen);                                                           // since C++17
 
   template<class R, copy_constructible F>
     requires invocable<F&> && output_range<R, invoke_result_t<F&>>
-    constexpr borrowed_iterator_t<R> generate(R&& r, F gen);                                // Since C++20
+    constexpr borrowed_iterator_t<R> generate(R&& r, F gen);                                // since C++20
 
   template<input_or_output_iterator O, copy_constructible F>
     requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
-    constexpr O generate_n(O first, iter_difference_t<O> n, F gen);                         // Since C++20
+    constexpr O generate_n(O first, iter_difference_t<O> n, F gen);                         // since C++20
+
+  template<class ExecutionPolicy, class ForwardIterator, class Size, class Generator>
+    ForwardIterator generate_n(ExecutionPolicy&& exec,
+                               ForwardIterator first, Size n, Generator gen);               // since C++17
 
  template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
@@ -424,27 +433,39 @@ namespace ranges {
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {});      // since C++20
+    constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {});              // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
-    constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {});                // since C++20
+    constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {});                        // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {});      // since C++20
+    constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {});              // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
-    constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {});                // since C++20
+    constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {});                        // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {});     // since C++20
+    constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {});             // since C++20
 
   template<input_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
-    constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {});               // since C++20
+    constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {});                       // since C++20
+
+  template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+          class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+    requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+    constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
+                                      Proj1 proj1 = {}, Proj2 proj2 = {});                 // since C++23
+
+  template<input_range R1, input_range R2, class Pred = ranges::equal_to, class Proj1 = identity,
+          class Proj2 = identity>
+    requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+    constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {},
+                                      Proj1 proj1 = {}, Proj2 proj2 = {});                // since C++23
 
   template<input_iterator I1, sentinel_for<I1> S1,
           random_access_iterator I2, sentinel_for<I2> S2,
@@ -453,7 +474,7 @@ namespace ranges {
             indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>>
     constexpr partial_sort_copy_result<I1, I2>
       partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last,
-                        Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});        // Since C++20
+                        Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});                // since C++20
 
   template<input_range R1, random_access_range R2, class Comp = ranges::less,
           class Proj1 = identity, class Proj2 = identity>
@@ -463,7 +484,7 @@ namespace ranges {
                                         projected<iterator_t<R2>, Proj2>>
     constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
       partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {},
-                        Proj1 proj1 = {}, Proj2 proj2 = {});                        // Since C++20
+                        Proj1 proj1 = {}, Proj2 proj2 = {});                                // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
@@ -486,64 +507,64 @@ namespace ranges {
           class Proj = identity>
     requires sortable<I, Comp, Proj>
     constexpr I
-      ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {});            // since C++20
+      ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {});          // since C++20
 
   template<random_access_range R, class Comp = ranges::less, class Proj = identity>
     requires sortable<iterator_t<R>, Comp, Proj>
     constexpr borrowed_iterator_t<R>
-      ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {});          // since C++20
+      ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {});        // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
-           indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
-    constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
+           indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>    // since C++20
+    constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {});
 
   template<forward_range R, class T, class Proj = identity,
            indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
              ranges::less>
     constexpr borrowed_iterator_t<R>
-      upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {});                     // since C++20
+      upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {});                   // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
            indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
     constexpr I lower_bound(I first, S last, const T& value, Comp comp = {},
-                                    Proj proj = {});                                          // since C++20
+                                    Proj proj = {});                                        // since C++20
   template<forward_range R, class T, class Proj = identity,
            indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
              ranges::less>
     constexpr borrowed_iterator_t<R>
-      lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {});                     // since C++20
+      lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {});                   // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
            indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
     constexpr bool binary_search(I first, S last, const T& value, Comp comp = {},
-                                         Proj proj = {});                                     // since C++20
+                                         Proj proj = {});                                   // since C++20
 
   template<forward_range R, class T, class Proj = identity,
            indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
              ranges::less>
     constexpr bool binary_search(R&& r, const T& value, Comp comp = {},
-                                         Proj proj = {});                                     // since C++20
+                                         Proj proj = {});                                   // since C++20
 
   template<permutable I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
     constexpr subrange<I>
-      partition(I first, S last, Pred pred, Proj proj = {});                                  // Since C++20
+      partition(I first, S last, Pred pred, Proj proj = {});                                // since C++20
 
   template<forward_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     requires permutable<iterator_t<R>>
     constexpr borrowed_subrange_t<R>
-      partition(R&& r, Pred pred, Proj proj = {});                                            // Since C++20
+      partition(R&& r, Pred pred, Proj proj = {});                                          // since C++20
 
   template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
     requires permutable<I>
-    subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {});                 // Since C++20
+    subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {});               // since C++20
 
   template<bidirectional_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     requires permutable<iterator_t<R>>
-    borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {});                // Since C++20
+    borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {});              // since C++20
 
   template<input_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2,
            class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
@@ -563,7 +584,7 @@ namespace ranges {
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_binary_predicate<projected<I, Proj>,
                                      projected<I, Proj>> Pred = ranges::equal_to>
-    constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {});     // since C+20
+    constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {});     // since C++20
 
   template<forward_range R, class Proj = identity,
            indirect_binary_predicate<projected<iterator_t<R>, Proj>,
@@ -604,7 +625,7 @@ namespace ranges {
                                       projected<I2, Proj2>> Comp = ranges::less>
     constexpr bool
       ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2,
-                                      Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});    // since C++20
+                                      Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});          // since C++20
 
   template<input_range R1, input_range R2, class Proj1 = identity,
            class Proj2 = identity,
@@ -612,7 +633,7 @@ namespace ranges {
                                       projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
     constexpr bool
       ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {},
-                                      Proj1 proj1 = {}, Proj2 proj2 = {});                    // since C++20
+                                      Proj1 proj1 = {}, Proj2 proj2 = {});                          // since C++20
 
   template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
     requires indirectly_movable<I1, I2>
@@ -643,7 +664,7 @@ namespace ranges {
     requires indirectly_copyable<I, O1> && indirectly_copyable<I, O2>
     constexpr partition_copy_result<I, O1, O2>
       partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred,
-                    Proj proj = {});                                                                // Since C++20
+                    Proj proj = {});                                                                // since C++20
 
   template<input_range R, weakly_incrementable O1, weakly_incrementable O2,
           class Proj = identity,
@@ -651,16 +672,16 @@ namespace ranges {
     requires indirectly_copyable<iterator_t<R>, O1> &&
             indirectly_copyable<iterator_t<R>, O2>
     constexpr partition_copy_result<borrowed_iterator_t<R>, O1, O2>
-      partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {});                  // Since C++20
+      partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {});                  // since C++20
 
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_unary_predicate<projected<I, Proj>> Pred>
-    constexpr I partition_point(I first, S last, Pred pred, Proj proj = {});                        // Since C++20
+    constexpr I partition_point(I first, S last, Pred pred, Proj proj = {});                        // since C++20
 
   template<forward_range R, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     constexpr borrowed_iterator_t<R>
-      partition_point(R&& r, Pred pred, Proj proj = {});                                            // Since C++20
+      partition_point(R&& r, Pred pred, Proj proj = {});                                            // since C++20
 
   template<class I1, class I2, class O>
     using merge_result = in_in_out_result<I1, I2, O>;                                               // since C++20
@@ -755,7 +776,7 @@ namespace ranges {
 
   template<forward_range R>
     requires permutable<iterator_t<R>>
-    constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle);                           // Since C++20
+    constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle);                           // since C++20
 
   template <class _InIter, class _OutIter>
   using rotate_copy_result = in_out_result<_InIter, _OutIter>;                                      // since C++20
@@ -774,23 +795,23 @@ namespace ranges {
     requires (forward_iterator<I> || random_access_iterator<O>) &&
             indirectly_copyable<I, O> &&
             uniform_random_bit_generator<remove_reference_t<Gen>>
-    O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g);                              // Since C++20
+    O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g);                              // since C++20
 
   template<input_range R, weakly_incrementable O, class Gen>
     requires (forward_range<R> || random_access_iterator<O>) &&
             indirectly_copyable<iterator_t<R>, O> &&
             uniform_random_bit_generator<remove_reference_t<Gen>>
-    O sample(R&& r, O out, range_difference_t<R> n, Gen&& g);                                       // Since C++20
+    O sample(R&& r, O out, range_difference_t<R> n, Gen&& g);                                       // since C++20
 
   template<random_access_iterator I, sentinel_for<I> S, class Gen>
     requires permutable<I> &&
             uniform_random_bit_generator<remove_reference_t<Gen>>
-    I shuffle(I first, S last, Gen&& g);                                                           // Since C++20
+    I shuffle(I first, S last, Gen&& g);                                                            // since C++20
 
   template<random_access_range R, class Gen>
     requires permutable<iterator_t<R>> &&
             uniform_random_bit_generator<remove_reference_t<Gen>>
-    borrowed_iterator_t<R> shuffle(R&& r, Gen&& g);                                                // Since C++20
+    borrowed_iterator_t<R> shuffle(R&& r, Gen&& g);                                                 // since C++20
 
   template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
          sentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,
@@ -798,14 +819,14 @@ namespace ranges {
                                        projected<I2, Proj2>> Pred = ranges::equal_to>
   constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
                                         Pred pred = {},
-                                        Proj1 proj1 = {}, Proj2 proj2 = {});                       // Since C++20
+                                        Proj1 proj1 = {}, Proj2 proj2 = {});                       // since C++20
 
   template<forward_range R1, forward_range R2,
          class Proj1 = identity, class Proj2 = identity,
          indirect_equivalence_relation<projected<iterator_t<R1>, Proj1>,
                                        projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to>
   constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {},
-                                        Proj1 proj1 = {}, Proj2 proj2 = {});                       // Since C++20
+                                        Proj1 proj1 = {}, Proj2 proj2 = {});                       // since C++20
 
   template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
            sentinel_for<I2> S2, class Pred = ranges::equal_to,
@@ -904,35 +925,35 @@ namespace ranges {
            indirect_strict_weak_order<projected<I1, Proj1>, projected<I2, Proj2>> Comp =
              ranges::less>
     constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {},
-                            Proj1 proj1 = {}, Proj2 proj2 = {});                                   // Since C++20
+                            Proj1 proj1 = {}, Proj2 proj2 = {});                                   // since C++20
 
   template<input_range R1, input_range R2, class Proj1 = identity,
            class Proj2 = identity,
            indirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,
                                       projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
     constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {},
-                            Proj1 proj1 = {}, Proj2 proj2 = {});                                   // Since C++20
+                            Proj1 proj1 = {}, Proj2 proj2 = {});                                   // since C++20
 
   template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
            class Proj = identity>
     requires sortable<I, Comp, Proj>
-    I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {});                    // Since C++20
+    I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {});                    // since C++20
 
   template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
     requires sortable<iterator_t<R>, Comp, Proj>
     borrowed_iterator_t<R>
       inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {},
-                    Proj proj = {});                                                               // Since C++20
+                    Proj proj = {});                                                               // since C++20
 
   template<permutable I, sentinel_for<I> S, class Proj = identity,
            indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
-    constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {});                    // Since C++20
+    constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {});                    // since C++20
 
   template<forward_range R, class Proj = identity,
            indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
     requires permutable<iterator_t<R>>
     constexpr borrowed_subrange_t<R>
-      unique(R&& r, C comp = {}, Proj proj = {});                                                  // Since C++20
+      unique(R&& r, C comp = {}, Proj proj = {});                                                  // since C++20
 
   template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity,
            indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
@@ -941,7 +962,7 @@ namespace ranges {
               (input_iterator<O> && same_as<iter_value_t<I>, iter_value_t<O>>) ||
               indirectly_copyable_storable<I, O>)
     constexpr unique_copy_result<I, O>
-      unique_copy(I first, S last, O result, C comp = {}, Proj proj = {});                         // Since C++20
+      unique_copy(I first, S last, O result, C comp = {}, Proj proj = {});                         // since C++20
 
   template<input_range R, weakly_incrementable O, class Proj = identity,
            indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
@@ -950,41 +971,41 @@ namespace ranges {
               (input_iterator<O> && same_as<range_value_t<R>, iter_value_t<O>>) ||
               indirectly_copyable_storable<iterator_t<R>, O>)
     constexpr unique_copy_result<borrowed_iterator_t<R>, O>
-      unique_copy(R&& r, O result, C comp = {}, Proj proj = {});                                   // Since C++20
+      unique_copy(R&& r, O result, C comp = {}, Proj proj = {});                                   // since C++20
 
   template<class I, class O>
-      using remove_copy_result = in_out_result<I, O>;                                              // Since C++20
+      using remove_copy_result = in_out_result<I, O>;                                              // since C++20
 
   template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T,
            class Proj = identity>
              indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
     constexpr remove_copy_result<I, O>
-      remove_copy(I first, S last, O result, const T& value, Proj proj = {});                      // Since C++20
+      remove_copy(I first, S last, O result, const T& value, Proj proj = {});                      // since C++20
 
   template<input_range R, weakly_incrementable O, class T, class Proj = identity>
     requires indirectly_copyable<iterator_t<R>, O> &&
              indirect_binary_predicate<ranges::equal_to,
                                        projected<iterator_t<R>, Proj>, const T*>
     constexpr remove_copy_result<borrowed_iterator_t<R>, O>
-      remove_copy(R&& r, O result, const T& value, Proj proj = {});                                // Since C++20
+      remove_copy(R&& r, O result, const T& value, Proj proj = {});                                // since C++20
 
   template<class I, class O>
-      using remove_copy_if_result = in_out_result<I, O>;                                           // Since C++20
+      using remove_copy_if_result = in_out_result<I, O>;                                           // since C++20
 
   template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
            class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
     requires indirectly_copyable<I, O>
     constexpr remove_copy_if_result<I, O>
-      remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {});                        // Since C++20
+      remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {});                        // since C++20
 
   template<input_range R, weakly_incrementable O, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     requires indirectly_copyable<iterator_t<R>, O>
     constexpr remove_copy_if_result<borrowed_iterator_t<R>, O>
-      remove_copy_if(R&& r, O result, Pred pred, Proj proj = {});                                  // Since C++20
+      remove_copy_if(R&& r, O result, Pred pred, Proj proj = {});                                  // since C++20
 
   template<class I, class O>
-      using replace_copy_result = in_out_result<I, O>;                                             // Since C++20
+      using replace_copy_result = in_out_result<I, O>;                                             // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class T1, class T2,
            output_iterator<const T2&> O, class Proj = identity>
@@ -992,7 +1013,7 @@ namespace ranges {
              indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
     constexpr replace_copy_result<I, O>
       replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value,
-                   Proj proj = {});                                                                // Since C++20
+                   Proj proj = {});                                                                // since C++20
 
   template<input_range R, class T1, class T2, output_iterator<const T2&> O,
            class Proj = identity>
@@ -1001,54 +1022,54 @@ namespace ranges {
                                        projected<iterator_t<R>, Proj>, const T1*>
     constexpr replace_copy_result<borrowed_iterator_t<R>, O>
       replace_copy(R&& r, O result, const T1& old_value, const T2& new_value,
-                   Proj proj = {});                                                                // Since C++20
+                   Proj proj = {});                                                                // since C++20
 
   template<class I, class O>
-      using replace_copy_if_result = in_out_result<I, O>;                                          // Since C++20
+      using replace_copy_if_result = in_out_result<I, O>;                                          // since C++20
 
   template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O,
            class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
     requires indirectly_copyable<I, O>
     constexpr replace_copy_if_result<I, O>
       replace_copy_if(I first, S last, O result, Pred pred, const T& new_value,
-                      Proj proj = {});                                                             // Since C++20
+                      Proj proj = {});                                                             // since C++20
 
   template<input_range R, class T, output_iterator<const T&> O, class Proj = identity,
            indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
     requires indirectly_copyable<iterator_t<R>, O>
     constexpr replace_copy_if_result<borrowed_iterator_t<R>, O>
       replace_copy_if(R&& r, O result, Pred pred, const T& new_value,
-                      Proj proj = {});                                                             // Since C++20
+                      Proj proj = {});                                                             // since C++20
 
   template<class I>
-    using prev_permutation_result = in_found_result<I>;                                            // Since C++20
+    using prev_permutation_result = in_found_result<I>;                                            // since C++20
 
   template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
            class Proj = identity>
     requires sortable<I, Comp, Proj>
     constexpr ranges::prev_permutation_result<I>
-      ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {});                   // Since C++20
+      ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {});                   // since C++20
 
   template<bidirectional_range R, class Comp = ranges::less,
            class Proj = identity>
     requires sortable<iterator_t<R>, Comp, Proj>
     constexpr ranges::prev_permutation_result<borrowed_iterator_t<R>>
-      ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {});                             // Since C++20
+      ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {});                             // since C++20
 
   template<class I>
-    using next_permutation_result = in_found_result<I>;                                            // Since C++20
+    using next_permutation_result = in_found_result<I>;                                            // since C++20
 
   template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
            class Proj = identity>
     requires sortable<I, Comp, Proj>
     constexpr ranges::next_permutation_result<I>
-      ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {});                   // Since C++20
+      ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {});                   // since C++20
 
   template<bidirectional_range R, class Comp = ranges::less,
            class Proj = identity>
     requires sortable<iterator_t<R>, Comp, Proj>
     constexpr ranges::next_permutation_result<borrowed_iterator_t<R>>
-      ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {});                             // Since C++20
+      ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {});                             // since C++20
 
 }
 
@@ -1684,6 +1705,18 @@ template <class InputIterator1, class InputIterator2, class Compare>
     lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2, Compare comp);
 
+template<class InputIterator1, class InputIterator2, class Cmp>
+    constexpr auto
+    lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1,
+                                      InputIterator2 first2, InputIterator2 last2,
+                                      Cmp comp)
+      -> decltype(comp(*b1, *b2));                                                        // since C++20
+
+template<class InputIterator1, class InputIterator2>
+    constexpr auto
+    lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1,
+                                      InputIterator2 first2, InputIterator2 last2);      // since C++20
+
 template <class BidirectionalIterator>
     constexpr bool     // constexpr in C++20
     next_permutation(BidirectionalIterator first, BidirectionalIterator last);
@@ -1705,9 +1738,7 @@ template <class BidirectionalIterator, class Compare>
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <cstddef>
-#include <type_traits>
 #include <version>
 
 #include <__algorithm/adjacent_find.h>
@@ -1753,6 +1784,7 @@ template <class BidirectionalIterator, class Compare>
 #include <__algorithm/is_sorted_until.h>
 #include <__algorithm/iter_swap.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/lower_bound.h>
 #include <__algorithm/make_heap.h>
 #include <__algorithm/max.h>
@@ -1776,6 +1808,19 @@ template <class BidirectionalIterator, class Compare>
 #include <__algorithm/partition_point.h>
 #include <__algorithm/pop_heap.h>
 #include <__algorithm/prev_permutation.h>
+#include <__algorithm/pstl_any_all_none_of.h>
+#include <__algorithm/pstl_copy.h>
+#include <__algorithm/pstl_count.h>
+#include <__algorithm/pstl_fill.h>
+#include <__algorithm/pstl_find.h>
+#include <__algorithm/pstl_for_each.h>
+#include <__algorithm/pstl_generate.h>
+#include <__algorithm/pstl_is_partitioned.h>
+#include <__algorithm/pstl_merge.h>
+#include <__algorithm/pstl_replace.h>
+#include <__algorithm/pstl_sort.h>
+#include <__algorithm/pstl_stable_sort.h>
+#include <__algorithm/pstl_transform.h>
 #include <__algorithm/push_heap.h>
 #include <__algorithm/ranges_adjacent_find.h>
 #include <__algorithm/ranges_all_of.h>
@@ -1857,6 +1902,7 @@ template <class BidirectionalIterator, class Compare>
 #include <__algorithm/ranges_sort_heap.h>
 #include <__algorithm/ranges_stable_partition.h>
 #include <__algorithm/ranges_stable_sort.h>
+#include <__algorithm/ranges_starts_with.h>
 #include <__algorithm/ranges_swap_ranges.h>
 #include <__algorithm/ranges_transform.h>
 #include <__algorithm/ranges_unique.h>
@@ -1905,21 +1951,16 @@ template <class BidirectionalIterator, class Compare>
 #  pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
-#  include <__pstl_algorithm>
-#endif
-
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
-#  include <chrono>
-#endif
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
+#  include <bit>
 #  include <concepts>
+#  include <cstdlib>
 #  include <cstring>
 #  include <iterator>
 #  include <memory>
 #  include <stdexcept>
+#  include <type_traits>
 #  include <utility>
 #endif
 
lib/libcxx/include/any
@@ -87,13 +87,27 @@ namespace std {
 #include <__memory/allocator_destructor.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/unique_ptr.h>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/aligned_storage.h>
+#include <__type_traits/alignment_of.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
 #include <__utility/unreachable.h>
-#include <cstdlib>
+#include <__verbose_abort>
 #include <initializer_list>
-#include <type_traits>
 #include <typeinfo>
 #include <version>
 
@@ -101,8 +115,11 @@ namespace std {
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 namespace std {
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
 {
 public:
     const char* what() const _NOEXCEPT override;
@@ -111,16 +128,16 @@ public:
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
 void __throw_bad_any_cast()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw bad_any_cast();
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
 #endif
 }
 
@@ -311,7 +328,7 @@ private:
       const void* __fallback_info);
 
     union _Storage {
-        constexpr _Storage() : __ptr(nullptr) {}
+        _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
         void *  __ptr;
         __any_imp::_Buffer __buf;
     };
@@ -692,10 +709,12 @@ any_cast(any * __any) _NOEXCEPT
     return nullptr;
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
 #  include <chrono>
 #endif
@@ -703,9 +722,12 @@ _LIBCPP_END_NAMESPACE_STD
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iosfwd>
 #  include <iterator>
 #  include <memory>
+#  include <stdexcept>
+#  include <type_traits>
 #  include <variant>
 #endif
 
lib/libcxx/include/array
@@ -77,15 +77,18 @@ template <class T, class... U>
 template <class T, size_t N>
   bool operator==(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
 template <class T, size_t N>
-  bool operator!=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
+  bool operator!=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
 template <class T, size_t N>
-  bool operator<(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
+  bool operator<(const array<T,N>& x, const array<T,N>& y);     // removed in C++20
 template <class T, size_t N>
-  bool operator>(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
+  bool operator>(const array<T,N>& x, const array<T,N>& y);     // removed in C++20
 template <class T, size_t N>
-  bool operator<=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
+  bool operator<=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
 template <class T, size_t N>
-  bool operator>=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
+  bool operator>=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
+template<class T, size_t N>
+  constexpr synth-three-way-result<T>
+    operator<=>(const array<T, N>& x, const array<T, N>& y);    // since C++20
 
 template <class T, size_t N >
   void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
@@ -111,16 +114,27 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
 #include <__algorithm/equal.h>
 #include <__algorithm/fill_n.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/swap_ranges.h>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__fwd/array.h>
 #include <__iterator/reverse_iterator.h>
-#include <__tuple_dir/sfinae_helpers.h>
+#include <__tuple/sfinae_helpers.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/remove_cv.h>
 #include <__utility/integer_sequence.h>
 #include <__utility/move.h>
 #include <__utility/unreachable.h>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -137,8 +151,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
 #include <initializer_list>
 
 // [tuple.helper]
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_size.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -215,23 +229,23 @@ struct _LIBCPP_TEMPLATE_VIS array
     // element access:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference operator[](size_type __n) _NOEXCEPT {
-        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
         return __elems_[__n];
     }
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
     const_reference operator[](size_type __n) const _NOEXCEPT {
-        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
         return __elems_[__n];
     }
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
     {
         if (__n >= _Size)
             __throw_out_of_range("array::at");
         return __elems_[__n];
     }
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
     {
         if (__n >= _Size)
             __throw_out_of_range("array::at");
@@ -328,13 +342,13 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
     // element access:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference operator[](size_type) _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
       __libcpp_unreachable();
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
     const_reference operator[](size_type) const _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
       __libcpp_unreachable();
     }
 
@@ -352,31 +366,31 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference front() _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
       __libcpp_unreachable();
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
     const_reference front() const _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
       __libcpp_unreachable();
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
     reference back() _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
       __libcpp_unreachable();
     }
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
     const_reference back() const _NOEXCEPT {
-      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
       __libcpp_unreachable();
     }
 };
 
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Tp, class... _Args,
          class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
          >
@@ -392,47 +406,44 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
     return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
-{
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
     return !(__x == __y);
 }
 
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
-{
-    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
-                                          __y.begin(), __y.end());
+inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
 }
 
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
-{
+inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
     return __y < __x;
 }
 
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
-{
+inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
     return !(__y < __x);
 }
 
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
-{
+inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
     return !(__x < __y);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Tp, size_t _Size>
+_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
+operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
 __enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void>
@@ -489,7 +500,7 @@ get(const array<_Tp, _Size>&& __a) _NOEXCEPT
     return _VSTD::move(__a.__elems_[_Ip]);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <typename _Tp, size_t _Size, size_t... _Index>
 _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
@@ -528,14 +539,16 @@ to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
                                        make_index_sequence<_Size>());
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <algorithm>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iterator>
+#  include <type_traits>
 #  include <utility>
 #endif
 
lib/libcxx/include/atomic
@@ -519,2154 +519,39 @@ template <class T>
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
-#include <__availability>
-#include <__chrono/duration.h>
+#include <__atomic/aliases.h>
+#include <__atomic/atomic.h>
+#include <__atomic/atomic_base.h>
+#include <__atomic/atomic_flag.h>
+#include <__atomic/atomic_init.h>
+#include <__atomic/atomic_lock_free.h>
+#include <__atomic/atomic_sync.h>
+#include <__atomic/check_memory_order.h>
+#include <__atomic/contention_t.h>
+#include <__atomic/cxx_atomic_impl.h>
+#include <__atomic/fence.h>
+#include <__atomic/is_always_lock_free.h>
+#include <__atomic/kill_dependency.h>
+#include <__atomic/memory_order.h>
 #include <__config>
-#include <__thread/poll_with_backoff.h>
-#include <__thread/timed_backoff_policy.h>
-#include <__type_traits/conditional.h>
-#include <__type_traits/decay.h>
-#include <__type_traits/is_assignable.h>
-#include <__type_traits/is_function.h>
-#include <__type_traits/is_nothrow_default_constructible.h>
-#include <__type_traits/is_same.h>
-#include <__type_traits/is_trivially_copyable.h>
-#include <__type_traits/remove_const.h>
-#include <__type_traits/remove_pointer.h>
-#include <__type_traits/underlying_type.h>
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
 #include <version>
 
-#ifndef _LIBCPP_HAS_NO_THREADS
-# include <__threading_support>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
 #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
-# error <atomic> is not implemented
-#endif
-#ifdef kill_dependency
-# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
+#  error <atomic> is not implemented
 #endif
 
-#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
-  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
-                           __m == memory_order_acquire || \
-                           __m == memory_order_acq_rel,   \
-                        "memory order argument to atomic operation is invalid")
-
-#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
-  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
-                           __m == memory_order_acq_rel,   \
-                        "memory order argument to atomic operation is invalid")
-
-#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
-  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
-                           __f == memory_order_acq_rel,   \
-                        "memory order argument to atomic operation is invalid")
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// Figure out what the underlying type for `memory_order` would be if it were
-// declared as an unscoped enum (accounting for -fshort-enums). Use this result
-// to pin the underlying type in C++20.
-enum __legacy_memory_order {
-    __mo_relaxed,
-    __mo_consume,
-    __mo_acquire,
-    __mo_release,
-    __mo_acq_rel,
-    __mo_seq_cst
-};
-
-typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
-
-#if _LIBCPP_STD_VER > 17
-
-enum class memory_order : __memory_order_underlying_t {
-  relaxed = __mo_relaxed,
-  consume = __mo_consume,
-  acquire = __mo_acquire,
-  release = __mo_release,
-  acq_rel = __mo_acq_rel,
-  seq_cst = __mo_seq_cst
-};
-
-inline constexpr auto memory_order_relaxed = memory_order::relaxed;
-inline constexpr auto memory_order_consume = memory_order::consume;
-inline constexpr auto memory_order_acquire = memory_order::acquire;
-inline constexpr auto memory_order_release = memory_order::release;
-inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
-inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
-
-#else
-
-typedef enum memory_order {
-  memory_order_relaxed = __mo_relaxed,
-  memory_order_consume = __mo_consume,
-  memory_order_acquire = __mo_acquire,
-  memory_order_release = __mo_release,
-  memory_order_acq_rel = __mo_acq_rel,
-  memory_order_seq_cst = __mo_seq_cst,
-} memory_order;
-
-#endif // _LIBCPP_STD_VER > 17
-
-template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
-bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
-    return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
-}
-
-static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
-  "unexpected underlying type for std::memory_order");
-
-#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
-    defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
-
-// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
-// the default operator= in an object is not volatile, a byte-by-byte copy
-// is required.
-template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
-__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
-  __a_value = __val;
-}
-template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
-__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
-  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
-  volatile char* __end = __to + sizeof(_Tp);
-  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
-  while (__to != __end)
-    *__to++ = *__from++;
-}
-
-#endif
-
-#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
-
-template <typename _Tp>
-struct __cxx_atomic_base_impl {
-
-  _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_CXX03_LANG
-    __cxx_atomic_base_impl() _NOEXCEPT = default;
-#else
-    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
-#endif // _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
-    : __a_value(value) {}
-  _Tp __a_value;
-};
-
-_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
-  // Avoid switch statement to make this a constexpr.
-  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
-         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
-          (__order == memory_order_release ? __ATOMIC_RELEASE:
-           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
-            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
-              __ATOMIC_CONSUME))));
-}
-
-_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
-  // Avoid switch statement to make this a constexpr.
-  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
-         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
-          (__order == memory_order_release ? __ATOMIC_RELAXED:
-           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
-            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
-              __ATOMIC_CONSUME))));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
-  __cxx_atomic_assign_volatile(__a->__a_value, __val);
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
-  __a->__a_value = __val;
-}
-
-_LIBCPP_INLINE_VISIBILITY inline
-void __cxx_atomic_thread_fence(memory_order __order) {
-  __atomic_thread_fence(__to_gcc_order(__order));
-}
-
-_LIBCPP_INLINE_VISIBILITY inline
-void __cxx_atomic_signal_fence(memory_order __order) {
-  __atomic_signal_fence(__to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
-                        memory_order __order) {
-  __atomic_store(&__a->__a_value, &__val,
-                 __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
-                        memory_order __order) {
-  __atomic_store(&__a->__a_value, &__val,
-                 __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
-                      memory_order __order) {
-  _Tp __ret;
-  __atomic_load(&__a->__a_value, &__ret,
-                __to_gcc_order(__order));
-  return __ret;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
-  _Tp __ret;
-  __atomic_load(&__a->__a_value, &__ret,
-                __to_gcc_order(__order));
-  return __ret;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                          _Tp __value, memory_order __order) {
-  _Tp __ret;
-  __atomic_exchange(&__a->__a_value, &__value, &__ret,
-                    __to_gcc_order(__order));
-  return __ret;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
-                          memory_order __order) {
-  _Tp __ret;
-  __atomic_exchange(&__a->__a_value, &__value, &__ret,
-                    __to_gcc_order(__order));
-  return __ret;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(
-    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
-    memory_order __success, memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   false,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(
-    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
-    memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   false,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(
-    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
-    memory_order __success, memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   true,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(
-    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
-    memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   true,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
-}
-
-template <typename _Tp>
-struct __skip_amt { enum {value = 1}; };
-
-template <typename _Tp>
-struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
-
-// FIXME: Haven't figured out what the spec says about using arrays with
-// atomic_fetch_add. Force a failure rather than creating bad behavior.
-template <typename _Tp>
-struct __skip_amt<_Tp[]> { };
-template <typename _Tp, int n>
-struct __skip_amt<_Tp[n]> { };
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                           _Td __delta, memory_order __order) {
-  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
-                           memory_order __order) {
-  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                           _Td __delta, memory_order __order) {
-  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
-                           memory_order __order) {
-  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_and(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_and(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                          _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_or(&__a->__a_value, __pattern,
-                           __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
-                          memory_order __order) {
-  return __atomic_fetch_or(&__a->__a_value, __pattern,
-                           __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_xor(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
-                           memory_order __order) {
-  return __atomic_fetch_xor(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
-}
-
-#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
-
-#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
-
-template <typename _Tp>
-struct __cxx_atomic_base_impl {
-
-  _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_CXX03_LANG
-    __cxx_atomic_base_impl() _NOEXCEPT = default;
-#else
-    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
-#endif // _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
-    : __a_value(__value) {}
-  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
-};
-
-#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
-
-_LIBCPP_INLINE_VISIBILITY inline
-void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
-    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
-}
-
-_LIBCPP_INLINE_VISIBILITY inline
-void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
-    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
-    __c11_atomic_init(&__a->__a_value, __val);
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
-    __c11_atomic_init(&__a->__a_value, __val);
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
-    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
-    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
-    using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
-    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
-    using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
-    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
-}
-
-_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
-  // Avoid switch statement to make this a constexpr.
-  return __order == memory_order_release ? memory_order_relaxed:
-         (__order == memory_order_acq_rel ? memory_order_acquire:
-             __order);
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
-}
-
-#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp kill_dependency(_Tp __y) _NOEXCEPT
-{
-    return __y;
-}
-
-#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
-# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
-# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-# define ATOMIC_CHAR8_T_LOCK_FREE   __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
-#endif
-# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
-# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
-# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
-# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
-# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
-# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
-# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
-# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
-#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
-# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
-# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-# define ATOMIC_CHAR8_T_LOCK_FREE   __GCC_ATOMIC_CHAR8_T_LOCK_FREE
-#endif
-# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
-# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
-# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
-# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
-# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
-# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
-# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
-# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
-#endif
-
-template <class _Tp>
-struct __libcpp_is_always_lock_free {
-  // __atomic_always_lock_free is available in all Standard modes
-  static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
-};
-
-#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
-
-template<typename _Tp>
-struct __cxx_atomic_lock_impl {
-
-  _LIBCPP_INLINE_VISIBILITY
-  __cxx_atomic_lock_impl() _NOEXCEPT
-    : __a_value(), __a_lock(0) {}
-  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
-  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
-    : __a_value(value), __a_lock(0) {}
-
-  _Tp __a_value;
-  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
-
-  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
-    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
-        /*spin*/;
-  }
-  _LIBCPP_INLINE_VISIBILITY void __lock() const {
-    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
-        /*spin*/;
-  }
-  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
-    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
-  }
-  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
-    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
-  }
-  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
-    __lock();
-    _Tp __old;
-    __cxx_atomic_assign_volatile(__old, __a_value);
-    __unlock();
-    return __old;
-  }
-  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
-    __lock();
-    _Tp __old = __a_value;
-    __unlock();
-    return __old;
-  }
-};
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
-  __cxx_atomic_assign_volatile(__a->__a_value, __val);
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
-  __a->__a_value = __val;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
-  __a->__lock();
-  __cxx_atomic_assign_volatile(__a->__a_value, __val);
-  __a->__unlock();
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
-  __a->__lock();
-  __a->__a_value = __val;
-  __a->__unlock();
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
-  return __a->__read();
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
-  return __a->__read();
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, __value);
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value = __value;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
-  _Tp __temp;
-  __a->__lock();
-  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
-  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
-  if(__ret)
-    __cxx_atomic_assign_volatile(__a->__a_value, __value);
-  else
-    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
-  __a->__unlock();
-  return __ret;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
-                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
-  __a->__lock();
-  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
-  if(__ret)
-    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
-  else
-    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
-  __a->__unlock();
-  return __ret;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
-  _Tp __temp;
-  __a->__lock();
-  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
-  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
-  if(__ret)
-    __cxx_atomic_assign_volatile(__a->__a_value, __value);
-  else
-    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
-  __a->__unlock();
-  return __ret;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
-                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
-  __a->__lock();
-  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
-  if(__ret)
-    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
-  else
-    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
-  __a->__unlock();
-  return __ret;
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                           _Td __delta, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
-                           _Td __delta, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value += __delta;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
-                           ptrdiff_t __delta, memory_order) {
-  __a->__lock();
-  _Tp* __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
-                           ptrdiff_t __delta, memory_order) {
-  __a->__lock();
-  _Tp* __old = __a->__a_value;
-  __a->__a_value += __delta;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                           _Td __delta, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp, typename _Td>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
-                           _Td __delta, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value -= __delta;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value &= __pattern;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                          _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
-                          _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value |= __pattern;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old;
-  __cxx_atomic_assign_volatile(__old, __a->__a_value);
-  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
-  __a->__unlock();
-  return __old;
-}
-template <typename _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
-                           _Tp __pattern, memory_order) {
-  __a->__lock();
-  _Tp __old = __a->__a_value;
-  __a->__a_value ^= __pattern;
-  __a->__unlock();
-  return __old;
-}
-
-template <typename _Tp,
-          typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
-                                                __cxx_atomic_base_impl<_Tp>,
-                                                __cxx_atomic_lock_impl<_Tp> >::type>
-#else
-template <typename _Tp,
-          typename _Base = __cxx_atomic_base_impl<_Tp> >
-#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
-struct __cxx_atomic_impl : public _Base {
-    static_assert(is_trivially_copyable<_Tp>::value,
-      "std::atomic<T> requires that 'T' be a trivially copyable type");
-
-  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
-  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
-    : _Base(__value) {}
-};
-
-#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
-    using __cxx_contention_t = int32_t;
-#else
-    using __cxx_contention_t = int64_t;
-#endif // __linux__ || (_AIX && !__64BIT__)
-
-using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
-
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
-
-template <class _Atp, class _Fn>
-struct __libcpp_atomic_wait_backoff_impl {
-    _Atp* __a;
-    _Fn __test_fn;
-    _LIBCPP_AVAILABILITY_SYNC
-    _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
-    {
-        if(__elapsed > chrono::microseconds(64))
-        {
-            auto const __monitor = std::__libcpp_atomic_monitor(__a);
-            if(__test_fn())
-                return true;
-            std::__libcpp_atomic_wait(__a, __monitor);
-        }
-        else if(__elapsed > chrono::microseconds(4))
-            __libcpp_thread_yield();
-        else
-            {} // poll
-        return false;
-    }
-};
-
-template <class _Atp, class _Fn>
-_LIBCPP_AVAILABILITY_SYNC
-_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
-{
-    __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
-    return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
-}
-
-#else // _LIBCPP_HAS_NO_THREADS
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
-template <class _Atp, class _Fn>
-_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
-{
-    return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
-}
-
-#endif // _LIBCPP_HAS_NO_THREADS
-
-template <class _Atp, class _Tp>
-struct __cxx_atomic_wait_test_fn_impl {
-    _Atp* __a;
-    _Tp __val;
-    memory_order __order;
-    _LIBCPP_INLINE_VISIBILITY bool operator()() const
-    {
-        return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
-    }
-};
-
-template <class _Atp, class _Tp>
-_LIBCPP_AVAILABILITY_SYNC
-_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
-{
-    __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
-    return std::__cxx_atomic_wait(__a, __test_fn);
-}
-
-// general atomic<T>
-
-template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
-struct __atomic_base  // false
-{
-    mutable __cxx_atomic_impl<_Tp> __a_;
-
-#if defined(__cpp_lib_atomic_is_always_lock_free)
-  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
-#endif
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool is_lock_free() const volatile _NOEXCEPT
-        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
-    _LIBCPP_INLINE_VISIBILITY
-    bool is_lock_free() const _NOEXCEPT
-        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
-    _LIBCPP_INLINE_VISIBILITY
-    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-        {std::__cxx_atomic_store(&__a_, __d, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-        {std::__cxx_atomic_store(&__a_, __d, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-        {return std::__cxx_atomic_load(&__a_, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-        {return std::__cxx_atomic_load(&__a_, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    operator _Tp() const volatile _NOEXCEPT {return load();}
-    _LIBCPP_INLINE_VISIBILITY
-    operator _Tp() const _NOEXCEPT          {return load();}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __s, memory_order __f) volatile _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __s, memory_order __f) _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __s, memory_order __f) _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
-
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-        {std::__cxx_atomic_wait(&__a_, __v, __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-        {std::__cxx_atomic_wait(&__a_, __v, __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
-        {std::__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
-        {std::__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
-        {std::__cxx_atomic_notify_all(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
-        {std::__cxx_atomic_notify_all(&__a_);}
-
-#if _LIBCPP_STD_VER > 17
-    _LIBCPP_INLINE_VISIBILITY constexpr
-    __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
-#else
-    _LIBCPP_INLINE_VISIBILITY
-    __atomic_base() _NOEXCEPT = default;
-#endif
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
-
-    __atomic_base(const __atomic_base&) = delete;
-};
-
-#if defined(__cpp_lib_atomic_is_always_lock_free)
-template <class _Tp, bool __b>
-_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
-#endif
-
-// atomic<Integral>
-
-template <class _Tp>
-struct __atomic_base<_Tp, true>
-    : public __atomic_base<_Tp, false>
-{
-    typedef __atomic_base<_Tp, false> __base;
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __atomic_base() _NOEXCEPT = default;
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
-};
-
-// atomic<T>
-
-template <class _Tp>
-struct atomic
-    : public __atomic_base<_Tp>
-{
-    typedef __atomic_base<_Tp> __base;
-    typedef _Tp value_type;
-    typedef value_type difference_type;
-
-#if _LIBCPP_STD_VER > 17
-    _LIBCPP_INLINE_VISIBILITY
-    atomic() = default;
-#else
-    _LIBCPP_INLINE_VISIBILITY
-    atomic() _NOEXCEPT = default;
-#endif
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator=(_Tp __d) volatile _NOEXCEPT
-        {__base::store(__d); return __d;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp operator=(_Tp __d) _NOEXCEPT
-        {__base::store(__d); return __d;}
-
-    atomic& operator=(const atomic&) = delete;
-    atomic& operator=(const atomic&) volatile = delete;
-};
-
-// atomic<T*>
-
-template <class _Tp>
-struct atomic<_Tp*>
-    : public __atomic_base<_Tp*>
-{
-    typedef __atomic_base<_Tp*> __base;
-    typedef _Tp* value_type;
-    typedef ptrdiff_t difference_type;
-
-    _LIBCPP_INLINE_VISIBILITY
-    atomic() _NOEXCEPT = default;
-
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
-        {__base::store(__d); return __d;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator=(_Tp* __d) _NOEXCEPT
-        {__base::store(__d); return __d;}
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
-        // __atomic_fetch_add accepts function pointers, guard against them.
-        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
-        // __atomic_fetch_add accepts function pointers, guard against them.
-        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
-        // __atomic_fetch_add accepts function pointers, guard against them.
-        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
-        // __atomic_fetch_add accepts function pointers, guard against them.
-        static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
-    _LIBCPP_INLINE_VISIBILITY
-    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
-
-    atomic& operator=(const atomic&) = delete;
-    atomic& operator=(const atomic&) volatile = delete;
-};
-
-// atomic_is_lock_free
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
-{
-    return __o->is_lock_free();
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
-{
-    return __o->is_lock_free();
-}
-
-// atomic_init
-
-template <class _Tp>
-_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
-void
-atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    std::__cxx_atomic_init(&__o->__a_, __d);
-}
-
-template <class _Tp>
-_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
-void
-atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    std::__cxx_atomic_init(&__o->__a_, __d);
-}
-
-// atomic_store
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void
-atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    __o->store(__d);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void
-atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    __o->store(__d);
-}
-
-// atomic_store_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void
-atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-{
-    __o->store(__d, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-void
-atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-{
-    __o->store(__d, __m);
-}
-
-// atomic_load
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
-{
-    return __o->load();
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
-{
-    return __o->load();
-}
-
-// atomic_load_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-{
-    return __o->load(__m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-{
-    return __o->load(__m);
-}
-
-// atomic_exchange
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->exchange(__d);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->exchange(__d);
-}
-
-// atomic_exchange_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
-{
-    return __o->exchange(__d, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
-{
-    return __o->exchange(__d, __m);
-}
-
-// atomic_compare_exchange_weak
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->compare_exchange_weak(*__e, __d);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->compare_exchange_weak(*__e, __d);
-}
-
-// atomic_compare_exchange_strong
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->compare_exchange_strong(*__e, __d);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
-{
-    return __o->compare_exchange_strong(*__e, __d);
-}
-
-// atomic_compare_exchange_weak_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
-                                      typename atomic<_Tp>::value_type __d,
-                                      memory_order __s, memory_order __f) _NOEXCEPT
-  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-{
-    return __o->compare_exchange_weak(*__e, __d, __s, __f);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
-                                      memory_order __s, memory_order __f) _NOEXCEPT
-  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-{
-    return __o->compare_exchange_weak(*__e, __d, __s, __f);
-}
-
-// atomic_compare_exchange_strong_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
-                                        typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
-                                        memory_order __s, memory_order __f) _NOEXCEPT
-  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-{
-    return __o->compare_exchange_strong(*__e, __d, __s, __f);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-bool
-atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
-                                        typename atomic<_Tp>::value_type __d,
-                                        memory_order __s, memory_order __f) _NOEXCEPT
-  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-{
-    return __o->compare_exchange_strong(*__e, __d, __s, __f);
-}
-
-// atomic_wait
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_wait(const volatile atomic<_Tp>* __o,
-                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
-{
-    return __o->wait(__v);
-}
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_wait(const atomic<_Tp>* __o,
-                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
-{
-    return __o->wait(__v);
-}
-
-// atomic_wait_explicit
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
-                          typename atomic<_Tp>::value_type __v,
-                          memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-{
-    return __o->wait(__v, __m);
-}
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_wait_explicit(const atomic<_Tp>* __o,
-                          typename atomic<_Tp>::value_type __v,
-                          memory_order __m) _NOEXCEPT
-  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-{
-    return __o->wait(__v, __m);
-}
-
-// atomic_notify_one
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
-{
-    __o->notify_one();
-}
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
-{
-    __o->notify_one();
-}
-
-// atomic_notify_all
-
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
-{
-    __o->notify_all();
-}
-template <class _Tp>
-_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
-{
-    __o->notify_all();
-}
-
-// atomic_fetch_add
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
-{
-    return __o->fetch_add(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp
-atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
-{
-    return __o->fetch_add(__op);
-}
-
-// atomic_fetch_add_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_add(__op, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_add(__op, __m);
-}
-
-// atomic_fetch_sub
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
-{
-    return __o->fetch_sub(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
-{
-    return __o->fetch_sub(__op);
-}
-
-// atomic_fetch_sub_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_sub(__op, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_sub(__op, __m);
-}
-
-// atomic_fetch_and
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_and(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_and(__op);
-}
-
-// atomic_fetch_and_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_and(__op, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_and(__op, __m);
-}
-
-// atomic_fetch_or
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_or(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_or(__op);
-}
-
-// atomic_fetch_or_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_or(__op, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_or(__op, __m);
-}
-
-// atomic_fetch_xor
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_xor(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
-{
-    return __o->fetch_xor(__op);
-}
-
-// atomic_fetch_xor_explicit
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_xor(__op, __m);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
-    _Tp
->::type
-atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
-{
-    return __o->fetch_xor(__op, __m);
-}
-
-// flag type and operations
-
-typedef struct atomic_flag
-{
-    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
-    _LIBCPP_INLINE_VISIBILITY
-    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
-
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void notify_one() volatile _NOEXCEPT
-        {__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void notify_one() _NOEXCEPT
-        {__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void notify_all() volatile _NOEXCEPT
-        {__cxx_atomic_notify_all(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    void notify_all() _NOEXCEPT
-        {__cxx_atomic_notify_all(&__a_);}
-
-#if _LIBCPP_STD_VER > 17
-    _LIBCPP_INLINE_VISIBILITY constexpr
-    atomic_flag() _NOEXCEPT : __a_(false) {}
-#else
-    _LIBCPP_INLINE_VISIBILITY
-    atomic_flag() _NOEXCEPT = default;
-#endif
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
-
-    atomic_flag(const atomic_flag&) = delete;
-    atomic_flag& operator=(const atomic_flag&) = delete;
-    atomic_flag& operator=(const atomic_flag&) volatile = delete;
-
-} atomic_flag;
-
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
-{
-    return __o->test();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
-{
-    return __o->test();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    return __o->test(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    return __o->test(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
-{
-    return __o->test_and_set();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
-{
-    return __o->test_and_set();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    return __o->test_and_set(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    return __o->test_and_set(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
-{
-    __o->clear();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
-{
-    __o->clear();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    __o->clear(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
-{
-    __o->clear(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
-{
-    __o->wait(__v);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
-{
-    __o->wait(__v);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_wait_explicit(const volatile atomic_flag* __o,
-                          bool __v, memory_order __m) _NOEXCEPT
-{
-    __o->wait(__v, __m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_wait_explicit(const atomic_flag* __o,
-                          bool __v, memory_order __m) _NOEXCEPT
-{
-    __o->wait(__v, __m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
-{
-    __o->notify_one();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
-{
-    __o->notify_one();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
-{
-    __o->notify_all();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
-void
-atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
-{
-    __o->notify_all();
-}
-
-// fences
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_thread_fence(memory_order __m) _NOEXCEPT
-{
-    __cxx_atomic_thread_fence(__m);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void
-atomic_signal_fence(memory_order __m) _NOEXCEPT
-{
-    __cxx_atomic_signal_fence(__m);
-}
-
-// Atomics for standard typedef types
-
-typedef atomic<bool>               atomic_bool;
-typedef atomic<char>               atomic_char;
-typedef atomic<signed char>        atomic_schar;
-typedef atomic<unsigned char>      atomic_uchar;
-typedef atomic<short>              atomic_short;
-typedef atomic<unsigned short>     atomic_ushort;
-typedef atomic<int>                atomic_int;
-typedef atomic<unsigned int>       atomic_uint;
-typedef atomic<long>               atomic_long;
-typedef atomic<unsigned long>      atomic_ulong;
-typedef atomic<long long>          atomic_llong;
-typedef atomic<unsigned long long> atomic_ullong;
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-typedef atomic<char8_t>            atomic_char8_t;
-#endif
-typedef atomic<char16_t>           atomic_char16_t;
-typedef atomic<char32_t>           atomic_char32_t;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-typedef atomic<wchar_t>            atomic_wchar_t;
-#endif
-
-typedef atomic<int_least8_t>   atomic_int_least8_t;
-typedef atomic<uint_least8_t>  atomic_uint_least8_t;
-typedef atomic<int_least16_t>  atomic_int_least16_t;
-typedef atomic<uint_least16_t> atomic_uint_least16_t;
-typedef atomic<int_least32_t>  atomic_int_least32_t;
-typedef atomic<uint_least32_t> atomic_uint_least32_t;
-typedef atomic<int_least64_t>  atomic_int_least64_t;
-typedef atomic<uint_least64_t> atomic_uint_least64_t;
-
-typedef atomic<int_fast8_t>   atomic_int_fast8_t;
-typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
-typedef atomic<int_fast16_t>  atomic_int_fast16_t;
-typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
-typedef atomic<int_fast32_t>  atomic_int_fast32_t;
-typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
-typedef atomic<int_fast64_t>  atomic_int_fast64_t;
-typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
-
-typedef atomic< int8_t>  atomic_int8_t;
-typedef atomic<uint8_t>  atomic_uint8_t;
-typedef atomic< int16_t> atomic_int16_t;
-typedef atomic<uint16_t> atomic_uint16_t;
-typedef atomic< int32_t> atomic_int32_t;
-typedef atomic<uint32_t> atomic_uint32_t;
-typedef atomic< int64_t> atomic_int64_t;
-typedef atomic<uint64_t> atomic_uint64_t;
-
-typedef atomic<intptr_t>  atomic_intptr_t;
-typedef atomic<uintptr_t> atomic_uintptr_t;
-typedef atomic<size_t>    atomic_size_t;
-typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
-typedef atomic<intmax_t>  atomic_intmax_t;
-typedef atomic<uintmax_t> atomic_uintmax_t;
-
-// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
-
-#ifdef __cpp_lib_atomic_is_always_lock_free
-# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
-#else
-# define _LIBCPP_CONTENTION_LOCK_FREE false
-#endif
-
-#if ATOMIC_LLONG_LOCK_FREE == 2
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>          __libcpp_signed_lock_free;
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long> __libcpp_unsigned_lock_free;
-#elif ATOMIC_INT_LOCK_FREE == 2
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>                __libcpp_signed_lock_free;
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>       __libcpp_unsigned_lock_free;
-#elif ATOMIC_SHORT_LOCK_FREE == 2
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>              __libcpp_signed_lock_free;
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>     __libcpp_unsigned_lock_free;
-#elif ATOMIC_CHAR_LOCK_FREE == 2
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>               __libcpp_signed_lock_free;
-typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>      __libcpp_unsigned_lock_free;
-#else
-    // No signed/unsigned lock-free types
-#define _LIBCPP_NO_LOCK_FREE_TYPES
-#endif
-
-#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
-typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
-typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
+#ifdef kill_dependency
+#  error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
 #endif
 
-#define ATOMIC_FLAG_INIT {false}
-#define ATOMIC_VAR_INIT(__v) {__v}
-
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
-#  pragma clang deprecated(ATOMIC_VAR_INIT)
-# endif
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-
-_LIBCPP_END_NAMESPACE_STD
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <cmath>
 #  include <compare>
+#  include <cstring>
 #  include <type_traits>
 #endif
 
lib/libcxx/include/barrier
@@ -46,13 +46,18 @@ namespace std
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__atomic/atomic_base.h>
+#include <__atomic/memory_order.h>
 #include <__availability>
 #include <__config>
 #include <__memory/unique_ptr.h>
+#include <__thread/poll_with_backoff.h>
 #include <__thread/timed_backoff_policy.h>
 #include <__utility/move.h>
-#include <atomic>
+#include <cstddef>
+#include <cstdint>
 #include <limits>
+#include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -119,7 +124,7 @@ class __barrier_base {
 public:
     using arrival_token = __barrier_phase_t;
 
-    static constexpr ptrdiff_t max() noexcept {
+    static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
         return numeric_limits<ptrdiff_t>::max();
     }
 
@@ -130,9 +135,12 @@ public:
               __expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0)
     {
     }
-    [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
+    [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     arrival_token arrive(ptrdiff_t __update)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update <= __expected_, "update is greater than the expected count for the current barrier phase");
+
         auto const __old_phase = __phase_.load(memory_order_relaxed);
         for(; __update; --__update)
             if(__arrive_barrier_algorithm_base(__base_.get(), __old_phase)) {
@@ -200,7 +208,11 @@ public:
         auto const __old_phase = __phase.load(memory_order_relaxed);
         auto const __result = __arrived.fetch_sub(update, memory_order_acq_rel) - update;
         auto const new_expected = __expected.load(memory_order_relaxed);
-        if(0 == __result) {
+
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            update <= new_expected, "update is greater than the expected count for the current barrier phase");
+
+        if (0 == __result) {
             __completion();
             __arrived.store(new_expected, memory_order_relaxed);
             __phase.store(!__old_phase, memory_order_release);
@@ -256,7 +268,11 @@ public:
     {
         auto const __inc = __arrived_unit * update;
         auto const __old = __phase_arrived_expected.fetch_add(__inc, memory_order_acq_rel);
-        if((__old ^ (__old + __inc)) & __phase_bit) {
+
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            update <= __old, "update is greater than the expected count for the current barrier phase");
+
+        if ((__old ^ (__old + __inc)) & __phase_bit) {
             __phase_arrived_expected.fetch_add((__old & __expected_mask) << 32, memory_order_relaxed);
             __phase_arrived_expected.notify_all();
         }
@@ -288,21 +304,29 @@ class barrier {
 public:
     using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;
 
-    static constexpr ptrdiff_t max() noexcept {
+    static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
         return __barrier_base<_CompletionF>::max();
     }
 
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
+    explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
         : __b_(__count, _VSTD::move(__completion)) {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __count >= 0,
+            "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with a negative value");
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __count <= max(),
+            "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with "
+            "a value greater than max()");
     }
 
     barrier(barrier const&) = delete;
     barrier& operator=(barrier const&) = delete;
 
-    [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
+    [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     arrival_token arrive(ptrdiff_t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(__update > 0, "barrier:arrive must be called with a value greater than 0");
         return __b_.arrive(__update);
     }
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
@@ -329,6 +353,7 @@ _LIBCPP_END_NAMESPACE_STD
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
 #  include <iterator>
 #  include <memory>
lib/libcxx/include/bit
@@ -83,6 +83,7 @@ namespace std {
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
 #  include <iosfwd>
 #  include <limits>
 #  include <type_traits>
lib/libcxx/include/bitset
@@ -79,7 +79,7 @@ public:
     size_t count() const noexcept;                     // constexpr since C++23
     constexpr size_t size() const noexcept;            // constexpr since C++23
     bool operator==(const bitset& rhs) const noexcept; // constexpr since C++23
-    bool operator!=(const bitset& rhs) const noexcept; // constexpr since C++23
+    bool operator!=(const bitset& rhs) const noexcept; // removed in C++20
     bool test(size_t pos) const;                       // constexpr since C++23
     bool all() const noexcept;                         // constexpr since C++23
     bool any() const noexcept;                         // constexpr since C++23
@@ -122,6 +122,7 @@ template <size_t N> struct hash<std::bitset<N>>;
 #include <climits>
 #include <cstddef>
 #include <stdexcept>
+#include <string_view>
 #include <version>
 
 // standard-mandated includes
@@ -691,18 +692,30 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
         bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
-    template<class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-        explicit bitset(const _CharT* __str,
-                        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
-                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
-    template<class _CharT, class _Traits, class _Allocator>
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-        explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
-                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
-                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
-                                (basic_string<_CharT,_Traits,_Allocator>::npos),
-                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
+    template <class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
+        const _CharT* __str,
+        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
+        _CharT __zero                                = _CharT('0'),
+        _CharT __one                                 = _CharT('1')) {
+
+        size_t __rlen = std::min(__n, char_traits<_CharT>::length(__str));
+        __init_from_string_view(basic_string_view<_CharT>(__str, __rlen), __zero, __one);
+    }
+    template <class _CharT, class _Traits, class _Allocator>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
+        const basic_string<_CharT, _Traits, _Allocator>& __str,
+        typename basic_string<_CharT, _Traits, _Allocator>::size_type __pos = 0,
+        typename basic_string<_CharT, _Traits, _Allocator>::size_type __n =
+            basic_string<_CharT, _Traits, _Allocator>::npos,
+        _CharT __zero = _CharT('0'),
+        _CharT __one  = _CharT('1')) {
+        if (__pos > __str.size())
+            std::__throw_out_of_range("bitset string pos out of range");
+
+        size_t __rlen = std::min(__n, __str.size() - __pos);
+        __init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one);
+    }
 
     // 23.3.5.2 bitset operations:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
@@ -761,8 +774,10 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
     bool operator==(const bitset& __rhs) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
+#if _LIBCPP_STD_VER <= 17
+    _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const bitset& __rhs) const _NOEXCEPT;
+#endif
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
     bool test(size_t __pos) const;
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
@@ -776,6 +791,22 @@ public:
     bitset operator>>(size_t __pos) const _NOEXCEPT;
 
 private:
+    template <class _CharT, class _Traits>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
+    __init_from_string_view(basic_string_view<_CharT, _Traits> __str, _CharT __zero, _CharT __one) {
+
+        for (size_t __i = 0; __i < __str.size(); ++__i)
+            if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
+              std::__throw_invalid_argument("bitset string ctor has invalid argument");
+
+        size_t __mp = std::min(__str.size(), _Size);
+        size_t __i  = 0;
+        for (; __i < __mp; ++__i) {
+            _CharT __c   = __str[__mp - 1 - __i];
+            (*this)[__i] = _Traits::eq(__c, __one);
+        }
+        std::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}
@@ -783,54 +814,6 @@ private:
     friend struct hash<bitset>;
 };
 
-template <size_t _Size>
-template<class _CharT, class>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-bitset<_Size>::bitset(const _CharT* __str,
-                      typename basic_string<_CharT>::size_type __n,
-                      _CharT __zero, _CharT __one)
-{
-    size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));
-    for (size_t __i = 0; __i < __rlen; ++__i)
-        if (__str[__i] != __zero && __str[__i] != __one)
-            __throw_invalid_argument("bitset string ctor has invalid argument");
-
-    size_t _Mp = _VSTD::min(__rlen, _Size);
-    size_t __i = 0;
-    for (; __i < _Mp; ++__i)
-    {
-        _CharT __c = __str[_Mp - 1 - __i];
-        (*this)[__i] = (__c == __one);
-    }
-    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
-}
-
-template <size_t _Size>
-template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
-       typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
-       typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
-       _CharT __zero, _CharT __one)
-{
-    if (__pos > __str.size())
-        __throw_out_of_range("bitset string pos out of range");
-
-    size_t __rlen = _VSTD::min(__n, __str.size() - __pos);
-    for (size_t __i = __pos; __i < __pos + __rlen; ++__i)
-        if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
-            __throw_invalid_argument("bitset string ctor has invalid argument");
-
-    size_t _Mp = _VSTD::min(__rlen, _Size);
-    size_t __i = 0;
-    for (; __i < _Mp; ++__i)
-    {
-        _CharT __c = __str[__pos + _Mp - 1 - __i];
-        (*this)[__i] = _Traits::eq(__c, __one);
-    }
-    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
-}
-
 template <size_t _Size>
 inline
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
@@ -956,8 +939,8 @@ bitset<_Size>::flip(size_t __pos)
     if (__pos >= _Size)
         __throw_out_of_range("bitset flip argument out of range");
 
-    reference r = base::__make_ref(__pos);
-    r = ~r;
+    reference __r = base::__make_ref(__pos);
+    __r = ~__r;
     return *this;
 }
 
@@ -1041,15 +1024,19 @@ bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
     return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <size_t _Size>
 inline
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
+_LIBCPP_HIDE_FROM_ABI
 bool
 bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
 {
     return !(*this == __rhs);
 }
 
+#endif
+
 template <size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
 bool
@@ -1154,6 +1141,8 @@ _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_BITSET
lib/libcxx/include/charconv
@@ -63,785 +63,41 @@ namespace std {
   constexpr from_chars_result from_chars(const char* first, const char* last,
                                see below& value, int base = 10);                         // constexpr since C++23
 
-  from_chars_result from_chars(const char* first, const char* last,
-                               float& value,
-                               chars_format fmt = chars_format::general);
-  from_chars_result from_chars(const char* first, const char* last,
-                               double& value,
-                               chars_format fmt = chars_format::general);
-  from_chars_result from_chars(const char* first, const char* last,
-                               long double& value,
-                               chars_format fmt = chars_format::general);
-
 } // namespace std
 
 */
 
-#include <__algorithm/copy_n.h>
 #include <__assert> // all public C++ headers provide the assertion handler
-#include <__availability>
-#include <__bit/countl.h>
 #include <__charconv/chars_format.h>
+#include <__charconv/from_chars_integral.h>
 #include <__charconv/from_chars_result.h>
 #include <__charconv/tables.h>
+#include <__charconv/to_chars.h>
 #include <__charconv/to_chars_base_10.h>
+#include <__charconv/to_chars_floating_point.h>
+#include <__charconv/to_chars_integral.h>
 #include <__charconv/to_chars_result.h>
+#include <__charconv/traits.h>
 #include <__config>
-#include <__debug>
-#include <__errc>
-#include <__memory/addressof.h>
-#include <__type_traits/make_32_64_or_128_bit.h>
-#include <__utility/unreachable.h>
+#include <__system_error/errc.h>
 #include <cmath> // for log2f
 #include <cstdint>
-#include <cstdlib>
-#include <cstring>
 #include <limits>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
-
-to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
-from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
-
-namespace __itoa
-{
-
-template <typename _Tp, typename = void>
-struct _LIBCPP_HIDDEN __traits_base;
-
-template <typename _Tp>
-struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>>
-{
-    using type = uint32_t;
-
-    /// The width estimation using a log10 algorithm.
-    ///
-    /// The algorithm is based on
-    /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-    /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
-    /// function requires its input to have at least one bit set the value of
-    /// zero is set to one. This means the first element of the lookup table is
-    /// zero.
-    static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
-    {
-        auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
-        return __t - (__v < __itoa::__pow10_32[__t]) + 1;
-    }
-
-    static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
-    {
-        return __itoa::__base_10_u32(__p, __v);
-    }
-
-    static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { return __itoa::__pow10_32; }
-};
-
-template <typename _Tp>
-struct _LIBCPP_HIDDEN
-    __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
-  using type = uint64_t;
-
-  /// The width estimation using a log10 algorithm.
-  ///
-  /// The algorithm is based on
-  /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-  /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
-  /// function requires its input to have at least one bit set the value of
-  /// zero is set to one. This means the first element of the lookup table is
-  /// zero.
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
-    auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
-    return __t - (__v < __itoa::__pow10_64[__t]) + 1;
-  }
-
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); }
-
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { return __itoa::__pow10_64; }
-};
-
-
-#  ifndef _LIBCPP_HAS_NO_INT128
-template <typename _Tp>
-struct _LIBCPP_HIDDEN
-    __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
-  using type = __uint128_t;
-
-  /// The width estimation using a log10 algorithm.
-  ///
-  /// The algorithm is based on
-  /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-  /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
-  /// function requires its input to have at least one bit set the value of
-  /// zero is set to one. This means the first element of the lookup table is
-  /// zero.
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
-    _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
-    // There's always a bit set in the upper 64-bits.
-    auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
-    _LIBCPP_ASSERT(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
-    // __t is adjusted since the lookup table misses the lower entries.
-    return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
-  }
-
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); }
-
-  // TODO FMT This pow function should get an index.
-  // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
-  static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { return __itoa::__pow10_128; }
-};
-#endif
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
-__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
-{
-    auto __c = __a * __b;
-    __r = __c;
-    return __c > numeric_limits<unsigned char>::max();
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
-__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
-{
-    auto __c = __a * __b;
-    __r = __c;
-    return __c > numeric_limits<unsigned short>::max();
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
-__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
-{
-    static_assert(is_unsigned<_Tp>::value, "");
-    return __builtin_mul_overflow(__a, __b, &__r);
-}
-
-template <typename _Tp, typename _Up>
-inline _LIBCPP_HIDE_FROM_ABI bool
-_LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
-{
-    return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
-}
-
-template <typename _Tp>
-struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
-{
-    static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
-    using __traits_base<_Tp>::__pow;
-    using typename __traits_base<_Tp>::type;
-
-    // precondition: at least one non-zero character available
-    static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
-    __read(char const* __p, char const* __ep, type& __a, type& __b)
-    {
-        type __cprod[digits];
-        int __j = digits - 1;
-        int __i = digits;
-        do
-        {
-            if (*__p < '0' || *__p > '9')
-                break;
-            __cprod[--__i] = *__p++ - '0';
-        } while (__p != __ep && __i != 0);
-
-        __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
-                              __cprod[__i]);
-        if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
-            --__p;
-        return __p;
-    }
-
-    template <typename _It1, typename _It2, class _Up>
-    static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
-    __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
-    {
-        for (; __first1 < __last1; ++__first1, ++__first2)
-            __init = __init + *__first1 * *__first2;
-        return __init;
-    }
-};
-
-}  // namespace __itoa
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp
-__complement(_Tp __x)
-{
-    static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
-    return _Tp(~__x + 1);
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
-{
-    auto __x = std::__to_unsigned_like(__value);
-    if (__value < 0 && __first != __last)
-    {
-        *__first++ = '-';
-        __x = std::__complement(__x);
-    }
-
-    return std::__to_chars_itoa(__first, __last, __x, false_type());
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
-{
-    using __tx = __itoa::__traits<_Tp>;
-    auto __diff = __last - __first;
-
-    if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
-        return {__tx::__convert(__first, __value), errc(0)};
-    else
-        return {__last, errc::value_too_large};
-}
-
-#  ifndef _LIBCPP_HAS_NO_INT128
-template <>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type)
-{
-    // When the value fits in 64-bits use the 64-bit code path. This reduces
-    // the number of expensive calculations on 128-bit values.
-    //
-    // NOTE the 128-bit code path requires this optimization.
-    if(__value <= numeric_limits<uint64_t>::max())
-        return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
-
-    using __tx = __itoa::__traits<__uint128_t>;
-    auto __diff = __last - __first;
-
-    if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
-        return {__tx::__convert(__first, __value), errc(0)};
-    else
-        return {__last, errc::value_too_large};
-}
-#endif
-
-template <class _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
-                    true_type)
-{
-    auto __x = std::__to_unsigned_like(__value);
-    if (__value < 0 && __first != __last)
-    {
-        *__first++ = '-';
-        __x = std::__complement(__x);
-    }
-
-    return std::__to_chars_integral(__first, __last, __x, __base, false_type());
-}
-
-namespace __itoa {
-
-template <unsigned _Base>
-struct _LIBCPP_HIDDEN __integral;
-
-template <>
-struct _LIBCPP_HIDDEN __integral<2> {
-  template <typename _Tp>
-  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
-    // If value == 0 still need one digit. If the value != this has no
-    // effect since the code scans for the most significant bit set. (Note
-    // that __libcpp_clz doesn't work for 0.)
-    return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
-  }
-
-  template <typename _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
-    ptrdiff_t __cap = __last - __first;
-    int __n = __width(__value);
-    if (__n > __cap)
-      return {__last, errc::value_too_large};
-
-    __last = __first + __n;
-    char* __p = __last;
-    const unsigned __divisor = 16;
-    while (__value > __divisor) {
-      unsigned __c = __value % __divisor;
-      __value /= __divisor;
-      __p -= 4;
-      std::copy_n(&__base_2_lut[4 * __c], 4, __p);
-    }
-    do {
-      unsigned __c = __value % 2;
-      __value /= 2;
-      *--__p = "01"[__c];
-    } while (__value != 0);
-    return {__last, errc(0)};
-  }
-};
-
-template <>
-struct _LIBCPP_HIDDEN __integral<8> {
-  template <typename _Tp>
-  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
-    // If value == 0 still need one digit. If the value != this has no
-    // effect since the code scans for the most significat bit set. (Note
-    // that __libcpp_clz doesn't work for 0.)
-    return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
-  }
-
-  template <typename _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
-    ptrdiff_t __cap = __last - __first;
-    int __n = __width(__value);
-    if (__n > __cap)
-      return {__last, errc::value_too_large};
-
-    __last = __first + __n;
-    char* __p = __last;
-    unsigned __divisor = 64;
-    while (__value > __divisor) {
-      unsigned __c = __value % __divisor;
-      __value /= __divisor;
-      __p -= 2;
-      std::copy_n(&__base_8_lut[2 * __c], 2, __p);
-    }
-    do {
-      unsigned __c = __value % 8;
-      __value /= 8;
-      *--__p = "01234567"[__c];
-    } while (__value != 0);
-    return {__last, errc(0)};
-  }
-
-};
-
-template <>
-struct _LIBCPP_HIDDEN __integral<16> {
-  template <typename _Tp>
-  _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
-    // If value == 0 still need one digit. If the value != this has no
-    // effect since the code scans for the most significat bit set. (Note
-    // that __libcpp_clz doesn't work for 0.)
-    return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
-  }
-
-  template <typename _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
-    ptrdiff_t __cap = __last - __first;
-    int __n = __width(__value);
-    if (__n > __cap)
-      return {__last, errc::value_too_large};
-
-    __last = __first + __n;
-    char* __p = __last;
-    unsigned __divisor = 256;
-    while (__value > __divisor) {
-      unsigned __c = __value % __divisor;
-      __value /= __divisor;
-      __p -= 2;
-      std::copy_n(&__base_16_lut[2 * __c], 2, __p);
-    }
-    if (__first != __last)
-      do {
-        unsigned __c = __value % 16;
-        __value /= 16;
-        *--__p = "0123456789abcdef"[__c];
-      } while (__value != 0);
-    return {__last, errc(0)};
-  }
-};
-
-} // namespace __itoa
-
-template <unsigned _Base, typename _Tp,
-          typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
-__to_chars_integral_width(_Tp __value) {
-  return __itoa::__integral<_Base>::__width(__value);
-}
-
-template <unsigned _Base, typename _Tp,
-          typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
-__to_chars_integral_width(_Tp __value) {
-  return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
-}
-
-template <unsigned _Base, typename _Tp,
-          typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_integral(char* __first, char* __last, _Tp __value) {
-  return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
-}
-
-template <unsigned _Base, typename _Tp,
-          typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_integral(char* __first, char* __last, _Tp __value) {
-  return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
-}
-
-template <typename _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
-__to_chars_integral_width(_Tp __value, unsigned __base) {
-  _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value.");
-
-  unsigned __base_2 = __base * __base;
-  unsigned __base_3 = __base_2 * __base;
-  unsigned __base_4 = __base_2 * __base_2;
-
-  int __r = 0;
-  while (true) {
-    if (__value < __base)
-      return __r + 1;
-    if (__value < __base_2)
-      return __r + 2;
-    if (__value < __base_3)
-      return __r + 3;
-    if (__value < __base_4)
-      return __r + 4;
-
-    __value /= __base_4;
-    __r += 4;
-  }
-
-  __libcpp_unreachable();
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
-                    false_type)
-{
-  if (__base == 10) [[likely]]
-    return std::__to_chars_itoa(__first, __last, __value, false_type());
-
-  switch (__base) {
-  case 2:
-    return std::__to_chars_integral<2>(__first, __last, __value);
-  case 8:
-    return std::__to_chars_integral<8>(__first, __last, __value);
-  case 16:
-    return std::__to_chars_integral<16>(__first, __last, __value);
-  }
-
-  ptrdiff_t __cap = __last - __first;
-  int __n = std::__to_chars_integral_width(__value, __base);
-  if (__n > __cap)
-    return {__last, errc::value_too_large};
-
-  __last = __first + __n;
-  char* __p = __last;
-  do {
-    unsigned __c = __value % __base;
-    __value /= __base;
-    *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
-  } while (__value != 0);
-  return {__last, errc(0)};
-}
-
-template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-to_chars(char* __first, char* __last, _Tp __value)
-{
-  using _Type = __make_32_64_or_128_bit_t<_Tp>;
-  static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
-  return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
-}
-
-template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
-to_chars(char* __first, char* __last, _Tp __value, int __base)
-{
-  _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
-
-  using _Type = __make_32_64_or_128_bit_t<_Tp>;
-  return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
-}
-
-template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
-{
-    using __tl = numeric_limits<_Tp>;
-    decltype(std::__to_unsigned_like(__value)) __x;
-
-    bool __neg = (__first != __last && *__first == '-');
-    auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
-    switch (__r.ec)
-    {
-    case errc::invalid_argument:
-        return {__first, __r.ec};
-    case errc::result_out_of_range:
-        return __r;
-    default:
-        break;
-    }
-
-    if (__neg)
-    {
-        if (__x <= std::__complement(std::__to_unsigned_like(__tl::min())))
-        {
-            __x = std::__complement(__x);
-            std::copy_n(std::addressof(__x), 1, std::addressof(__value));
-            return __r;
-        }
-    }
-    else
-    {
-        if (__x <= std::__to_unsigned_like(__tl::max()))
-        {
-            __value = __x;
-            return __r;
-        }
-    }
-
-    return {__r.ptr, errc::result_out_of_range};
-}
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
-__in_pattern(_Tp __c)
-{
-    return '0' <= __c && __c <= '9';
-}
-
-struct _LIBCPP_HIDDEN __in_pattern_result
-{
-    bool __ok;
-    int __val;
-
-    explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
-};
-
-template <typename _Tp>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result
-__in_pattern(_Tp __c, int __base)
-{
-    if (__base <= 10)
-        return {'0' <= __c && __c < '0' + __base, __c - '0'};
-    else if (std::__in_pattern(__c))
-        return {true, __c - '0'};
-    else if ('a' <= __c && __c < 'a' + __base - 10)
-        return {true, __c - 'a' + 10};
-    else
-        return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
-}
-
-template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
-                         _Ts... __args)
-{
-    auto __find_non_zero = [](_It __firstit, _It __lastit) {
-        for (; __firstit != __lastit; ++__firstit)
-            if (*__firstit != '0')
-                break;
-        return __firstit;
-    };
-
-    auto __p = __find_non_zero(__first, __last);
-    if (__p == __last || !std::__in_pattern(*__p, __args...))
-    {
-        if (__p == __first)
-            return {__first, errc::invalid_argument};
-        else
-        {
-            __value = 0;
-            return {__p, {}};
-        }
-    }
-
-    auto __r = __f(__p, __last, __value, __args...);
-    if (__r.ec == errc::result_out_of_range)
-    {
-        for (; __r.ptr != __last; ++__r.ptr)
-        {
-            if (!std::__in_pattern(*__r.ptr, __args...))
-                break;
-        }
-    }
-
-    return __r;
-}
-
-template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
-{
-    using __tx = __itoa::__traits<_Tp>;
-    using __output_type = typename __tx::type;
-
-    return std::__subject_seq_combinator(
-        __first, __last, __value,
-        [](const char* __f, const char* __l,
-           _Tp& __val) -> from_chars_result {
-            __output_type __a, __b;
-            auto __p = __tx::__read(__f, __l, __a, __b);
-            if (__p == __l || !std::__in_pattern(*__p))
-            {
-                __output_type __m = numeric_limits<_Tp>::max();
-                if (__m >= __a && __m - __a >= __b)
-                {
-                    __val = __a + __b;
-                    return {__p, {}};
-                }
-            }
-            return {__p, errc::result_out_of_range};
-        });
-}
-
-template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
-{
-    using __t = decltype(std::__to_unsigned_like(__value));
-    return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
-}
-
-
-/*
-// Code used to generate __from_chars_log2f_lut.
-#include <cmath>
-#include <iostream>
-#include <format>
-
-int main() {
-  for (int i = 2; i <= 36; ++i)
-    std::cout << std::format("{},\n", log2f(i));
-}
-*/
-/// log2f table for bases [2, 36].
-inline constexpr float __from_chars_log2f_lut[35] = {
-    1,         1.5849625, 2,         2.321928, 2.5849626, 2.807355, 3,        3.169925,  3.321928,
-    3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4,        4.087463, 4.169925,  4.2479277,
-    4.321928,  4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044,  4.7548876, 4.807355,
-    4.857981,  4.9068904, 4.9541965, 5,        5.044394,  5.087463, 5.129283, 5.169925};
-
-template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
-                      int __base)
-{
-    if (__base == 10)
-        return std::__from_chars_atoi(__first, __last, __value);
-
-    return std::__subject_seq_combinator(
-        __first, __last, __value,
-        [](const char* __p, const char* __lastp, _Tp& __val,
-           int __b) -> from_chars_result {
-            using __tl = numeric_limits<_Tp>;
-            // __base is always between 2 and 36 inclusive.
-            auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2];
-            _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
-
-            for (int __i = 1; __p != __lastp; ++__i, ++__p)
-            {
-                if (auto __c = __in_pattern(*__p, __b))
-                {
-                    if (__i < __digits - 1)
-                        __x = __x * __b + __c.__val;
-                    else
-                    {
-                        if (!__itoa::__mul_overflowed(__x, __b, __x))
-                            ++__p;
-                        __y = __c.__val;
-                        break;
-                    }
-                }
-                else
-                    break;
-            }
-
-            if (__p == __lastp || !__in_pattern(*__p, __b))
-            {
-                if (__tl::max() - __x >= __y)
-                {
-                    __val = __x + __y;
-                    return {__p, {}};
-                }
-            }
-            return {__p, errc::result_out_of_range};
-        },
-        __base);
-}
-
-template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
-                      int __base)
-{
-    using __t = decltype(std::__to_unsigned_like(__value));
-    return std::__sign_combinator(__first, __last, __value,
-                                  __from_chars_integral<__t>, __base);
-}
-
-template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-from_chars(const char* __first, const char* __last, _Tp& __value)
-{
-    return std::__from_chars_atoi(__first, __last, __value);
-}
-
-template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
-from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
-{
-    _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
-    return std::__from_chars_integral(__first, __last, __value, __base);
-}
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, float __value);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, double __value);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, long double __value);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
-
-_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
-to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
-
-#endif // _LIBCPP_STD_VER > 14
-
 _LIBCPP_END_NAMESPACE_STD
 
-_LIBCPP_POP_MACROS
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
+#  include <cstring>
 #  include <iosfwd>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_CHARCONV
lib/libcxx/include/chrono
@@ -182,7 +182,7 @@ template <class Rep1, class Period1, class Rep2, class Period2>
    bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
 template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
-   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); // removed in C++20
 template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
    bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
@@ -195,6 +195,10 @@ template <class Rep1, class Period1, class Rep2, class Period2>
 template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
    bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template<class Rep1, class Period1, class Rep2, class Period2>
+  requires three_way_comparable<typename CT::rep>
+  constexpr auto operator<=>(const duration<Rep1, Period1>& lhs,
+                             const duration<Rep2, Period2>& rhs);                           // since C++20
 
 // duration_cast
 template <class ToDuration, class Rep, class Period>
@@ -231,7 +235,7 @@ template <class Clock, class Duration1, class Duration2>
 template <class Clock, class Duration1, class Duration2>
    bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 template <class Clock, class Duration1, class Duration2>
-   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); // removed in C++20
 template <class Clock, class Duration1, class Duration2>
    bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 template <class Clock, class Duration1, class Duration2>
@@ -240,6 +244,10 @@ template <class Clock, class Duration1, class Duration2>
    bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 template <class Clock, class Duration1, class Duration2>
    bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template<class Clock, class Duration1,
+         three_way_comparable_with<Duration1> Duration2>
+  constexpr auto operator<=>(const time_point<Clock, Duration1>& lhs,
+                             const time_point<Clock, Duration2>& rhs);                                // since C++20
 
 // time_point_cast (constexpr in C++14)
 
@@ -282,6 +290,10 @@ template <class Duration>
 using sys_seconds = sys_time<seconds>;                  // C++20
 using sys_days    = sys_time<days>;                     // C++20
 
+template<class charT, class traits, class Duration>     // C++20
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);
+
 class file_clock                                        // C++20
 {
 public:
@@ -303,6 +315,10 @@ public:
 template<class Duration>
   using file_time = time_point<file_clock, Duration>;   // C++20
 
+template<class charT, class traits, class Duration>     // C++20
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& tp);
+
 class steady_clock
 {
 public:
@@ -324,6 +340,10 @@ template<class Duration>
 using local_seconds = local_time<seconds>;
 using local_days    = local_time<days>;
 
+template<class charT, class traits, class Duration>     // C++20
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& tp);
+
 // 25.8.2, class last_spec    // C++20
 struct last_spec;
 
@@ -370,7 +390,6 @@ template<class charT, class traits>
 class weekday;
 
 constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
-constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
 constexpr weekday operator+(const weekday& x, const days&    y) noexcept;
 constexpr weekday operator+(const days&    x, const weekday& y) noexcept;
 constexpr weekday operator-(const weekday& x, const days&    y) noexcept;
@@ -383,7 +402,6 @@ template<class charT, class traits>
 
 class weekday_indexed;
 constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
-constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
 
 template<class charT, class traits>
   basic_ostream<charT, traits>&
@@ -393,7 +411,6 @@ template<class charT, class traits>
 class weekday_last;
 
 constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
-constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
 
 template<class charT, class traits>
   basic_ostream<charT, traits>&
@@ -423,7 +440,6 @@ template<class charT, class traits>
 class month_weekday;
 
 constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
-constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
 
 template<class charT, class traits>
   basic_ostream<charT, traits>&
@@ -433,7 +449,6 @@ template<class charT, class traits>
 class month_weekday_last;
 
 constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
-constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
 
 template<class charT, class traits>
   basic_ostream<charT, traits>&
@@ -503,8 +518,6 @@ class year_month_weekday;
 
 constexpr bool operator==(const year_month_weekday& x,
                           const year_month_weekday& y) noexcept;
-constexpr bool operator!=(const year_month_weekday& x,
-                          const year_month_weekday& y) noexcept;
 
 constexpr year_month_weekday
   operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
@@ -528,8 +541,6 @@ class year_month_weekday_last;
 
 constexpr bool operator==(const year_month_weekday_last& x,
                           const year_month_weekday_last& y) noexcept;
-constexpr bool operator!=(const year_month_weekday_last& x,
-                          const year_month_weekday_last& y) noexcept;
 constexpr year_month_weekday_last
   operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
 constexpr year_month_weekday_last
@@ -656,6 +667,10 @@ public:
     constexpr          precision to_duration() const noexcept;
 };
 
+template<class charT, class traits, class Duration>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms); // C++20
+
 // 26.10, 12/24 hour functions
 constexpr bool is_am(hours const& h) noexcept;
 constexpr bool is_pm(hours const& h) noexcept;
@@ -674,6 +689,12 @@ bool operator>=(const time_zone& x, const time_zone& y) noexcept;
 }  // chrono
 
 namespace std {
+  template<class Duration, class charT>
+    struct formatter<chrono::sys_time<Duration>, charT>;                          // C++20
+  template<class Duration, class charT>
+    struct formatter<chrono::filetime<Duration>, charT>;                          // C++20
+  template<class Duration, class charT>
+    struct formatter<chrono::local_time<Duration>, charT>;                        // C++20
   template<class Rep, class Period, class charT>
     struct formatter<chrono::duration<Rep, Period>, charT>;                       // C++20
   template<class charT> struct formatter<chrono::day, charT>;                     // C++20
@@ -691,6 +712,8 @@ namespace std {
   template<class charT> struct formatter<chrono::year_month_day_last, charT>;     // C++20
   template<class charT> struct formatter<chrono::year_month_weekday, charT>;      // C++20
   template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20
+  template<class Rep, class Period, class charT>
+    struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>;             // C++20
 } // namespace std
 
 namespace chrono {
@@ -769,7 +792,7 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 // [time.syn]
 #include <compare>
 
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && _LIBCPP_STD_VER > 17
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && _LIBCPP_STD_VER >= 20
 #  include <__chrono/formatter.h>
 #  include <__chrono/ostream.h>
 #  include <__chrono/parser_std_format_spec.h>
@@ -782,7 +805,13 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <bit>
 #  include <concepts>
+#  include <cstring>
+#endif
+
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER == 20
+#  include <charconv>
 #endif
 
 #endif // _LIBCPP_CHRONO
lib/libcxx/include/cmath
@@ -311,6 +311,7 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
 #include <__type_traits/is_constant_evaluated.h>
 #include <__type_traits/is_floating_point.h>
 #include <__type_traits/is_same.h>
+#include <__type_traits/promote.h>
 #include <__type_traits/remove_cv.h>
 #include <version>
 
@@ -543,7 +544,7 @@ using ::scalbnl _LIBCPP_USING_IF_EXISTS;
 using ::tgammal _LIBCPP_USING_IF_EXISTS;
 using ::truncl _LIBCPP_USING_IF_EXISTS;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 inline _LIBCPP_INLINE_VISIBILITY float       hypot(       float __x,       float __y,       float __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
 inline _LIBCPP_INLINE_VISIBILITY double      hypot(      double __x,      double __y,      double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
 inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double __x, long double __y, long double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
@@ -782,7 +783,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp _
   return __builtin_scalbn(__x, __exp);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <typename _Fp>
 _LIBCPP_HIDE_FROM_ABI constexpr
 _Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept {
@@ -823,7 +824,7 @@ lerp(_A1 __a, _A2 __b, _A3 __t) noexcept
                     _IsSame<_A3, __result_type>::value));
     return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/codecvt
@@ -78,7 +78,7 @@ template <class _Elem> class __codecvt_utf8;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<wchar_t>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -115,7 +115,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char16_t>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -149,7 +149,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char32_t>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -203,7 +203,7 @@ template <class _Elem, bool _LittleEndian> class __codecvt_utf16;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, false>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -239,7 +239,7 @@ protected:
 };
 
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, true>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -276,7 +276,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, false>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -310,7 +310,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, true>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -344,7 +344,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, false>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -378,7 +378,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, true>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -432,7 +432,7 @@ template <class _Elem> class __codecvt_utf8_utf16;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<wchar_t>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -469,7 +469,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char32_t>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
@@ -503,7 +503,7 @@ protected:
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t>
+class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char16_t>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long __maxcode_;
lib/libcxx/include/compare
@@ -151,6 +151,7 @@ namespace std {
 #include <__compare/ordering.h>
 #include <__compare/partial_order.h>
 #include <__compare/strong_order.h>
+#include <__compare/synth_three_way.h>
 #include <__compare/three_way_comparable.h>
 #include <__compare/weak_order.h>
 #include <__config>
lib/libcxx/include/complex
@@ -148,12 +148,12 @@ template<class T> complex<T> operator/(const complex<T>&, const T&);          //
 template<class T> complex<T> operator/(const T&, const complex<T>&);          // constexpr in C++20
 template<class T> complex<T> operator+(const complex<T>&);                    // constexpr in C++20
 template<class T> complex<T> operator-(const complex<T>&);                    // constexpr in C++20
-template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
-template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
-template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator==(const complex<T>&, const complex<T>&);      // constexpr in C++14
+template<class T> bool operator==(const complex<T>&, const T&);               // constexpr in C++14
+template<class T> bool operator==(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20
+template<class T> bool operator!=(const complex<T>&, const complex<T>&);      // constexpr in C++14, removed in C++20
+template<class T> bool operator!=(const complex<T>&, const T&);               // constexpr in C++14, removed in C++20
+template<class T> bool operator!=(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20
 
 template<class T, class charT, class traits>
   basic_istream<charT, traits>&
@@ -236,7 +236,6 @@ template<class T> complex<T> tanh (const complex<T>&);
 #include <cmath>
 #include <iosfwd>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
@@ -828,6 +827,8 @@ operator==(const complex<_Tp>& __x, const _Tp& __y)
     return __x.real() == __y && __x.imag() == 0;
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
 bool
@@ -860,6 +861,8 @@ operator!=(const _Tp& __x, const complex<_Tp>& __y)
     return !(__x == __y);
 }
 
+#endif
+
 // 26.3.7 values:
 
 template <class _Tp, bool = is_integral<_Tp>::value,
@@ -1522,7 +1525,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
 }
 #endif // !_LIBCPP_HAS_NO_LOCALIZATION
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 // Literal suffix for complex number literals [complex.literals]
 inline namespace literals
 {
@@ -1565,4 +1568,8 @@ inline namespace literals
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <type_traits>
+#endif
+
 #endif // _LIBCPP_COMPLEX
lib/libcxx/include/condition_variable
@@ -107,10 +107,18 @@ public:
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__chrono/duration.h>
+#include <__chrono/steady_clock.h>
+#include <__chrono/time_point.h>
+#include <__condition_variable/condition_variable.h>
 #include <__config>
 #include <__memory/shared_ptr.h>
 #include <__memory/unique_ptr.h>
-#include <__mutex_base>
+#include <__mutex/lock_guard.h>
+#include <__mutex/mutex.h>
+#include <__mutex/tag_types.h>
+#include <__mutex/unique_lock.h>
+#include <__utility/move.h>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -121,7 +129,7 @@ public:
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS condition_variable_any
+class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any
 {
     condition_variable __cv_;
     shared_ptr<mutex>  __mut_;
@@ -191,7 +199,7 @@ condition_variable_any::notify_all() _NOEXCEPT
 struct __lock_external
 {
     template <class _Lock>
-    void operator()(_Lock* __m) {__m->lock();}
+    _LIBCPP_HIDE_FROM_ABI void operator()(_Lock* __m) {__m->lock();}
 };
 
 template <class _Lock>
@@ -202,7 +210,7 @@ condition_variable_any::wait(_Lock& __lock)
     unique_lock<mutex> __lk(*__mut);
     __lock.unlock();
     unique_ptr<_Lock, __lock_external> __lxx(&__lock);
-    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
     __cv_.wait(__lk);
 }  // __mut_.unlock(), __lock.lock()
 
@@ -224,7 +232,7 @@ condition_variable_any::wait_until(_Lock& __lock,
     unique_lock<mutex> __lk(*__mut);
     __lock.unlock();
     unique_ptr<_Lock, __lock_external> __lxx(&__lock);
-    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
     return __cv_.wait_until(__lk, __t);
 }  // __mut_.unlock(), __lock.lock()
 
@@ -261,16 +269,24 @@ condition_variable_any::wait_for(_Lock& __lock,
                       _VSTD::move(__pred));
 }
 
-_LIBCPP_FUNC_VIS
-void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
+_LIBCPP_EXPORTED_FROM_ABI void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
 
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // !_LIBCPP_HAS_NO_THREADS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
+#  include <cstdint>
+#  include <cstdlib>
+#  include <cstring>
+#  include <initializer_list>
+#  include <new>
+#  include <stdexcept>
+#  include <system_error>
 #  include <type_traits>
+#  include <typeinfo>
 #endif
 
 #endif // _LIBCPP_CONDITION_VARIABLE
lib/libcxx/include/cstddef
@@ -66,7 +66,7 @@ using ::max_align_t _LIBCPP_USING_IF_EXISTS;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 namespace std  // purposefully not versioned
 {
 enum class byte : unsigned char {};
lib/libcxx/include/cstdlib
@@ -144,7 +144,7 @@ using ::wcstombs _LIBCPP_USING_IF_EXISTS;
 using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 #endif
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
 #endif
 
lib/libcxx/include/cstring
@@ -100,53 +100,6 @@ using ::memset _LIBCPP_USING_IF_EXISTS;
 using ::strerror _LIBCPP_USING_IF_EXISTS;
 using ::strlen _LIBCPP_USING_IF_EXISTS;
 
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
-  // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
-  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
-#ifdef _LIBCPP_COMPILER_GCC
-  if (__libcpp_is_constant_evaluated()) {
-    size_t __i = 0;
-    for (; __str[__i] != '\0'; ++__i)
-      ;
-    return __i;
-  }
-#endif
-  return __builtin_strlen(__str);
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
-__constexpr_memcmp(const _Tp* __lhs, const _Tp* __rhs, size_t __count) {
-#ifdef _LIBCPP_COMPILER_GCC
-  if (__libcpp_is_constant_evaluated()) {
-    for (; __count; --__count, ++__lhs, ++__rhs) {
-      if (*__lhs < *__rhs)
-        return -1;
-      if (*__rhs < *__lhs)
-        return 1;
-    }
-    return 0;
-  }
-#endif
-  return __builtin_memcmp(__lhs, __rhs, __count);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char*
-__constexpr_char_memchr(const char* __str, int __char, size_t __count) {
-#if __has_builtin(__builtin_char_memchr)
-  return __builtin_char_memchr(__str, __char, __count);
-#else
-  if (!__libcpp_is_constant_evaluated())
-    return static_cast<const char*>(std::memchr(__str, __char, __count));
-  for (; __count; --__count) {
-    if (*__str == __char)
-      return __str;
-    ++__str;
-  }
-  return nullptr;
-#endif
-}
-
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_CSTRING
lib/libcxx/include/ctime
@@ -66,7 +66,7 @@ using ::clock_t _LIBCPP_USING_IF_EXISTS;
 using ::size_t _LIBCPP_USING_IF_EXISTS;
 using ::time_t _LIBCPP_USING_IF_EXISTS;
 using ::tm _LIBCPP_USING_IF_EXISTS;
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 using ::timespec _LIBCPP_USING_IF_EXISTS;
 #endif
 using ::clock _LIBCPP_USING_IF_EXISTS;
@@ -78,7 +78,7 @@ using ::ctime _LIBCPP_USING_IF_EXISTS;
 using ::gmtime _LIBCPP_USING_IF_EXISTS;
 using ::localtime _LIBCPP_USING_IF_EXISTS;
 using ::strftime _LIBCPP_USING_IF_EXISTS;
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 using ::timespec_get _LIBCPP_USING_IF_EXISTS;
 #endif
 
lib/libcxx/include/cwchar
@@ -104,7 +104,11 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__type_traits/apply_cv.h>
 #include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
 #include <cwctype>
 
 #include <wchar.h>
@@ -222,21 +226,31 @@ __constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count)
 #endif
 }
 
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const wchar_t*
-__constexpr_wmemchr(const wchar_t* __str, wchar_t __char, size_t __count) {
-#if __has_feature(cxx_constexpr_string_builtins)
-  return __builtin_wmemchr(__str, __char, __count);
-#else
-  if (!__libcpp_is_constant_evaluated())
-    return std::wmemchr(__str, __char, __count);
+template <class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_wmemchr(_Tp* __str, _Up __value, size_t __count) {
+  static_assert(sizeof(_Tp) == sizeof(wchar_t)&& _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
+                    __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
+                "Calling wmemchr on non-trivially equality comparable types is unsafe.");
+
+#if __has_builtin(__builtin_wmemchr)
+  if (!__libcpp_is_constant_evaluated()) {
+    wchar_t __value_buffer = 0;
+    __builtin_memcpy(&__value_buffer, &__value, sizeof(wchar_t));
+    return reinterpret_cast<_Tp*>(
+        __builtin_wmemchr(reinterpret_cast<__apply_cv_t<_Tp, wchar_t>*>(__str), __value_buffer, __count));
+  }
+#  if _LIBCPP_STD_VER >= 17
+  else if constexpr (is_same_v<remove_cv_t<_Tp>, wchar_t>)
+    return __builtin_wmemchr(__str, __value, __count);
+#  endif
+#endif // __has_builtin(__builtin_wmemchr)
 
   for (; __count; --__count) {
-    if (*__str == __char)
+    if (*__str == __value)
       return __str;
     ++__str;
   }
   return nullptr;
-#endif
 }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/deque
@@ -47,6 +47,8 @@ public:
         deque(InputIterator f, InputIterator l);
     template <class InputIterator>
         deque(InputIterator f, InputIterator l, const allocator_type& a);
+    template<container-compatible-range<T> R>
+        deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
     deque(const deque& c);
     deque(deque&& c)
         noexcept(is_nothrow_move_constructible<allocator_type>::value);
@@ -64,6 +66,8 @@ public:
 
     template <class InputIterator>
         void assign(InputIterator f, InputIterator l);
+    template<container-compatible-range<T> R>
+      void assign_range(R&& rg); // C++23
     void assign(size_type n, const value_type& v);
     void assign(initializer_list<value_type> il);
 
@@ -107,8 +111,12 @@ public:
     // modifiers:
     void push_front(const value_type& v);
     void push_front(value_type&& v);
+    template<container-compatible-range<T> R>
+      void prepend_range(R&& rg); // C++23
     void push_back(const value_type& v);
     void push_back(value_type&& v);
+    template<container-compatible-range<T> R>
+      void append_range(R&& rg); // C++23
     template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
     template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
     template <class... Args> iterator emplace(const_iterator p, Args&&... args);
@@ -117,6 +125,8 @@ public:
     iterator insert(const_iterator p, size_type n, const value_type& v);
     template <class InputIterator>
         iterator insert(const_iterator p, InputIterator f, InputIterator l);
+    template<container-compatible-range<T> R>
+      iterator insert_range(const_iterator position, R&& rg); // C++23
     iterator insert(const_iterator p, initializer_list<value_type> il);
     void pop_front();
     void pop_back();
@@ -131,18 +141,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
    deque(InputIterator, InputIterator, Allocator = Allocator())
    -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
+  deque(from_range_t, R&&, Allocator = Allocator())
+    -> deque<ranges::range_value_t<R>, Allocator>; // C++23
+
 template <class T, class Allocator>
     bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
 template <class T, class Allocator>
-    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
 template <class T, class Allocator>
-    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
 template <class T, class Allocator>
-    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
 template <class T, class Allocator>
-    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
 template <class T, class Allocator>
-    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
+template<class T, class Allocator>
+    synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
+                                          const deque<T, Allocator>& y);       // since C++20
 
 // specialized algorithms:
 template <class T, class Allocator>
@@ -162,34 +179,47 @@ template <class T, class Allocator, class Predicate>
 
 #include <__algorithm/copy.h>
 #include <__algorithm/copy_backward.h>
+#include <__algorithm/copy_n.h>
 #include <__algorithm/equal.h>
 #include <__algorithm/fill_n.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/min.h>
 #include <__algorithm/remove.h>
 #include <__algorithm/remove_if.h>
 #include <__algorithm/unwrap_iter.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
 #include <__format/enable_insertable.h>
+#include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
 #include <__iterator/prev.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/segmented_iterator.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator_destructor.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/temp_value.h>
 #include <__memory/unique_ptr.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__ranges/size.h>
 #include <__split_buffer>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
+#include <__utility/pair.h>
 #include <__utility/swap.h>
 #include <limits>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -249,7 +279,7 @@ public:
     typedef _Reference                  reference;
 
     _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
      : __m_iter_(nullptr), __ptr_(nullptr)
 #endif
      {}
@@ -451,6 +481,7 @@ public:
   using __map_alloc_traits        = allocator_traits<__pointer_allocator>;
   using __map_pointer             = typename __map_alloc_traits::pointer;
   using __map_const_pointer       = typename allocator_traits<__const_pointer_allocator>::const_pointer;
+  using __map_const_iterator      = typename __map::const_iterator;
 
   using reference       = value_type&;
   using const_reference = const value_type&;
@@ -550,10 +581,13 @@ public:
     // construct/copy/destroy:
     _LIBCPP_HIDE_FROM_ABI
     deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-        : __start_(0), __size_(0, __default_init_tag()) {}
+        : __start_(0), __size_(0, __default_init_tag()) {
+      __annotate_new(0);
+    }
 
     _LIBCPP_HIDE_FROM_ABI ~deque() {
       clear();
+      __annotate_delete();
       typename __map::iterator __i = __map_.begin();
       typename __map::iterator __e = __map_.end();
       for (; __i != __e; ++__i)
@@ -561,10 +595,12 @@ public:
     }
 
     _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)
-        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
+        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
+      __annotate_new(0);
+    }
 
     explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);
 #endif
     _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
@@ -573,16 +609,34 @@ public:
     _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
         : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
     {
+        __annotate_new(0);
         if (__n > 0)
             __append(__n, __v);
     }
 
     template <class _InputIter>
     _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l,
-              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
+              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
     template <class _InputIter>
     _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
-              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
+              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range,
+      const allocator_type& __a = allocator_type())
+    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
+    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+      __append_with_size(ranges::begin(__range), ranges::distance(__range));
+
+    } else {
+      for (auto&& __e : __range) {
+        emplace_back(std::forward<decltype(__e)>(__e));
+      }
+    }
+  }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);
     _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
 
@@ -610,11 +664,30 @@ public:
 
     template <class _InputIter>
     _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l,
-                    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
-                                      !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
+                    typename enable_if<__has_input_iterator_category<_InputIter>::value &&
+                                      !__has_random_access_iterator_category<_InputIter>::value>::type* = 0);
     template <class _RAIter>
     _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l,
-                    typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
+                    typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void assign_range(_Range&& __range) {
+      if constexpr (ranges::random_access_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        __assign_with_size_random_access(ranges::begin(__range), __n);
+
+      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        __assign_with_size(ranges::begin(__range), __n);
+
+      } else {
+        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
 
     _LIBCPP_HIDE_FROM_ABI
@@ -713,7 +786,7 @@ public:
     _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
     _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
 #ifndef _LIBCPP_CXX03_LANG
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
     template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args);
 #else
@@ -724,6 +797,21 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
     _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void prepend_range(_Range&& __range) {
+      insert_range(begin(), std::forward<_Range>(__range));
+    }
+
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void append_range(_Range&& __range) {
+      insert_range(end(), std::forward<_Range>(__range));
+    }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
 
     _LIBCPP_HIDE_FROM_ABI
@@ -734,13 +822,31 @@ public:
     _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
     template <class _InputIter>
     _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
-                         typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
+                         typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0);
     template <class _ForwardIterator>
     _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
-                        typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
+                        typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
     template <class _BiIter>
     _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
-                         typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
+                         typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator insert_range(const_iterator __position, _Range&& __range) {
+      if constexpr (ranges::bidirectional_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n);
+
+      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        return __insert_with_size(__position, ranges::begin(__range), __n);
+
+      } else {
+        return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
 
     _LIBCPP_HIDE_FROM_ABI void pop_front();
     _LIBCPP_HIDE_FROM_ABI void pop_back();
@@ -764,7 +870,7 @@ public:
             return false;
         if (__map_.size() >= size_type(-1) / __block_size)
             return false;
-        for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
+        for (__map_const_iterator __i = __map_.begin(), __e = __map_.end();
             __i != __e; ++__i)
             if (*__i == nullptr)
                 return false;
@@ -851,9 +957,264 @@ public:
     }
 
  private:
+   enum __asan_annotation_type {
+     __asan_unposion,
+     __asan_poison
+   };
+
+   enum __asan_annotation_place {
+     __asan_front_moved,
+     __asan_back_moved,
+   };
+
+// The following functions are no-ops outside of AddressSanitizer mode.
+// We call annotations for every allocator, unless explicitly disabled.
+//
+// To disable annotations for a particular allocator, change value of
+// __asan_annotate_container_with_allocator to false.
+// For more details, see the "Using libc++" documentation page or
+// the documentation for __sanitizer_annotate_contiguous_container.
+#if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
+    // TODO LLVM18: Remove the special-casing
+    _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
+        const void* __beg,
+        const void* __end,
+        const void* __old_con_beg,
+        const void* __old_con_end,
+        const void* __new_con_beg,
+        const void* __new_con_end) const {
+        if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
+            __sanitizer_annotate_double_ended_contiguous_container(
+                __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end);
+    }
+#else
+    _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
+        const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {}
+#endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT {
+        // __beg - index of the first item to annotate
+        // __end - index behind the last item to annotate (so last item + 1)
+        // __annotation_type - __asan_unposion or __asan_poison
+        // __place - __asan_front_moved or __asan_back_moved
+        // Note: All indexes in __map_
+        if (__beg == __end)
+            return;
+        // __annotations_beg_map - first chunk which annotations we want to modify
+        // __annotations_end_map - last chunk which annotations we want to modify
+        // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist
+        __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size;
+        __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size;
+
+        bool const __poisoning = __annotation_type == __asan_poison;
+        // __old_c_beg_index - index of the first element in old container
+        // __old_c_end_index - index of the end of old container (last + 1)
+        // Note: may be outside the area we are annotating
+        size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_;
+        size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved)  ? __end : __start_ + size();
+        bool const __front = __place == __asan_front_moved;
+
+        if (__poisoning && empty()) {
+            // Special case: we shouldn't trust __start_
+            __old_c_beg_index = __beg;
+            __old_c_end_index = __end;
+        }
+        // __old_c_beg_map - memory block (chunk) with first element
+        // __old_c_end_map - memory block (chunk) with end of old container
+        // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block,
+        // which may not exist
+        __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size;
+        __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size;
+
+        // One edge (front/end) of the container was moved and one was not modified.
+        // __new_edge_index - index of new edge
+        // __new_edge_map    - memory block (chunk) with new edge, it always equals to
+        //                    __annotations_beg_map or __annotations_end_map
+        // __old_edge_map    - memory block (chunk) with old edge, it always equals to
+        //                    __old_c_beg_map or __old_c_end_map
+        size_t __new_edge_index                      = (__poisoning ^ __front) ? __beg : __end;
+        __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size;
+        __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map;
+
+        // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last.
+        // First and last chunk may be partially poisoned.
+        // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it.
+        for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) {
+            if (__map_it == __annotations_end_map && __end % __block_size == 0)
+                // Chunk may not exist, but nothing to do here anyway
+                break;
+
+            // The beginning and the end of the current memory block
+            const void* __mem_beg = std::__to_address(*__map_it);
+            const void* __mem_end = std::__to_address(*__map_it + __block_size);
+
+            // The beginning of memory-in-use in the memory block before container modification
+            const void* __old_beg =
+                (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg;
+
+            // The end of memory-in-use in the memory block before container modification
+            const void* __old_end;
+            if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty()))
+                __old_end = __old_beg;
+            else
+                __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size))
+                                                   : __mem_end;
+
+            // New edge of the container in current memory block
+            // If the edge is in a different chunk it points on corresponding end of the memory block
+            const void* __new_edge;
+            if (__map_it == __new_edge_map)
+                __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size));
+            else
+                __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end;
+
+            // Not modified edge of the container
+            // If the edge is in a different chunk it points on corresponding end of the memory block
+            const void* __old_edge;
+            if (__map_it == __old_edge_map)
+                __old_edge = __front ? __old_end : __old_beg;
+            else
+                __old_edge = __front ? __mem_end : __mem_beg;
+
+            // __new_beg - the beginning of memory-in-use in the memory block after container modification
+            // __new_end - the end of memory-in-use in the memory block after container modification
+            const void* __new_beg = __front ? __new_edge : __old_edge;
+            const void* __new_end = __front ? __old_edge : __new_edge;
+
+            __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end);
+        }
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_new(size_type __current_size) const _NOEXCEPT {
+        if (__current_size == 0)
+            __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
+        else {
+            __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved);
+            __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
+        }
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_delete() const _NOEXCEPT {
+        if (empty()) {
+            for(size_t __i = 0; __i < __map_.size(); ++__i) {
+                __annotate_whole_block(__i, __asan_unposion);
+            }
+        }
+        else {
+            __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved);
+            __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved);
+        }
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_increase_front(size_type __n) const _NOEXCEPT {
+        __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_increase_back(size_type __n) const _NOEXCEPT {
+        __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT {
+        __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT {
+        __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT {
+        __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT {
+        __map_const_iterator __block_it = __map_.begin() + __block_index;
+        const void* __block_start = std::__to_address(*__block_it);
+        const void* __block_end = std::__to_address(*__block_it + __block_size);
+
+        if(__annotation_type == __asan_poison)
+            __annotate_poison_block(__block_start, __block_end);
+        else {
+            __annotate_double_ended_contiguous_container(
+                __block_start, __block_end, __block_start, __block_start, __block_start, __block_end);
+        }
+    }
+#if !defined(_LIBCPP_HAS_NO_ASAN)
+
+  public:
+    _LIBCPP_HIDE_FROM_ABI
+    bool __verify_asan_annotations() const _NOEXCEPT {
+        // This function tests deque object annotations.
+        if (empty()) {
+            for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
+                if (!__sanitizer_verify_double_ended_contiguous_container(
+                        std::__to_address(*__it),
+                        std::__to_address(*__it),
+                        std::__to_address(*__it),
+                        std::__to_address(*__it + __block_size)))
+                  return false;
+            }
+
+            return true;
+        }
+
+        size_type __end                           = __start_ + size();
+        __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size;
+        __map_const_iterator __last_mp  = __map_.begin() + (__end - 1) / __block_size;
+
+        // Pointers to first and after last elements
+        // Those can be in different deque blocks
+        const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size));
+        const void* __p_end =
+            std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size));
+
+        for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
+            // Go over all blocks, find the place we are in and verify its annotations
+            // Note that __p_end points *behind* the last item.
+
+            // - blocks before the first block with container elements
+            // - first block with items
+            // - last block with items
+            // - blocks after last block with ciontainer elements
+
+            // Is the block before or after deque blocks that contain elements?
+            if (__it < __first_mp || __it > __last_mp) {
+                if (!__sanitizer_verify_double_ended_contiguous_container(
+                        std::__to_address(*__it),
+                        std::__to_address(*__it),
+                        std::__to_address(*__it),
+                        std::__to_address(*__it + __block_size)))
+                  return false;
+            } else {
+                const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);
+                const void* __containers_buffer_end =
+                    (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);
+                if (!__sanitizer_verify_double_ended_contiguous_container(
+                        std::__to_address(*__it),
+                        __containers_buffer_beg,
+                        __containers_buffer_end,
+                        std::__to_address(*__it + __block_size))) {
+                  return false;
+                }
+            }
+        }
+        return true;
+    }
+
+  private:
+#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS
     _LIBCPP_HIDE_FROM_ABI
     bool __maybe_remove_front_spare(bool __keep_one = true) {
       if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
+        __annotate_whole_block(0, __asan_unposion);
         __alloc_traits::deallocate(__alloc(), __map_.front(),
                                    __block_size);
         __map_.pop_front();
@@ -866,6 +1227,7 @@ public:
     _LIBCPP_HIDE_FROM_ABI
     bool __maybe_remove_back_spare(bool __keep_one = true) {
       if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
+        __annotate_whole_block(__map_.size() - 1, __asan_unposion);
         __alloc_traits::deallocate(__alloc(), __map_.back(),
                                    __block_size);
         __map_.pop_back();
@@ -874,12 +1236,44 @@ public:
       return false;
     }
 
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
+
+    template <class _RandomAccessIterator>
+    _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);
+    template <class _Iterator>
+    _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_size(_Iterator __f, difference_type __n);
+
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
+
+    template <class _Iterator>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n);
+
+    template <class _BiIter, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n);
+    template <class _BiIter>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n);
+
     template <class _InpIter>
     _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l,
-                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
+                 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0);
     template <class _ForIter>
     _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l,
-                      typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
+                      typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0);
+
+    template <class _InputIterator>
+    _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n);
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l);
+
     _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
     _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);
     _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);
@@ -929,7 +1323,7 @@ _LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator,
          class _Alloc = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 deque(_InputIterator, _InputIterator)
@@ -937,26 +1331,37 @@ deque(_InputIterator, _InputIterator)
 
 template<class _InputIterator,
          class _Alloc,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 deque(_InputIterator, _InputIterator, _Alloc)
   -> deque<__iter_value_type<_InputIterator>, _Alloc>;
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Alloc = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Alloc>::value>
+          >
+deque(from_range_t, _Range&&, _Alloc = _Alloc())
+  -> deque<ranges::range_value_t<_Range>, _Alloc>;
+#endif
+
 template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(size_type __n)
     : __start_(0), __size_(0, __default_init_tag())
 {
+    __annotate_new(0);
     if (__n > 0)
         __append(__n);
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
     : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
 {
+    __annotate_new(0);
     if (__n > 0)
         __append(__n);
 }
@@ -966,6 +1371,7 @@ template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
     : __start_(0), __size_(0, __default_init_tag())
 {
+    __annotate_new(0);
     if (__n > 0)
         __append(__n, __v);
 }
@@ -973,18 +1379,20 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
 template <class _Tp, class _Allocator>
 template <class _InputIter>
 deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
-              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
+              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
     : __start_(0), __size_(0, __default_init_tag())
 {
+    __annotate_new(0);
     __append(__f, __l);
 }
 
 template <class _Tp, class _Allocator>
 template <class _InputIter>
 deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
-              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
+              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
     : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
 {
+    __annotate_new(0);
     __append(__f, __l);
 }
 
@@ -994,6 +1402,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
       __start_(0),
       __size_(0, __map_.__alloc())
 {
+    __annotate_new(0);
     __append(__c.begin(), __c.end());
 }
 
@@ -1001,6 +1410,7 @@ template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
     : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
 {
+    __annotate_new(0);
     __append(__c.begin(), __c.end());
 }
 
@@ -1022,6 +1432,7 @@ template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
     : __start_(0), __size_(0, __default_init_tag())
 {
+    __annotate_new(0);
     __append(__il.begin(), __il.end());
 }
 
@@ -1029,6 +1440,7 @@ template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
     : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
 {
+    __annotate_new(0);
     __append(__il.begin(), __il.end());
 }
 
@@ -1105,15 +1517,22 @@ template <class _Tp, class _Allocator>
 template <class _InputIter>
 void
 deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
-                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
-                                                 !__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
+                               typename enable_if<__has_input_iterator_category<_InputIter>::value &&
+                                                 !__has_random_access_iterator_category<_InputIter>::value>::type*)
 {
+  __assign_with_sentinel(__f, __l);
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
     iterator __i = begin();
     iterator __e = end();
     for (; __f != __l && __i != __e; ++__f, (void) ++__i)
         *__i = *__f;
     if (__f != __l)
-        __append(__f, __l);
+        __append_with_sentinel(std::move(__f), std::move(__l));
     else
         __erase_to_end(__i);
 }
@@ -1122,16 +1541,42 @@ template <class _Tp, class _Allocator>
 template <class _RAIter>
 void
 deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
-                               typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
+                               typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*)
 {
-    if (static_cast<size_type>(__l - __f) > size())
+  __assign_with_size_random_access(__f, __l - __f);
+}
+
+template <class _Tp, class _Allocator>
+template <class _RandomAccessIterator>
+_LIBCPP_HIDE_FROM_ABI
+void deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) {
+    if (static_cast<size_type>(__n) > size())
     {
-        _RAIter __m = __f + size();
-        _VSTD::copy(__f, __m, begin());
-        __append(__m, __l);
+        auto __l = __f + size();
+        std::copy(__f, __l, begin());
+        __append_with_size(__l, __n - size());
     }
     else
-        __erase_to_end(_VSTD::copy(__f, __l, begin()));
+        __erase_to_end(std::copy_n(__f, __n, begin()));
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator>
+_LIBCPP_HIDE_FROM_ABI
+void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {
+  if (static_cast<size_type>(__n) > size()) {
+    auto __added_size = __n - size();
+
+    auto __i = begin();
+    for (auto __count = size(); __count != 0; --__count) {
+      *__i++ = *__f++;
+    }
+
+    __append_with_size(__f, __added_size);
+
+  } else {
+    __erase_to_end(std::copy_n(__f, __n, begin()));
+  }
 }
 
 template <class _Tp, class _Allocator>
@@ -1183,6 +1628,7 @@ deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
     allocator_type& __a = __alloc();
     if (empty())
     {
+        __annotate_delete();
         while (__map_.size() > 0)
         {
             __alloc_traits::deallocate(__a, __map_.back(), __block_size);
@@ -1282,6 +1728,7 @@ deque<_Tp, _Allocator>::push_back(const value_type& __v)
     if (__back_spare() == 0)
         __add_back_capacity();
     // __back_spare() >= 1
+    __annotate_increase_back(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
     ++__size();
 }
@@ -1294,6 +1741,7 @@ deque<_Tp, _Allocator>::push_front(const value_type& __v)
     if (__front_spare() == 0)
         __add_front_capacity();
     // __front_spare() >= 1
+    __annotate_increase_front(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
     --__start_;
     ++__size();
@@ -1308,13 +1756,14 @@ deque<_Tp, _Allocator>::push_back(value_type&& __v)
     if (__back_spare() == 0)
         __add_back_capacity();
     // __back_spare() >= 1
+    __annotate_increase_back(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
     ++__size();
 }
 
 template <class _Tp, class _Allocator>
 template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename deque<_Tp, _Allocator>::reference
 #else
 void
@@ -1325,10 +1774,11 @@ deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
     if (__back_spare() == 0)
         __add_back_capacity();
     // __back_spare() >= 1
+    __annotate_increase_back(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*end()),
                               _VSTD::forward<_Args>(__args)...);
     ++__size();
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return *--end();
 #endif
 }
@@ -1341,6 +1791,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v)
     if (__front_spare() == 0)
         __add_front_capacity();
     // __front_spare() >= 1
+    __annotate_increase_front(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
     --__start_;
     ++__size();
@@ -1349,7 +1800,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v)
 
 template <class _Tp, class _Allocator>
 template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename deque<_Tp, _Allocator>::reference
 #else
 void
@@ -1360,10 +1811,11 @@ deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
     if (__front_spare() == 0)
         __add_front_capacity();
     // __front_spare() >= 1
+    __annotate_increase_front(1);
     __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
     --__start_;
     ++__size();
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return *begin();
 #endif
 }
@@ -1380,6 +1832,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
         if (__front_spare() == 0)
             __add_front_capacity();
         // __front_spare() >= 1
+        __annotate_increase_front(1);
         if (__pos == 0)
         {
             __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
@@ -1403,6 +1856,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
         if (__back_spare() == 0)
             __add_back_capacity();
         // __back_capacity >= 1
+        __annotate_increase_back(1);
         size_type __de = size() - __pos;
         if (__de == 0)
         {
@@ -1436,6 +1890,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
         if (__front_spare() == 0)
             __add_front_capacity();
         // __front_spare() >= 1
+        __annotate_increase_front(1);
         if (__pos == 0)
         {
             __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
@@ -1460,6 +1915,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
         if (__back_spare() == 0)
             __add_back_capacity();
         // __back_capacity >= 1
+        __annotate_increase_back(1);
         size_type __de = size() - __pos;
         if (__de == 0)
         {
@@ -1496,6 +1952,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
         if (__front_spare() == 0)
             __add_front_capacity();
         // __front_spare() >= 1
+        __annotate_increase_front(1);
         if (__pos == 0)
         {
             __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
@@ -1522,6 +1979,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
         if (__back_spare() == 0)
             __add_back_capacity();
         // __back_capacity >= 1
+        __annotate_increase_back(1);
         size_type __de = size() - __pos;
         if (__de == 0)
         {
@@ -1557,6 +2015,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty
         if (__n > __front_spare())
             __add_front_capacity(__n - __front_spare());
         // __n <= __front_spare()
+        __annotate_increase_front(__n);
         iterator __old_begin = begin();
         iterator __i = __old_begin;
         if (__n > __pos)
@@ -1581,6 +2040,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty
         if (__n > __back_capacity)
             __add_back_capacity(__n - __back_capacity);
         // __n <= __back_capacity
+        __annotate_increase_back(__n);
         iterator __old_end = end();
         iterator __i = __old_end;
         size_type __de = size() - __pos;
@@ -1607,10 +2067,18 @@ template <class _Tp, class _Allocator>
 template <class _InputIter>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
-                               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
+                               typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*)
 {
+  return __insert_with_sentinel(__p, __f, __l);
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
     __split_buffer<value_type, allocator_type&> __buf(__alloc());
-    __buf.__construct_at_end(__f, __l);
+    __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));
     typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
     return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
 }
@@ -1619,11 +2087,18 @@ template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
-                               typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
+                               typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*)
 {
-    size_type __n = _VSTD::distance(__f, __l);
+  return __insert_with_size(__p, __f, std::distance(__f, __l));
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator>
+_LIBCPP_HIDE_FROM_ABI
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {
     __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
-    __buf.__construct_at_end(__f, __l);
+    __buf.__construct_at_end_with_size(__f, __n);
     typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
     return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
 }
@@ -1632,9 +2107,24 @@ template <class _Tp, class _Allocator>
 template <class _BiIter>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
-                               typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
+                               typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*)
 {
-    size_type __n = _VSTD::distance(__f, __l);
+  return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l));
+}
+
+template <class _Tp, class _Allocator>
+template <class _BiIter, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) {
+  return __insert_bidirectional(__p, __f, std::next(__f, __n), __n);
+}
+
+template <class _Tp, class _Allocator>
+template <class _BiIter>
+_LIBCPP_HIDE_FROM_ABI
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) {
     size_type __pos = __p - begin();
     size_type __to_end = size() - __pos;
     allocator_type& __a = __alloc();
@@ -1643,6 +2133,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
         if (__n > __front_spare())
             __add_front_capacity(__n - __front_spare());
         // __n <= __front_spare()
+        __annotate_increase_front(__n);
         iterator __old_begin = begin();
         iterator __i = __old_begin;
         _BiIter __m = __f;
@@ -1673,6 +2164,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
         if (__n > __back_capacity)
             __add_back_capacity(__n - __back_capacity);
         // __n <= __back_capacity
+        __annotate_increase_back(__n);
         iterator __old_end = end();
         iterator __i = __old_end;
         _BiIter __m = __l;
@@ -1701,8 +2193,15 @@ template <class _Tp, class _Allocator>
 template <class _InpIter>
 void
 deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
-                                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
+                                 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*)
 {
+  __append_with_sentinel(__f, __l);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) {
     for (; __f != __l; ++__f)
 #ifdef _LIBCPP_CXX03_LANG
         push_back(*__f);
@@ -1715,14 +2214,22 @@ template <class _Tp, class _Allocator>
 template <class _ForIter>
 void
 deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
-                                 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
+                                 typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*)
 {
-    size_type __n = _VSTD::distance(__f, __l);
+    __append_with_size(__f, std::distance(__f, __l));
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator>
+_LIBCPP_HIDE_FROM_ABI
+void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) {
     allocator_type& __a = __alloc();
     size_type __back_capacity = __back_spare();
     if (__n > __back_capacity)
         __add_back_capacity(__n - __back_capacity);
+
     // __n <= __back_capacity
+    __annotate_increase_back(__n);
     for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
       _ConstructTransaction __tx(this, __br);
       for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
@@ -1740,6 +2247,7 @@ deque<_Tp, _Allocator>::__append(size_type __n)
     if (__n > __back_capacity)
         __add_back_capacity(__n - __back_capacity);
     // __n <= __back_capacity
+    __annotate_increase_back(__n);
     for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
       _ConstructTransaction __tx(this, __br);
       for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
@@ -1757,6 +2265,7 @@ deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
     if (__n > __back_capacity)
         __add_back_capacity(__n - __back_capacity);
     // __n <= __back_capacity
+    __annotate_increase_back(__n);
     for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
       _ConstructTransaction __tx(this, __br);
       for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
@@ -1824,6 +2333,7 @@ deque<_Tp, _Allocator>::__add_front_capacity()
                                __block_size / 2 :
                                __start_ + __block_size;
     }
+    __annotate_whole_block(0, __asan_poison);
 }
 
 // Create front capacity for __n elements.
@@ -1859,6 +2369,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
             if (__map_.__front_spare() == 0)
                 break;
             __map_.push_front(__alloc_traits::allocate(__a, __block_size));
+            __annotate_whole_block(0, __asan_poison);
         }
         for (; __nb > 0; --__nb, ++__back_capacity)
             __map_.push_back(__alloc_traits::allocate(__a, __block_size));
@@ -1869,6 +2380,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
             pointer __pt = __map_.back();
             __map_.pop_back();
             __map_.push_front(__pt);
+            __annotate_whole_block(0, __asan_poison);
         }
     }
     // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
@@ -1879,22 +2391,28 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
             __buf(std::max<size_type>(2* __map_.capacity(),
                                       __nb + __map_.size()),
                   0, __map_.__alloc());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
-            for (; __nb > 0; --__nb)
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+            for (; __nb > 0; --__nb) {
                 __buf.push_back(__alloc_traits::allocate(__a, __block_size));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+                // ASan: this is empty container, we have to poison whole block
+                __annotate_poison_block(
+                    std::__to_address(__buf.back()),
+                    std::__to_address(__buf.back() + __block_size));
+            }
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
+            __annotate_delete();
             for (__map_pointer __i = __buf.begin();
                     __i != __buf.end(); ++__i)
                 __alloc_traits::deallocate(__a, *__i, __block_size);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         for (; __back_capacity > 0; --__back_capacity)
         {
             __buf.push_back(__map_.back());
@@ -1940,6 +2458,7 @@ deque<_Tp, _Allocator>::__add_back_capacity()
             __map_.pop_front();
             __map_.push_back(__pt);
         }
+        __annotate_whole_block(__map_.size() - 1, __asan_poison);
     }
     // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
     else
@@ -1963,6 +2482,7 @@ deque<_Tp, _Allocator>::__add_back_capacity()
         _VSTD::swap(__map_.__begin_, __buf.__begin_);
         _VSTD::swap(__map_.__end_, __buf.__end_);
         _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
+        __annotate_whole_block(__map_.size() - 1, __asan_poison);
     }
 }
 
@@ -1999,10 +2519,13 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
             if (__map_.__back_spare() == 0)
                 break;
             __map_.push_back(__alloc_traits::allocate(__a, __block_size));
+            __annotate_whole_block(__map_.size() - 1, __asan_poison);
         }
         for (; __nb > 0; --__nb, ++__front_capacity, __start_ +=
-                                 __block_size - (__map_.size() == 1))
+                                 __block_size - (__map_.size() == 1)) {
             __map_.push_front(__alloc_traits::allocate(__a, __block_size));
+            __annotate_whole_block(0, __asan_poison);
+        }
         // Done allocating, reorder capacity
         __start_ -= __block_size * __front_capacity;
         for (; __front_capacity > 0; --__front_capacity)
@@ -2021,22 +2544,28 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
                                       __nb + __map_.size()),
                   __map_.size() - __front_capacity,
                   __map_.__alloc());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
-            for (; __nb > 0; --__nb)
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+            for (; __nb > 0; --__nb) {
                 __buf.push_back(__alloc_traits::allocate(__a, __block_size));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+                // ASan: this is an empty container, we have to poison the whole block
+                __annotate_poison_block(
+                    std::__to_address(__buf.back()),
+                    std::__to_address(__buf.back() + __block_size));
+            }
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
+            __annotate_delete();
             for (__map_pointer __i = __buf.begin();
                     __i != __buf.end(); ++__i)
                 __alloc_traits::deallocate(__a, *__i, __block_size);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         for (; __front_capacity > 0; --__front_capacity)
         {
             __buf.push_back(__map_.front());
@@ -2057,12 +2586,15 @@ template <class _Tp, class _Allocator>
 void
 deque<_Tp, _Allocator>::pop_front()
 {
+    size_type __old_sz    = size();
+    size_type __old_start = __start_;
     allocator_type& __a = __alloc();
     __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
                                                     __start_ / __block_size) +
                                                     __start_ % __block_size));
     --__size();
     ++__start_;
+    __annotate_shrink_front(__old_sz, __old_start);
     __maybe_remove_front_spare();
 }
 
@@ -2070,13 +2602,16 @@ template <class _Tp, class _Allocator>
 void
 deque<_Tp, _Allocator>::pop_back()
 {
-    _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque");
+    size_type __old_sz    = size();
+    size_type __old_start = __start_;
     allocator_type& __a = __alloc();
     size_type __p = size() + __start_ - 1;
     __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
                                                     __p / __block_size) +
                                                     __p % __block_size));
     --__size();
+    __annotate_shrink_back(__old_sz, __old_start);
     __maybe_remove_back_spare();
 }
 
@@ -2216,6 +2751,8 @@ template <class _Tp, class _Allocator>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::erase(const_iterator __f)
 {
+    size_type __old_sz    = size();
+    size_type __old_start = __start_;
     iterator __b = begin();
     difference_type __pos = __f - __b;
     iterator __p = __b + __pos;
@@ -2226,6 +2763,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f)
         __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
         --__size();
         ++__start_;
+        __annotate_shrink_front(__old_sz, __old_start);
         __maybe_remove_front_spare();
     }
     else
@@ -2233,6 +2771,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f)
         iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p);
         __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
         --__size();
+        __annotate_shrink_back(__old_sz, __old_start);
         __maybe_remove_back_spare();
     }
     return begin() + __pos;
@@ -2242,6 +2781,8 @@ template <class _Tp, class _Allocator>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
 {
+    size_type __old_sz    = size();
+    size_type __old_start = __start_;
     difference_type __n = __l - __f;
     iterator __b = begin();
     difference_type __pos = __f - __b;
@@ -2256,6 +2797,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
                 __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
             __size() -= __n;
             __start_ += __n;
+            __annotate_shrink_front(__old_sz, __old_start);
             while (__maybe_remove_front_spare()) {
             }
         }
@@ -2265,6 +2807,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
             for (iterator __e = end(); __i != __e; ++__i)
                 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
             __size() -= __n;
+            __annotate_shrink_back(__old_sz, __old_start);
             while (__maybe_remove_back_spare()) {
             }
         }
@@ -2276,6 +2819,8 @@ template <class _Tp, class _Allocator>
 void
 deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
 {
+    size_type __old_sz    = size();
+    size_type __old_start = __start_;
     iterator __e = end();
     difference_type __n = __e - __f;
     if (__n > 0)
@@ -2286,6 +2831,7 @@ deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
         for (iterator __p = __b + __pos; __p != __e; ++__p)
             __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
         __size() -= __n;
+        __annotate_shrink_back(__old_sz, __old_start);
         while (__maybe_remove_back_spare()) {
         }
     }
@@ -2313,6 +2859,7 @@ inline
 void
 deque<_Tp, _Allocator>::clear() _NOEXCEPT
 {
+    __annotate_delete();
     allocator_type& __a = __alloc();
     for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
         __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
@@ -2331,6 +2878,7 @@ deque<_Tp, _Allocator>::clear() _NOEXCEPT
         __start_ = __block_size;
         break;
     }
+    __annotate_new(0);
 }
 
 template <class _Tp, class _Allocator>
@@ -2342,6 +2890,8 @@ operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
     return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI
 bool
@@ -2382,6 +2932,17 @@ operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
     return !(__y < __x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Tp, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
+operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI
 void
@@ -2391,7 +2952,7 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Up>
 inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
 erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
@@ -2415,15 +2976,15 @@ template <>
 inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
 #endif
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _ValueT>
-using deque = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
+using deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
@@ -2434,9 +2995,11 @@ _LIBCPP_POP_MACROS
 #  include <algorithm>
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iosfwd>
 #  include <iterator>
+#  include <type_traits>
 #  include <typeinfo>
 #endif
 
lib/libcxx/include/exception
@@ -77,307 +77,20 @@ template <class E> void rethrow_if_nested(const E& e);
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
-#include <__availability>
 #include <__config>
-#include <__memory/addressof.h>
-#include <__type_traits/decay.h>
-#include <__type_traits/is_base_of.h>
-#include <__type_traits/is_class.h>
-#include <__type_traits/is_convertible.h>
-#include <__type_traits/is_copy_constructible.h>
-#include <__type_traits/is_final.h>
-#include <__type_traits/is_polymorphic.h>
-#include <cstddef>
-#include <cstdlib>
+#include <__exception/exception.h>
+#include <__exception/exception_ptr.h>
+#include <__exception/nested_exception.h>
+#include <__exception/operations.h>
+#include <__exception/terminate.h>
 #include <version>
 
-// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
-// which we use in order to be ABI-compatible with other STLs on Windows.
-#if defined(_LIBCPP_ABI_VCRUNTIME)
-#  include <vcruntime_exception.h>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-namespace std  // purposefully not using versioning namespace
-{
-
-#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
-// The std::exception class was already included above, but we're explicit about this condition here for clarity.
-
-#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
-// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
-// when _HAS_EXCEPTIONS == 0.
-//
-// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
-// (after all those are simply types like any other), we define an ABI-compatible version
-// of the VCRuntime std::exception and std::bad_exception types in that mode.
-
-struct __std_exception_data {
-  char const* _What;
-  bool _DoFree;
-};
-
-class exception { // base of all library exceptions
-public:
-  exception() _NOEXCEPT : __data_() {}
-
-  explicit exception(char const* __message) _NOEXCEPT : __data_() {
-    __data_._What = __message;
-    __data_._DoFree = true;
-  }
-
-  exception(exception const&) _NOEXCEPT {}
-
-  exception& operator=(exception const&) _NOEXCEPT { return *this; }
-
-  virtual ~exception() _NOEXCEPT {}
-
-  virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
-
-private:
-  __std_exception_data __data_;
-};
-
-class bad_exception : public exception {
-public:
-  bad_exception() _NOEXCEPT : exception("bad exception") {}
-};
-
-#else // !defined(_LIBCPP_ABI_VCRUNTIME)
-// On all other platforms, we define our own std::exception and std::bad_exception types
-// regardless of whether exceptions are turned on as a language feature.
-
-class _LIBCPP_EXCEPTION_ABI exception {
-public:
-  _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
-  _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default;
-
-  virtual ~exception() _NOEXCEPT;
-  virtual const char* what() const _NOEXCEPT;
-};
-
-class _LIBCPP_EXCEPTION_ABI bad_exception : public exception {
-public:
-  _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
-  ~bad_exception() _NOEXCEPT override;
-  const char* what() const _NOEXCEPT override;
-};
-#endif // !_LIBCPP_ABI_VCRUNTIME
-
-#if _LIBCPP_STD_VER <= 14 \
-    || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \
-    || defined(_LIBCPP_BUILDING_LIBRARY)
-typedef void (*unexpected_handler)();
-_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
-#endif
-
-typedef void (*terminate_handler)();
-_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
-
-_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
-_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
-
-class _LIBCPP_TYPE_VIS exception_ptr;
-
-_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-
-#ifndef _LIBCPP_ABI_MICROSOFT
-
-class _LIBCPP_TYPE_VIS exception_ptr
-{
-    void* __ptr_;
-public:
-    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
-    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
-
-    exception_ptr(const exception_ptr&) _NOEXCEPT;
-    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
-    ~exception_ptr() _NOEXCEPT;
-
-    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
-    {return __ptr_ != nullptr;}
-
-    friend _LIBCPP_INLINE_VISIBILITY
-    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-        {return __x.__ptr_ == __y.__ptr_;}
-
-    friend _LIBCPP_INLINE_VISIBILITY
-    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-        {return !(__x == __y);}
-
-    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-};
-
-template<class _Ep>
-_LIBCPP_INLINE_VISIBILITY exception_ptr
-make_exception_ptr(_Ep __e) _NOEXCEPT
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
-    {
-        throw __e;
-    }
-    catch (...)
-    {
-        return current_exception();
-    }
-#else
-    ((void)__e);
-    _VSTD::abort();
-#endif
-}
-
-#else // _LIBCPP_ABI_MICROSOFT
-
-class _LIBCPP_TYPE_VIS exception_ptr
-{
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
-    void* __ptr1_;
-    void* __ptr2_;
-_LIBCPP_DIAGNOSTIC_POP
-public:
-    exception_ptr() _NOEXCEPT;
-    exception_ptr(nullptr_t) _NOEXCEPT;
-    exception_ptr(const exception_ptr& __other) _NOEXCEPT;
-    exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
-    exception_ptr& operator=(nullptr_t) _NOEXCEPT;
-    ~exception_ptr() _NOEXCEPT;
-    explicit operator bool() const _NOEXCEPT;
-};
-
-_LIBCPP_FUNC_VIS
-bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-    {return !(__x == __y);}
-
-_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
-
-_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
-_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-
-// This is a built-in template function which automagically extracts the required
-// information.
-template <class _E> void *__GetExceptionInfo(_E);
-
-template<class _Ep>
-_LIBCPP_INLINE_VISIBILITY exception_ptr
-make_exception_ptr(_Ep __e) _NOEXCEPT
-{
-  return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
-}
-
-#endif // _LIBCPP_ABI_MICROSOFT
-// nested_exception
-
-class _LIBCPP_EXCEPTION_ABI nested_exception
-{
-    exception_ptr __ptr_;
-public:
-    nested_exception() _NOEXCEPT;
-//     nested_exception(const nested_exception&) noexcept = default;
-//     nested_exception& operator=(const nested_exception&) noexcept = default;
-    virtual ~nested_exception() _NOEXCEPT;
-
-    // access functions
-    _LIBCPP_NORETURN void rethrow_nested() const;
-    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
-};
-
-template <class _Tp>
-struct __nested
-    : public _Tp,
-      public nested_exception
-{
-    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
-};
-
-#ifndef _LIBCPP_NO_EXCEPTIONS
-template <class _Tp, class _Up, bool>
-struct __throw_with_nested;
-
-template <class _Tp, class _Up>
-struct __throw_with_nested<_Tp, _Up, true> {
-    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
-    __do_throw(_Tp&& __t)
-    {
-        throw __nested<_Up>(static_cast<_Tp&&>(__t));
-    }
-};
-
-template <class _Tp, class _Up>
-struct __throw_with_nested<_Tp, _Up, false> {
-    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
-#ifndef _LIBCPP_CXX03_LANG
-    __do_throw(_Tp&& __t)
-#else
-    __do_throw (_Tp& __t)
-#endif // _LIBCPP_CXX03_LANG
-    {
-        throw static_cast<_Tp&&>(__t);
-    }
-};
-#endif
-
-template <class _Tp>
-_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
-void
-throw_with_nested(_Tp&& __t)
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    typedef typename decay<_Tp>::type _Up;
-    static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
-    __throw_with_nested<_Tp, _Up,
-        is_class<_Up>::value &&
-        !is_base_of<nested_exception, _Up>::value &&
-        !__libcpp_is_final<_Up>::value>::
-            __do_throw(static_cast<_Tp&&>(__t));
-#else
-    ((void)__t);
-    // FIXME: Make this abort
-#endif
-}
-
-template <class _From, class _To>
-struct __can_dynamic_cast : _BoolConstant<
-              is_polymorphic<_From>::value &&
-                 (!is_base_of<_To, _From>::value ||
-                   is_convertible<const _From*, const _To*>::value)> {};
-
-template <class _Ep>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-rethrow_if_nested(const _Ep& __e,
-                  __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
-{
-    const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
-    if (__nep)
-        __nep->rethrow_nested();
-}
-
-template <class _Ep>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-rethrow_if_nested(const _Ep&,
-                  __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
-{
-}
-
-} // namespace std
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
 #  include <type_traits>
 #endif
 
lib/libcxx/include/execution
@@ -10,16 +10,137 @@
 #ifndef _LIBCPP_EXECUTION
 #define _LIBCPP_EXECUTION
 
+/*
+namespace std::execution {
+  struct sequenced_policy;
+  struct parallel_policy;
+  struct parallel_unsequenced_policy;
+  struct unsequenced_policy; // since C++20
+
+  inline constexpr sequenced_policy seq = implementation-defined;
+  inline constexpr parallel_policy par = implementation-defined;
+  inline constexpr parallel_unsequenced_policy par_unseq = implementation-defined;
+  inline constexpr unsequenced_policy unseq = implementation-defined; // since C++20
+}
+
+namespace std {
+  template <class T>
+  struct is_execution_policy;
+
+  template <class T>
+  inline constexpr bool is_execution_policy_v;
+}
+*/
+
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cvref.h>
 #include <version>
 
-#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
-#   include <__pstl_execution>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace execution {
+struct sequenced_policy {
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit sequenced_policy(__disable_user_instantiations_tag) {}
+  sequenced_policy(const sequenced_policy&)            = delete;
+  sequenced_policy& operator=(const sequenced_policy&) = delete;
+};
+
+inline constexpr sequenced_policy seq{__disable_user_instantiations_tag{}};
+
+struct parallel_policy {
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_policy(__disable_user_instantiations_tag) {}
+  parallel_policy(const parallel_policy&)            = delete;
+  parallel_policy& operator=(const parallel_policy&) = delete;
+};
+
+inline constexpr parallel_policy par{__disable_user_instantiations_tag{}};
+
+struct parallel_unsequenced_policy {
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_unsequenced_policy(__disable_user_instantiations_tag) {}
+  parallel_unsequenced_policy(const parallel_unsequenced_policy&)            = delete;
+  parallel_unsequenced_policy& operator=(const parallel_unsequenced_policy&) = delete;
+};
+
+inline constexpr parallel_unsequenced_policy par_unseq{__disable_user_instantiations_tag{}};
+
+struct __unsequenced_policy {
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __unsequenced_policy(__disable_user_instantiations_tag) {}
+  __unsequenced_policy(const __unsequenced_policy&)            = delete;
+  __unsequenced_policy& operator=(const __unsequenced_policy&) = delete;
+};
+
+constexpr __unsequenced_policy __unseq{__disable_user_instantiations_tag{}};
+
+#  if _LIBCPP_STD_VER >= 20
+
+struct unsequenced_policy {
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit unsequenced_policy(__disable_user_instantiations_tag) {}
+  unsequenced_policy(const unsequenced_policy&)            = delete;
+  unsequenced_policy& operator=(const unsequenced_policy&) = delete;
+};
+
+inline constexpr unsequenced_policy unseq{__disable_user_instantiations_tag{}};
+
+#  endif // _LIBCPP_STD_VER >= 20
+
+} // namespace execution
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::sequenced_policy> = true;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::parallel_policy> = true;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::parallel_unsequenced_policy> = true;
+
+template <>
+inline constexpr bool is_execution_policy_v<execution::__unsequenced_policy> = true;
+
+template <>
+inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_policy> = true;
+
+template <>
+inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
+
+template <>
+inline constexpr bool __is_unsequenced_execution_policy_impl<execution::__unsequenced_policy> = true;
+
+template <>
+inline constexpr bool __is_unsequenced_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
+
+#  if _LIBCPP_STD_VER >= 20
+template <>
+inline constexpr bool is_execution_policy_v<execution::unsequenced_policy> = true;
+
+template <>
+inline constexpr bool __is_unsequenced_execution_policy_impl<execution::unsequenced_policy> = true;
+
+#  endif
+
+template <class _Tp>
+struct is_execution_policy : bool_constant<is_execution_policy_v<_Tp>> {};
+
+template <class _ExecutionPolicy>
+_LIBCPP_HIDE_FROM_ABI auto __remove_parallel_policy(const _ExecutionPolicy&) {
+  if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_policy>) {
+    return execution::sequenced_policy(execution::__disable_user_instantiations_tag{});
+  } else if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_unsequenced_policy>) {
+    return execution::__unsequenced_policy{execution::__disable_user_instantiations_tag{}};
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
 #endif // _LIBCPP_EXECUTION
lib/libcxx/include/filesystem
@@ -159,6 +159,9 @@
     void swap(path& lhs, path& rhs) noexcept;
     size_t hash_value(const path& p) noexcept;
 
+    // [fs.path.hash], hash support
+    template<> struct hash<filesystem::path>;
+
     template <class Source>
       path u8path(const Source& source);
     template <class InputIterator>
@@ -233,19 +236,120 @@
       friend class directory_iterator;    // exposition only
     };
 
-    class directory_iterator;
+  class directory_iterator {
+  public:
+    using iterator_category = input_iterator_tag;
+    using value_type        = directory_entry;
+    using difference_type   = ptrdiff_t;
+    using pointer           = const directory_entry*;
+    using reference         = const directory_entry&;
+
+    // [fs.dir.itr.members], member functions
+    directory_iterator() noexcept;
+    explicit directory_iterator(const path& p);
+    directory_iterator(const path& p, directory_options options);
+    directory_iterator(const path& p, error_code& ec);
+    directory_iterator(const path& p, directory_options options,
+                       error_code& ec);
+    directory_iterator(const directory_iterator& rhs);
+    directory_iterator(directory_iterator&& rhs) noexcept;
+    ~directory_iterator();
+
+    directory_iterator& operator=(const directory_iterator& rhs);
+    directory_iterator& operator=(directory_iterator&& rhs) noexcept;
+
+    const directory_entry& operator*() const;
+    const directory_entry* operator->() const;
+    directory_iterator&    operator++();
+    directory_iterator&    increment(error_code& ec);
+
+    bool operator==(default_sentinel_t) const noexcept {          // since C++20
+      return *this == directory_iterator();
+    }
+
+    // other members as required by [input.iterators], input iterators
+  };
 
     // enable directory_iterator range-based for statements
     directory_iterator begin(directory_iterator iter) noexcept;
     directory_iterator end(directory_iterator) noexcept;
 
-    class recursive_directory_iterator;
+class recursive_directory_iterator {
+  public:
+    using iterator_category = input_iterator_tag;
+    using value_type        = directory_entry;
+    using difference_type   = ptrdiff_t;
+    using pointer           = const directory_entry*;
+    using reference         = const directory_entry&;
+
+    // [fs.rec.dir.itr.members], constructors and destructor
+    recursive_directory_iterator() noexcept;
+    explicit recursive_directory_iterator(const path& p);
+    recursive_directory_iterator(const path& p, directory_options options);
+    recursive_directory_iterator(const path& p, directory_options options,
+                                 error_code& ec);
+    recursive_directory_iterator(const path& p, error_code& ec);
+    recursive_directory_iterator(const recursive_directory_iterator& rhs);
+    recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
+    ~recursive_directory_iterator();
+
+    // [fs.rec.dir.itr.members], observers
+    directory_options  options() const;
+    int                depth() const;
+    bool               recursion_pending() const;
+
+    const directory_entry& operator*() const;
+    const directory_entry* operator->() const;
+
+    // [fs.rec.dir.itr.members], modifiers
+    recursive_directory_iterator&
+      operator=(const recursive_directory_iterator& rhs);
+    recursive_directory_iterator&
+      operator=(recursive_directory_iterator&& rhs) noexcept;
+
+    recursive_directory_iterator& operator++();
+    recursive_directory_iterator& increment(error_code& ec);
+
+    void pop();
+    void pop(error_code& ec);
+    void disable_recursion_pending();
+
+    bool operator==(default_sentinel_t) const noexcept {          // since C++20
+      return *this == recursive_directory_iterator();
+    }
+
+    // other members as required by [input.iterators], input iterators
+  };
 
     // enable recursive_directory_iterator range-based for statements
     recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
     recursive_directory_iterator end(recursive_directory_iterator) noexcept;
 
-    class file_status;
+  class file_status {
+  public:
+    // [fs.file.status.cons], constructors and destructor
+    file_status() noexcept : file_status(file_type::none) {}
+    explicit file_status(file_type ft,
+                         perms prms = perms::unknown) noexcept;
+    file_status(const file_status&) noexcept = default;
+    file_status(file_status&&) noexcept = default;
+    ~file_status();
+
+    // assignments
+    file_status& operator=(const file_status&) noexcept = default;
+    file_status& operator=(file_status&&) noexcept = default;
+
+    // [fs.file.status.mods], modifiers
+    void       type(file_type ft) noexcept;
+    void       permissions(perms prms) noexcept;
+
+    // [fs.file.status.obs], observers
+    file_type  type() const noexcept;
+    perms      permissions() const noexcept;
+
+    friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept
+      { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } // C++20
+  };
 
     struct space_info
     {
@@ -454,16 +558,14 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct
 // [fs.filesystem.syn]
 #include <compare>
 
-#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-# error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem."
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
+#  include <system_error>
 #endif
 
 #endif // _LIBCPP_FILESYSTEM
lib/libcxx/include/format
@@ -170,11 +170,6 @@ namespace std {
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
-// Make sure all feature-test macros are available.
-#include <version>
-// Enable the contents of the header only when libc++ was built with experimental features enabled.
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-
 #include <__config>
 #include <__format/buffer.h>
 #include <__format/concepts.h>
@@ -202,11 +197,10 @@ namespace std {
 #include <__format/range_default_formatter.h>
 #include <__format/range_formatter.h>
 #include <__format/unicode.h>
+#include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-
 #endif // _LIBCPP_FORMAT
lib/libcxx/include/forward_list
@@ -44,6 +44,8 @@ public:
         forward_list(InputIterator first, InputIterator last);
     template <class InputIterator>
         forward_list(InputIterator first, InputIterator last, const allocator_type& a);
+    template<container-compatible-range<T> R>
+        forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
     forward_list(const forward_list& x);
     forward_list(const forward_list& x, const allocator_type& a);
     forward_list(forward_list&& x)
@@ -63,6 +65,8 @@ public:
 
     template <class InputIterator>
         void assign(InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      void assign_range(R&& rg); // C++23
     void assign(size_type n, const value_type& v);
     void assign(initializer_list<value_type> il);
 
@@ -89,6 +93,8 @@ public:
     template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
     void push_front(const value_type& v);
     void push_front(value_type&& v);
+    template<container-compatible-range<T> R>
+      void prepend_range(R&& rg); // C++23
 
     void pop_front();
 
@@ -100,6 +106,8 @@ public:
     template <class InputIterator>
         iterator insert_after(const_iterator p,
                               InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      iterator insert_range_after(const_iterator position, R&& rg); // C++23
     iterator insert_after(const_iterator p, initializer_list<value_type> il);
 
     iterator erase_after(const_iterator p);
@@ -140,29 +148,37 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
     forward_list(InputIterator, InputIterator, Allocator = Allocator())
     -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;  // C++17
 
+template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
+  forward_list(from_range_t, R&&, Allocator = Allocator())
+      -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23
+
 template <class T, class Allocator>
     bool operator==(const forward_list<T, Allocator>& x,
                     const forward_list<T, Allocator>& y);
 
 template <class T, class Allocator>
     bool operator< (const forward_list<T, Allocator>& x,
-                    const forward_list<T, Allocator>& y);
+                    const forward_list<T, Allocator>& y); // removed in C++20
 
 template <class T, class Allocator>
     bool operator!=(const forward_list<T, Allocator>& x,
-                    const forward_list<T, Allocator>& y);
+                    const forward_list<T, Allocator>& y); // removed in C++20
 
 template <class T, class Allocator>
     bool operator> (const forward_list<T, Allocator>& x,
-                    const forward_list<T, Allocator>& y);
+                    const forward_list<T, Allocator>& y); // removed in C++20
 
 template <class T, class Allocator>
     bool operator>=(const forward_list<T, Allocator>& x,
-                    const forward_list<T, Allocator>& y);
+                    const forward_list<T, Allocator>& y); // removed in C++20
 
 template <class T, class Allocator>
     bool operator<=(const forward_list<T, Allocator>& x,
-                    const forward_list<T, Allocator>& y);
+                    const forward_list<T, Allocator>& y); // removed in C++20
+
+template<class T, class Allocator>
+    synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
+                                          const forward_list<T, Allocator>& y); // since C++20
 
 template <class T, class Allocator>
     void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
@@ -181,14 +197,17 @@ template <class T, class Allocator, class Predicate>
 
 #include <__algorithm/comp.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/min.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/move_iterator.h>
 #include <__iterator/next.h>
 #include <__memory/addressof.h>
+#include <__memory/allocation_guard.h>
 #include <__memory/allocator.h>
 #include <__memory/allocator_destructor.h>
 #include <__memory/allocator_traits.h>
@@ -197,11 +216,22 @@ template <class T, class Allocator, class Predicate>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__type_traits/conditional.h>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <limits>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -279,6 +309,7 @@ struct __forward_begin_node
     pointer __next_;
 
     _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __forward_begin_node(pointer __n) : __next_(__n) {}
 
     _LIBCPP_INLINE_VISIBILITY
     __begin_node_pointer __next_as_begin() const {
@@ -294,8 +325,13 @@ struct _LIBCPP_STANDALONE_DEBUG __forward_list_node
     : public __begin_node_of<_Tp, _VoidPtr>
 {
     typedef _Tp value_type;
+    typedef __begin_node_of<_Tp, _VoidPtr> _Base;
+    typedef typename _Base::pointer _NodePtr;
 
     value_type __value_;
+
+    _LIBCPP_HIDE_FROM_ABI __forward_list_node() = default;
+    _LIBCPP_HIDE_FROM_ABI __forward_list_node(const value_type& __v, _NodePtr __next) : _Base(__next), __value_(__v) {}
 };
 
 
@@ -395,11 +431,11 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
 
     __iter_node_pointer __ptr_;
 
-    __begin_node_pointer __get_begin() const {
+    _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
         return static_cast<__begin_node_pointer>(
                 static_cast<__void_pointer>(__ptr_));
     }
-    __node_pointer __get_unsafe_node_pointer() const {
+    _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
         return static_cast<__node_pointer>(
                 static_cast<__void_pointer>(__ptr_));
     }
@@ -482,14 +518,6 @@ protected:
     typedef typename allocator_traits<__begin_node_allocator>::pointer
                                                       __begin_node_pointer;
 
-    static_assert((!is_same<allocator_type, __node_allocator>::value),
-                  "internal allocator type must differ from user-specified "
-                  "type; otherwise overload resolution breaks");
-
-    static_assert(is_same<allocator_type, __rebind_alloc<__node_traits, value_type> >::value,
-                  "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
-                  "original allocator");
-
     __compressed_pair<__begin_node, __node_allocator> __before_begin_;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -533,7 +561,7 @@ private:
     __forward_list_base& operator=(const __forward_list_base&);
 
 public:
-    ~__forward_list_base();
+    _LIBCPP_HIDE_FROM_ABI ~__forward_list_base();
 
 protected:
     _LIBCPP_INLINE_VISIBILITY
@@ -558,7 +586,7 @@ public:
                     __is_nothrow_swappable<__node_allocator>::value);
 #endif
 protected:
-    void clear() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
 
 private:
     _LIBCPP_INLINE_VISIBILITY
@@ -659,9 +687,17 @@ public:
     typedef _Tp    value_type;
     typedef _Alloc allocator_type;
 
-    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+    static_assert(is_same<value_type, typename allocator_type::value_type>::value,
                   "Allocator::value_type must be same type as value_type");
 
+    static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
+                  "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
+                  "original allocator");
+
+    static_assert((!is_same<allocator_type, __node_allocator>::value),
+                  "internal allocator type must differ from user-specified "
+                  "type; otherwise overload resolution breaks");
+
     typedef value_type&                                                 reference;
     typedef const value_type&                                           const_reference;
     typedef typename allocator_traits<allocator_type>::pointer          pointer;
@@ -671,7 +707,7 @@ public:
 
     typedef typename base::iterator       iterator;
     typedef typename base::const_iterator const_iterator;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef size_type                                __remove_return_type;
 #else
     typedef void                                     __remove_return_type;
@@ -683,39 +719,48 @@ public:
         {} // = default;
     _LIBCPP_INLINE_VISIBILITY
     explicit forward_list(const allocator_type& __a);
-    explicit forward_list(size_type __n);
-#if _LIBCPP_STD_VER > 11
-    explicit forward_list(size_type __n, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n);
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a);
 #endif
-    forward_list(size_type __n, const value_type& __v);
+    _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
 
     template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
-    forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
+    _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
     {
         insert_after(cbefore_begin(), __n, __v);
     }
 
     template <class _InputIterator>
-        forward_list(_InputIterator __f, _InputIterator __l,
-                     __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
+    _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l,
+                     __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr);
     template <class _InputIterator>
-        forward_list(_InputIterator __f, _InputIterator __l,
+    _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l,
                      const allocator_type& __a,
-                     __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
-    forward_list(const forward_list& __x);
-    forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
+                     __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr);
 
-    forward_list& operator=(const forward_list& __x);
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range,
+        const allocator_type& __a = allocator_type()) : base(__a) {
+      prepend_range(std::forward<_Range>(__range));
+    }
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x);
+    _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
+
+    _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
 
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     forward_list(forward_list&& __x)
         _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
         : base(_VSTD::move(__x)) {}
-    forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
+    _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
 
-    forward_list(initializer_list<value_type> __il);
-    forward_list(initializer_list<value_type> __il, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a);
 
     _LIBCPP_INLINE_VISIBILITY
     forward_list& operator=(forward_list&& __x)
@@ -733,9 +778,18 @@ public:
     // ~forward_list() = default;
 
     template <class _InputIterator>
-    __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
-        assign(_InputIterator __f, _InputIterator __l);
-    void assign(size_type __n, const value_type& __v);
+    __enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>
+    _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void assign_range(_Range&& __range) {
+      __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+    }
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT
@@ -787,34 +841,56 @@ public:
     const_reference front() const {return base::__before_begin()->__next_->__value_;}
 
 #ifndef _LIBCPP_CXX03_LANG
-#if _LIBCPP_STD_VER > 14
-    template <class... _Args> reference emplace_front(_Args&&... __args);
+#if _LIBCPP_STD_VER >= 17
+    template <class... _Args>
+    _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
 #else
-    template <class... _Args> void      emplace_front(_Args&&... __args);
+    template <class... _Args>
+    _LIBCPP_HIDE_FROM_ABI void      emplace_front(_Args&&... __args);
 #endif
-    void push_front(value_type&& __v);
+    _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
 #endif // _LIBCPP_CXX03_LANG
-    void push_front(const value_type& __v);
+    _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
 
-    void pop_front();
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void prepend_range(_Range&& __range) {
+      insert_range_after(cbefore_begin(), std::forward<_Range>(__range));
+    }
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI void pop_front();
 
 #ifndef _LIBCPP_CXX03_LANG
     template <class... _Args>
-        iterator emplace_after(const_iterator __p, _Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args);
 
-    iterator insert_after(const_iterator __p, value_type&& __v);
-    iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
+    _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v);
+    _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
         {return insert_after(__p, __il.begin(), __il.end());}
 #endif // _LIBCPP_CXX03_LANG
-    iterator insert_after(const_iterator __p, const value_type& __v);
-    iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
+    _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v);
+    _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
     template <class _InputIterator>
     _LIBCPP_INLINE_VISIBILITY
-    __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, iterator>
+    __enable_if_t<__has_input_iterator_category<_InputIterator>::value, iterator>
         insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
 
-    iterator erase_after(const_iterator __p);
-    iterator erase_after(const_iterator __f, const_iterator __l);
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator insert_range_after(const_iterator __position, _Range&& __range) {
+      return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
+    }
+#endif
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
+
+    _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
+    _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
 
     _LIBCPP_INLINE_VISIBILITY
     void swap(forward_list& __x)
@@ -826,8 +902,8 @@ public:
 #endif
         {base::swap(__x);}
 
-    void resize(size_type __n);
-    void resize(size_type __n, const value_type& __v);
+    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
+    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {base::clear();}
 
@@ -838,46 +914,54 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void splice_after(const_iterator __p, forward_list&& __x,
                       const_iterator __f, const_iterator __l);
-    void splice_after(const_iterator __p, forward_list& __x);
-    void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
-    void splice_after(const_iterator __p, forward_list& __x,
+    _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x);
+    _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
+    _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x,
                       const_iterator __f, const_iterator __l);
-    __remove_return_type remove(const value_type& __v);
-    template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v);
+    template <class _Predicate>
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred);
     _LIBCPP_INLINE_VISIBILITY
     __remove_return_type unique() { return unique(__equal_to()); }
-    template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
+    template <class _BinaryPredicate>
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
+    void merge(forward_list&& __x) {merge(__x, __less<>());}
     template <class _Compare>
         _LIBCPP_INLINE_VISIBILITY
         void merge(forward_list&& __x, _Compare __comp)
         {merge(__x, _VSTD::move(__comp));}
 #endif // _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    void merge(forward_list& __x) {merge(__x, __less<value_type>());}
-    template <class _Compare> void merge(forward_list& __x, _Compare __comp);
+    void merge(forward_list& __x) {merge(__x, __less<>());}
+    template <class _Compare>
+    _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp);
     _LIBCPP_INLINE_VISIBILITY
-    void sort() {sort(__less<value_type>());}
+    void sort() {sort(__less<>());}
     template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
-    void reverse() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
 
 private:
 
 #ifndef _LIBCPP_CXX03_LANG
-    void __move_assign(forward_list& __x, true_type)
+    _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type)
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
-    void __move_assign(forward_list& __x, false_type);
+    _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type);
 #endif // _LIBCPP_CXX03_LANG
 
+    template <class _Iter, class _Sent>
+    _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_sentinel(_Iter __f, _Sent __l);
+
     template <class _Compare>
-        static
+    static _LIBCPP_HIDE_FROM_ABI
         __node_pointer
         __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
 
+    // TODO: Make this _LIBCPP_HIDE_FROM_ABI
     template <class _Compare>
-        static
+    static _LIBCPP_HIDDEN
         __node_pointer
         __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
 };
@@ -886,7 +970,7 @@ private:
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator,
          class _Alloc = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 forward_list(_InputIterator, _InputIterator)
@@ -894,13 +978,22 @@ forward_list(_InputIterator, _InputIterator)
 
 template<class _InputIterator,
          class _Alloc,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 forward_list(_InputIterator, _InputIterator, _Alloc)
   -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Alloc = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Alloc>::value>
+          >
+forward_list(from_range_t, _Range&&, _Alloc = _Alloc())
+  -> forward_list<ranges::range_value_t<_Range>, _Alloc>;
+#endif
+
 template <class _Tp, class _Alloc>
 inline
 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
@@ -927,7 +1020,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n)
     }
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(size_type __n,
                                         const allocator_type& __base_alloc)
@@ -959,7 +1052,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
 template <class _Tp, class _Alloc>
 template <class _InputIterator>
 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
-                                        __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
+                                        __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*)
 {
     insert_after(cbefore_begin(), __f, __l);
 }
@@ -968,7 +1061,7 @@ template <class _Tp, class _Alloc>
 template <class _InputIterator>
 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
                                         const allocator_type& __a,
-                                        __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
+                                        __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*)
     : base(__a)
 {
     insert_after(cbefore_begin(), __f, __l);
@@ -1078,16 +1171,23 @@ forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
 
 template <class _Tp, class _Alloc>
 template <class _InputIterator>
-__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
+__enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>
 forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
 {
+  __assign_with_sentinel(__f, __l);
+}
+
+template <class _Tp, class _Alloc>
+template <class _Iter, class _Sent>
+_LIBCPP_HIDE_FROM_ABI
+void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) {
     iterator __i = before_begin();
     iterator __j = _VSTD::next(__i);
     iterator __e = end();
     for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
         *__j = *__f;
     if (__j == __e)
-        insert_after(__i, __f, __l);
+        __insert_after_with_sentinel(__i, std::move(__f), std::move(__l));
     else
         erase_after(__i, __e);
 }
@@ -1119,7 +1219,7 @@ forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
 
 template <class _Tp, class _Alloc>
 template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename forward_list<_Tp, _Alloc>::reference
 #else
 void
@@ -1133,7 +1233,7 @@ forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
                                   _VSTD::forward<_Args>(__args)...);
     __h->__next_ = base::__before_begin()->__next_;
     base::__before_begin()->__next_ = __h.release();
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return base::__before_begin()->__next_->__value_;
 #endif
 }
@@ -1228,26 +1328,33 @@ typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
                                         const value_type& __v)
 {
+    using _Guard = __allocation_guard<__node_allocator>;
+
     __begin_node_pointer __r = __p.__get_begin();
     if (__n > 0)
     {
         __node_allocator& __a = base::__alloc();
-        typedef __allocator_destructor<__node_allocator> _Dp;
-        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
-        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
-        __node_pointer __first = __h.release();
+
+        __node_pointer __first = nullptr;
+        {
+          _Guard __h(__a, 1);
+          __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v);
+          __h.__get()->__next_ = nullptr;
+          __first = __h.__release_ptr();
+        }
         __node_pointer __last = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (--__n; __n != 0; --__n, __last = __last->__next_)
             {
-                __h.reset(__node_traits::allocate(__a, 1));
-                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
-                __last->__next_ = __h.release();
+                _Guard __h(__a, 1);
+                __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v);
+                __h.__get()->__next_ = nullptr;
+                __last->__next_ = __h.__release_ptr();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1260,7 +1367,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __last->__next_ = __r->__next_;
         __r->__next_ = __first;
         __r = static_cast<__begin_node_pointer>(__last);
@@ -1270,30 +1377,45 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
 
 template <class _Tp, class _Alloc>
 template <class _InputIterator>
-__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
+__enable_if_t<__has_input_iterator_category<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
                                         _InputIterator __f, _InputIterator __l)
 {
+  return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l));
+}
+
+template <class _Tp, class _Alloc>
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) {
+    using _Guard = __allocation_guard<__node_allocator>;
     __begin_node_pointer __r = __p.__get_begin();
+
     if (__f != __l)
     {
         __node_allocator& __a = base::__alloc();
-        typedef __allocator_destructor<__node_allocator> _Dp;
-        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
-        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
-        __node_pointer __first = __h.release();
+        __node_pointer __first = nullptr;
+        {
+          _Guard __h(__a, 1);
+          __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f);
+          __h.__get()->__next_ = nullptr;
+          __first = __h.__release_ptr();
+        }
         __node_pointer __last = __first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
             {
-                __h.reset(__node_traits::allocate(__a, 1));
-                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
-                __last->__next_ = __h.release();
+                _Guard __h(__a, 1);
+                __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f);
+                __h.__get()->__next_ = nullptr;
+                __last->__next_ = __h.__release_ptr();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1306,11 +1428,13 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+
         __last->__next_ = __r->__next_;
         __r->__next_ = __first;
         __r = static_cast<__begin_node_pointer>(__last);
     }
+
     return iterator(__r);
 }
 
@@ -1711,6 +1835,8 @@ bool operator==(const forward_list<_Tp, _Alloc>& __x,
     return (__ix == __ex) == (__iy == __ey);
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool operator!=(const forward_list<_Tp, _Alloc>& __x,
@@ -1752,6 +1878,17 @@ bool operator<=(const forward_list<_Tp, _Alloc>& __x,
     return !(__y < __x);
 }
 
+#else // #if _LIBCPP_STD_VER <= 17
+
+template <class _Tp, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
+operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
+}
+
+#endif // #if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -1761,7 +1898,7 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
     typename forward_list<_Tp, _Allocator>::size_type
@@ -1779,11 +1916,11 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _ValueT>
-using forward_list = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
+using forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
@@ -1794,9 +1931,11 @@ _LIBCPP_POP_MACROS
 #  include <algorithm>
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iosfwd>
 #  include <iterator>
+#  include <type_traits>
 #  include <typeinfo>
 #endif
 
lib/libcxx/include/fstream
@@ -183,22 +183,18 @@ typedef basic_fstream<wchar_t> wfstream;
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
+#include <__fwd/fstream.h>
 #include <__locale>
 #include <__utility/move.h>
 #include <__utility/swap.h>
 #include <__utility/unreachable.h>
 #include <cstdio>
-#include <cstdlib>
-#include <cstring>
+#include <filesystem>
 #include <istream>
 #include <ostream>
 #include <typeinfo>
 #include <version>
 
-#if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-#   include <filesystem>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
@@ -210,7 +206,7 @@ _LIBCPP_PUSH_MACROS
 #  define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
 #endif
 
-#if !defined(_LIBCPP_HAS_NO_FSTREAM)
+#if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -246,8 +242,8 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     basic_filebuf* open(const string& __s, ios_base::openmode __mode);
 
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
       return open(__p.c_str(), __mode);
     }
@@ -398,17 +394,17 @@ basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
 template <class _CharT, class _Traits>
 basic_filebuf<_CharT, _Traits>::~basic_filebuf()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         close();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     if (__owns_eb_)
         delete [] __extbuf_;
     if (__owns_ib_)
@@ -754,8 +750,8 @@ basic_filebuf<_CharT, _Traits>::underflow()
         else
         {
             if (__extbufend_ != __extbufnext_) {
-                _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr");
-                _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr");
+                _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
+                _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
                 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
             }
             __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
@@ -1169,8 +1165,8 @@ public:
 #endif
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
       : basic_ifstream(__p.c_str(), __mode) {}
 #endif // _LIBCPP_STD_VER >= 17
@@ -1190,8 +1186,8 @@ public:
     void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
 #endif
     void open(const string& __s, ios_base::openmode __mode = ios_base::in);
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     void open(const filesystem::path& __p,
               ios_base::openmode __mode = ios_base::in) {
       return open(__p.c_str(), __mode);
@@ -1370,8 +1366,8 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
 
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
       : basic_ofstream(__p.c_str(), __mode) {}
 #endif // _LIBCPP_STD_VER >= 17
@@ -1393,8 +1389,8 @@ public:
 #endif
     void open(const string& __s, ios_base::openmode __mode = ios_base::out);
 
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
     { return open(__p.c_str(), __mode); }
 #endif // _LIBCPP_STD_VER >= 17
@@ -1571,8 +1567,8 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
 
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
       : basic_fstream(__p.c_str(), __mode) {}
 #endif // _LIBCPP_STD_VER >= 17
@@ -1590,14 +1586,14 @@ public:
     basic_filebuf<char_type, traits_type>* rdbuf() const;
     _LIBCPP_INLINE_VISIBILITY
     bool is_open() const;
-    void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+    _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
     void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
 #endif
-    void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+    _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
 
-#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
     void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
     { return open(__p.c_str(), __mode); }
 #endif // _LIBCPP_STD_VER >= 17
@@ -1746,13 +1742,14 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_HAS_NO_FSTREAM
+#endif // _LIBCPP_HAS_NO_FILESYSTEM
 
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iosfwd>
 #  include <limits>
 #  include <new>
lib/libcxx/include/functional
@@ -43,20 +43,22 @@ public:
 
     // construct/copy/destroy
     template<class U>
-      reference_wrapper(U&&);
-    reference_wrapper(const reference_wrapper<T>& x) noexcept;
+      constexpr reference_wrapper(U&&);                                   // constexpr since C++20
+    constexpr reference_wrapper(const reference_wrapper<T>& x) noexcept;  // constexpr since C++20
 
     // assignment
-    reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
+    constexpr reference_wrapper&
+    operator=(const reference_wrapper<T>& x) noexcept;                    // constexpr since C++20
 
     // access
-    operator T& () const noexcept;
-    T& get() const noexcept;
+    constexpr operator T& () const noexcept;                              // constexpr since C++20
+    constexpr T& get() const noexcept;                                    // constexpr since C++20
 
     // invoke
     template <class... ArgTypes>
-      typename result_of<T&(ArgTypes&&...)>::type
-          operator() (ArgTypes&&...) const;
+      constexpr typename result_of<T&(ArgTypes&&...)>::type               // constexpr since C++20
+          operator() (ArgTypes&&...) const
+              noexcept(is_nothrow_invocable_v<T&, ArgTypes...>);          // noexcept since C++17
 };
 
 template <class T>
@@ -220,11 +222,16 @@ template<class Fn, class... BoundArgs>
 template<class R, class Fn, class... BoundArgs>
   constexpr unspecified bind(Fn&&, BoundArgs&&...);  // constexpr in C++20
 
+// [func.invoke]
 template<class F, class... Args>
  constexpr // constexpr in C++20
  invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17
     noexcept(is_nothrow_invocable_v<F, Args...>);
 
+template<class R, class F, class... Args>
+  constexpr R invoke_r(F&& f, Args&&... args)              // C++23
+    noexcept(is_nothrow_invocable_r_v<R, F, Args...>);
+
 namespace placeholders {
   // M is the implementation-defined number of placeholders
   extern unspecified _1;
@@ -250,10 +257,10 @@ public:
 };
 
 template <class Operation, class T>
-binder1st<Operation> bind1st(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
+binder1st<Operation> bind1st(const Operation& op, const T& x);                  // deprecated in C++11, removed in C++17
 
 template <class Operation>
-class binder2nd     // deprecated in C++11, removed in C++17
+class binder2nd                                                                 // deprecated in C++11, removed in C++17
     : public unary_function<typename Operation::first_argument_type,
                             typename Operation::result_type>
 {
@@ -267,9 +274,9 @@ public:
 };
 
 template <class Operation, class T>
-binder2nd<Operation> bind2nd(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
+binder2nd<Operation> bind2nd(const Operation& op, const T& x);                  // deprecated in C++11, removed in C++17
 
-template <class Arg, class Result>      // deprecated in C++11, removed in C++17
+template <class Arg, class Result>                                              // deprecated in C++11, removed in C++17
 class pointer_to_unary_function : public unary_function<Arg, Result>
 {
 public:
@@ -278,9 +285,9 @@ public:
 };
 
 template <class Arg, class Result>
-pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));      // deprecated in C++11, removed in C++17
+pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));                // deprecated in C++11, removed in C++17
 
-template <class Arg1, class Arg2, class Result>      // deprecated in C++11, removed in C++17
+template <class Arg1, class Arg2, class Result>                                 // deprecated in C++11, removed in C++17
 class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
 {
 public:
@@ -289,9 +296,9 @@ public:
 };
 
 template <class Arg1, class Arg2, class Result>
-pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));      // deprecated in C++11, removed in C++17
+pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));   // deprecated in C++11, removed in C++17
 
-template<class S, class T>      // deprecated in C++11, removed in C++17
+template<class S, class T>                                                      // deprecated in C++11, removed in C++17
 class mem_fun_t : public unary_function<T*, S>
 {
 public:
@@ -300,18 +307,18 @@ public:
 };
 
 template<class S, class T, class A>
-class mem_fun1_t : public binary_function<T*, A, S>      // deprecated in C++11, removed in C++17
+class mem_fun1_t : public binary_function<T*, A, S>                             // deprecated in C++11, removed in C++17
 {
 public:
     explicit mem_fun1_t(S (T::*p)(A));
     S operator()(T* p, A x) const;
 };
 
-template<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());      // deprecated in C++11, removed in C++17
-template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));     // deprecated in C++11, removed in C++17
+template<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());     // deprecated in C++11, removed in C++17
+template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));    // deprecated in C++11, removed in C++17
 
 template<class S, class T>
-class mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
+class mem_fun_ref_t : public unary_function<T, S>                               // deprecated in C++11, removed in C++17
 {
 public:
     explicit mem_fun_ref_t(S (T::*p)());
@@ -319,18 +326,20 @@ public:
 };
 
 template<class S, class T, class A>
-class mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
+class mem_fun1_ref_t : public binary_function<T, A, S>                          // deprecated in C++11, removed in C++17
 {
 public:
     explicit mem_fun1_ref_t(S (T::*p)(A));
     S operator()(T& p, A x) const;
 };
 
-template<class S, class T>          mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());      // deprecated in C++11, removed in C++17
-template<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));     // deprecated in C++11, removed in C++17
+template<class S, class T>
+mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());                                 // deprecated in C++11, removed in C++17
+template<class S, class T, class A>
+mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));                                // deprecated in C++11, removed in C++17
 
 template <class S, class T>
-class const_mem_fun_t : public unary_function<const T*, S>      // deprecated in C++11, removed in C++17
+class const_mem_fun_t : public unary_function<const T*, S>                      // deprecated in C++11, removed in C++17
 {
 public:
     explicit const_mem_fun_t(S (T::*p)() const);
@@ -338,18 +347,20 @@ public:
 };
 
 template <class S, class T, class A>
-class const_mem_fun1_t : public binary_function<const T*, A, S>      // deprecated in C++11, removed in C++17
+class const_mem_fun1_t : public binary_function<const T*, A, S>                 // deprecated in C++11, removed in C++17
 {
 public:
     explicit const_mem_fun1_t(S (T::*p)(A) const);
     S operator()(const T* p, A x) const;
 };
 
-template <class S, class T>          const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);      // deprecated in C++11, removed in C++17
-template <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);     // deprecated in C++11, removed in C++17
+template <class S, class T>
+const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);                             // deprecated in C++11, removed in C++17
+template <class S, class T, class A>
+const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);                            // deprecated in C++11, removed in C++17
 
 template <class S, class T>
-class const_mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
+class const_mem_fun_ref_t : public unary_function<T, S>                         // deprecated in C++11, removed in C++17
 {
 public:
     explicit const_mem_fun_ref_t(S (T::*p)() const);
@@ -357,18 +368,19 @@ public:
 };
 
 template <class S, class T, class A>
-class const_mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
+class const_mem_fun1_ref_t : public binary_function<T, A, S>                    // deprecated in C++11, removed in C++17
 {
 public:
     explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
     S operator()(const T& p, A x) const;
 };
 
-template <class S, class T>          const_mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)() const);   // deprecated in C++11, removed in C++17
-template <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);  // deprecated in C++11, removed in C++17
+template <class S, class T>
+const_mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)() const);                     // deprecated in C++11, removed in C++17
+template <class S, class T, class A>
+const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);                    // deprecated in C++11, removed in C++17
 
-template<class R, class T>
-constexpr unspecified mem_fn(R T::*); // constexpr in C++20
+template<class R, class T> constexpr unspecified mem_fn(R T::*);                // constexpr in C++20
 
 class bad_function_call
     : public exception
@@ -444,13 +456,13 @@ template <class R, class ... ArgTypes>
   bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
 
 template <class R, class ... ArgTypes>
-  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20
 
 template <class R, class ... ArgTypes>
-  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
+  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // removed in C++20
 
 template <class  R, class ... ArgTypes>
-  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20
 
 // specialized algorithms:
 template <class  R, class ... ArgTypes>
@@ -504,8 +516,7 @@ POLICY:  For non-variadic implementations, the number of arguments is limited
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__compare/compare_three_way.h>
 #include <__config>
-#include <__debug>
-#include <__functional/binary_function.h> // TODO: deprecate
+#include <__functional/binary_function.h>
 #include <__functional/binary_negate.h>
 #include <__functional/bind.h>
 #include <__functional/bind_back.h>
@@ -527,13 +538,11 @@ POLICY:  For non-variadic implementations, the number of arguments is limited
 #include <__functional/pointer_to_unary_function.h>
 #include <__functional/ranges_operations.h>
 #include <__functional/reference_wrapper.h>
-#include <__functional/unary_function.h> // TODO: deprecate
+#include <__functional/unary_function.h>
 #include <__functional/unary_negate.h>
-#include <__functional/unwrap_ref.h>
+#include <__type_traits/unwrap_ref.h>
 #include <__utility/forward.h>
-#include <exception>
 #include <memory> // TODO: find out why removing this breaks the modules build
-#include <type_traits>
 #include <typeinfo>
 #include <version>
 
@@ -542,8 +551,12 @@ POLICY:  For non-variadic implementations, the number of arguments is limited
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
+#  include <exception>
 #  include <tuple>
+#  include <type_traits>
 #  include <utility>
 #endif
 
lib/libcxx/include/future
@@ -366,17 +366,29 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
 #include <__chrono/duration.h>
 #include <__chrono/time_point.h>
 #include <__config>
+#include <__exception/exception_ptr.h>
+#include <__memory/addressof.h>
+#include <__memory/allocator.h>
 #include <__memory/allocator_arg_t.h>
 #include <__memory/allocator_destructor.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/compressed_pair.h>
+#include <__memory/pointer_traits.h>
+#include <__memory/shared_ptr.h>
+#include <__memory/unique_ptr.h>
 #include <__memory/uses_allocator.h>
+#include <__system_error/error_category.h>
+#include <__system_error/error_code.h>
+#include <__system_error/error_condition.h>
+#include <__type_traits/aligned_storage.h>
+#include <__type_traits/alignment_of.h>
 #include <__type_traits/strip_signature.h>
 #include <__utility/auto_cast.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
-#include <exception>
 #include <mutex>
 #include <new>
-#include <system_error>
+#include <stdexcept>
 #include <thread>
 #include <version>
 
@@ -488,8 +500,7 @@ _LIBCPP_DECLARE_STRONG_ENUM(future_status)
 };
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
 
-_LIBCPP_FUNC_VIS
-const error_category& future_category() _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
 
 inline _LIBCPP_INLINE_VISIBILITY
 error_code
@@ -505,7 +516,7 @@ make_error_condition(future_errc __e) _NOEXCEPT
     return error_condition(static_cast<int>(__e), future_category());
 }
 
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
     : public logic_error
 {
     error_code __ec_;
@@ -515,25 +526,25 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const error_code& code() const _NOEXCEPT {return __ec_;}
 
-    future_error(const future_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
     ~future_error() _NOEXCEPT override;
 };
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
 _LIBCPP_AVAILABILITY_FUTURE_ERROR
 #endif
 void __throw_future_error(future_errc __ev)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw future_error(make_error_code(__ev));
 #else
-    ((void)__ev);
-    _VSTD::abort();
+    (void)__ev;
+    _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
 #endif
 }
 
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
     : public __shared_count
 {
 protected:
@@ -631,17 +642,17 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 protected:
     _Up __value_;
 
-    void __on_zero_shared() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
 public:
 
     template <class _Arg>
-    void set_value(_Arg&& __arg);
+    _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
 
     template <class _Arg>
-    void set_value_at_thread_exit(_Arg&& __arg);
+    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
 
-    _Rp move();
-    __add_lvalue_reference_t<_Rp> copy();
+    _LIBCPP_HIDE_FROM_ABI _Rp move();
+    _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
 };
 
 template <class _Rp>
@@ -711,13 +722,13 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
 protected:
     _Up __value_;
 
-    void __on_zero_shared() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
 public:
 
-    void set_value(_Rp& __arg);
-    void set_value_at_thread_exit(_Rp& __arg);
+    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
+    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
 
-    _Rp& copy();
+    _LIBCPP_HIDE_FROM_ABI _Rp& copy();
 };
 
 template <class _Rp>
@@ -769,7 +780,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
     typedef __assoc_state<_Rp> base;
     _Alloc __alloc_;
 
-    virtual void __on_zero_shared() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
 public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __assoc_state_alloc(const _Alloc& __a)
@@ -797,7 +808,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
     typedef __assoc_state<_Rp&> base;
     _Alloc __alloc_;
 
-    virtual void __on_zero_shared() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
 public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __assoc_state_alloc(const _Alloc& __a)
@@ -823,7 +834,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
     typedef __assoc_sub_state base;
     _Alloc __alloc_;
 
-    void __on_zero_shared() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
 public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __assoc_sub_state_alloc(const _Alloc& __a)
@@ -854,7 +865,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __deferred_assoc_state(_Fp&& __f);
 
-    virtual void __execute();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
 };
 
 template <class _Rp, class _Fp>
@@ -869,18 +880,18 @@ template <class _Rp, class _Fp>
 void
 __deferred_assoc_state<_Rp, _Fp>::__execute()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->set_value(__func_());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _Fp>
@@ -895,7 +906,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __deferred_assoc_state(_Fp&& __f);
 
-    void __execute() override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
 };
 
 template <class _Fp>
@@ -910,19 +921,19 @@ template <class _Fp>
 void
 __deferred_assoc_state<void, _Fp>::__execute()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __func_();
         this->set_value();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _Rp, class _Fp>
@@ -933,12 +944,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
 
     _Fp __func_;
 
-    virtual void __on_zero_shared() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
 public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __async_assoc_state(_Fp&& __f);
 
-    virtual void __execute();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
 };
 
 template <class _Rp, class _Fp>
@@ -952,18 +963,18 @@ template <class _Rp, class _Fp>
 void
 __async_assoc_state<_Rp, _Fp>::__execute()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->set_value(__func_());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _Rp, class _Fp>
@@ -982,12 +993,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
 
     _Fp __func_;
 
-    void __on_zero_shared() _NOEXCEPT override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
 public:
     _LIBCPP_INLINE_VISIBILITY
     explicit __async_assoc_state(_Fp&& __f);
 
-    void __execute() override;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
 };
 
 template <class _Fp>
@@ -1001,19 +1012,19 @@ template <class _Fp>
 void
 __async_assoc_state<void, _Fp>::__execute()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __func_();
         this->set_value();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _Fp>
@@ -1044,7 +1055,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
 {
     __assoc_state<_Rp>* __state_;
 
-    explicit future(__assoc_state<_Rp>* __state);
+    explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
 
     template <class> friend class promise;
     template <class> friend class shared_future;
@@ -1069,12 +1080,12 @@ public:
             return *this;
         }
 
-    ~future();
+    _LIBCPP_HIDE_FROM_ABI ~future();
     _LIBCPP_INLINE_VISIBILITY
     shared_future<_Rp> share() _NOEXCEPT;
 
     // retrieving the value
-    _Rp get();
+    _LIBCPP_HIDE_FROM_ABI _Rp get();
 
     _LIBCPP_INLINE_VISIBILITY
     void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
@@ -1106,7 +1117,7 @@ future<_Rp>::future(__assoc_state<_Rp>* __state)
 
 struct __release_shared_count
 {
-    void operator()(__shared_count* __p) {__p->__release_shared();}
+    _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) {__p->__release_shared();}
 };
 
 template <class _Rp>
@@ -1120,7 +1131,7 @@ template <class _Rp>
 _Rp
 future<_Rp>::get()
 {
-    unique_ptr<__shared_count, __release_shared_count> __(__state_);
+    unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
     __assoc_state<_Rp>* __s = __state_;
     __state_ = nullptr;
     return __s->move();
@@ -1131,7 +1142,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
 {
     __assoc_state<_Rp&>* __state_;
 
-    explicit future(__assoc_state<_Rp&>* __state);
+    explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
 
     template <class> friend class promise;
     template <class> friend class shared_future;
@@ -1156,12 +1167,12 @@ public:
             return *this;
         }
 
-    ~future();
+    _LIBCPP_HIDE_FROM_ABI ~future();
     _LIBCPP_INLINE_VISIBILITY
     shared_future<_Rp&> share() _NOEXCEPT;
 
     // retrieving the value
-    _Rp& get();
+    _LIBCPP_HIDE_FROM_ABI _Rp& get();
 
     _LIBCPP_INLINE_VISIBILITY
     void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
@@ -1202,14 +1213,14 @@ template <class _Rp>
 _Rp&
 future<_Rp&>::get()
 {
-    unique_ptr<__shared_count, __release_shared_count> __(__state_);
+    unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
     __assoc_state<_Rp&>* __s = __state_;
     __state_ = nullptr;
     return __s->copy();
 }
 
 template <>
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE future<void>
 {
     __assoc_sub_state* __state_;
 
@@ -1288,14 +1299,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
 
     template <class> friend class packaged_task;
 public:
-    promise();
+    _LIBCPP_HIDE_FROM_ABI promise();
     template <class _Alloc>
-        promise(allocator_arg_t, const _Alloc& __a);
+    _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
     _LIBCPP_INLINE_VISIBILITY
     promise(promise&& __rhs) _NOEXCEPT
         : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
     promise(const promise& __rhs) = delete;
-    ~promise();
+    _LIBCPP_HIDE_FROM_ABI ~promise();
 
     // assignment
     _LIBCPP_INLINE_VISIBILITY
@@ -1310,17 +1321,17 @@ public:
     void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
 
     // retrieving the result
-    future<_Rp> get_future();
+    _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
 
     // setting the result
-    void set_value(const _Rp& __r);
-    void set_value(_Rp&& __r);
-    void set_exception(exception_ptr __p);
+    _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
+    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
+    _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
 
     // setting the result with deferred notification
-    void set_value_at_thread_exit(const _Rp& __r);
-    void set_value_at_thread_exit(_Rp&& __r);
-    void set_exception_at_thread_exit(exception_ptr __p);
+    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
+    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
+    _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
 };
 
 template <class _Rp>
@@ -1386,7 +1397,7 @@ template <class _Rp>
 void
 promise<_Rp>::set_exception(exception_ptr __p)
 {
-    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
+    _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
     if (__state_ == nullptr)
         __throw_future_error(future_errc::no_state);
     __state_->set_exception(__p);
@@ -1414,7 +1425,7 @@ template <class _Rp>
 void
 promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
 {
-    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
+    _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
     if (__state_ == nullptr)
         __throw_future_error(future_errc::no_state);
     __state_->set_exception_at_thread_exit(__p);
@@ -1433,14 +1444,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
     template <class> friend class packaged_task;
 
 public:
-    promise();
+    _LIBCPP_HIDE_FROM_ABI promise();
     template <class _Allocator>
-        promise(allocator_arg_t, const _Allocator& __a);
+    _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
     _LIBCPP_INLINE_VISIBILITY
     promise(promise&& __rhs) _NOEXCEPT
         : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
     promise(const promise& __rhs) = delete;
-    ~promise();
+    _LIBCPP_HIDE_FROM_ABI ~promise();
 
     // assignment
     _LIBCPP_INLINE_VISIBILITY
@@ -1455,15 +1466,15 @@ public:
     void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
 
     // retrieving the result
-    future<_Rp&> get_future();
+    _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
 
     // setting the result
-    void set_value(_Rp& __r);
-    void set_exception(exception_ptr __p);
+    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
+    _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
 
     // setting the result with deferred notification
-    void set_value_at_thread_exit(_Rp&);
-    void set_exception_at_thread_exit(exception_ptr __p);
+    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
+    _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
 };
 
 template <class _Rp>
@@ -1520,7 +1531,7 @@ template <class _Rp>
 void
 promise<_Rp&>::set_exception(exception_ptr __p)
 {
-    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
+    _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
     if (__state_ == nullptr)
         __throw_future_error(future_errc::no_state);
     __state_->set_exception(__p);
@@ -1539,7 +1550,7 @@ template <class _Rp>
 void
 promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
 {
-    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
+    _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
     if (__state_ == nullptr)
         __throw_future_error(future_errc::no_state);
     __state_->set_exception_at_thread_exit(__p);
@@ -1548,7 +1559,7 @@ promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
 // promise<void>
 
 template <>
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE promise<void>
 {
     __assoc_sub_state* __state_;
 
@@ -1654,10 +1665,10 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __packaged_task_func(_Fp&& __f, const _Alloc& __a)
         : __f_(_VSTD::move(__f), __a) {}
-    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
-    virtual void destroy();
-    virtual void destroy_deallocate();
-    virtual _Rp operator()(_ArgTypes&& ... __args);
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&& ... __args);
 };
 
 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -1716,22 +1727,22 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
     template<class _Fp>
-      __packaged_task_function(_Fp&& __f);
+    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
     template<class _Fp, class _Alloc>
-      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
+    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
 
-    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
-    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
 
     __packaged_task_function(const __packaged_task_function&) =  delete;
     __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
 
-    ~__packaged_task_function();
+    _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
 
-    void swap(__packaged_task_function&) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
-    _Rp operator()(_ArgTypes...) const;
+    _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
 };
 
 template<class _Rp, class ..._ArgTypes>
@@ -1756,7 +1767,7 @@ template <class _Fp>
 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
     : __f_(nullptr)
 {
-    typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR;
+    typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
     typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
     if (sizeof(_FF) <= sizeof(__buf_))
     {
@@ -1780,7 +1791,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
                                   allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
     : __f_(nullptr)
 {
-    typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR;
+    typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
     typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
     if (sizeof(_FF) <= sizeof(__buf_))
     {
@@ -1902,8 +1913,8 @@ public:
               class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
         _LIBCPP_INLINE_VISIBILITY
         packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
-             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
-               __p_(allocator_arg, __a) {}
+             : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)),
+               __p_(allocator_arg_t(), __a) {}
     // ~packaged_task() = default;
 
     // no copy
@@ -1936,10 +1947,10 @@ public:
     future<result_type> get_future() {return __p_.get_future();}
 
     // execution
-    void operator()(_ArgTypes... __args);
-    void make_ready_at_thread_exit(_ArgTypes... __args);
+    _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
+    _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
 
-    void reset();
+    _LIBCPP_HIDE_FROM_ABI void reset();
 };
 
 template<class _Rp, class ..._ArgTypes>
@@ -1950,18 +1961,18 @@ packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
         __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
         __throw_future_error(future_errc::promise_already_satisfied);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __p_.set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template<class _Rp, class ..._ArgTypes>
@@ -1972,18 +1983,18 @@ packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
         __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
         __throw_future_error(future_errc::promise_already_satisfied);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __p_.set_exception_at_thread_exit(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template<class _Rp, class ..._ArgTypes>
@@ -2017,8 +2028,8 @@ public:
               class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
         _LIBCPP_INLINE_VISIBILITY
         packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
-             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
-               __p_(allocator_arg, __a) {}
+             : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)),
+               __p_(allocator_arg_t(), __a) {}
     // ~packaged_task() = default;
 
     // no copy
@@ -2051,10 +2062,10 @@ public:
     future<result_type> get_future() {return __p_.get_future();}
 
     // execution
-    void operator()(_ArgTypes... __args);
-    void make_ready_at_thread_exit(_ArgTypes... __args);
+    _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
+    _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
 
-    void reset();
+    _LIBCPP_HIDE_FROM_ABI void reset();
 };
 
 #if _LIBCPP_STD_VER >= 17
@@ -2075,19 +2086,19 @@ packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
         __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
         __throw_future_error(future_errc::promise_already_satisfied);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __f_(_VSTD::forward<_ArgTypes>(__args)...);
         __p_.set_value();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __p_.set_exception(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template<class ..._ArgTypes>
@@ -2098,19 +2109,19 @@ packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args
         __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
         __throw_future_error(future_errc::promise_already_satisfied);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __f_(_VSTD::forward<_ArgTypes>(__args)...);
         __p_.set_value_at_thread_exit();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __p_.set_exception_at_thread_exit(current_exception());
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template<class ..._ArgTypes>
@@ -2170,14 +2181,14 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
 
-    _Rp operator()()
+    _LIBCPP_HIDE_FROM_ABI _Rp operator()()
     {
         typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
         return __execute(_Index());
     }
 private:
     template <size_t ..._Indices>
-    _Rp
+    _LIBCPP_HIDE_FROM_ABI _Rp
     __execute(__tuple_indices<_Indices...>)
     {
         return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
@@ -2189,20 +2200,20 @@ inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, lau
 
 template <class _Fp, class... _Args>
 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
-future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
+future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
 async(launch __policy, _Fp&& __f, _Args&&... __args)
 {
-    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
+    typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
     typedef typename _BF::_Rp _Rp;
 
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
 #endif
         if (__does_policy_contain(__policy, launch::async))
         return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
                                                         _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch ( ... ) { if (__policy == launch::async) throw ; }
 #endif
@@ -2215,7 +2226,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args)
 
 template <class _Fp, class... _Args>
 _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
-future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
+future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
 async(_Fp&& __f, _Args&&... __args)
 {
     return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
@@ -2243,8 +2254,8 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
         {__rhs.__state_ = nullptr;}
-    ~shared_future();
-    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI ~shared_future();
+    _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
         {
@@ -2313,8 +2324,8 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
         {__rhs.__state_ = nullptr;}
-    ~shared_future();
-    shared_future& operator=(const shared_future& __rhs);
+    _LIBCPP_HIDE_FROM_ABI ~shared_future();
+    _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
     _LIBCPP_INLINE_VISIBILITY
     shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
         {
@@ -2367,7 +2378,7 @@ shared_future<_Rp&>::operator=(const shared_future& __rhs)
 }
 
 template <>
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
 {
     __assoc_sub_state* __state_;
 
@@ -2454,4 +2465,11 @@ _LIBCPP_END_NAMESPACE_STD
 #  include <chrono>
 #endif
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
+#  include <cstdlib>
+#  include <exception>
+#  include <system_error>
+#endif
+
 #endif // _LIBCPP_FUTURE
lib/libcxx/include/iomanip
@@ -301,10 +301,10 @@ template <class _CharT, class _Traits, class _MoneyT>
 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_istream<_CharT, _Traits>::sentry __s(__is);
         if (__s)
         {
@@ -315,13 +315,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
             __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
             __is.setstate(__err);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __is.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __is;
 }
 
@@ -361,10 +361,10 @@ template <class _CharT, class _Traits, class _MoneyT>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
         if (__s)
         {
@@ -374,13 +374,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
             if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
                 __os.setstate(ios_base::badbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __os.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __os;
 }
 
@@ -420,10 +420,10 @@ template <class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_istream<_CharT, _Traits>::sentry __s(__is);
         if (__s)
         {
@@ -435,13 +435,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
                      __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
             __is.setstate(__err);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __is.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __is;
 }
 
@@ -481,10 +481,10 @@ template <class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
         if (__s)
         {
@@ -495,13 +495,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
                          __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed())
                 __os.setstate(ios_base::badbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __os.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __os;
 }
 
@@ -513,8 +513,6 @@ put_time(const tm* __tm, const _CharT* __fmt)
     return __iom_t10<_CharT>(__tm, __fmt);
 }
 
-#if _LIBCPP_STD_VER >= 11
-
 template <class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 __quoted_output(basic_ostream<_CharT, _Traits>& __os,
@@ -622,9 +620,7 @@ __quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT
     return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
 }
 
-#endif // _LIBCPP_STD_VER >= 11
-
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 template <class _CharT>
 _LIBCPP_HIDE_FROM_ABI
@@ -656,7 +652,7 @@ auto quoted(basic_string_view<_CharT, _Traits> __sv, _CharT __delim = _CharT('"'
     return __quoted_output_proxy<_CharT, _Traits>(__sv.data(), __sv.data() + __sv.size(), __delim, __escape);
 }
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_END_NAMESPACE_STD
 
lib/libcxx/include/ios
@@ -217,10 +217,15 @@ storage-class-specifier const error_category& iostream_category() noexcept;
 #endif
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__fwd/ios.h>
 #include <__ios/fpos.h>
 #include <__locale>
+#include <__system_error/error_category.h>
+#include <__system_error/error_code.h>
+#include <__system_error/error_condition.h>
+#include <__system_error/system_error.h>
 #include <__utility/swap.h>
-#include <system_error>
+#include <__verbose_abort>
 #include <version>
 
 // standard-mandated includes
@@ -229,7 +234,7 @@ storage-class-specifier const error_category& iostream_category() noexcept;
 #include <iosfwd>
 
 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
-#include <atomic>     // for __xindex_
+#  include <__atomic/atomic.h> // for __xindex_
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -240,10 +245,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 typedef ptrdiff_t streamsize;
 
-class _LIBCPP_TYPE_VIS ios_base
+class _LIBCPP_EXPORTED_FROM_ABI ios_base
 {
 public:
-    class _LIBCPP_EXCEPTION_ABI failure;
+    class _LIBCPP_EXPORTED_FROM_ABI failure;
 
     typedef unsigned int fmtflags;
     static const fmtflags boolalpha   = 0x0001;
@@ -290,7 +295,7 @@ public:
     typedef _VSTD::streampos streampos;
 #endif
 
-    class _LIBCPP_TYPE_VIS Init;
+    class _LIBCPP_EXPORTED_FROM_ABI Init;
 
     // 27.5.2.2 fmtflags state:
     _LIBCPP_INLINE_VISIBILITY fmtflags flags() const;
@@ -419,8 +424,7 @@ template <>
 struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<io_errc::__lx> : public true_type { };
 #endif
 
-_LIBCPP_FUNC_VIS
-const error_category& iostream_category() _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
 
 inline _LIBCPP_INLINE_VISIBILITY
 error_code
@@ -436,27 +440,26 @@ make_error_condition(io_errc __e) _NOEXCEPT
     return error_condition(static_cast<int>(__e), iostream_category());
 }
 
-class _LIBCPP_EXCEPTION_ABI ios_base::failure
+class _LIBCPP_EXPORTED_FROM_ABI ios_base::failure
     : public system_error
 {
 public:
     explicit failure(const string& __msg, const error_code& __ec = io_errc::stream);
     explicit failure(const char* __msg, const error_code& __ec = io_errc::stream);
-    failure(const failure&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI failure(const failure&) _NOEXCEPT = default;
     ~failure() _NOEXCEPT override;
 };
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_failure(char const* __msg) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw ios_base::failure(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("ios_base::failure was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
-class _LIBCPP_TYPE_VIS ios_base::Init
+class _LIBCPP_EXPORTED_FROM_ABI ios_base::Init
 {
 public:
     Init();
@@ -844,6 +847,12 @@ basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* _
     ios_base::set_rdbuf(__sb);
 }
 
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>;
+#endif
+
 _LIBCPP_HIDE_FROM_ABI inline
 ios_base&
 boolalpha(ios_base& __str)
@@ -1039,6 +1048,7 @@ defaultfloat(ios_base& __str)
 _LIBCPP_END_NAMESPACE_STD
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
 #  include <cstddef>
 #  include <cstdlib>
@@ -1047,6 +1057,7 @@ _LIBCPP_END_NAMESPACE_STD
 #  include <limits>
 #  include <new>
 #  include <stdexcept>
+#  include <system_error>
 #  include <type_traits>
 #  include <typeinfo>
 #endif
lib/libcxx/include/iosfwd
@@ -96,8 +96,14 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__fwd/fstream.h>
+#include <__fwd/ios.h>
+#include <__fwd/istream.h>
+#include <__fwd/ostream.h>
+#include <__fwd/sstream.h>
+#include <__fwd/streambuf.h>
 #include <__fwd/string.h>
-#include <__mbstate_t.h>
+#include <__std_mbstate_t.h>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -106,114 +112,13 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS ios_base;
-
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_ios;
-
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_streambuf;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_istream;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_ostream;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_iostream;
-
-template <class _CharT, class _Traits = char_traits<_CharT>,
-          class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_stringbuf;
-template <class _CharT, class _Traits = char_traits<_CharT>,
-          class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_istringstream;
-template <class _CharT, class _Traits = char_traits<_CharT>,
-          class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_ostringstream;
-template <class _CharT, class _Traits = char_traits<_CharT>,
-          class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_stringstream;
-
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_filebuf;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_ifstream;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_ofstream;
-template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_fstream;
+class _LIBCPP_EXPORTED_FROM_ABI ios_base;
 
 template <class _CharT, class _Traits = char_traits<_CharT> >
     class _LIBCPP_TEMPLATE_VIS istreambuf_iterator;
 template <class _CharT, class _Traits = char_traits<_CharT> >
     class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator;
 
-typedef basic_ios<char>              ios;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-typedef basic_ios<wchar_t>           wios;
-#endif
-
-typedef basic_streambuf<char>        streambuf;
-typedef basic_istream<char>          istream;
-typedef basic_ostream<char>          ostream;
-typedef basic_iostream<char>         iostream;
-
-typedef basic_stringbuf<char>        stringbuf;
-typedef basic_istringstream<char>    istringstream;
-typedef basic_ostringstream<char>    ostringstream;
-typedef basic_stringstream<char>     stringstream;
-
-typedef basic_filebuf<char>          filebuf;
-typedef basic_ifstream<char>         ifstream;
-typedef basic_ofstream<char>         ofstream;
-typedef basic_fstream<char>          fstream;
-
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-typedef basic_streambuf<wchar_t>     wstreambuf;
-typedef basic_istream<wchar_t>       wistream;
-typedef basic_ostream<wchar_t>       wostream;
-typedef basic_iostream<wchar_t>      wiostream;
-
-typedef basic_stringbuf<wchar_t>     wstringbuf;
-typedef basic_istringstream<wchar_t> wistringstream;
-typedef basic_ostringstream<wchar_t> wostringstream;
-typedef basic_stringstream<wchar_t>  wstringstream;
-
-typedef basic_filebuf<wchar_t>       wfilebuf;
-typedef basic_ifstream<wchar_t>      wifstream;
-typedef basic_ofstream<wchar_t>      wofstream;
-typedef basic_fstream<wchar_t>       wfstream;
-#endif
-
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
-
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream;
-
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(istringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(ostringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(stringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream;
-
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream;
-
 template <class _State>             class _LIBCPP_TEMPLATE_VIS fpos;
 typedef fpos<mbstate_t>    streampos;
 typedef fpos<mbstate_t>    wstreampos;
@@ -223,13 +128,6 @@ typedef fpos<mbstate_t>    u8streampos;
 typedef fpos<mbstate_t>    u16streampos;
 typedef fpos<mbstate_t>    u32streampos;
 
-#if defined(_NEWLIB_VERSION)
-// On newlib, off_t is 'long int'
-typedef long int streamoff;         // for char_traits in <string>
-#else
-typedef long long streamoff;        // for char_traits in <string>
-#endif
-
 // Include other forward declarations here
 template <class _Tp, class _Alloc = allocator<_Tp> >
 class _LIBCPP_TEMPLATE_VIS vector;
lib/libcxx/include/iostream
@@ -51,16 +51,16 @@ extern wostream wclog;
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-extern _LIBCPP_FUNC_VIS istream cin;
-extern _LIBCPP_FUNC_VIS ostream cout;
-extern _LIBCPP_FUNC_VIS ostream cerr;
-extern _LIBCPP_FUNC_VIS ostream clog;
+extern _LIBCPP_EXPORTED_FROM_ABI istream cin;
+extern _LIBCPP_EXPORTED_FROM_ABI ostream cout;
+extern _LIBCPP_EXPORTED_FROM_ABI ostream cerr;
+extern _LIBCPP_EXPORTED_FROM_ABI ostream clog;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-extern _LIBCPP_FUNC_VIS wistream wcin;
-extern _LIBCPP_FUNC_VIS wostream wcout;
-extern _LIBCPP_FUNC_VIS wostream wcerr;
-extern _LIBCPP_FUNC_VIS wostream wclog;
+extern _LIBCPP_EXPORTED_FROM_ABI wistream wcin;
+extern _LIBCPP_EXPORTED_FROM_ABI wostream wcout;
+extern _LIBCPP_EXPORTED_FROM_ABI wostream wcerr;
+extern _LIBCPP_EXPORTED_FROM_ABI wostream wclog;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/istream
@@ -160,7 +160,12 @@ template <class Stream, class T>
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__fwd/istream.h>
 #include <__iterator/istreambuf_iterator.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_base_of.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <ostream>
 #include <version>
@@ -360,14 +365,14 @@ __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
     typename basic_istream<_CharT, _Traits>::sentry __s(__is);
     if (__s)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef istreambuf_iterator<_CharT, _Traits> _Ip;
             typedef num_get<_CharT, _Ip> _Fp;
             std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -469,10 +474,10 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
     typename basic_istream<_CharT, _Traits>::sentry __s(__is);
     if (__s)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef istreambuf_iterator<_CharT, _Traits> _Ip;
             typedef num_get<_CharT, _Ip> _Fp;
             long __temp;
@@ -491,7 +496,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
             {
                 __n = static_cast<_Tp>(__temp);
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -502,7 +507,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __is.setstate(__state);
     }
     return __is;
@@ -531,7 +536,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -555,7 +560,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
             __is.width(0);
             if (__s == __p)
                __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -572,7 +577,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
     return __is;
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template<class _CharT, class _Traits, size_t _Np>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -630,7 +635,7 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
     return __is >> (char*)__s;
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template<class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
@@ -640,7 +645,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -649,7 +654,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
                 __state |= ios_base::eofbit | ios_base::failbit;
             else
                 __c = _Traits::to_char_type(__i);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -693,10 +698,10 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
     {
         if (__sb)
         {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             try
             {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
                 while (true)
                 {
                     typename traits_type::int_type __i = this->rdbuf()->sgetc();
@@ -714,7 +719,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
                 }
                 if (__gc_ == 0)
                    __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             }
             catch (...)
             {
@@ -728,7 +733,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
                     throw;
                 }
             }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         }
         else
         {
@@ -749,7 +754,7 @@ basic_istream<_CharT, _Traits>::get()
     sentry __s(*this, true);
     if (__s)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -758,7 +763,7 @@ basic_istream<_CharT, _Traits>::get()
                __state |= ios_base::failbit | ios_base::eofbit;
             else
                 __gc_ = 1;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -785,7 +790,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __
     {
         if (__n > 0)
         {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             try
             {
 #endif
@@ -806,7 +811,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __
                 }
                 if (__gc_ == 0)
                    __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             }
             catch (...)
             {
@@ -845,10 +850,10 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             while (true)
             {
                 typename traits_type::int_type __i = this->rdbuf()->sgetc();
@@ -865,14 +870,14 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
                 ++__gc_;
                 this->rdbuf()->sbumpc();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __state |= ios_base::badbit;
             // according to the spec, exceptions here are caught but not rethrown
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         if (__gc_ == 0)
            __state |= ios_base::failbit;
         this->setstate(__state);
@@ -889,10 +894,10 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             while (true)
             {
                 typename traits_type::int_type __i = this->rdbuf()->sgetc();
@@ -917,7 +922,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
                 this->rdbuf()->sbumpc();
                 ++__gc_;
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -932,7 +937,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     if (__n > 0)
         *__s = char_type();
@@ -951,10 +956,10 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (__n == numeric_limits<streamsize>::max())
             {
                 while (true)
@@ -985,7 +990,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
                         break;
                 }
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -996,7 +1001,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return *this;
@@ -1012,14 +1017,14 @@ basic_istream<_CharT, _Traits>::peek()
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             __r = this->rdbuf()->sgetc();
             if (traits_type::eq_int_type(__r, traits_type::eof()))
                 __state |= ios_base::eofbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1030,7 +1035,7 @@ basic_istream<_CharT, _Traits>::peek()
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return __r;
@@ -1045,14 +1050,14 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             __gc_ = this->rdbuf()->sgetn(__s, __n);
             if (__gc_ != __n)
                 __state |= ios_base::failbit | ios_base::eofbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1063,7 +1068,7 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     else
     {
@@ -1082,10 +1087,10 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             streamsize __c = this->rdbuf()->in_avail();
             switch (__c)
             {
@@ -1101,7 +1106,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
                     __state |= ios_base::failbit | ios_base::eofbit;
                 break;
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1112,7 +1117,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     else
     {
@@ -1132,13 +1137,13 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (this->rdbuf() == nullptr || this->rdbuf()->sputbackc(__c) == traits_type::eof())
                 __state |= ios_base::badbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1149,7 +1154,7 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     else
     {
@@ -1169,13 +1174,13 @@ basic_istream<_CharT, _Traits>::unget()
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (this->rdbuf() == nullptr || this->rdbuf()->sungetc() == traits_type::eof())
                 __state |= ios_base::badbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1186,7 +1191,7 @@ basic_istream<_CharT, _Traits>::unget()
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     else
     {
@@ -1205,10 +1210,10 @@ basic_istream<_CharT, _Traits>::sync()
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (this->rdbuf() == nullptr)
                 return -1;
             if (this->rdbuf()->pubsync() == -1)
@@ -1216,7 +1221,7 @@ basic_istream<_CharT, _Traits>::sync()
                 __state |= ios_base::badbit;
                 return -1;
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1227,7 +1232,7 @@ basic_istream<_CharT, _Traits>::sync()
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return __r;
@@ -1242,12 +1247,12 @@ basic_istream<_CharT, _Traits>::tellg()
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1258,7 +1263,7 @@ basic_istream<_CharT, _Traits>::tellg()
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return __r;
@@ -1273,13 +1278,13 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
                 __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1290,7 +1295,7 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return *this;
@@ -1305,13 +1310,13 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
     sentry __sen(*this, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
                 __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1322,7 +1327,7 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         this->setstate(__state);
     }
     return *this;
@@ -1336,10 +1341,10 @@ ws(basic_istream<_CharT, _Traits>& __is)
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
             while (true)
             {
@@ -1353,7 +1358,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
                     break;
                 __is.rdbuf()->sbumpc();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1364,7 +1369,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
                 throw;
             }
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __is.setstate(__state);
     }
     return __is;
@@ -1450,7 +1455,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -1480,7 +1485,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
             __is.width(0);
             if (__c == 0)
                __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1506,7 +1511,7 @@ getline(basic_istream<_CharT, _Traits>& __is,
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -1533,7 +1538,7 @@ getline(basic_istream<_CharT, _Traits>& __is,
             }
             if (__extr == 0)
                __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1585,7 +1590,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
     typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
     if (__sen)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
 #endif
@@ -1612,7 +1617,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
             __x = bitset<_Size>(__str);
             if (_Size > 0 && __c == 0)
                __state |= ios_base::failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
lib/libcxx/include/iterator
@@ -387,7 +387,7 @@ template <class Iterator>
 class move_iterator {
 public:
     using iterator_type     = Iterator;
-    using iterator_concept  = input_iterator_tag; // From C++20
+    using iterator_concept  = see below; // From C++20
     using iterator_category = see below; // not always present starting from C++20
     using value_type        = iter_value_t<Iterator>; // Until C++20, iterator_traits<Iterator>::value_type
     using difference_type   = iter_difference_t<Iterator>; // Until C++20, iterator_traits<Iterator>::difference_type;
@@ -676,7 +676,6 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <__iterator/access.h>
 #include <__iterator/advance.h>
 #include <__iterator/back_insert_iterator.h>
@@ -732,6 +731,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
 #  include <exception>
 #  include <new>
 #  include <type_traits>
lib/libcxx/include/latch
@@ -41,9 +41,12 @@ namespace std
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__atomic/atomic_base.h>
+#include <__atomic/atomic_sync.h>
+#include <__atomic/memory_order.h>
 #include <__availability>
 #include <__config>
-#include <atomic>
+#include <cstddef>
 #include <limits>
 #include <version>
 
@@ -67,22 +70,35 @@ class latch
     __atomic_base<ptrdiff_t> __a_;
 
 public:
-    static constexpr ptrdiff_t max() noexcept {
+    static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
         return numeric_limits<ptrdiff_t>::max();
     }
 
     inline _LIBCPP_INLINE_VISIBILITY
-    constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) { }
+    constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(__expected >= 0,
+                                     "latch::latch(ptrdiff_t): latch cannot be "
+                                     "initialized with a negative value");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__expected <= max(),
+                                     "latch::latch(ptrdiff_t): latch cannot be "
+                                     "initialized with a value greater than max()");
+    }
 
-    ~latch() = default;
+    _LIBCPP_HIDE_FROM_ABI ~latch() = default;
     latch(const latch&) = delete;
     latch& operator=(const latch&) = delete;
 
     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void count_down(ptrdiff_t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update >= 0, "latch::count_down called with a negative value");
         auto const __old = __a_.fetch_sub(__update, memory_order_release);
-        if(__old == __update)
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update <= __old, "latch::count_down called with a value greater "
+                               "than the internal counter");
+        if (__old == __update)
             __a_.notify_all();
     }
     inline _LIBCPP_INLINE_VISIBILITY
@@ -93,13 +109,17 @@ public:
     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void wait() const
     {
-        __cxx_atomic_wait(&__a_.__a_, [&]() -> bool {
+        __cxx_atomic_wait(&__a_.__a_, [this]() -> bool {
             return try_wait();
         });
     }
     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void arrive_and_wait(ptrdiff_t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update >= 0, "latch::arrive_and_wait called with a negative value");
+        // other preconditions on __update are checked in count_down()
+
         count_down(__update);
         wait();
     }
@@ -111,4 +131,8 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
+#endif
+
 #endif //_LIBCPP_LATCH
lib/libcxx/include/list
@@ -46,6 +46,8 @@ public:
         list(Iter first, Iter last);
     template <class Iter>
         list(Iter first, Iter last, const allocator_type& a);
+    template<container-compatible-range<T> R>
+      list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
     list(const list& x);
     list(const list&, const allocator_type& a);
     list(list&& x)
@@ -64,6 +66,8 @@ public:
     list& operator=(initializer_list<value_type>);
     template <class Iter>
         void assign(Iter first, Iter last);
+    template<container-compatible-range<T> R>
+      void assign_range(R&& rg); // C++23
     void assign(size_type n, const value_type& t);
     void assign(initializer_list<value_type>);
 
@@ -99,8 +103,12 @@ public:
     void pop_back();
     void push_front(const value_type& x);
     void push_front(value_type&& x);
+    template<container-compatible-range<T> R>
+      void prepend_range(R&& rg); // C++23
     void push_back(const value_type& x);
     void push_back(value_type&& x);
+    template<container-compatible-range<T> R>
+      void append_range(R&& rg); // C++23
     template <class... Args>
         iterator emplace(const_iterator position, Args&&... args);
     iterator insert(const_iterator position, const value_type& x);
@@ -108,6 +116,8 @@ public:
     iterator insert(const_iterator position, size_type n, const value_type& x);
     template <class Iter>
         iterator insert(const_iterator position, Iter first, Iter last);
+    template<container-compatible-range<T> R>
+      iterator insert_range(const_iterator position, R&& rg); // C++23
     iterator insert(const_iterator position, initializer_list<value_type> il);
 
     iterator erase(const_iterator position);
@@ -152,18 +162,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
     list(InputIterator, InputIterator, Allocator = Allocator())
     -> list<typename iterator_traits<InputIterator>::value_type, Allocator>;  // C++17
 
+template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
+  list(from_range_t, R&&, Allocator = Allocator())
+    -> list<ranges::range_value_t<R>, Allocator>; // C++23
+
 template <class T, class Alloc>
     bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
 template <class T, class Alloc>
-    bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);
+    bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);     // removed in C++20
 template <class T, class Alloc>
-    bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+    bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);     // removed in C++20
 template <class T, class Alloc>
-    bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);
+    bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);     // removed in C++20
 template <class T, class Alloc>
-    bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+    bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);     // removed in C++20
 template <class T, class Alloc>
-    bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+    bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);     // removed in C++20
+template<class T, class Allocator>
+  synth-three-way-result<T> operator<=>(const list<T, Allocator>& x,
+                                        const list<T, Allocator>& y);    // since C++20
 
 template <class T, class Alloc>
     void swap(list<T,Alloc>& x, list<T,Alloc>& y)
@@ -171,10 +188,10 @@ template <class T, class Alloc>
 
 template <class T, class Allocator, class U>
     typename list<T, Allocator>::size_type
-    erase(list<T, Allocator>& c, const U& value);       // C++20
+    erase(list<T, Allocator>& c, const U& value);       // since C++20
 template <class T, class Allocator, class Predicate>
     typename list<T, Allocator>::size_type
-    erase_if(list<T, Allocator>& c, Predicate pred);    // C++20
+    erase_if(list<T, Allocator>& c, Predicate pred);    // since C++20
 
 }  // std
 
@@ -183,10 +200,11 @@ template <class T, class Allocator, class Predicate>
 #include <__algorithm/comp.h>
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/min.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
-#include <__debug>
 #include <__format/enable_insertable.h>
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
@@ -203,13 +221,23 @@ template <class T, class Allocator, class Predicate>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__type_traits/conditional.h>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
 #include <cstring>
 #include <limits>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -320,13 +348,9 @@ class _LIBCPP_TEMPLATE_VIS __list_iterator
     __link_pointer __ptr_;
 
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
+    explicit __list_iterator(__link_pointer __p) _NOEXCEPT
         : __ptr_(__p)
     {
-        (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __get_db()->__insert_ic(this, __c);
-#endif
     }
 
     template<class, class> friend class list;
@@ -342,57 +366,22 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __list_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
-        _VSTD::__debug_db_insert_i(this);
-    }
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    _LIBCPP_INLINE_VISIBILITY
-    __list_iterator(const __list_iterator& __p)
-        : __ptr_(__p.__ptr_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__list_iterator()
-    {
-        __get_db()->__erase_i(this);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    __list_iterator& operator=(const __list_iterator& __p)
-    {
-        if (this != _VSTD::addressof(__p))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
-            __ptr_ = __p.__ptr_;
-        }
-        return *this;
     }
 
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable list::iterator");
         return __ptr_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable list::iterator");
         return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __list_iterator& operator++()
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to increment a non-incrementable list::iterator");
         __ptr_ = __ptr_->__next_;
         return *this;
     }
@@ -402,8 +391,6 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __list_iterator& operator--()
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
-                             "Attempted to decrement a non-decrementable list::iterator");
         __ptr_ = __ptr_->__prev_;
         return *this;
     }
@@ -429,13 +416,9 @@ class _LIBCPP_TEMPLATE_VIS __list_const_iterator
     __link_pointer __ptr_;
 
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
+    explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT
         : __ptr_(__p)
     {
-        (void)__c;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __get_db()->__insert_ic(this, __c);
-#endif
     }
 
     template<class, class> friend class list;
@@ -450,64 +433,27 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
-        _VSTD::__debug_db_insert_i(this);
     }
     _LIBCPP_INLINE_VISIBILITY
     __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT
         : __ptr_(__p.__ptr_)
     {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
-#endif
-    }
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    _LIBCPP_INLINE_VISIBILITY
-    __list_const_iterator(const __list_const_iterator& __p)
-        : __ptr_(__p.__ptr_)
-    {
-        __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~__list_const_iterator()
-    {
-        __get_db()->__erase_i(this);
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    __list_const_iterator& operator=(const __list_const_iterator& __p)
-    {
-        if (this != _VSTD::addressof(__p))
-        {
-            __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
-            __ptr_ = __p.__ptr_;
-        }
-        return *this;
     }
 
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable list::const_iterator");
         return __ptr_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to dereference a non-dereferenceable list::const_iterator");
         return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
     __list_const_iterator& operator++()
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
-                             "Attempted to increment a non-incrementable list::const_iterator");
         __ptr_ = __ptr_->__next_;
         return *this;
     }
@@ -517,8 +463,6 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __list_const_iterator& operator--()
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
-                             "Attempted to decrement a non-decrementable list::const_iterator");
         __ptr_ = __ptr_->__prev_;
         return *this;
     }
@@ -604,35 +548,35 @@ protected:
     _LIBCPP_INLINE_VISIBILITY
     __list_imp(const __node_allocator& __a);
 #ifndef _LIBCPP_CXX03_LANG
-    __list_imp(__node_allocator&& __a) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI __list_imp(__node_allocator&& __a) _NOEXCEPT;
 #endif
-    ~__list_imp();
-    void clear() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI ~__list_imp();
+    _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     bool empty() const _NOEXCEPT {return __sz() == 0;}
 
     _LIBCPP_INLINE_VISIBILITY
     iterator begin() _NOEXCEPT
     {
-        return iterator(__end_.__next_, this);
+        return iterator(__end_.__next_);
     }
     _LIBCPP_INLINE_VISIBILITY
     const_iterator begin() const  _NOEXCEPT
     {
-        return const_iterator(__end_.__next_, this);
+        return const_iterator(__end_.__next_);
     }
     _LIBCPP_INLINE_VISIBILITY
     iterator end() _NOEXCEPT
     {
-        return iterator(__end_as_link(), this);
+        return iterator(__end_as_link());
     }
     _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT
     {
-        return const_iterator(__end_as_link(), this);
+        return const_iterator(__end_as_link());
     }
 
-    void swap(__list_imp& __c)
+    _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c)
 #if _LIBCPP_STD_VER >= 14
         _NOEXCEPT;
 #else
@@ -718,7 +662,6 @@ inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT
 template <class _Tp, class _Alloc>
 __list_imp<_Tp, _Alloc>::~__list_imp() {
   clear();
-  std::__debug_db_erase_c(this);
 }
 
 template <class _Tp, class _Alloc>
@@ -739,7 +682,6 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
             __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
             __node_alloc_traits::deallocate(__na, __np, 1);
         }
-        std::__debug_db_invalidate_all(this);
     }
 }
 
@@ -753,10 +695,10 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
                     __is_nothrow_swappable<allocator_type>::value)
 #endif
 {
-    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
-                   this->__node_alloc() == __c.__node_alloc(),
-                   "list::swap: Either propagate_on_container_swap must be true"
-                   " or the allocators must compare equal");
+    _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"
+                                        " or the allocators must compare equal");
     using _VSTD::swap;
     _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc());
     swap(__sz(), __c.__sz());
@@ -769,42 +711,6 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
         __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link();
     else
         __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link();
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    __libcpp_db* __db = __get_db();
-    __c_node* __cn1 = __db->__find_c_and_lock(this);
-    __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
-    _VSTD::swap(__cn1->beg_, __cn2->beg_);
-    _VSTD::swap(__cn1->end_, __cn2->end_);
-    _VSTD::swap(__cn1->cap_, __cn2->cap_);
-    for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;)
-    {
-        --__p;
-        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == __c.__end_as_link())
-        {
-            __cn2->__add(*__p);
-            if (--__cn1->end_ != __p)
-                _VSTD::memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*));
-        }
-        else
-            (*__p)->__c_ = __cn1;
-    }
-    for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
-    {
-        --__p;
-        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == __end_as_link())
-        {
-            __cn1->__add(*__p);
-            if (--__cn2->end_ != __p)
-                _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
-        }
-        else
-            (*__p)->__c_ = __cn2;
-    }
-    __db->unlock();
-#endif
 }
 
 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
@@ -824,7 +730,7 @@ public:
     typedef _Tp                                            value_type;
     typedef _Alloc                                         allocator_type;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
-                  "Invalid allocator::value_type");
+                  "Allocator::value_type must be same type as value_type");
     typedef value_type&                                    reference;
     typedef const value_type&                              const_reference;
     typedef typename base::pointer                         pointer;
@@ -835,7 +741,7 @@ public:
     typedef typename base::const_iterator                  const_iterator;
     typedef _VSTD::reverse_iterator<iterator>              reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>        const_reverse_iterator;
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     typedef size_type                                      __remove_return_type;
 #else
     typedef void                                           __remove_return_type;
@@ -849,40 +755,45 @@ public:
     list()
         _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
     _LIBCPP_INLINE_VISIBILITY
     explicit list(const allocator_type& __a) : base(__a)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
-    explicit list(size_type __n);
-#if _LIBCPP_STD_VER > 11
-    explicit list(size_type __n, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n);
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a);
 #endif
-    list(size_type __n, const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x);
     template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
-    list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a)
+    _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a)
     {
-        _VSTD::__debug_db_insert_c(this);
         for (; __n > 0; --__n)
             push_back(__x);
     }
 
     template <class _InpIter>
-        list(_InpIter __f, _InpIter __l,
-             __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
+    _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l,
+             __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
     template <class _InpIter>
-        list(_InpIter __f, _InpIter __l, const allocator_type& __a,
-             __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
+    _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, const allocator_type& __a,
+             __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI list(from_range_t, _Range&& __range,
+        const allocator_type& __a = allocator_type()) : base(__a) {
+      prepend_range(std::forward<_Range>(__range));
+    }
+#endif
 
-    list(const list& __c);
-    list(const list& __c, const __type_identity_t<allocator_type>& __a);
+    _LIBCPP_HIDE_FROM_ABI list(const list& __c);
+    _LIBCPP_HIDE_FROM_ABI list(const list& __c, const __type_identity_t<allocator_type>& __a);
     _LIBCPP_INLINE_VISIBILITY
     list& operator=(const list& __c);
 #ifndef _LIBCPP_CXX03_LANG
-    list(initializer_list<value_type> __il);
-    list(initializer_list<value_type> __il, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il, const allocator_type& __a);
 
     _LIBCPP_INLINE_VISIBILITY
     list(list&& __c)
@@ -905,9 +816,18 @@ public:
 #endif // _LIBCPP_CXX03_LANG
 
     template <class _InpIter>
-        void assign(_InpIter __f, _InpIter __l,
-                    __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
-    void assign(size_type __n, const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI void assign(_InpIter __f, _InpIter __l,
+                    __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void assign_range(_Range&& __range) {
+      __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+    }
+#endif
+
+    _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x);
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT;
@@ -959,56 +879,70 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     reference front()
     {
-        _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
         return base::__end_.__next_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     const_reference front() const
     {
-        _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
         return base::__end_.__next_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     reference back()
     {
-        _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
         return base::__end_.__prev_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     const_reference back() const
     {
-        _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
         return base::__end_.__prev_->__as_node()->__value_;
     }
 
 #ifndef _LIBCPP_CXX03_LANG
-    void push_front(value_type&& __x);
-    void push_back(value_type&& __x);
+    _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
+    _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void prepend_range(_Range&& __range) {
+      insert_range(begin(), std::forward<_Range>(__range));
+    }
+
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void append_range(_Range&& __range) {
+      insert_range(end(), std::forward<_Range>(__range));
+    }
+#endif
 
     template <class... _Args>
-#if _LIBCPP_STD_VER > 14
-       reference emplace_front(_Args&&... __args);
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
 #else
-       void      emplace_front(_Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI void      emplace_front(_Args&&... __args);
 #endif
     template <class... _Args>
-#if _LIBCPP_STD_VER > 14
-        reference emplace_back(_Args&&... __args);
+#if _LIBCPP_STD_VER >= 17
+    _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args);
 #else
-       void       emplace_back(_Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI void       emplace_back(_Args&&... __args);
 #endif
     template <class... _Args>
-        iterator emplace(const_iterator __p, _Args&&... __args);
+    _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
 
-    iterator insert(const_iterator __p, value_type&& __x);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __x);
 
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __p, initializer_list<value_type> __il)
         {return insert(__p, __il.begin(), __il.end());}
 #endif // _LIBCPP_CXX03_LANG
 
-    void push_front(const value_type& __x);
-    void push_back(const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __x);
 
 #ifndef _LIBCPP_CXX03_LANG
     template <class _Arg>
@@ -1019,11 +953,19 @@ public:
     void __emplace_back(value_type const& __arg) { push_back(__arg); }
 #endif
 
-    iterator insert(const_iterator __p, const value_type& __x);
-    iterator insert(const_iterator __p, size_type __n, const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __x);
     template <class _InpIter>
-        iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
-                        __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
+                        __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator insert_range(const_iterator __position, _Range&& __range) {
+      return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
+    }
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     void swap(list& __c)
@@ -1037,16 +979,16 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {base::clear();}
 
-    void pop_front();
-    void pop_back();
+    _LIBCPP_HIDE_FROM_ABI void pop_front();
+    _LIBCPP_HIDE_FROM_ABI void pop_back();
 
-    iterator erase(const_iterator __p);
-    iterator erase(const_iterator __f, const_iterator __l);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
+    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
 
-    void resize(size_type __n);
-    void resize(size_type __n, const value_type& __x);
+    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
+    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __x);
 
-    void splice(const_iterator __p, list& __c);
+    _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     void splice(const_iterator __p, list&& __c) {splice(__p, __c);}
@@ -1057,15 +999,16 @@ public:
     void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)
         {splice(__p, __c, __f, __l);}
 #endif
-    void splice(const_iterator __p, list& __c, const_iterator __i);
-    void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
+    _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __i);
+    _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
 
-    __remove_return_type remove(const value_type& __x);
-    template <class _Pred> __remove_return_type remove_if(_Pred __pred);
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __x);
+    template <class _Pred>
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Pred __pred);
     _LIBCPP_INLINE_VISIBILITY
     __remove_return_type unique() { return unique(__equal_to()); }
     template <class _BinaryPred>
-        __remove_return_type unique(_BinaryPred __binary_pred);
+    _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPred __binary_pred);
     _LIBCPP_INLINE_VISIBILITY
     void merge(list& __c);
 #ifndef _LIBCPP_CXX03_LANG
@@ -1077,7 +1020,7 @@ public:
         void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}
 #endif
     template <class _Comp>
-        void merge(list& __c, _Comp __comp);
+    _LIBCPP_HIDE_FROM_ABI void merge(list& __c, _Comp __comp);
 
     _LIBCPP_INLINE_VISIBILITY
     void sort();
@@ -1085,9 +1028,9 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         void sort(_Comp __comp);
 
-    void reverse() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
 
-    bool __invariants() const;
+    _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
 
     typedef __allocator_destructor<__node_allocator> __node_destructor;
     typedef unique_ptr<__node, __node_destructor> __hold_pointer;
@@ -1099,35 +1042,35 @@ public:
       return __hold_pointer(__p, __node_destructor(__na, 1));
     }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const;
-    bool __decrementable(const const_iterator* __i) const;
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+private:
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
 
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
 
-private:
     _LIBCPP_INLINE_VISIBILITY
     static void __link_nodes  (__link_pointer __p, __link_pointer __f, __link_pointer __l);
     _LIBCPP_INLINE_VISIBILITY
     void __link_nodes_at_front(__link_pointer __f, __link_pointer __l);
     _LIBCPP_INLINE_VISIBILITY
     void __link_nodes_at_back (__link_pointer __f, __link_pointer __l);
-    iterator __iterator(size_type __n);
+    _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n);
+    // TODO: Make this _LIBCPP_HIDE_FROM_ABI
     template <class _Comp>
-        static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
+    _LIBCPP_HIDDEN static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
 
-    void __move_assign(list& __c, true_type)
+    _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type)
         _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);
-    void __move_assign(list& __c, false_type);
+    _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type);
 };
 
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator,
          class _Alloc = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 list(_InputIterator, _InputIterator)
@@ -1135,13 +1078,22 @@ list(_InputIterator, _InputIterator)
 
 template<class _InputIterator,
          class _Alloc,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 list(_InputIterator, _InputIterator, _Alloc)
   -> list<__iter_value_type<_InputIterator>, _Alloc>;
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Alloc = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Alloc>::value>
+          >
+list(from_range_t, _Range&&, _Alloc = _Alloc())
+  -> list<ranges::range_value_t<_Range>, _Alloc>;
+#endif
+
 // Link in nodes [__f, __l] just prior to __p
 template <class _Tp, class _Alloc>
 inline
@@ -1191,7 +1143,6 @@ list<_Tp, _Alloc>::__iterator(size_type __n)
 template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(size_type __n)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (; __n > 0; --__n)
 #ifndef _LIBCPP_CXX03_LANG
         emplace_back();
@@ -1200,11 +1151,10 @@ list<_Tp, _Alloc>::list(size_type __n)
 #endif
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (; __n > 0; --__n)
         emplace_back();
 }
@@ -1213,7 +1163,6 @@ list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
 template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (; __n > 0; --__n)
         push_back(__x);
 }
@@ -1221,9 +1170,8 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
 template <class _Tp, class _Alloc>
 template <class _InpIter>
 list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
-                        __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
+                        __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (; __f != __l; ++__f)
         __emplace_back(*__f);
 }
@@ -1231,10 +1179,9 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
 template <class _Tp, class _Alloc>
 template <class _InpIter>
 list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
-                        __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
+                        __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
     : base(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (; __f != __l; ++__f)
         __emplace_back(*__f);
 }
@@ -1243,7 +1190,6 @@ template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(const list& __c)
     : base(__node_alloc_traits::select_on_container_copy_construction(
           __c.__node_alloc())) {
-    _VSTD::__debug_db_insert_c(this);
     for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
         push_back(*__i);
 }
@@ -1252,7 +1198,6 @@ template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t<allocator_type>& __a)
     : base(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
         push_back(*__i);
 }
@@ -1263,7 +1208,6 @@ template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)
     : base(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
             __e = __il.end(); __i != __e; ++__i)
         push_back(*__i);
@@ -1272,7 +1216,6 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type&
 template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
 {
-    _VSTD::__debug_db_insert_c(this);
     for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
             __e = __il.end(); __i != __e; ++__i)
         push_back(*__i);
@@ -1282,7 +1225,6 @@ template <class _Tp, class _Alloc>
 inline list<_Tp, _Alloc>::list(list&& __c)
         _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
         : base(_VSTD::move(__c.__node_alloc())) {
-    _VSTD::__debug_db_insert_c(this);
     splice(end(), __c);
 }
 
@@ -1291,7 +1233,6 @@ inline
 list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t<allocator_type>& __a)
     : base(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
     if (__a == __c.get_allocator())
         splice(end(), __c);
     else
@@ -1356,17 +1297,23 @@ template <class _Tp, class _Alloc>
 template <class _InpIter>
 void
 list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
-                          __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
+                          __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
 {
+  __assign_with_sentinel(__f, __l);
+}
+
+template <class _Tp, class _Alloc>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+void list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
     iterator __i = begin();
     iterator __e = end();
     for (; __f != __l && __i != __e; ++__f, (void) ++__i)
         *__i = *__f;
     if (__i == __e)
-        insert(__e, __f, __l);
+        __insert_with_sentinel(__e, std::move(__f), std::move(__l));
     else
         erase(__i, __e);
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Tp, class _Alloc>
@@ -1381,7 +1328,6 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
         insert(__e, __n, __x);
     else
         erase(__i, __e);
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Tp, class _Alloc>
@@ -1396,23 +1342,19 @@ template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::insert(iterator, x) called with an iterator not referring to this list");
     __node_allocator& __na = base::__node_alloc();
     __hold_pointer __hold = __allocate_node(__na);
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
     __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link());
     ++base::__sz();
-    return iterator(__hold.release()->__as_link(), this);
+    return iterator(__hold.release()->__as_link());
 }
 
 template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::insert(iterator, n, x) called with an iterator not referring to this list");
-    iterator __r(__p.__ptr_, this);
+    iterator __r(__p.__ptr_);
     if (__n > 0)
     {
         size_type __ds = 0;
@@ -1420,13 +1362,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
         __hold_pointer __hold = __allocate_node(__na);
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
         ++__ds;
-        __r = iterator(__hold->__as_link(), this);
+        __r = iterator(__hold->__as_link());
         __hold.release();
         iterator __e = __r;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
@@ -1435,7 +1377,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1446,11 +1388,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
                 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
-                __e = iterator(__prev, this);
+                __e = iterator(__prev);
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
@@ -1461,11 +1403,17 @@ template <class _Tp, class _Alloc>
 template <class _InpIter>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
-                          __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
+                          __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::insert(iterator, range) called with an iterator not referring to this list");
-    iterator __r(__p.__ptr_, this);
+    return __insert_with_sentinel(__p, __f, __l);
+}
+
+template <class _Tp, class _Alloc>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
+    iterator __r(__p.__ptr_);
     if (__f != __l)
     {
         size_type __ds = 0;
@@ -1473,13 +1421,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
         __hold_pointer __hold = __allocate_node(__na);
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
         ++__ds;
-        __r = iterator(__hold.get()->__as_link(), this);
+        __r = iterator(__hold.get()->__as_link());
         __hold.release();
         iterator __e = __r;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds)
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
@@ -1488,7 +1436,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1499,11 +1447,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
                 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
-                __e = iterator(__prev, this);
+                __e = iterator(__prev);
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
@@ -1563,7 +1511,7 @@ list<_Tp, _Alloc>::push_back(value_type&& __x)
 
 template <class _Tp, class _Alloc>
 template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename list<_Tp, _Alloc>::reference
 #else
 void
@@ -1575,7 +1523,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
     __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
     ++base::__sz();
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return __hold.release()->__value_;
 #else
     __hold.release();
@@ -1584,7 +1532,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
 
 template <class _Tp, class _Alloc>
 template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename list<_Tp, _Alloc>::reference
 #else
 void
@@ -1597,7 +1545,7 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
     __link_pointer __nl = __hold->__as_link();
     __link_nodes_at_back(__nl, __nl);
     ++base::__sz();
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return __hold.release()->__value_;
 #else
     __hold.release();
@@ -1609,8 +1557,6 @@ template <class... _Args>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::emplace(iterator, args...) called with an iterator not referring to this list");
     __node_allocator& __na = base::__node_alloc();
     __hold_pointer __hold = __allocate_node(__na);
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
@@ -1618,15 +1564,13 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
     __link_nodes(__p.__ptr_, __nl, __nl);
     ++base::__sz();
     __hold.release();
-    return iterator(__nl, this);
+    return iterator(__nl);
 }
 
 template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::insert(iterator, x) called with an iterator not referring to this list");
     __node_allocator& __na = base::__node_alloc();
     __hold_pointer __hold = __allocate_node(__na);
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
@@ -1634,7 +1578,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
     __link_nodes(__p.__ptr_, __nl, __nl);
     ++base::__sz();
     __hold.release();
-    return iterator(__nl, this);
+    return iterator(__nl);
 }
 
 #endif // _LIBCPP_CXX03_LANG
@@ -1643,26 +1587,11 @@ template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::pop_front()
 {
-    _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list");
     __node_allocator& __na = base::__node_alloc();
     __link_pointer __n = base::__end_.__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    __c_node* __c = __get_db()->__find_c_and_lock(this);
-    for (__i_node** __p = __c->end_; __p != __c->beg_; )
-    {
-        --__p;
-        iterator* __i = static_cast<iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == __n)
-        {
-            (*__p)->__c_ = nullptr;
-            if (--__c->end_ != __p)
-                _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-        }
-    }
-    __get_db()->unlock();
-#endif
     __node_pointer __np = __n->__as_node();
     __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
     __node_alloc_traits::deallocate(__na, __np, 1);
@@ -1672,26 +1601,11 @@ template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::pop_back()
 {
-    _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list");
     __node_allocator& __na = base::__node_alloc();
     __link_pointer __n = base::__end_.__prev_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    __c_node* __c = __get_db()->__find_c_and_lock(this);
-    for (__i_node** __p = __c->end_; __p != __c->beg_; )
-    {
-        --__p;
-        iterator* __i = static_cast<iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == __n)
-        {
-            (*__p)->__c_ = nullptr;
-            if (--__c->end_ != __p)
-                _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-        }
-    }
-    __get_db()->unlock();
-#endif
     __node_pointer __np = __n->__as_node();
     __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
     __node_alloc_traits::deallocate(__na, __np, 1);
@@ -1701,44 +1615,23 @@ template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::erase(const_iterator __p)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::erase(iterator) called with an iterator not referring to this list");
-    _LIBCPP_ASSERT(__p != end(),
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
         "list::erase(iterator) called with a non-dereferenceable iterator");
     __node_allocator& __na = base::__node_alloc();
     __link_pointer __n = __p.__ptr_;
     __link_pointer __r = __n->__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    __c_node* __c = __get_db()->__find_c_and_lock(this);
-    for (__i_node** __ip = __c->end_; __ip != __c->beg_; )
-    {
-        --__ip;
-        iterator* __i = static_cast<iterator*>((*__ip)->__i_);
-        if (__i->__ptr_ == __n)
-        {
-            (*__ip)->__c_ = nullptr;
-            if (--__c->end_ != __ip)
-                _VSTD::memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*));
-        }
-    }
-    __get_db()->unlock();
-#endif
     __node_pointer __np = __n->__as_node();
     __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
     __node_alloc_traits::deallocate(__na, __np, 1);
-    return iterator(__r, this);
+    return iterator(__r);
 }
 
 template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this,
-                         "list::erase(iterator, iterator) called with an iterator not referring to this list");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this,
-                         "list::erase(iterator, iterator) called with an iterator not referring to this list");
     if (__f != __l)
     {
         __node_allocator& __na = base::__node_alloc();
@@ -1748,27 +1641,12 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
             __link_pointer __n = __f.__ptr_;
             ++__f;
             --base::__sz();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-            __c_node* __c = __get_db()->__find_c_and_lock(this);
-            for (__i_node** __p = __c->end_; __p != __c->beg_; )
-            {
-                --__p;
-                iterator* __i = static_cast<iterator*>((*__p)->__i_);
-                if (__i->__ptr_ == __n)
-                {
-                    (*__p)->__c_ = nullptr;
-                    if (--__c->end_ != __p)
-                        _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-                }
-            }
-            __get_db()->unlock();
-#endif
             __node_pointer __np = __n->__as_node();
             __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
             __node_alloc_traits::deallocate(__na, __np, 1);
         }
     }
-    return iterator(__l.__ptr_, this);
+    return iterator(__l.__ptr_);
 }
 
 template <class _Tp, class _Alloc>
@@ -1785,12 +1663,12 @@ list<_Tp, _Alloc>::resize(size_type __n)
         __hold_pointer __hold = __allocate_node(__na);
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
         ++__ds;
-        iterator __r = iterator(__hold.release()->__as_link(), this);
+        iterator __r = iterator(__hold.release()->__as_link());
         iterator __e = __r;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
@@ -1799,7 +1677,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1810,11 +1688,11 @@ list<_Tp, _Alloc>::resize(size_type __n)
                 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
-                __e = iterator(__prev, this);
+                __e = iterator(__prev);
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __link_nodes_at_back(__r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
@@ -1835,12 +1713,12 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
         ++__ds;
         __link_pointer __nl = __hold.release()->__as_link();
-        iterator __r = iterator(__nl, this);
+        iterator __r = iterator(__nl);
         iterator __e = __r;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
@@ -1849,7 +1727,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -1860,11 +1738,11 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
                 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
-                __e = iterator(__prev, this);
+                __e = iterator(__prev);
             }
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
@@ -1874,10 +1752,8 @@ template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
 {
-    _LIBCPP_ASSERT(this != _VSTD::addressof(__c),
-                   "list::splice(iterator, list) called with this == &list");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                         "list::splice(iterator, list) called with an iterator not referring to this list");
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(this != _VSTD::addressof(__c),
+                                     "list::splice(iterator, list) called with this == &list");
     if (!__c.empty())
     {
         __link_pointer __f = __c.__end_.__next_;
@@ -1886,26 +1762,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
         __link_nodes(__p.__ptr_, __f, __l);
         base::__sz() += __c.__sz();
         __c.__sz() = 0;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        if (_VSTD::addressof(__c) != this) {
-            __libcpp_db* __db = __get_db();
-            __c_node* __cn1 = __db->__find_c_and_lock(this);
-            __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
-            for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
-            {
-                --__ip;
-                iterator* __i = static_cast<iterator*>((*__ip)->__i_);
-                if (__i->__ptr_ != __c.__end_as_link())
-                {
-                    __cn1->__add(*__ip);
-                    (*__ip)->__c_ = __cn1;
-                    if (--__cn2->end_ != __ip)
-                        _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
-                }
-            }
-            __db->unlock();
-        }
-#endif
     }
 }
 
@@ -1913,13 +1769,6 @@ template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-        "list::splice(iterator, list, iterator) called with the first iterator not referring to this list");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c),
-        "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)),
-        "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable");
-
     if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
     {
         __link_pointer __f = __i.__ptr_;
@@ -1927,26 +1776,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
         __link_nodes(__p.__ptr_, __f, __f);
         --__c.__sz();
         ++base::__sz();
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        if (_VSTD::addressof(__c) != this) {
-            __libcpp_db* __db = __get_db();
-            __c_node* __cn1 = __db->__find_c_and_lock(this);
-            __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
-            for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
-            {
-                --__ip;
-                iterator* __j = static_cast<iterator*>((*__ip)->__i_);
-                if (__j->__ptr_ == __f)
-                {
-                    __cn1->__add(*__ip);
-                    (*__ip)->__c_ = __cn1;
-                    if (--__cn2->end_ != __ip)
-                        _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
-                }
-            }
-            __db->unlock();
-        }
-#endif
     }
 }
 
@@ -1965,16 +1794,6 @@ template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-        "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c),
-        "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c),
-        "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument");
-    _LIBCPP_DEBUG_ASSERT(this != std::addressof(__c) || !std::__iterator_in_range(__f, __l, __p),
-        "list::splice(iterator, list, iterator, iterator)"
-        " called with the first iterator within the range of the second and third iterators");
-
     if (__f != __l)
     {
         __link_pointer __first = __f.__ptr_;
@@ -1988,30 +1807,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
         }
         base::__unlink_nodes(__first, __last);
         __link_nodes(__p.__ptr_, __first, __last);
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        if (_VSTD::addressof(__c) != this) {
-            __libcpp_db* __db = __get_db();
-            __c_node* __cn1 = __db->__find_c_and_lock(this);
-            __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
-            for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
-            {
-                --__ip;
-                iterator* __j = static_cast<iterator*>((*__ip)->__i_);
-                for (__link_pointer __k = __f.__ptr_;
-                                              __k != __l.__ptr_; __k = __k->__next_)
-                {
-                    if (__j->__ptr_ == __k)
-                    {
-                        __cn1->__add(*__ip);
-                        (*__ip)->__c_ = __cn1;
-                        if (--__cn2->end_ != __ip)
-                            _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
-                    }
-                }
-            }
-            __db->unlock();
-        }
-#endif
     }
 }
 
@@ -2089,7 +1884,7 @@ inline
 void
 list<_Tp, _Alloc>::merge(list& __c)
 {
-    merge(__c, __less<value_type>());
+    merge(__c, __less<>());
 }
 
 template <class _Tp, class _Alloc>
@@ -2125,24 +1920,6 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
                 ++__f1;
         }
         splice(__e1, __c);
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-        __libcpp_db* __db = __get_db();
-        __c_node* __cn1 = __db->__find_c_and_lock(this);
-        __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
-        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
-        {
-            --__p;
-            iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__ptr_ != __c.__end_as_link())
-            {
-                __cn1->__add(*__p);
-                (*__p)->__c_ = __cn1;
-                if (--__cn2->end_ != __p)
-                    _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
-            }
-        }
-        __db->unlock();
-#endif
     }
 }
 
@@ -2151,7 +1928,7 @@ inline
 void
 list<_Tp, _Alloc>::sort()
 {
-    sort(__less<value_type>());
+    sort(__less<>());
 }
 
 template <class _Tp, class _Alloc>
@@ -2249,38 +2026,6 @@ list<_Tp, _Alloc>::__invariants() const
     return size() == _VSTD::distance(begin(), end());
 }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-template <class _Tp, class _Alloc>
-bool
-list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
-{
-    return __i->__ptr_ != this->__end_as_link();
-}
-
-template <class _Tp, class _Alloc>
-bool
-list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const
-{
-    return !empty() &&  __i->__ptr_ != base::__end_.__next_;
-}
-
-template <class _Tp, class _Alloc>
-bool
-list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
-{
-    return false;
-}
-
-template <class _Tp, class _Alloc>
-bool
-list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
-{
-    return false;
-}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -2289,6 +2034,8 @@ operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -2329,6 +2076,17 @@ operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
     return !(__y < __x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Tp, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
+operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -2338,7 +2096,7 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
 erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) {
@@ -2358,15 +2116,15 @@ template <>
 inline constexpr bool __format::__enable_insertable<std::list<wchar_t>> = true;
 #endif
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _ValueT>
-using list = std::list<_ValueT, polymorphic_allocator<_ValueT>>;
+using list _LIBCPP_AVAILABILITY_PMR = std::list<_ValueT, polymorphic_allocator<_ValueT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
@@ -2377,9 +2135,11 @@ _LIBCPP_POP_MACROS
 #  include <algorithm>
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iosfwd>
 #  include <iterator>
+#  include <type_traits>
 #  include <typeinfo>
 #endif
 
lib/libcxx/include/locale
@@ -53,7 +53,7 @@ public:
     // locale operations:
     basic_string<char> name() const;
     bool operator==(const locale& other) const;
-    bool operator!=(const locale& other) const;
+    bool operator!=(const locale& other) const;                              // removed C++20
     template <class charT, class Traits, class Allocator>
       bool operator()(const basic_string<charT,Traits,Allocator>& s1,
                       const basic_string<charT,Traits,Allocator>& s2) const;
@@ -195,13 +195,14 @@ template <class charT> class messages_byname;
 #include <__algorithm/unwrap_iter.h>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <__iterator/access.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/istreambuf_iterator.h>
 #include <__iterator/ostreambuf_iterator.h>
 #include <__locale>
 #include <__memory/unique_ptr.h>
+#include <__type_traits/make_unsigned.h>
+#include <cerrno>
 #include <cstdio>
 #include <cstdlib>
 #include <ctime>
@@ -223,9 +224,9 @@ template <class charT> class messages_byname;
 #endif
 
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-#include <__bsd_locale_defaults.h>
+#  include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
 #else
-#include <__bsd_locale_fallbacks.h>
+#  include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -245,7 +246,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #else
 #  define _LIBCPP_GET_C_LOCALE __cloc()
    // Get the C locale object
-   _LIBCPP_FUNC_VIS locale_t __cloc();
+   _LIBCPP_EXPORTED_FROM_ABI  locale_t __cloc();
 #define __cloc_defined
 #endif
 
@@ -377,7 +378,7 @@ __scan_keyword(_InputIterator& __b, _InputIterator __e,
     return __kb;
 }
 
-struct _LIBCPP_TYPE_VIS __num_get_base
+struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base
 {
     static const int __num_get_buf_sz = 40;
 
@@ -385,8 +386,7 @@ struct _LIBCPP_TYPE_VIS __num_get_base
     static const char __src[33];
 };
 
-_LIBCPP_FUNC_VIS
-void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
+_LIBCPP_EXPORTED_FROM_ABI void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
                       ios_base::iostate& __err);
 
 template <class _CharT>
@@ -1126,7 +1126,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>;
 #endif
 
-struct _LIBCPP_TYPE_VIS __num_put_base
+struct _LIBCPP_EXPORTED_FROM_ABI __num_put_base
 {
 protected:
     static void __format_int(char* __fmt, const char* __len, bool __signd,
@@ -1464,12 +1464,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
         return do_put(__s, __iob, __fl, (unsigned long)__v);
     const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc());
     typedef typename numpunct<char_type>::string_type string_type;
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    string_type __tmp(__v ? __np.truename() : __np.falsename());
-    string_type __nm = _VSTD::move(__tmp);
-#else
     string_type __nm = __v ? __np.truename() : __np.falsename();
-#endif
     for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
         *__s = *__i;
     return __s;
@@ -1681,7 +1676,7 @@ __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
     return __r;
 }
 
-class _LIBCPP_TYPE_VIS time_base
+class _LIBCPP_EXPORTED_FROM_ABI time_base
 {
 public:
     enum dateorder {no_order, dmy, mdy, ymd, ydm};
@@ -1705,22 +1700,22 @@ protected:
     ~__time_get_c_storage() {}
 };
 
-template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const;
-template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const;
-template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const;
-template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const;
-template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const;
-template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const;
-template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
-template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const;
-template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
-template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const;
-template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const;
-template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const;
-template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const;
+template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const;
 #endif
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
@@ -2337,7 +2332,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;
 #endif
 
-class _LIBCPP_TYPE_VIS __time_get
+class _LIBCPP_EXPORTED_FROM_ABI __time_get
 {
 protected:
     locale_t __loc_;
@@ -2375,16 +2370,16 @@ private:
 };
 
 #define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
-template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
-template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
-template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
-template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
-template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
-extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
-extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
-extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
-extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
-extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+template <> _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
+template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
+template <> _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
+extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
+extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
 /**/
 
 _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
@@ -2432,7 +2427,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;
 #endif
 
-class _LIBCPP_TYPE_VIS __time_put
+class _LIBCPP_EXPORTED_FROM_ABI __time_put
 {
     locale_t __loc_;
 protected:
@@ -2572,7 +2567,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;
 
 // money_base
 
-class _LIBCPP_TYPE_VIS money_base
+class _LIBCPP_EXPORTED_FROM_ABI money_base
 {
 public:
     enum part {none, space, symbol, sign, value};
@@ -2686,14 +2681,14 @@ private:
     void init(const char*);
 };
 
-template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*);
-template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*);
+template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, false>::init(const char*);
+template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, true>::init(const char*);
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>;
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*);
-template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*);
+template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, false>::init(const char*);
+template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, true>::init(const char*);
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>;
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>;
 #endif
@@ -2810,7 +2805,7 @@ template <class _CharT, class _InputIterator>
 locale::id
 money_get<_CharT, _InputIterator>::id;
 
-_LIBCPP_FUNC_VIS void __do_nothing(void*);
+_LIBCPP_EXPORTED_FROM_ABI void __do_nothing(void*);
 
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI
@@ -3457,7 +3452,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>;
 
 // messages
 
-class _LIBCPP_TYPE_VIS messages_base
+class _LIBCPP_EXPORTED_FROM_ABI messages_base
 {
 public:
     typedef ptrdiff_t catalog;
@@ -3598,15 +3593,15 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
 #endif
 
 template<class _Codecvt, class _Elem = wchar_t,
-         class _Wide_alloc = allocator<_Elem>,
-         class _Byte_alloc = allocator<char> >
+         class _WideAlloc = allocator<_Elem>,
+         class _ByteAlloc = allocator<char> >
 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert
 {
 public:
-    typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
-    typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
-    typedef typename _Codecvt::state_type                        state_type;
-    typedef typename wide_string::traits_type::int_type          int_type;
+    typedef basic_string<char, char_traits<char>, _ByteAlloc>   byte_string;
+    typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string;
+    typedef typename _Codecvt::state_type                       state_type;
+    typedef typename wide_string::traits_type::int_type         int_type;
 
 private:
     byte_string __byte_err_string_;
@@ -3625,19 +3620,19 @@ public:
     explicit wstring_convert(_Codecvt* __pcvt);
 #else
     _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_EXPLICIT_AFTER_CXX11
+    _LIBCPP_EXPLICIT_SINCE_CXX14
     wstring_convert(_Codecvt* __pcvt = new _Codecvt);
 #endif
 
     _LIBCPP_INLINE_VISIBILITY
     wstring_convert(_Codecvt* __pcvt, state_type __state);
-    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
+    _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI wstring_convert(const byte_string& __byte_err,
                     const wide_string& __wide_err = wide_string());
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     wstring_convert(wstring_convert&& __wc);
 #endif
-    ~wstring_convert();
+    _LIBCPP_HIDE_FROM_ABI ~wstring_convert();
 
     _LIBCPP_INLINE_VISIBILITY
     wide_string from_bytes(char __byte)
@@ -3648,7 +3643,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     wide_string from_bytes(const byte_string& __str)
         {return from_bytes(__str.data(), __str.data() + __str.size());}
-    wide_string from_bytes(const char* __first, const char* __last);
+    _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);
 
     _LIBCPP_INLINE_VISIBILITY
     byte_string to_bytes(_Elem __wchar)
@@ -3659,7 +3654,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     byte_string to_bytes(const wide_string& __wstr)
         {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
-    byte_string to_bytes(const _Elem* __first, const _Elem* __last);
+    _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);
 
     _LIBCPP_INLINE_VISIBILITY
     size_t converted() const _NOEXCEPT {return __cvtcount_;}
@@ -3668,25 +3663,25 @@ public:
 };
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
 inline
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     wstring_convert(_Codecvt* __pcvt)
         : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
 {
 }
 _LIBCPP_SUPPRESS_DEPRECATED_POP
 
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
 inline
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     wstring_convert(_Codecvt* __pcvt, state_type __state)
         : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
 {
 }
 
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
         : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
           __cvtstate_(), __cvtcount_(0)
@@ -3696,9 +3691,9 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
 #ifndef _LIBCPP_CXX03_LANG
 
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
 inline
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     wstring_convert(wstring_convert&& __wc)
         : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
           __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
@@ -3711,15 +3706,15 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 #endif // _LIBCPP_CXX03_LANG
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert()
 {
     delete __cvtptr_;
 }
 
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
+typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     from_bytes(const char* __frm, const char* __frm_end)
 {
 _LIBCPP_SUPPRESS_DEPRECATED_POP
@@ -3779,9 +3774,9 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
     return __wide_err_string_;
 }
 
-template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
-wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
+typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string
+wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
     to_bytes(const _Elem* __frm, const _Elem* __frm_end)
 {
     __cvtcount_ = 0;
@@ -3902,18 +3897,18 @@ private:
 
 public:
 #ifndef _LIBCPP_CXX03_LANG
-    wbuffer_convert() : wbuffer_convert(nullptr) {}
-    explicit wbuffer_convert(streambuf* __bytebuf,
+    _LIBCPP_HIDE_FROM_ABI wbuffer_convert() : wbuffer_convert(nullptr) {}
+    explicit _LIBCPP_HIDE_FROM_ABI wbuffer_convert(streambuf* __bytebuf,
                              _Codecvt* __pcvt = new _Codecvt,
                              state_type __state = state_type());
 #else
-    _LIBCPP_EXPLICIT_AFTER_CXX11
+    _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
     wbuffer_convert(streambuf* __bytebuf = nullptr,
                     _Codecvt* __pcvt = new _Codecvt,
                     state_type __state = state_type());
 #endif
 
-    ~wbuffer_convert();
+    _LIBCPP_HIDE_FROM_ABI ~wbuffer_convert();
 
     _LIBCPP_INLINE_VISIBILITY
     streambuf* rdbuf() const {return __bufptr_;}
@@ -3929,21 +3924,21 @@ public:
     state_type state() const {return __st_;}
 
 protected:
-    virtual int_type underflow();
-    virtual int_type pbackfail(int_type __c = traits_type::eof());
-    virtual int_type overflow (int_type __c = traits_type::eof());
-    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type pbackfail(int_type __c = traits_type::eof());
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type overflow (int_type __c = traits_type::eof());
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
                                                             streamsize __n);
-    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
                              ios_base::openmode __wch = ios_base::in | ios_base::out);
-    virtual pos_type seekpos(pos_type __sp,
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekpos(pos_type __sp,
                              ios_base::openmode __wch = ios_base::in | ios_base::out);
-    virtual int sync();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int sync();
 
 private:
-    bool __read_mode();
-    void __write_mode();
-    wbuffer_convert* __close();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool __read_mode();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __write_mode();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL wbuffer_convert* __close();
 };
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
@@ -4009,8 +4004,8 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
         else
         {
              if (__extbufend_ != __extbufnext_) {
-                _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr");
-                _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr");
+                _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
+                _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
                 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
              }
             __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
lib/libcxx/include/map
@@ -70,6 +70,8 @@ public:
     template <class InputIterator>
         map(InputIterator first, InputIterator last,
             const key_compare& comp, const allocator_type& a);
+    template<container-compatible-range<value_type> R>
+      map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
     map(const map& m);
     map(map&& m)
         noexcept(
@@ -83,6 +85,9 @@ public:
     template <class InputIterator>
         map(InputIterator first, InputIterator last, const allocator_type& a)
             : map(first, last, Compare(), a) {}  // C++14
+    template<container-compatible-range<value_type> R>
+      map(from_range_t, R&& rg, const Allocator& a))
+        : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
     map(initializer_list<value_type> il, const allocator_type& a)
         : map(il, Compare(), a) {}  // C++14
    ~map();
@@ -138,6 +143,8 @@ public:
         iterator insert(const_iterator position, P&& p);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                                      // C++23
     void insert(initializer_list<value_type> il);
 
     node_type extract(const_iterator position);                                       // C++17
@@ -229,6 +236,11 @@ template <class InputIterator,
 map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
   -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
 
+template<ranges::input_range R, class Compare = less<range-key-type<R>,
+         class Allocator = allocator<range-to-alloc-type<R>>>
+  map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
+    -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
+
 template<class Key, class T, class Compare = less<Key>,
     class Allocator = allocator<pair<const Key, T>>>
 map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
@@ -239,6 +251,10 @@ map(InputIterator, InputIterator, Allocator)
   -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
     Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  map(from_range_t, R&&, Allocator)
+    -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
+
 template<class Key, class T, class Allocator>
 map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17
 
@@ -250,27 +266,32 @@ operator==(const map<Key, T, Compare, Allocator>& x,
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator< (const map<Key, T, Compare, Allocator>& x,
-           const map<Key, T, Compare, Allocator>& y);
+           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator!=(const map<Key, T, Compare, Allocator>& x,
-           const map<Key, T, Compare, Allocator>& y);
+           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator> (const map<Key, T, Compare, Allocator>& x,
-           const map<Key, T, Compare, Allocator>& y);
+           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator>=(const map<Key, T, Compare, Allocator>& x,
-           const map<Key, T, Compare, Allocator>& y);
+           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator<=(const map<Key, T, Compare, Allocator>& x,
-           const map<Key, T, Compare, Allocator>& y);
+           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
+
+template<class Key, class T, class Compare, class Allocator>
+  synth-three-way-result<pair<const Key, T>>
+    operator<=>(const map<Key, T, Compare, Allocator>& x,
+                const map<Key, T, Compare, Allocator>& y); // since C++20
 
 // specialized algorithms:
 template <class Key, class T, class Compare, class Allocator>
@@ -333,6 +354,9 @@ public:
     template <class InputIterator>
         multimap(InputIterator first, InputIterator last, const key_compare& comp,
                  const allocator_type& a);
+    template<container-compatible-range<value_type> R>
+      multimap(from_range_t, R&& rg,
+               const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
     multimap(const multimap& m);
     multimap(multimap&& m)
         noexcept(
@@ -347,6 +371,9 @@ public:
     template <class InputIterator>
         multimap(InputIterator first, InputIterator last, const allocator_type& a)
             : multimap(first, last, Compare(), a) {} // C++14
+    template<container-compatible-range<value_type> R>
+      multimap(from_range_t, R&& rg, const Allocator& a))
+        : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
     multimap(initializer_list<value_type> il, const allocator_type& a)
         : multimap(il, Compare(), a) {} // C++14
     ~multimap();
@@ -395,6 +422,8 @@ public:
         iterator insert(const_iterator position, P&& p);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                                      // C++23
     void insert(initializer_list<value_type> il);
 
     node_type extract(const_iterator position);                                       // C++17
@@ -469,6 +498,11 @@ template <class InputIterator,
 multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
   -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
 
+template<ranges::input_range R, class Compare = less<range-key-type<R>>,
+          class Allocator = allocator<range-to-alloc-type<R>>>
+  multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
+    -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
+
 template<class Key, class T, class Compare = less<Key>,
     class Allocator = allocator<pair<const Key, T>>>
 multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
@@ -479,6 +513,10 @@ multimap(InputIterator, InputIterator, Allocator)
   -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
     less<iter_key_t<InputIterator>>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  multimap(from_range_t, R&&, Allocator)
+    -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
+
 template<class Key, class T, class Allocator>
 multimap(initializer_list<pair<const Key, T>>, Allocator)
   -> multimap<Key, T, less<Key>, Allocator>; // C++17
@@ -491,27 +529,32 @@ operator==(const multimap<Key, T, Compare, Allocator>& x,
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator< (const multimap<Key, T, Compare, Allocator>& x,
-           const multimap<Key, T, Compare, Allocator>& y);
+           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator!=(const multimap<Key, T, Compare, Allocator>& x,
-           const multimap<Key, T, Compare, Allocator>& y);
+           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator> (const multimap<Key, T, Compare, Allocator>& x,
-           const multimap<Key, T, Compare, Allocator>& y);
+           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator>=(const multimap<Key, T, Compare, Allocator>& x,
-           const multimap<Key, T, Compare, Allocator>& y);
+           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
 
 template <class Key, class T, class Compare, class Allocator>
 bool
 operator<=(const multimap<Key, T, Compare, Allocator>& x,
-           const multimap<Key, T, Compare, Allocator>& y);
+           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
+
+template<class Key, class T, class Compare, class Allocator>
+  synth-three-way-result<pair<const Key, T>>
+    operator<=>(const multimap<Key, T, Compare, Allocator>& x,
+                const multimap<Key, T, Compare, Allocator>& y); // since c++20
 
 // specialized algorithms:
 template <class Key, class T, class Compare, class Allocator>
@@ -530,24 +573,30 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
 
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
 #include <__functional/binary_function.h>
 #include <__functional/is_transparent.h>
 #include <__functional/operations.h>
 #include <__iterator/erase_if_container.h>
 #include <__iterator/iterator_traits.h>
+#include <__iterator/ranges_iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator.h>
 #include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
 #include <__tree>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
 #include <__utility/piecewise_construct.h>
 #include <__utility/swap.h>
 #include <tuple>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -594,14 +643,14 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _CP& __y) const
         {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
-    void swap(__map_value_compare& __y)
+    _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y)
         _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
     {
       using _VSTD::swap;
       swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
     }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _K2& __x, const _CP& __y) const
@@ -647,7 +696,7 @@ public:
         swap(__comp_, __y.__comp_);
     }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _K2& __x, const _CP& __y) const
@@ -742,7 +791,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     value_type& __get_value()
     {
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         return *_VSTD::launder(_VSTD::addressof(__cc_));
 #else
         return __cc_;
@@ -752,7 +801,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const value_type& __get_value() const
     {
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         return *_VSTD::launder(_VSTD::addressof(__cc_));
 #else
         return __cc_;
@@ -1020,7 +1069,7 @@ public:
     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
     typedef __insert_return_type<iterator, node_type> insert_return_type;
 #endif
@@ -1067,13 +1116,30 @@ public:
             insert(__f, __l);
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    map(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
+        const allocator_type& __a = allocator_type())
+      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 14
     template <class _InputIterator>
     _LIBCPP_INLINE_VISIBILITY
     map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
         : map(__f, __l, key_compare(), __a) {}
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    map(from_range_t, _Range&& __range, const allocator_type& __a)
+      : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     map(const map& __m)
         : __tree_(__m.__tree_)
@@ -1106,7 +1172,7 @@ public:
         {
         }
 
-    map(map&& __m, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
 
     _LIBCPP_INLINE_VISIBILITY
     map& operator=(map&& __m)
@@ -1130,7 +1196,7 @@ public:
             insert(__il.begin(), __il.end());
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     map(initializer_list<value_type> __il, const allocator_type& __a)
         : map(__il, key_compare(), __a) {}
@@ -1200,13 +1266,13 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
 
-    mapped_type& operator[](const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
 #ifndef _LIBCPP_CXX03_LANG
-    mapped_type& operator[](key_type&& __k);
+    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
 #endif
 
-          mapped_type& at(const key_type& __k);
-    const mapped_type& at(const key_type& __k) const;
+    _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
@@ -1273,7 +1339,18 @@ public:
                 insert(__e.__i_, *__f);
         }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      const_iterator __end = cend();
+      for (auto&& __element : __range) {
+        insert(__end.__i_, std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 17
 
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
@@ -1367,7 +1444,7 @@ public:
       return __r;
     }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
     _LIBCPP_INLINE_VISIBILITY
     iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
@@ -1382,11 +1459,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {__tree_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     insert_return_type insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to map::insert()");
         return __tree_.template __node_handle_insert_unique<
             node_type, insert_return_type>(_VSTD::move(__nh));
@@ -1394,7 +1471,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to map::insert()");
         return __tree_.template __node_handle_insert_unique<node_type>(
             __hint.__i_, _VSTD::move(__nh));
@@ -1413,32 +1490,32 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
 #endif
@@ -1452,7 +1529,7 @@ public:
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -1466,21 +1543,21 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_unique(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
     count(const _K2& __k) const {return __tree_.__count_multi(__k);}
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
     contains(const _K2& __k) const { return find(__k) != end(); }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     iterator lower_bound(const key_type& __k)
@@ -1488,7 +1565,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
         {return __tree_.lower_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -1506,7 +1583,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
         {return __tree_.upper_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -1523,7 +1600,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
         {return __tree_.__equal_range_unique(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
@@ -1545,19 +1622,28 @@ private:
     typedef unique_ptr<__node, _Dp> __node_holder;
 
 #ifdef _LIBCPP_CXX03_LANG
-    __node_holder __construct_node_with_key(const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
 #endif
 };
 
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
   -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
+          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
+          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
+  -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
+#endif
+
 template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
          class _Allocator = allocator<pair<const _Key, _Tp>>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
@@ -1566,12 +1652,19 @@ map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allo
   -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 map(_InputIterator, _InputIterator, _Allocator)
   -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
          less<__iter_key_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+map(from_range_t, _Range&&, _Allocator)
+  -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
+#endif
+
 template<class _Key, class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 map(initializer_list<pair<_Key, _Tp>>, _Allocator)
@@ -1677,6 +1770,8 @@ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1722,6 +1817,21 @@ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
     return !(__y < __x);
 }
 
+#else // #if _LIBCPP_STD_VER <= 17
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
+operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(),
+        __x.end(),
+        __y.begin(),
+        __y.end(),
+        std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
+}
+
+#endif // #if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -1732,7 +1842,7 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Tp, class _Compare, class _Allocator,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1800,7 +1910,7 @@ public:
     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
 #endif
 
@@ -1846,13 +1956,30 @@ public:
             insert(__f, __l);
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    multimap(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
+        const allocator_type& __a = allocator_type())
+      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 14
     template <class _InputIterator>
     _LIBCPP_INLINE_VISIBILITY
     multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
         : multimap(__f, __l, key_compare(), __a) {}
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    multimap(from_range_t, _Range&& __range, const allocator_type& __a)
+      : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     multimap(const multimap& __m)
         : __tree_(__m.__tree_.value_comp(),
@@ -1886,7 +2013,7 @@ public:
         {
         }
 
-    multimap(multimap&& __m, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
 
     _LIBCPP_INLINE_VISIBILITY
     multimap& operator=(multimap&& __m)
@@ -1910,7 +2037,7 @@ public:
             insert(__il.begin(), __il.end());
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     multimap(initializer_list<value_type> __il, const allocator_type& __a)
         : multimap(__il, key_compare(), __a) {}
@@ -2043,6 +2170,17 @@ public:
                 __tree_.__insert_multi(__e.__i_, *__f);
         }
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      const_iterator __end = cend();
+      for (auto&& __element : __range) {
+        __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
     _LIBCPP_INLINE_VISIBILITY
@@ -2053,11 +2191,11 @@ public:
     iterator  erase(const_iterator __f, const_iterator __l)
         {return __tree_.erase(__f.__i_, __l.__i_);}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to multimap::insert()");
         return __tree_.template __node_handle_insert_multi<node_type>(
             _VSTD::move(__nh));
@@ -2065,7 +2203,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to multimap::insert()");
         return __tree_.template __node_handle_insert_multi<node_type>(
             __hint.__i_, _VSTD::move(__nh));
@@ -2085,32 +2223,32 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __tree_.__node_handle_merge_multi(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __tree_.__node_handle_merge_multi(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __tree_.__node_handle_merge_multi(__source.__tree_);
     }
     template <class _Compare2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __tree_.__node_handle_merge_multi(__source.__tree_);
     }
 #endif
@@ -2127,7 +2265,7 @@ public:
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -2141,21 +2279,21 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_multi(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
     count(const _K2& __k) const {return __tree_.__count_multi(__k);}
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
     contains(const _K2& __k) const { return find(__k) != end(); }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     iterator lower_bound(const key_type& __k)
@@ -2163,7 +2301,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
             {return __tree_.lower_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -2181,7 +2319,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
             {return __tree_.upper_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
@@ -2198,7 +2336,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
             {return __tree_.__equal_range_multi(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
@@ -2221,12 +2359,21 @@ private:
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
   -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
+          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
+          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
+  -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
+#endif
+
 template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
          class _Allocator = allocator<pair<const _Key, _Tp>>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
@@ -2235,12 +2382,19 @@ multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator =
   -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 multimap(_InputIterator, _InputIterator, _Allocator)
   -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
          less<__iter_key_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+multimap(from_range_t, _Range&&, _Allocator)
+  -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
+#endif
+
 template<class _Key, class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
@@ -2271,6 +2425,8 @@ operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -2316,6 +2472,22 @@ operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
     return !(__y < __x);
 }
 
+#else // #if _LIBCPP_STD_VER <= 17
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
+operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+            const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(),
+        __x.end(),
+        __y.begin(),
+        __y.end(),
+        std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
+}
+
+#endif // #if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -2326,7 +2498,7 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Tp, class _Compare, class _Allocator,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -2339,22 +2511,24 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
-using map = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+using map _LIBCPP_AVAILABILITY_PMR = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
 
 template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
-using multimap = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+using multimap _LIBCPP_AVAILABILITY_PMR = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iterator>
+#  include <type_traits>
 #  include <utility>
 #endif
 
lib/libcxx/include/math.h
@@ -554,7 +554,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2
 
 // acos
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       acos(float __x) _NOEXCEPT       {return __builtin_acosf(__x);}
 
 template <class = int>
@@ -563,7 +562,6 @@ _LIBCPP_HIDE_FROM_ABI double acos(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double acos(long double __x) _NOEXCEPT {return __builtin_acosl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -572,7 +570,6 @@ acos(_A1 __x) _NOEXCEPT {return __builtin_acos((double)__x);}
 
 // asin
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       asin(float __x) _NOEXCEPT       {return __builtin_asinf(__x);}
 
 template <class = int>
@@ -581,7 +578,6 @@ _LIBCPP_HIDE_FROM_ABI double asin(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double asin(long double __x) _NOEXCEPT {return __builtin_asinl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -590,7 +586,6 @@ asin(_A1 __x) _NOEXCEPT {return __builtin_asin((double)__x);}
 
 // atan
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       atan(float __x) _NOEXCEPT       {return __builtin_atanf(__x);}
 
 template <class = int>
@@ -599,7 +594,6 @@ _LIBCPP_HIDE_FROM_ABI double atan(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double atan(long double __x) _NOEXCEPT {return __builtin_atanl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -608,7 +602,6 @@ atan(_A1 __x) _NOEXCEPT {return __builtin_atan((double)__x);}
 
 // atan2
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       atan2(float __y, float __x) _NOEXCEPT             {return __builtin_atan2f(__y, __x);}
 
 template <class = int>
@@ -617,7 +610,6 @@ _LIBCPP_HIDE_FROM_ABI double atan2(double __x, double __y) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double atan2(long double __y, long double __x) _NOEXCEPT {return __builtin_atan2l(__y, __x);}
-#    endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -637,7 +629,6 @@ atan2(_A1 __y, _A2 __x) _NOEXCEPT
 
 // ceil
 
-#    if !defined(__sun__)
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float       ceil(float __x) _NOEXCEPT       {return __builtin_ceilf(__x);}
 
 template <class = int>
@@ -646,7 +637,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT {
 }
 
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);}
-#    endif
 
 template <class _A1>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
@@ -655,7 +645,6 @@ ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);}
 
 // cos
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       cos(float __x) _NOEXCEPT       {return __builtin_cosf(__x);}
 
 template <class = int>
@@ -664,7 +653,6 @@ _LIBCPP_HIDE_FROM_ABI double cos(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double cos(long double __x) _NOEXCEPT {return __builtin_cosl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -673,7 +661,6 @@ cos(_A1 __x) _NOEXCEPT {return __builtin_cos((double)__x);}
 
 // cosh
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       cosh(float __x) _NOEXCEPT       {return __builtin_coshf(__x);}
 
 template <class = int>
@@ -682,7 +669,6 @@ _LIBCPP_HIDE_FROM_ABI double cosh(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double cosh(long double __x) _NOEXCEPT {return __builtin_coshl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -691,7 +677,6 @@ cosh(_A1 __x) _NOEXCEPT {return __builtin_cosh((double)__x);}
 
 // exp
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       exp(float __x) _NOEXCEPT       {return __builtin_expf(__x);}
 
 template <class = int>
@@ -700,7 +685,6 @@ _LIBCPP_HIDE_FROM_ABI double exp(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double exp(long double __x) _NOEXCEPT {return __builtin_expl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -709,7 +693,6 @@ exp(_A1 __x) _NOEXCEPT {return __builtin_exp((double)__x);}
 
 // fabs
 
-#    if !defined(__sun__)
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float       fabs(float __x) _NOEXCEPT       {return __builtin_fabsf(__x);}
 
 template <class = int>
@@ -718,7 +701,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT {
 }
 
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);}
-#    endif
 
 template <class _A1>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
@@ -727,7 +709,6 @@ fabs(_A1 __x) _NOEXCEPT {return __builtin_fabs((double)__x);}
 
 // floor
 
-#    if !defined(__sun__)
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float       floor(float __x) _NOEXCEPT       {return __builtin_floorf(__x);}
 
 template <class = int>
@@ -736,7 +717,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT {
 }
 
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);}
-#    endif
 
 template <class _A1>
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
@@ -745,7 +725,6 @@ floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);}
 
 // fmod
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       fmod(float __x, float __y) _NOEXCEPT             {return __builtin_fmodf(__x, __y);}
 
 template <class = int>
@@ -754,7 +733,6 @@ _LIBCPP_HIDE_FROM_ABI double fmod(double __x, double __y) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double fmod(long double __x, long double __y) _NOEXCEPT {return __builtin_fmodl(__x, __y);}
-#    endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -774,7 +752,6 @@ fmod(_A1 __x, _A2 __y) _NOEXCEPT
 
 // frexp
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       frexp(float __x, int* __e) _NOEXCEPT       {return __builtin_frexpf(__x, __e);}
 
 template <class = int>
@@ -783,7 +760,6 @@ _LIBCPP_HIDE_FROM_ABI double frexp(double __x, int* __e) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double frexp(long double __x, int* __e) _NOEXCEPT {return __builtin_frexpl(__x, __e);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -792,7 +768,6 @@ frexp(_A1 __x, int* __e) _NOEXCEPT {return __builtin_frexp((double)__x, __e);}
 
 // ldexp
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       ldexp(float __x, int __e) _NOEXCEPT       {return __builtin_ldexpf(__x, __e);}
 
 template <class = int>
@@ -801,7 +776,6 @@ _LIBCPP_HIDE_FROM_ABI double ldexp(double __x, int __e) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double ldexp(long double __x, int __e) _NOEXCEPT {return __builtin_ldexpl(__x, __e);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -810,7 +784,6 @@ ldexp(_A1 __x, int __e) _NOEXCEPT {return __builtin_ldexp((double)__x, __e);}
 
 // log
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       log(float __x) _NOEXCEPT       {return __builtin_logf(__x);}
 
 template <class = int>
@@ -819,7 +792,6 @@ _LIBCPP_HIDE_FROM_ABI double log(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double log(long double __x) _NOEXCEPT {return __builtin_logl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -828,7 +800,6 @@ log(_A1 __x) _NOEXCEPT {return __builtin_log((double)__x);}
 
 // log10
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       log10(float __x) _NOEXCEPT       {return __builtin_log10f(__x);}
 
 
@@ -838,7 +809,6 @@ _LIBCPP_HIDE_FROM_ABI double log10(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double log10(long double __x) _NOEXCEPT {return __builtin_log10l(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -847,7 +817,6 @@ log10(_A1 __x) _NOEXCEPT {return __builtin_log10((double)__x);}
 
 // modf
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       modf(float __x, float* __y) _NOEXCEPT             {return __builtin_modff(__x, __y);}
 
 template <class = int>
@@ -856,11 +825,9 @@ _LIBCPP_HIDE_FROM_ABI double modf(double __x, double* __y) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y) _NOEXCEPT {return __builtin_modfl(__x, __y);}
-#    endif
 
 // pow
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       pow(float __x, float __y) _NOEXCEPT             {return __builtin_powf(__x, __y);}
 
 template <class = int>
@@ -869,7 +836,6 @@ _LIBCPP_HIDE_FROM_ABI double pow(double __x, double __y) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double pow(long double __x, long double __y) _NOEXCEPT {return __builtin_powl(__x, __y);}
-#    endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -889,7 +855,6 @@ pow(_A1 __x, _A2 __y) _NOEXCEPT
 
 // sin
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       sin(float __x) _NOEXCEPT       {return __builtin_sinf(__x);}
 
 template <class = int>
@@ -898,7 +863,6 @@ _LIBCPP_HIDE_FROM_ABI double sin(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double sin(long double __x) _NOEXCEPT {return __builtin_sinl(__x);}
-#endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -907,7 +871,6 @@ sin(_A1 __x) _NOEXCEPT {return __builtin_sin((double)__x);}
 
 // sinh
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       sinh(float __x) _NOEXCEPT       {return __builtin_sinhf(__x);}
 
 template <class = int>
@@ -916,7 +879,6 @@ _LIBCPP_HIDE_FROM_ABI double sinh(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double sinh(long double __x) _NOEXCEPT {return __builtin_sinhl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -925,7 +887,6 @@ sinh(_A1 __x) _NOEXCEPT {return __builtin_sinh((double)__x);}
 
 // sqrt
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       sqrt(float __x) _NOEXCEPT       {return __builtin_sqrtf(__x);}
 
 template <class = int>
@@ -934,7 +895,6 @@ _LIBCPP_HIDE_FROM_ABI double sqrt(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double sqrt(long double __x) _NOEXCEPT {return __builtin_sqrtl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -943,7 +903,6 @@ sqrt(_A1 __x) _NOEXCEPT {return __builtin_sqrt((double)__x);}
 
 // tan
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       tan(float __x) _NOEXCEPT       {return __builtin_tanf(__x);}
 
 template <class = int>
@@ -952,7 +911,6 @@ _LIBCPP_HIDE_FROM_ABI double tan(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double tan(long double __x) _NOEXCEPT {return __builtin_tanl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -961,7 +919,6 @@ tan(_A1 __x) _NOEXCEPT {return __builtin_tan((double)__x);}
 
 // tanh
 
-#    if !defined(__sun__)
 inline _LIBCPP_HIDE_FROM_ABI float       tanh(float __x) _NOEXCEPT       {return __builtin_tanhf(__x);}
 
 template <class = int>
@@ -970,7 +927,6 @@ _LIBCPP_HIDE_FROM_ABI double tanh(double __x) _NOEXCEPT {
 }
 
 inline _LIBCPP_HIDE_FROM_ABI long double tanh(long double __x) _NOEXCEPT {return __builtin_tanhl(__x);}
-#    endif
 
 template <class _A1>
 inline _LIBCPP_HIDE_FROM_ABI
lib/libcxx/include/mdspan
@@ -0,0 +1,357 @@
+// -*-C++ - *-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+
+/*
+
+// Overall mdspan synopsis
+
+namespace std {
+  // [mdspan.extents], class template extents
+  template<class IndexType, size_t... Extents>
+    class extents;
+
+  // [mdspan.extents.dextents], alias template dextents
+  template<class IndexType, size_t Rank>
+    using dextents = see below;
+
+  // [mdspan.layout], layout mapping
+  struct layout_left;
+  struct layout_right;
+  struct layout_stride; // not implemented yet
+
+  // [mdspan.accessor.default], class template default_accessor
+  template<class ElementType>
+    class default_accessor;
+
+  // [mdspan.mdspan], class template mdspan
+  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
+           class AccessorPolicy = default_accessor<ElementType>>
+    class mdspan; // not implemented yet
+}
+
+// extents synopsis
+
+namespace std {
+  template<class _IndexType, size_t... _Extents>
+  class extents {
+  public:
+    using index_type = _IndexType;
+    using size_type = make_unsigned_t<index_type>;
+    using rank_type = size_t;
+
+    // [mdspan.extents.obs], observers of the multidimensional index space
+    static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
+    static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
+    static constexpr size_t static_extent(rank_type) noexcept;
+    constexpr index_type extent(rank_type) const noexcept;
+
+    // [mdspan.extents.cons], constructors
+    constexpr extents() noexcept = default;
+
+    template<class _OtherIndexType, size_t... _OtherExtents>
+      constexpr explicit(see below)
+        extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
+    template<class... _OtherIndexTypes>
+      constexpr explicit extents(_OtherIndexTypes...) noexcept;
+    template<class _OtherIndexType, size_t N>
+      constexpr explicit(N != rank_dynamic())
+        extents(span<_OtherIndexType, N>) noexcept;
+    template<class _OtherIndexType, size_t N>
+      constexpr explicit(N != rank_dynamic())
+        extents(const array<_OtherIndexType, N>&) noexcept;
+
+    // [mdspan.extents.cmp], comparison operators
+    template<class _OtherIndexType, size_t... _OtherExtents>
+      friend constexpr bool operator==(const extents&,
+                                       const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
+
+  private:
+    // libcxx note: we do not use an array here, but we need to preserve the as-if behavior
+    // for example the default constructor must zero initialize dynamic extents
+    array<index_type, rank_dynamic()> dynamic-extents{};                // exposition only
+  };
+
+  template<class... Integrals>
+    explicit extents(Integrals...)
+      -> see below;
+}
+
+// layout_left synopsis
+
+namespace std {
+  template<class Extents>
+  class layout_left::mapping {
+  public:
+    using extents_type = Extents;
+    using index_type = typename extents_type::index_type;
+    using size_type = typename extents_type::size_type;
+    using rank_type = typename extents_type::rank_type;
+    using layout_type = layout_left;
+
+    // [mdspan.layout.right.cons], constructors
+    constexpr mapping() noexcept = default;
+    constexpr mapping(const mapping&) noexcept = default;
+    constexpr mapping(const extents_type&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+        mapping(const mapping<OtherExtents>&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+        mapping(const layout_right::mapping<OtherExtents>&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(extents_type::rank() > 0)
+        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
+
+    constexpr mapping& operator=(const mapping&) noexcept = default;
+
+    // [mdspan.layout.right.obs], observers
+    constexpr const extents_type& extents() const noexcept { return extents_; }
+
+    constexpr index_type required_span_size() const noexcept;
+
+    template<class... Indices>
+      constexpr index_type operator()(Indices...) const noexcept;
+
+    static constexpr bool is_always_unique() noexcept { return true; }
+    static constexpr bool is_always_exhaustive() noexcept { return true; }
+    static constexpr bool is_always_strided() noexcept { return true; }
+
+    static constexpr bool is_unique() noexcept { return true; }
+    static constexpr bool is_exhaustive() noexcept { return true; }
+    static constexpr bool is_strided() noexcept { return true; }
+
+    constexpr index_type stride(rank_type) const noexcept;
+
+    template<class OtherExtents>
+      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
+
+  private:
+    extents_type extents_{};    // exposition only
+  };
+}
+
+// layout_right synopsis
+
+namespace std {
+  template<class Extents>
+  class layout_right::mapping {
+  public:
+    using extents_type = Extents;
+    using index_type = typename extents_type::index_type;
+    using size_type = typename extents_type::size_type;
+    using rank_type = typename extents_type::rank_type;
+    using layout_type = layout_right;
+
+    // [mdspan.layout.right.cons], constructors
+    constexpr mapping() noexcept = default;
+    constexpr mapping(const mapping&) noexcept = default;
+    constexpr mapping(const extents_type&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+        mapping(const mapping<OtherExtents>&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+        mapping(const layout_left::mapping<OtherExtents>&) noexcept;
+    template<class OtherExtents>
+      constexpr explicit(extents_type::rank() > 0)
+        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
+
+    constexpr mapping& operator=(const mapping&) noexcept = default;
+
+    // [mdspan.layout.right.obs], observers
+    constexpr const extents_type& extents() const noexcept { return extents_; }
+
+    constexpr index_type required_span_size() const noexcept;
+
+    template<class... Indices>
+      constexpr index_type operator()(Indices...) const noexcept;
+
+    static constexpr bool is_always_unique() noexcept { return true; }
+    static constexpr bool is_always_exhaustive() noexcept { return true; }
+    static constexpr bool is_always_strided() noexcept { return true; }
+
+    static constexpr bool is_unique() noexcept { return true; }
+    static constexpr bool is_exhaustive() noexcept { return true; }
+    static constexpr bool is_strided() noexcept { return true; }
+
+    constexpr index_type stride(rank_type) const noexcept;
+
+    template<class OtherExtents>
+      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
+
+  private:
+    extents_type extents_{};    // exposition only
+  };
+}
+
+// default_accessor synopsis
+
+namespace std {
+  template<class ElementType>
+  struct default_accessor {
+    using offset_policy = default_accessor;
+    using element_type = ElementType;
+    using reference = ElementType&;
+    using data_handle_type = ElementType*;
+
+    constexpr default_accessor() noexcept = default;
+    template<class OtherElementType>
+      constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
+    constexpr reference access(data_handle_type p, size_t i) const noexcept;
+    constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
+  };
+}
+
+// mdspan synopsis
+
+namespace std {
+  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
+           class AccessorPolicy = default_accessor<ElementType>>
+  class mdspan {
+  public:
+    using extents_type = Extents;
+    using layout_type = LayoutPolicy;
+    using accessor_type = AccessorPolicy;
+    using mapping_type = typename layout_type::template mapping<extents_type>;
+    using element_type = ElementType;
+    using value_type = remove_cv_t<element_type>;
+    using index_type = typename extents_type::index_type;
+    using size_type = typename extents_type::size_type;
+    using rank_type = typename extents_type::rank_type;
+    using data_handle_type = typename accessor_type::data_handle_type;
+    using reference = typename accessor_type::reference;
+
+    static constexpr rank_type rank() noexcept { return extents_type::rank(); }
+    static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
+    static constexpr size_t static_extent(rank_type r) noexcept
+      { return extents_type::static_extent(r); }
+    constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
+
+    // [mdspan.mdspan.cons], constructors
+    constexpr mdspan();
+    constexpr mdspan(const mdspan& rhs) = default;
+    constexpr mdspan(mdspan&& rhs) = default;
+
+    template<class... OtherIndexTypes>
+      constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
+    template<class OtherIndexType, size_t N>
+      constexpr explicit(N != rank_dynamic())
+        mdspan(data_handle_type p, span<OtherIndexType, N> exts);
+    template<class OtherIndexType, size_t N>
+      constexpr explicit(N != rank_dynamic())
+        mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
+    constexpr mdspan(data_handle_type p, const extents_type& ext);
+    constexpr mdspan(data_handle_type p, const mapping_type& m);
+    constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
+
+    template<class OtherElementType, class OtherExtents,
+             class OtherLayoutPolicy, class OtherAccessorPolicy>
+      constexpr explicit(see below)
+        mdspan(const mdspan<OtherElementType, OtherExtents,
+                            OtherLayoutPolicy, OtherAccessorPolicy>& other);
+
+    constexpr mdspan& operator=(const mdspan& rhs) = default;
+    constexpr mdspan& operator=(mdspan&& rhs) = default;
+
+    // [mdspan.mdspan.members], members
+    template<class... OtherIndexTypes>
+      constexpr reference operator[](OtherIndexTypes... indices) const;
+    template<class OtherIndexType>
+      constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
+    template<class OtherIndexType>
+      constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
+
+    constexpr size_type size() const noexcept;
+    [[nodiscard]] constexpr bool empty() const noexcept;
+
+    friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
+
+    constexpr const extents_type& extents() const noexcept { return map_.extents(); }
+    constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
+    constexpr const mapping_type& mapping() const noexcept { return map_; }
+    constexpr const accessor_type& accessor() const noexcept { return acc_; }
+
+    static constexpr bool is_always_unique()
+      { return mapping_type::is_always_unique(); }
+    static constexpr bool is_always_exhaustive()
+      { return mapping_type::is_always_exhaustive(); }
+    static constexpr bool is_always_strided()
+      { return mapping_type::is_always_strided(); }
+
+    constexpr bool is_unique() const
+      { return map_.is_unique(); }
+    constexpr bool is_exhaustive() const
+      { return map_.is_exhaustive(); }
+    constexpr bool is_strided() const
+      { return map_.is_strided(); }
+    constexpr index_type stride(rank_type r) const
+      { return map_.stride(r); }
+
+  private:
+    accessor_type acc_;         // exposition only
+    mapping_type map_;          // exposition only
+    data_handle_type ptr_;      // exposition only
+  };
+
+  template<class CArray>
+    requires(is_array_v<CArray> && rank_v<CArray> == 1)
+    mdspan(CArray&)
+      -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
+
+  template<class Pointer>
+    requires(is_pointer_v<remove_reference_t<Pointer>>)
+    mdspan(Pointer&&)
+      -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
+
+  template<class ElementType, class... Integrals>
+    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
+    explicit mdspan(ElementType*, Integrals...)
+      -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
+
+  template<class ElementType, class OtherIndexType, size_t N>
+    mdspan(ElementType*, span<OtherIndexType, N>)
+      -> mdspan<ElementType, dextents<size_t, N>>;
+
+  template<class ElementType, class OtherIndexType, size_t N>
+    mdspan(ElementType*, const array<OtherIndexType, N>&)
+      -> mdspan<ElementType, dextents<size_t, N>>;
+
+  template<class ElementType, class IndexType, size_t... ExtentsPack>
+    mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
+      -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
+
+  template<class ElementType, class MappingType>
+    mdspan(ElementType*, const MappingType&)
+      -> mdspan<ElementType, typename MappingType::extents_type,
+                typename MappingType::layout_type>;
+
+  template<class MappingType, class AccessorType>
+    mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
+           const AccessorType&)
+      -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
+                typename MappingType::layout_type, AccessorType>;
+}
+*/
+
+#ifndef _LIBCPP_MDSPAN
+#define _LIBCPP_MDSPAN
+
+#include <__config>
+#include <__fwd/mdspan.h>
+#include <__mdspan/default_accessor.h>
+#include <__mdspan/extents.h>
+#include <__mdspan/layout_left.h>
+#include <__mdspan/layout_right.h>
+#include <__mdspan/mdspan.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#endif // _LIBCPP_MDSPAN
lib/libcxx/include/memory
@@ -160,7 +160,7 @@ template <class T, class U>
 bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
 
 template <class T, class U>
-bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
+bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // removed in C++20
 
 template <class OutputIterator, class T>
 class raw_storage_iterator // deprecated in C++17, removed in C++20
@@ -912,14 +912,12 @@ template<size_t N, class T>
 #  pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
-#   include <__pstl_memory>
-#endif
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
 #  include <cstddef>
 #  include <cstdint>
+#  include <cstdlib>
 #  include <cstring>
 #  include <iosfwd>
 #  include <iterator>
lib/libcxx/include/memory_resource
@@ -22,7 +22,7 @@ namespace std::pmr {
   bool operator==(const memory_resource& a,
                   const memory_resource& b) noexcept;
   bool operator!=(const memory_resource& a,
-                  const memory_resource& b) noexcept;
+                  const memory_resource& b) noexcept;           // removed in C++20
 
   template <class Tp> class polymorphic_allocator;
 
@@ -31,7 +31,7 @@ namespace std::pmr {
                   const polymorphic_allocator<T2>& b) noexcept;
   template <class T1, class T2>
   bool operator!=(const polymorphic_allocator<T1>& a,
-                  const polymorphic_allocator<T2>& b) noexcept;
+                  const polymorphic_allocator<T2>& b) noexcept; // removed in C++20
 
   // Global memory resources
   memory_resource* set_default_resource(memory_resource* r) noexcept;
lib/libcxx/include/mutex
@@ -187,12 +187,20 @@ template<class Callable, class ...Args>
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__chrono/steady_clock.h>
+#include <__chrono/time_point.h>
+#include <__condition_variable/condition_variable.h>
 #include <__config>
 #include <__memory/shared_ptr.h>
-#include <__mutex_base>
+#include <__mutex/lock_guard.h>
+#include <__mutex/mutex.h>
+#include <__mutex/tag_types.h>
+#include <__mutex/unique_lock.h>
+#include <__thread/id.h>
 #include <__threading_support>
 #include <__utility/forward.h>
 #include <cstdint>
+#include <limits>
 #ifndef _LIBCPP_CXX03_LANG
 # include <tuple>
 #endif
@@ -210,7 +218,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-class _LIBCPP_TYPE_VIS recursive_mutex
+class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex
 {
     __libcpp_recursive_mutex_t __m_;
 
@@ -231,7 +239,7 @@ public:
     native_handle_type native_handle() {return &__m_;}
 };
 
-class _LIBCPP_TYPE_VIS timed_mutex
+class _LIBCPP_EXPORTED_FROM_ABI timed_mutex
 {
     mutex              __m_;
     condition_variable __cv_;
@@ -262,9 +270,9 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
 {
     using namespace chrono;
     unique_lock<mutex> __lk(__m_);
-    bool no_timeout = _Clock::now() < __t;
-    while (no_timeout && __locked_)
-        no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
+    bool __no_timeout = _Clock::now() < __t;
+    while (__no_timeout && __locked_)
+        __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
     if (!__locked_)
     {
         __locked_ = true;
@@ -273,7 +281,7 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
     return false;
 }
 
-class _LIBCPP_TYPE_VIS recursive_timed_mutex
+class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex
 {
     mutex              __m_;
     condition_variable __cv_;
@@ -304,7 +312,7 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration
 {
     using namespace chrono;
     __thread_id __id = this_thread::get_id();
-    unique_lock<mutex> lk(__m_);
+    unique_lock<mutex> __lk(__m_);
     if (__id == __id_)
     {
         if (__count_ == numeric_limits<size_t>::max())
@@ -312,9 +320,9 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration
         ++__count_;
         return true;
     }
-    bool no_timeout = _Clock::now() < __t;
-    while (no_timeout && __count_ != 0)
-        no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;
+    bool __no_timeout = _Clock::now() < __t;
+    while (__no_timeout && __count_ != 0)
+        __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
     if (__count_ == 0)
     {
         __count_ = 1;
@@ -328,7 +336,7 @@ template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI int
 try_lock(_L0& __l0, _L1& __l1)
 {
-    unique_lock<_L0> __u0(__l0, try_to_lock);
+    unique_lock<_L0> __u0(__l0, try_to_lock_t());
     if (__u0.owns_lock())
     {
         if (__l1.try_lock())
@@ -467,7 +475,7 @@ void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
 
 #endif // _LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class ..._Mutexes>
 class _LIBCPP_TEMPLATE_VIS scoped_lock;
 
@@ -544,7 +552,7 @@ private:
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 #endif // !_LIBCPP_HAS_NO_THREADS
 
 struct _LIBCPP_TEMPLATE_VIS once_flag;
@@ -652,8 +660,7 @@ __call_once_proxy(void* __vp)
     (*__p)();
 }
 
-_LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*,
-                                  void (*)(void*));
+_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));
 
 #ifndef _LIBCPP_CXX03_LANG
 
@@ -704,9 +711,17 @@ _LIBCPP_END_NAMESPACE_STD
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
-#  include <functional>
+#  include <cstdlib>
+#  include <cstring>
+#  include <ctime>
+#  include <initializer_list>
+#  include <new>
+#  include <stdexcept>
+#  include <system_error>
 #  include <type_traits>
+#  include <typeinfo>
 #endif
 
 #endif // _LIBCPP_MUTEX
lib/libcxx/include/new
@@ -89,12 +89,14 @@ void  operator delete[](void* ptr, void*) noexcept;
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
+#include <__exception/exception.h>
+#include <__type_traits/alignment_of.h>
 #include <__type_traits/is_function.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/remove_cv.h>
+#include <__verbose_abort>
 #include <cstddef>
 #include <cstdlib>
-#include <exception>
 #include <version>
 
 #if defined(_LIBCPP_ABI_VCRUNTIME)
@@ -123,10 +125,10 @@ namespace std  // purposefully not using versioning namespace
 {
 
 #if !defined(_LIBCPP_ABI_VCRUNTIME)
-struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
-extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
+struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t { explicit nothrow_t() = default; };
+extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow;
 
-class _LIBCPP_EXCEPTION_ABI bad_alloc
+class _LIBCPP_EXPORTED_FROM_ABI bad_alloc
     : public exception
 {
 public:
@@ -135,7 +137,7 @@ public:
     const char* what() const _NOEXCEPT override;
 };
 
-class _LIBCPP_EXCEPTION_ABI bad_array_new_length
+class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length
     : public bad_alloc
 {
 public:
@@ -145,8 +147,8 @@ public:
 };
 
 typedef void (*new_handler)();
-_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI new_handler set_new_handler(new_handler) _NOEXCEPT;
+_LIBCPP_EXPORTED_FROM_ABI new_handler get_new_handler() _NOEXCEPT;
 
 #elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
 
@@ -168,15 +170,15 @@ public:
 };
 #endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
 
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_bad_alloc();  // not in C++ spec
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_bad_array_new_length()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw bad_array_new_length();
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode");
 #endif
 }
 
@@ -189,14 +191,14 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
 #endif
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 // Enable the declaration even if the compiler doesn't support the language
 // feature.
 struct destroying_delete_t {
   explicit destroying_delete_t() = default;
 };
 inline constexpr destroying_delete_t destroying_delete{};
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 } // namespace std
 
@@ -332,46 +334,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
 #endif
 }
 
-#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
-// Low-level helpers to call the aligned allocation and deallocation functions
-// on the target platform. This is used to implement libc++'s own memory
-// allocation routines -- if you need to allocate memory inside the library,
-// chances are that you want to use `__libcpp_allocate` instead.
-//
-// Returns the allocated memory, or `nullptr` on failure.
-inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
-#  if defined(_LIBCPP_MSVCRT_LIKE)
-    return ::_aligned_malloc(__size, __alignment);
-#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
-    // aligned_alloc() requires that __size is a multiple of __alignment,
-    // but for C++ [new.delete.general], only states "if the value of an
-    // alignment argument passed to any of these functions is not a valid
-    // alignment value, the behavior is undefined".
-    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
-    // round __size up to the next multiple of __alignment.
-    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
-    // Rounding up could have wrapped around to zero, so we have to add another
-    // max() ternary to the actual call site to avoid succeeded in that case.
-    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
-#  else
-    void* __result = nullptr;
-    (void)::posix_memalign(&__result, __alignment, __size);
-    // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
-    return __result;
-#  endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void __libcpp_aligned_free(void* __ptr) {
-#if defined(_LIBCPP_MSVCRT_LIKE)
-  ::_aligned_free(__ptr);
-#else
-  ::free(__ptr);
-#endif
-}
-#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-
-
 template <class _Tp>
 _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
@@ -381,7 +343,7 @@ _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
     return __builtin_launder(__p);
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
 constexpr _Tp* launder(_Tp* __p) noexcept
@@ -390,7 +352,7 @@ constexpr _Tp* launder(_Tp* __p) noexcept
 }
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 #if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
 
@@ -399,11 +361,12 @@ inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUC
 
 #endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <exception>
 #  include <type_traits>
 #endif
 
lib/libcxx/include/numbers
@@ -63,7 +63,7 @@ namespace std::numbers {
 #include <__config>
 #include <version>
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -128,7 +128,7 @@ inline constexpr double phi        = phi_v<double>;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
lib/libcxx/include/numeric
@@ -158,6 +158,8 @@ template<class T>
 #include <__numeric/iota.h>
 #include <__numeric/midpoint.h>
 #include <__numeric/partial_sum.h>
+#include <__numeric/pstl_reduce.h>
+#include <__numeric/pstl_transform_reduce.h>
 #include <__numeric/reduce.h>
 #include <__numeric/transform_exclusive_scan.h>
 #include <__numeric/transform_inclusive_scan.h>
@@ -167,10 +169,6 @@ template<class T>
 #  pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
-#   include <__pstl_numeric>
-#endif
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
 #  include <functional>
lib/libcxx/include/optional
@@ -16,107 +16,126 @@
 // C++1z
 
 namespace std {
-  // 23.6.3, optional for object types
-  template <class T> class optional;
+  // [optional.optional], class template optional
+  template <class T>
+    class optional;
 
-  // 23.6.4, no-value state indicator
+  template<class T>
+    concept is-derived-from-optional = requires(const T& t) {       // exposition only
+      []<class U>(const optional<U>&){ }(t);
+    };
+
+  // [optional.nullopt], no-value state indicator
   struct nullopt_t{see below };
   inline constexpr nullopt_t nullopt(unspecified );
 
-  // 23.6.5, class bad_optional_access
+  // [optional.bad.access], class bad_optional_access
   class bad_optional_access;
 
-  // 23.6.6, relational operators
+  // [optional.relops], relational operators
   template <class T, class U>
-  constexpr bool operator==(const optional<T>&, const optional<U>&);
+    constexpr bool operator==(const optional<T>&, const optional<U>&);
   template <class T, class U>
-  constexpr bool operator!=(const optional<T>&, const optional<U>&);
+    constexpr bool operator!=(const optional<T>&, const optional<U>&);
   template <class T, class U>
-  constexpr bool operator<(const optional<T>&, const optional<U>&);
+    constexpr bool operator<(const optional<T>&, const optional<U>&);
   template <class T, class U>
-  constexpr bool operator>(const optional<T>&, const optional<U>&);
+    constexpr bool operator>(const optional<T>&, const optional<U>&);
   template <class T, class U>
-  constexpr bool operator<=(const optional<T>&, const optional<U>&);
+    constexpr bool operator<=(const optional<T>&, const optional<U>&);
   template <class T, class U>
-  constexpr bool operator>=(const optional<T>&, const optional<U>&);
-
-  // 23.6.7 comparison with nullopt
-  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
-  template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
-  template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
-  template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
-  template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
-  template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
-  template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
-
-  // 23.6.8, comparison with T
-  template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
-  template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
-  template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
-  template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
-  template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
-  template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
-  template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
-
-  // 23.6.9, specialized algorithms
-  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
-  template <class T> constexpr optional<see below > make_optional(T&&);
-  template <class T, class... Args>
+    constexpr bool operator>=(const optional<T>&, const optional<U>&);
+  template<class T, three_way_comparable_with<T> U>
+    constexpr compare_three_way_result_t<T, U>
+      operator<=>(const optional<T>&, const optional<U>&); // since C++20
+
+  // [optional.nullops], comparison with nullopt
+  template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
+  template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17
+  template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17
+  template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17
+  template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;  // until C++17
+  template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;  // until C++17
+  template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17
+  template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17
+  template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;  // until C++17
+  template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;  // until C++17
+  template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17
+  template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17
+  template<class T>
+    constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept;     // since C++20
+
+  // [optional.comp.with.t], comparison with T
+  template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
+  template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
+  template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
+  template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
+  template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
+  template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
+  template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
+  template<class T, class U>
+      requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
+    constexpr compare_three_way_result_t<T, U>
+      operator<=>(const optional<T>&, const U&);                                       // since C++20
+
+  // [optional.specalg], specialized algorithms
+  template<class T>
+    void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
+
+  template<class T>
+    constexpr optional<see below > make_optional(T&&);
+  template<class T, class... Args>
     constexpr optional<T> make_optional(Args&&... args);
-  template <class T, class U, class... Args>
+  template<class T, class U, class... Args>
     constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
 
-  // 23.6.10, hash support
-  template <class T> struct hash;
-  template <class T> struct hash<optional<T>>;
+  // [optional.hash], hash support
+  template<class T> struct hash;
+  template<class T> struct hash<optional<T>>;
 
-  template <class T> class optional {
+  template<class T>
+  class optional {
   public:
     using value_type = T;
 
-    // 23.6.3.1, constructors
+    // [optional.ctor], constructors
     constexpr optional() noexcept;
     constexpr optional(nullopt_t) noexcept;
     constexpr optional(const optional &);
     constexpr optional(optional &&) noexcept(see below);
-    template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
-    template <class U, class... Args>
+    template<class... Args>
+      constexpr explicit optional(in_place_t, Args &&...);
+    template<class U, class... Args>
       constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
-    template <class U = T>
+    template<class U = T>
       constexpr explicit(see-below) optional(U &&);
-    template <class U>
-      explicit(see-below) optional(const optional<U> &);         // constexpr in C++20
-    template <class U>
-      explicit(see-below) optional(optional<U> &&);              // constexpr in C++20
+    template<class U>
+      explicit(see-below) optional(const optional<U> &);                          // constexpr in C++20
+    template<class U>
+      explicit(see-below) optional(optional<U> &&);                               // constexpr in C++20
 
-    // 23.6.3.2, destructor
+    // [optional.dtor], destructor
     ~optional(); // constexpr in C++20
 
-    // 23.6.3.3, assignment
-    optional &operator=(nullopt_t) noexcept;                     // constexpr in C++20
+    // [optional.assign], assignment
+    optional &operator=(nullopt_t) noexcept;                                      // constexpr in C++20
     constexpr optional &operator=(const optional &);
     constexpr optional &operator=(optional &&) noexcept(see below);
-    template <class U = T> optional &operator=(U &&);            // constexpr in C++20
-    template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
-    template <class U> optional &operator=(optional<U> &&);      // constexpr in C++20
-    template <class... Args> T& emplace(Args &&...);             // constexpr in C++20
-    template <class U, class... Args>
-      T& emplace(initializer_list<U>, Args &&...);               // constexpr in C++20
-
-    // 23.6.3.4, swap
+    template<class U = T> optional &operator=(U &&);                              // constexpr in C++20
+    template<class U> optional &operator=(const optional<U> &);                   // constexpr in C++20
+    template<class U> optional &operator=(optional<U> &&);                        // constexpr in C++20
+    template<class... Args> T& emplace(Args &&...);                               // constexpr in C++20
+    template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
+
+    // [optional.swap], swap
     void swap(optional &) noexcept(see below ); // constexpr in C++20
 
-    // 23.6.3.5, observers
+    // [optional.observe], observers
     constexpr T const *operator->() const;
     constexpr T *operator->();
     constexpr T const &operator*() const &;
@@ -129,8 +148,8 @@ namespace std {
     constexpr T &value() &;
     constexpr T &&value() &&;
     constexpr const T &&value() const &&;
-    template <class U> constexpr T value_or(U &&) const &;
-    template <class U> constexpr T value_or(U &&) &&;
+    template<class U> constexpr T value_or(U &&) const &;
+    template<class U> constexpr T value_or(U &&) &&;
 
     // [optional.monadic], monadic operations
     template<class F> constexpr auto and_then(F&& f) &;         // since C++23
@@ -144,15 +163,15 @@ namespace std {
     template<class F> constexpr optional or_else(F&& f) &&;     // since C++23
     template<class F> constexpr optional or_else(F&& f) const&; // since C++23
 
-    // 23.6.3.6, modifiers
-    void reset() noexcept; // constexpr in C++20
+    // [optional.mod], modifiers
+    void reset() noexcept;                                      // constexpr in C++20
 
   private:
-    T *val; // exposition only
+    T *val;         // exposition only
   };
 
-template<class T>
-  optional(T) -> optional<T>;
+  template<class T>
+    optional(T) -> optional<T>;
 
 } // namespace std
 
@@ -160,21 +179,55 @@ template<class T>
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
+#include <__compare/compare_three_way_result.h>
+#include <__compare/three_way_comparable.h>
 #include <__concepts/invocable.h>
 #include <__config>
 #include <__functional/hash.h>
 #include <__functional/invoke.h>
+#include <__functional/reference_wrapper.h>
 #include <__functional/unary_function.h>
+#include <__memory/addressof.h>
 #include <__memory/construct_at.h>
-#include <__tuple_dir/sfinae_helpers.h>
+#include <__tuple/sfinae_helpers.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/is_trivially_move_assignable.h>
+#include <__type_traits/is_trivially_move_constructible.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
+#include <__verbose_abort>
 #include <initializer_list>
 #include <new>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -186,10 +239,13 @@ template<class T>
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 namespace std  // purposefully not using versioning namespace
 {
 
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
     : public exception
 {
 public:
@@ -200,7 +256,7 @@ public:
 
 } // namespace std
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -208,16 +264,16 @@ _LIBCPP_NORETURN
 inline _LIBCPP_INLINE_VISIBILITY
 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
 void __throw_bad_optional_access() {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         throw bad_optional_access();
 #else
-        _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
 #endif
 }
 
 struct nullopt_t
 {
-    struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
+    struct __secret_tag { explicit __secret_tag() = default; };
     _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
 };
 
@@ -259,7 +315,7 @@ struct __optional_destruct_base<_Tp, false>
         :  __val_(_VSTD::forward<_Args>(__args)...),
            __engaged_(true) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   template <class _Fp, class... _Args>
   _LIBCPP_HIDE_FROM_ABI
   constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
@@ -301,7 +357,7 @@ struct __optional_destruct_base<_Tp, true>
         :  __val_(_VSTD::forward<_Args>(__args)...),
            __engaged_(true) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   template <class _Fp, class... _Args>
   _LIBCPP_HIDE_FROM_ABI
   constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
@@ -356,8 +412,8 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args)
     {
-        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
-#if _LIBCPP_STD_VER > 17
+        _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
+#if _LIBCPP_STD_VER >= 20
         _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
 #else
         ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
@@ -403,7 +459,7 @@ struct __optional_storage_base<_Tp, true>
     __raw_type* __value_;
 
     template <class _Up>
-    static constexpr bool __can_bind_reference() {
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
         using _RawUp = __libcpp_remove_reference_t<_Up>;
         using _UpPtr = _RawUp*;
         using _RawTp = __libcpp_remove_reference_t<_Tp>;
@@ -451,7 +507,7 @@ struct __optional_storage_base<_Tp, true>
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val)
     {
-        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
+        _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
         static_assert(__can_bind_reference<_UArg>(),
             "Attempted to construct a reference element in tuple from a "
             "possible temporary");
@@ -623,12 +679,20 @@ using __optional_sfinae_assign_base_t = __sfinae_assign_base<
 
 template<class _Tp>
 class optional;
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
+
+#  endif // _LIBCPP_STD_VER >= 20
+
 template <class _Tp>
 struct __is_std_optional : false_type {};
 template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
 
 template <class _Tp>
-class optional
+class _LIBCPP_DECLSPEC_EMPTY_BASES optional
     : private __optional_move_assign_base<_Tp>
     , private __optional_sfinae_ctor_base_t<_Tp>
     , private __optional_sfinae_assign_base_t<_Tp>
@@ -653,13 +717,13 @@ private:
     // LWG2756: conditionally explicit conversion from _Up
     struct _CheckOptionalArgsConstructor {
       template <class _Up>
-      static constexpr bool __enable_implicit() {
+      _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
           return is_constructible_v<_Tp, _Up&&> &&
                  is_convertible_v<_Up&&, _Tp>;
       }
 
       template <class _Up>
-      static constexpr bool __enable_explicit() {
+      _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
           return is_constructible_v<_Tp, _Up&&> &&
                  !is_convertible_v<_Up&&, _Tp>;
       }
@@ -692,17 +756,17 @@ private:
           is_assignable<_Tp&, _Opt const&&>
       >;
       template <class _Up, class _QUp = _QualUp>
-      static constexpr bool __enable_implicit() {
+      _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
           return is_convertible<_QUp, _Tp>::value &&
               !__check_constructible_from_opt<_Up>::value;
       }
       template <class _Up, class _QUp = _QualUp>
-      static constexpr bool __enable_explicit() {
+      _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
           return !is_convertible<_QUp, _Tp>::value &&
               !__check_constructible_from_opt<_Up>::value;
       }
       template <class _Up, class _QUp = _QualUp>
-      static constexpr bool __enable_assign() {
+      _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
           // Construction and assignability of _QUp to _Tp has already been
           // checked.
           return !__check_constructible_from_opt<_Up>::value &&
@@ -805,7 +869,7 @@ public:
         this->__construct_from(_VSTD::move(__v));
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   template<class _Fp, class... _Args>
   _LIBCPP_HIDE_FROM_ABI
   constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
@@ -820,8 +884,8 @@ public:
         return *this;
     }
 
-    constexpr optional& operator=(const optional&) = default;
-    constexpr optional& operator=(optional&&) = default;
+    _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
+    _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
 
     // LWG2756
     template <class _Up = value_type,
@@ -932,7 +996,7 @@ public:
     add_pointer_t<value_type const>
     operator->() const
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
         return _VSTD::addressof(this->__get());
     }
 
@@ -941,7 +1005,7 @@ public:
     add_pointer_t<value_type>
     operator->()
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
         return _VSTD::addressof(this->__get());
     }
 
@@ -950,7 +1014,7 @@ public:
     const value_type&
     operator*() const& noexcept
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
         return this->__get();
     }
 
@@ -959,7 +1023,7 @@ public:
     value_type&
     operator*() & noexcept
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
         return this->__get();
     }
 
@@ -968,7 +1032,7 @@ public:
     value_type&&
     operator*() && noexcept
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
         return _VSTD::move(this->__get());
     }
 
@@ -977,7 +1041,7 @@ public:
     const value_type&&
     operator*() const&& noexcept
     {
-        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
         return _VSTD::move(this->__get());
     }
 
@@ -1047,7 +1111,7 @@ public:
                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   template<class _Func>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
   constexpr auto and_then(_Func&& __f) & {
@@ -1171,7 +1235,7 @@ public:
       return _VSTD::move(*this);
     return _VSTD::forward<_Func>(__f)();
   }
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     using __base::reset;
 };
@@ -1278,6 +1342,18 @@ operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
     return *__x >= *__y;
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp, three_way_comparable_with<_Tp> _Up>
+_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
+operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
+    if (__x && __y)
+        return *__x <=> *__y;
+    return __x.has_value() <=> __y.has_value();
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
 // Comparisons with nullopt
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
@@ -1287,6 +1363,8 @@ operator==(const optional<_Tp>& __x, nullopt_t) noexcept
     return !static_cast<bool>(__x);
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
 bool
@@ -1375,6 +1453,15 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
     return !static_cast<bool>(__x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
+    return __x.has_value() <=> false;
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 // Comparisons with T
 template <class _Tp, class _Up>
 _LIBCPP_INLINE_VISIBILITY constexpr
@@ -1520,6 +1607,17 @@ operator>=(const _Tp& __v, const optional<_Up>& __x)
     return static_cast<bool>(__x) ? __v >= *__x : true;
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp, class _Up>
+  requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
+_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
+operator<=>(const optional<_Tp>& __x, const _Up& __v) {
+    return __x.has_value() ? *__x <=> __v : strong_ordering::less;
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1572,7 +1670,9 @@ struct _LIBCPP_TEMPLATE_VIS hash<
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
@@ -1583,6 +1683,7 @@ _LIBCPP_END_NAMESPACE_STD
 #  include <memory>
 #  include <ratio>
 #  include <tuple>
+#  include <type_traits>
 #  include <typeinfo>
 #  include <utility>
 #  include <variant>
lib/libcxx/include/ostream
@@ -165,8 +165,16 @@ basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, cons
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__exception/operations.h>
+#include <__fwd/ostream.h>
 #include <__memory/shared_ptr.h>
 #include <__memory/unique_ptr.h>
+#include <__system_error/error_code.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
 #include <bitset>
 #include <ios>
 #include <locale>
@@ -244,7 +252,7 @@ public:
     basic_ostream& operator<<(long double __f);
     basic_ostream& operator<<(const void* __p);
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI
     basic_ostream& operator<<(const volatile void* __p) {
         return operator<<(const_cast<const void*>(__p));
@@ -253,7 +261,7 @@ public:
 
     basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 // LWG 2221 - nullptr. This is not backported to older standards modes.
 // See https://reviews.llvm.org/D127033 for more info on the rationale.
     _LIBCPP_INLINE_VISIBILITY
@@ -314,18 +322,18 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry()
     if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf)
                       && !uncaught_exception())
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             if (__os_.rdbuf()->pubsync() == -1)
                 __os_.setstate(ios_base::badbit);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -352,19 +360,19 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
             if (__sb)
             {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
                 try
                 {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
                     typedef istreambuf_iterator<_CharT, _Traits> _Ip;
                     typedef ostreambuf_iterator<_CharT, _Traits> _Op;
                     _Ip __i(__sb);
@@ -379,24 +387,24 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
                     }
                     if (__c == 0)
                         this->setstate(ios_base::failbit);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
                 }
                 catch (...)
                 {
                     this->__set_failbit_and_consider_rethrow();
                 }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             }
             else
                 this->setstate(ios_base::badbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -404,10 +412,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(bool __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -416,13 +424,13 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -430,10 +438,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(short __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -446,13 +454,13 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n)
                         static_cast<long>(__n)).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -460,10 +468,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -472,13 +480,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
             if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -486,10 +494,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(int __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -502,13 +510,13 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n)
                         static_cast<long>(__n)).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -516,10 +524,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -528,13 +536,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
             if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -542,10 +550,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(long __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -554,13 +562,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -568,10 +576,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -580,13 +588,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -594,10 +602,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(long long __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -606,13 +614,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -620,10 +628,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -632,13 +640,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -646,10 +654,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(float __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -658,13 +666,13 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n)
             if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -672,10 +680,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(double __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -684,13 +692,13 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -698,10 +706,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(long double __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -710,13 +718,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -724,10 +732,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -736,13 +744,13 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
             if (__f.put(*this, *this, this->fill(), __n).failed())
                 this->setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -751,10 +759,10 @@ _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
                           const _CharT* __str, size_t __len)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
         if (__s)
         {
@@ -769,13 +777,13 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
                                       __os.fill()).failed())
                 __os.setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __os.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __os;
 }
 
@@ -791,10 +799,10 @@ template<class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
         if (__s)
         {
@@ -810,13 +818,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
                                       __os.fill()).failed())
                 __os.setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __os.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __os;
 }
 
@@ -852,10 +860,10 @@ template<class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
         if (__s)
         {
@@ -884,13 +892,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
                                       __os.fill()).failed())
                 __os.setstate(ios_base::badbit | ios_base::failbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         __os.__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return __os;
 }
 
@@ -921,10 +929,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::put(char_type __c)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __s(*this);
         if (__s)
         {
@@ -934,13 +942,13 @@ basic_ostream<_CharT, _Traits>::put(char_type __c)
             if (__o.failed())
                 this->setstate(ios_base::badbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -948,23 +956,23 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         sentry __sen(*this);
         if (__sen && __n)
         {
             if (this->rdbuf()->sputn(__s, __n) != __n)
                 this->setstate(ios_base::badbit);
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -972,10 +980,10 @@ template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::flush()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         if (this->rdbuf())
         {
             sentry __s(*this);
@@ -985,13 +993,13 @@ basic_ostream<_CharT, _Traits>::flush()
                     this->setstate(ios_base::badbit);
             }
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
         this->__set_badbit_and_consider_rethrow();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return *this;
 }
 
@@ -1130,7 +1138,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
                          std::use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class _Traits>
@@ -1179,7 +1187,7 @@ basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const ch
 template <class _Traits>
 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>;
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -1189,7 +1197,9 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>;
 _LIBCPP_END_NAMESPACE_STD
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iterator>
 #  include <type_traits>
 #endif
lib/libcxx/include/print
@@ -0,0 +1,389 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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_PRINT
+#define _LIBCPP_PRINT
+
+/*
+namespace std {
+  // [print.fun], print functions
+  template<class... Args>
+    void print(format_string<Args...> fmt, Args&&... args);
+  template<class... Args>
+    void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
+
+  template<class... Args>
+    void println(format_string<Args...> fmt, Args&&... args);
+  template<class... Args>
+    void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
+
+  void vprint_unicode(string_view fmt, format_args args);
+  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
+
+  void vprint_nonunicode(string_view fmt, format_args args);
+  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
+}
+*/
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/buffer.h>
+#include <__format/format_arg_store.h>
+#include <__format/format_args.h>
+#include <__format/format_context.h>
+#include <__format/format_error.h>
+#include <__format/format_functions.h>
+#include <__format/unicode.h>
+#include <__system_error/system_error.h>
+#include <__utility/forward.h>
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <string_view>
+#include <version>
+
+#if __has_include(<unistd.h>)
+#  include <unistd.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef _WIN32
+_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream);
+
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+// A wrapper for WriteConsoleW which is used to write to the Windows
+// console. This function is in the dylib to avoid pulling in windows.h
+// in the library headers. The function itself uses some private parts
+// of the dylib too.
+//
+// The function does not depend on the language standard used. Guarding
+// it with C++23 would fail since the dylib is currently built using C++20.
+//
+// Note the function is only implemented on the Windows platform.
+_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view);
+#  endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+#endif // _WIN32
+
+#if _LIBCPP_STD_VER >= 23
+
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+// This is the code to transcode UTF-8 to UTF-16. This is used on
+// Windows for the native Unicode API. The code is modeled to make it
+// easier to extend to
+//
+//  P2728R0 Unicode in the Library, Part 1: UTF Transcoding
+//
+// This paper is still under heavy development so it makes no sense yet
+// to strictly follow the paper.
+namespace __unicode {
+
+// The names of these concepts are modelled after P2728R0, but the
+// implementation is not. char16_t may contain 32-bits so depending on the
+// number of bits is an issue.
+#    ifdef _LIBCPP_SHORT_WCHAR
+template <class _Tp>
+concept __utf16_code_unit =
+    same_as<_Tp, char16_t>
+#      ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+    || same_as<_Tp, wchar_t>
+#      endif
+    ;
+template <class _Tp>
+concept __utf32_code_unit = same_as<_Tp, char32_t>;
+#    else // _LIBCPP_SHORT_WCHAR
+template <class _Tp>
+concept __utf16_code_unit = same_as<_Tp, char16_t>;
+template <class _Tp>
+concept __utf32_code_unit =
+    same_as<_Tp, char32_t>
+#      ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+    || same_as<_Tp, wchar_t>
+#      endif
+    ;
+#    endif // _LIBCPP_SHORT_WCHAR
+
+// Pass by reference since an output_iterator may not be copyable.
+template <class _OutIt>
+_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete;
+
+template <class _OutIt>
+  requires __utf16_code_unit<iter_value_t<_OutIt>>
+_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16");
+
+  if (__value < 0x10000) {
+    *__out_it++ = __value;
+    return;
+  }
+
+  __value -= 0x10000;
+  *__out_it++ = 0xd800 + (__value >> 10);
+  *__out_it++ = 0xdc00 + (__value & 0x3FF);
+}
+
+template <class _OutIt>
+  requires __utf32_code_unit<iter_value_t<_OutIt>>
+_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32");
+  *__out_it++ = __value;
+}
+
+template <class _OutIt, input_iterator _InIt>
+  requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>)
+_LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) {
+  // The __code_point_view has a basic_string_view interface.
+  // When transcoding becomes part of the standard we probably want to
+  // look at smarter algorithms.
+  // For example, when processing a code point that is encoded in
+  // 1 to 3 code units in UTF-8, the result will always be encoded
+  // in 1 code unit in UTF-16 (code points that require 4 code
+  // units in UTF-8 will require 2 code units in UTF-16).
+  //
+  // Note if P2728 is accepted types like int may become valid. In that case
+  // the __code_point_view should use a span. Libc++ will remove support for
+  // char_traits<int>.
+
+  // TODO PRINT Validate with clang-tidy
+  // NOLINTNEXTLINE(bugprone-dangling-handle)
+  basic_string_view<iter_value_t<_InIt>> __data{__first, __last};
+  __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()};
+  while (!__view.__at_end())
+    __unicode::__encode(__out_it, __view.__consume().__code_point);
+  return __out_it;
+}
+
+} // namespace __unicode
+
+#  endif //  _LIBCPP_HAS_NO_UNICODE
+
+namespace __print {
+
+// [print.fun]/2
+//   Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to:
+//     vprint_unicode(stream, fmt.str, make_format_args(args...));
+//   Otherwise, equivalent to:
+//     vprint_nonunicode(stream, fmt.str, make_format_args(args...));
+//
+// Based on the compiler and its compilation flags this value is or is
+// not true. As mentioned in P2093R14 this only affects Windows. The
+// test below could also be done for
+// - GCC using __GNUC_EXECUTION_CHARSET_NAME
+//   https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+// - Clang using __clang_literal_encoding__
+//   https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros
+//   (note at the time of writing Clang is hard-coded to UTF-8.)
+//
+
+#  ifdef _LIBCPP_HAS_NO_UNICODE
+inline constexpr bool __use_unicode = false;
+#  elif defined(_MSVC_EXECUTION_CHARACTER_SET)
+// This is the same test MSVC STL uses in their implementation of <print>
+// See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
+inline constexpr bool __use_unicode = _MSVC_EXECUTION_CHARACTER_SET == 65001;
+#  else
+inline constexpr bool __use_unicode = true;
+#  endif
+
+_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) {
+#  ifdef _WIN32
+  return std::__is_windows_terminal(__stream);
+#  elif __has_include(<unistd.h>)
+  return isatty(fileno(__stream));
+#  else
+#    error "Provide a way to determine whether a FILE* is a terminal"
+#  endif
+}
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void
+__vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream");
+  string __str = std::vformat(__fmt, __args);
+  if (__write_nl)
+    __str.push_back('\n');
+
+  size_t __size = fwrite(__str.data(), 1, __str.size(), __stream);
+  if (__size < __str.size()) {
+    if (std::feof(__stream))
+      std::__throw_system_error(EIO, "EOF while writing the formatted output");
+    std::__throw_system_error(std::ferror(__stream), "failed to write formatted output");
+  }
+}
+
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+
+// Note these helper functions are mainly used to aid testing.
+// On POSIX systems and Windows the output is no longer considered a
+// terminal when the output is redirected. Typically during testing the
+// output is redirected to be able to capture it. This makes it hard to
+// test this code path.
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void
+__vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
+  // TODO PRINT Should flush errors throw too?
+  if (__is_terminal)
+    std::fflush(__stream);
+
+  __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
+}
+
+#    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void
+__vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
+  if (!__is_terminal)
+    return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
+
+  // TODO PRINT Should flush errors throw too?
+  std::fflush(__stream);
+
+  string __str = std::vformat(__fmt, __args);
+  // UTF-16 uses the same number or less code units than UTF-8.
+  // However the size of the code unit is 16 bits instead of 8 bits.
+  //
+  // The buffer uses the worst-case estimate and should never resize.
+  // However when the string is large this could lead to OOM. Using a
+  // smaller size might work, but since the buffer uses a grow factor
+  // the final size might be larger when the estimate is wrong.
+  //
+  // TODO PRINT profile and improve the speed of this code.
+  __format::__retarget_buffer<wchar_t> __buffer{__str.size()};
+  __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator());
+  if (__write_nl)
+    __buffer.push_back(L'\n');
+
+  [[maybe_unused]] wstring_view __view = __buffer.__view();
+
+  // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change
+  // the behavior in the test. This is not part of the public API.
+#      ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
+  _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view);
+#      elif defined(_WIN32)
+  std::__write_to_windows_console(__stream, __view);
+#      else
+  std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and "
+                             "__write_to_windows_console is not available.");
+#      endif
+}
+#    endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void
+__vprint_unicode([[maybe_unused]] FILE* __stream,
+                 [[maybe_unused]] string_view __fmt,
+                 [[maybe_unused]] format_args __args,
+                 [[maybe_unused]] bool __write_nl) {
+  _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream");
+
+  // [print.fun]
+  //   7 - Effects: If stream refers to a terminal capable of displaying
+  //       Unicode, writes out to the terminal using the native Unicode
+  //       API; if out contains invalid code units, the behavior is
+  //       undefined and implementations are encouraged to diagnose it.
+  //       Otherwise writes out to stream unchanged. If the native
+  //       Unicode API is used, the function flushes stream before
+  //       writing out.
+  //   8 - Throws: Any exception thrown by the call to vformat
+  //       ([format.err.report]). system_error if writing to the terminal
+  //       or stream fails. May throw bad_alloc.
+  //   9 - Recommended practice: If invoking the native Unicode API
+  //       requires transcoding, implementations should substitute
+  //       invalid code units with U+FFFD replacement character per the
+  //       Unicode Standard, Chapter 3.9 U+FFFD Substitution in
+  //       Conversion.
+
+  // On non-Windows platforms the Unicode API is the normal file I/O API
+  // so there the call can be forwarded to the non_unicode API. On
+  // Windows there is a different API. This API requires transcoding.
+
+#    ifndef _WIN32
+  __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
+#    elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+  __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
+#    else
+#      error "Windows builds with wchar_t disabled are not supported."
+#    endif
+}
+
+#  endif // _LIBCPP_HAS_NO_UNICODE
+
+} // namespace __print
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+  if constexpr (__print::__use_unicode)
+    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+  else
+    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+#  else  // _LIBCPP_HAS_NO_UNICODE
+  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+#  endif // _LIBCPP_HAS_NO_UNICODE
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) {
+  std::print(stdout, __fmt, std::forward<_Args>(__args)...);
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+  // Note the wording in the Standard is inefficient. The output of
+  // std::format is a std::string which is then copied. This solution
+  // just appends a newline at the end of the output.
+  if constexpr (__print::__use_unicode)
+    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
+  else
+    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
+#  else  // _LIBCPP_HAS_NO_UNICODE
+  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
+#  endif // _LIBCPP_HAS_NO_UNICODE
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) {
+  std::println(stdout, __fmt, std::forward<_Args>(__args)...);
+}
+
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
+  __print::__vprint_unicode(__stream, __fmt, __args, false);
+}
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) {
+  std::vprint_unicode(stdout, __fmt, __args);
+}
+
+#  endif // _LIBCPP_HAS_NO_UNICODE
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
+  __print::__vprint_nonunicode(__stream, __fmt, __args, false);
+}
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) {
+  std::vprint_nonunicode(stdout, __fmt, __args);
+}
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_PRINT
lib/libcxx/include/queue
@@ -43,6 +43,7 @@ public:
     explicit queue(container_type&& c)
     template<class InputIterator>
         queue(InputIterator first, InputIterator last); // since C++23
+    template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23
     template <class Alloc>
         explicit queue(const Alloc& a);
     template <class Alloc>
@@ -55,6 +56,8 @@ public:
         queue(queue&& q, const Alloc& a);
     template <class InputIterator, class Alloc>
         queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
+    template<container-compatible-range<T> R, class Alloc>
+        queue(from_range_t, R&& rg, const Alloc&); // since C++23
 
     bool      empty() const;
     size_type size() const;
@@ -66,6 +69,8 @@ public:
 
     void push(const value_type& v);
     void push(value_type&& v);
+    template<container-compatible-range<T> R>
+      void push_range(R&& rg); // C++23
     template <class... Args> reference emplace(Args&&... args); // reference in C++17
     void pop();
 
@@ -78,6 +83,9 @@ template<class Container>
 template<class InputIterator>
   queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
 
+template<ranges::input_range R>
+  queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23
+
 template<class Container, class Allocator>
   queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
 
@@ -86,6 +94,10 @@ template<class InputIterator, class Allocator>
   -> queue<iter-value-type<InputIterator>,
            deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
 
+template<ranges::input_range R, class Allocator>
+    queue(from_range_t, R&&, Allocator)
+      -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
+
 template <class T, class Container>
   bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
 
@@ -104,6 +116,10 @@ template <class T, class Container>
 template <class T, class Container>
   bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y);
 
+template<class T, three_way_comparable Container>
+  compare_three_way_result_t<Container>
+    operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);  // since C++20
+
 template <class T, class Container>
   void swap(queue<T, Container>& x, queue<T, Container>& y)
   noexcept(noexcept(x.swap(y)));
@@ -138,6 +154,8 @@ public:
     template <class InputIterator>
         priority_queue(InputIterator first, InputIterator last,
                        const Compare& comp, Container&& c);
+    template <container-compatible-range<T> R>
+        priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23
     template <class Alloc>
         explicit priority_queue(const Alloc& a);
     template <class Alloc>
@@ -160,6 +178,10 @@ public:
     template <class InputIterator>
         priority_queue(InputIterator first, InputIterator last,
                        const Compare& comp, Container&& c, const Alloc& a);
+    template <container-compatible-range<T> R, class Alloc>
+      priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23
+    template <container-compatible-range<T> R, class Alloc>
+      priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23
     template <class Alloc>
         priority_queue(const priority_queue& q, const Alloc& a);
     template <class Alloc>
@@ -171,6 +193,8 @@ public:
 
     void push(const value_type& v);
     void push(value_type&& v);
+    template<container-compatible-range<T> R>
+      void push_range(R&& rg); // C++23
     template <class... Args> void emplace(Args&&... args);
     void pop();
 
@@ -189,6 +213,10 @@ template<class InputIterator,
 priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
     -> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17
 
+template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
+  priority_queue(from_range_t, R&&, Compare = Compare())
+    -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23
+
 template<class Compare, class Container, class Allocator>
 priority_queue(Compare, Container, Allocator)
     -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
@@ -208,6 +236,15 @@ template<class InputIterator, class Compare, class Container, class Allocator>
 priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
     -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
 
+template<ranges::input_range R, class Compare, class Allocator>
+  priority_queue(from_range_t, R&&, Compare, Allocator)
+    -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
+                        Compare>; // C++23
+
+template<ranges::input_range R, class Allocator>
+  priority_queue(from_range_t, R&&, Allocator)
+    -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23
+
 template <class T, class Container, class Compare>
   void swap(priority_queue<T, Container, Compare>& x,
             priority_queue<T, Container, Compare>& y)
@@ -220,14 +257,19 @@ template <class T, class Container, class Compare>
 #include <__algorithm/make_heap.h>
 #include <__algorithm/pop_heap.h>
 #include <__algorithm/push_heap.h>
+#include <__algorithm/ranges_copy.h>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/operations.h>
+#include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
 #include <__utility/forward.h>
 #include <deque>
-#include <type_traits>
 #include <vector>
 #include <version>
 
@@ -278,18 +320,30 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     queue(const queue& __q) : c(__q.c) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class _InputIterator,
-              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+              class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
     _LIBCPP_HIDE_FROM_ABI
     queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
 
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
+
     template <class _InputIterator,
               class _Alloc,
-              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+              class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
               class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
     _LIBCPP_HIDE_FROM_ABI
     queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}
+
+    template <_ContainerCompatibleRange<_Tp> _Range,
+              class _Alloc,
+              class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    queue(from_range_t, _Range&& __range, const _Alloc& __alloc)
+      : c(from_range, std::forward<_Range>(__range), __alloc) {}
+
 #endif
 
     _LIBCPP_INLINE_VISIBILITY
@@ -361,9 +415,24 @@ public:
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     void push(value_type&& __v)      {c.push_back(_VSTD::move(__v));}
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void push_range(_Range&& __range) {
+      if constexpr (requires (container_type& __c) {
+        __c.append_range(std::forward<_Range>(__range));
+      }) {
+        c.append_range(std::forward<_Range>(__range));
+      } else {
+        ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
+      }
+    }
+#endif
+
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         decltype(auto) emplace(_Args&&... __args)
             { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
 #else
@@ -384,20 +453,20 @@ public:
 
     _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
 
-    template <class _T1, class _C1>
+    template <class _T1, class _OtherContainer>
     friend
     _LIBCPP_INLINE_VISIBILITY
     bool
-    operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
+    operator==(const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
 
-    template <class _T1, class _C1>
+    template <class _T1, class _OtherContainer>
     friend
     _LIBCPP_INLINE_VISIBILITY
     bool
-    operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
+    operator< (const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Container,
          class = enable_if_t<!__is_allocator<_Container>::value>
 >
@@ -413,18 +482,28 @@ queue(_Container, _Alloc)
     -> queue<typename _Container::value_type, _Container>;
 #endif
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class _InputIterator,
-          class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+          class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
 queue(_InputIterator, _InputIterator)
     -> queue<__iter_value_type<_InputIterator>>;
 
+template <ranges::input_range _Range>
+queue(from_range_t, _Range&&)
+    -> queue<ranges::range_value_t<_Range>>;
+
 template <class _InputIterator,
           class _Alloc,
-          class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+          class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
           class = __enable_if_t<__is_allocator<_Alloc>::value>>
 queue(_InputIterator, _InputIterator, _Alloc)
     -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
+
+template <ranges::input_range _Range,
+          class _Alloc,
+          class = __enable_if_t<__is_allocator<_Alloc>::value>>
+queue(from_range_t, _Range&&, _Alloc)
+    -> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
 #endif
 
 template <class _Tp, class _Container>
@@ -475,6 +554,17 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
     return !(__y < __x);
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp, three_way_comparable _Container>
+_LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container>
+operator<=>(const queue<_Tp, _Container>& __x, const queue<_Tp, _Container>& __y) {
+    // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors
+    return __x.__get_container() <=> __y.__get_container();
+}
+
+#endif
+
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
 __enable_if_t<__is_swappable<_Container>::value, void>
@@ -544,20 +634,31 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     priority_queue(const value_compare& __comp, container_type&& __c);
 #endif
-    template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp = value_compare());
-    template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp, const container_type& __c);
 #ifndef _LIBCPP_CXX03_LANG
-    template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp, container_type&& __c);
 #endif // _LIBCPP_CXX03_LANG
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare())
+    : c(from_range, std::forward<_Range>(__range)),
+      comp(__comp) {
+      std::make_heap(c.begin(), c.end(), comp);
+    }
+#endif
+
     template <class _Alloc>
         _LIBCPP_INLINE_VISIBILITY
         explicit priority_queue(const _Alloc& __a,
@@ -587,31 +688,55 @@ public:
                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
 #endif // _LIBCPP_CXX03_LANG
 
-    template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l, const _Alloc& __a,
                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
 
-    template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp, const _Alloc& __a,
                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
 
-    template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp, const container_type& __c, const _Alloc& __a,
                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
 
 #ifndef _LIBCPP_CXX03_LANG
-    template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
+    template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
         _LIBCPP_INLINE_VISIBILITY
         priority_queue(_InputIter __f, _InputIter __l,
                        const value_compare& __comp, container_type&& __c, const _Alloc& __a,
                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
 #endif  // _LIBCPP_CXX03_LANG
 
+#if _LIBCPP_STD_VER >= 23
+
+    template <_ContainerCompatibleRange<_Tp> _Range,
+              class _Alloc,
+              class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a)
+    : c(from_range, std::forward<_Range>(__range), __a),
+      comp(__comp) {
+      std::make_heap(c.begin(), c.end(), comp);
+    }
+
+    template <_ContainerCompatibleRange<_Tp> _Range,
+              class _Alloc,
+              class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    priority_queue(from_range_t, _Range&& __range, const _Alloc& __a)
+    : c(from_range, std::forward<_Range>(__range), __a),
+      comp() {
+      std::make_heap(c.begin(), c.end(), comp);
+    }
+
+#endif
+
     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
     bool            empty() const {return c.empty();}
     _LIBCPP_INLINE_VISIBILITY
@@ -624,6 +749,23 @@ public:
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     void push(value_type&& __v);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void push_range(_Range&& __range) {
+      if constexpr (requires (container_type& __c) {
+        __c.append_range(std::forward<_Range>(__range));
+      }) {
+        c.append_range(std::forward<_Range>(__range));
+      } else {
+        ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
+      }
+
+      std::make_heap(c.begin(), c.end(), comp);
+    }
+#endif
+
     template <class... _Args>
     _LIBCPP_INLINE_VISIBILITY
     void emplace(_Args&&... __args);
@@ -651,7 +793,7 @@ priority_queue(_Compare, _Container)
 template<class _InputIterator,
          class _Compare = less<__iter_value_type<_InputIterator>>,
          class _Container = vector<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Compare>::value>,
          class = enable_if_t<!__is_allocator<_Container>::value>
 >
@@ -669,7 +811,7 @@ priority_queue(_Compare, _Container, _Alloc)
     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>
 >
 priority_queue(_InputIterator, _InputIterator, _Allocator)
@@ -678,7 +820,7 @@ priority_queue(_InputIterator, _InputIterator, _Allocator)
                       less<__iter_value_type<_InputIterator>>>;
 
 template<class _InputIterator, class _Compare, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Compare>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>
 >
@@ -687,7 +829,7 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator)
                       vector<__iter_value_type<_InputIterator>, _Allocator>, _Compare>;
 
 template<class _InputIterator, class _Compare, class _Container, class _Alloc,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Compare>::value>,
          class = enable_if_t<!__is_allocator<_Container>::value>,
          class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
@@ -696,6 +838,31 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range,
+          class _Compare = less<ranges::range_value_t<_Range>>,
+          class = enable_if_t<!__is_allocator<_Compare>::value>>
+priority_queue(from_range_t, _Range&&, _Compare = _Compare())
+    -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;
+
+template <ranges::input_range _Range,
+          class _Compare,
+          class _Alloc,
+          class = enable_if_t<!__is_allocator<_Compare>::value>,
+          class = enable_if_t<__is_allocator<_Alloc>::value>>
+priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
+    -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>,
+                        _Compare>;
+
+template <ranges::input_range _Range,
+          class _Alloc,
+          class = enable_if_t<__is_allocator<_Alloc>::value>>
+priority_queue(from_range_t, _Range&&, _Alloc)
+    -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;
+
+#endif
+
 template <class _Tp, class _Container, class _Compare>
 inline
 priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
@@ -964,7 +1131,9 @@ _LIBCPP_END_NAMESPACE_STD
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_QUEUE
lib/libcxx/include/random
@@ -1734,6 +1734,7 @@ class piecewise_linear_distribution
 #  include <concepts>
 #  include <cstddef>
 #  include <cstdint>
+#  include <cstdlib>
 #  include <iosfwd>
 #  include <limits>
 #  include <numeric>
lib/libcxx/include/ranges
@@ -49,6 +49,8 @@ namespace std::ranges {
     using range_reference_t = iter_reference_t<iterator_t<R>>;
   template<range R>
     using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
+  template <range R>
+    using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
 
   // [range.sized], sized ranges
   template<class>
@@ -136,6 +138,16 @@ namespace std::ranges {
     inline constexpr auto values = elements<1>;
   }
 
+  // [range.utility.conv], range conversions
+  template<class C, input_range R, class... Args> requires (!view<C>)
+    constexpr C to(R&& r, Args&&... args);     // Since C++23
+  template<template<class...> class C, input_range R, class... Args>
+    constexpr auto to(R&& r, Args&&... args);  // Since C++23
+  template<class C, class... Args> requires (!view<C>)
+    constexpr auto to(Args&&... args);         // Since C++23
+  template<template<class...> class C, class... Args>
+    constexpr auto to(Args&&... args);         // Since C++23
+
   // [range.empty], empty view
   template<class T>
     requires is_object_v<T>
@@ -250,6 +262,19 @@ namespace std::ranges {
   template<class W, class Bound>
     inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
 
+  // [range.repeat], repeat view
+  template<class T>
+    concept integer-like-with-usable-difference-type =  // exposition only
+      is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>);
+
+  template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
+    requires (is_object_v<T> && same_as<T, remove_cv_t<T>> &&
+              (integer-like-with-usable-difference-type<Bound> ||
+               same_as<Bound, unreachable_sentinel_t>))
+  class repeat_view;
+
+  namespace views { inline constexpr unspecified repeat = unspecified; }
+
   // [range.join], join view
   template<input_range V>
     requires view<V> && input_range<range_reference_t<V>>
@@ -292,13 +317,13 @@ namespace std::ranges {
   // [range.zip], zip view
   template<input_range... Views>
     requires (view<Views> && ...) && (sizeof...(Views) > 0)
-  class zip_view;        // C++2b
+  class zip_view;        // C++23
 
   template<class... Views>
-    inline constexpr bool enable_borrowed_range<zip_view<Views...>> =    // C++2b
+    inline constexpr bool enable_borrowed_range<zip_view<Views...>> =    // C++23
       (enable_borrowed_range<Views> && ...);
 
-  namespace views { inline constexpr unspecified zip = unspecified; }    // C++2b
+  namespace views { inline constexpr unspecified zip = unspecified; }    // C++23
 
   // [range.as.rvalue]
   template <view V>
@@ -337,6 +362,9 @@ namespace std {
   struct tuple_element<1, const ranges::subrange<I, S, K>> {
     using type = S;
   };
+
+  struct from_range_t { explicit from_range_t() = default; };  // Since C++23
+  inline constexpr from_range_t from_range{};                  // Since C++23
 }
 */
 
@@ -358,12 +386,14 @@ namespace std {
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/enable_view.h>
 #include <__ranges/filter_view.h>
+#include <__ranges/from_range.h>
 #include <__ranges/iota_view.h>
 #include <__ranges/join_view.h>
 #include <__ranges/lazy_split_view.h>
 #include <__ranges/rbegin.h>
 #include <__ranges/ref_view.h>
 #include <__ranges/rend.h>
+#include <__ranges/repeat_view.h>
 #include <__ranges/reverse_view.h>
 #include <__ranges/single_view.h>
 #include <__ranges/size.h>
@@ -371,11 +401,11 @@ namespace std {
 #include <__ranges/subrange.h>
 #include <__ranges/take_view.h>
 #include <__ranges/take_while_view.h>
+#include <__ranges/to.h>
 #include <__ranges/transform_view.h>
 #include <__ranges/view_interface.h>
 #include <__ranges/views.h>
 #include <__ranges/zip_view.h>
-#include <type_traits>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
@@ -390,11 +420,16 @@ namespace std {
 #include <iterator>
 
 // [tuple.helper]
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_size.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
+#  include <type_traits>
+#endif
+
 #endif // _LIBCPP_RANGES
lib/libcxx/include/ratio
@@ -40,6 +40,8 @@ template <class R1, class R2> struct ratio_greater;
 template <class R1, class R2> struct ratio_greater_equal;
 
 // convenience SI typedefs
+using quecto = ratio <1, 1'000'000'000'000'000'000'000'000'000'000>; // Since C++26; not supported
+using ronto = ratio <1, 1'000'000'000'000'000'000'000'000'000>;      // Since C++26; not supported
 typedef ratio<1, 1000000000000000000000000> yocto;  // not supported
 typedef ratio<1,    1000000000000000000000> zepto;  // not supported
 typedef ratio<1,       1000000000000000000> atto;
@@ -60,6 +62,8 @@ typedef ratio<         1000000000000000, 1> peta;
 typedef ratio<      1000000000000000000, 1> exa;
 typedef ratio<   1000000000000000000000, 1> zetta;  // not supported
 typedef ratio<1000000000000000000000000, 1> yotta;  // not supported
+using ronna = ratio <1'000'000'000'000'000'000'000'000'000, 1>;      // Since C++26; not supported
+using quetta = ratio <1'000'000'000'000'000'000'000'000'000'000, 1>; // Since C++26; not supported
 
   // 20.11.5, ratio comparison
   template <class R1, class R2> inline constexpr bool ratio_equal_v
@@ -501,7 +505,7 @@ struct __ratio_gcd
                   __static_lcm<_R1::den, _R2::den>::value> type;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _R1, class _R2>
 inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value;
 
lib/libcxx/include/regex
@@ -13,6 +13,7 @@
 /*
     regex synopsis
 
+#include <compare>
 #include <initializer_list>
 
 namespace std
@@ -225,6 +226,8 @@ public:
     int compare(const sub_match& s) const;
     int compare(const string_type& s) const;
     int compare(const value_type* s) const;
+
+    void swap(sub_match& s) noexcept(see below);
 };
 
 typedef sub_match<const char*>             csub_match;
@@ -237,50 +240,54 @@ template <class BiIter>
     operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
 template <class BiIter>
+    auto
+    operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); // Since C++20
+
+ template <class BiIter>                                                     // Removed in C++20
     bool
     operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
                     const sub_match<BiIter>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
                const sub_match<BiIter>& rhs);
@@ -290,56 +297,62 @@ template <class BiIter, class ST, class SA>
     operator==(const sub_match<BiIter>& lhs,
                const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Since C++20
+    auto
+    operator<=>(const sub_match<BiIter>& lhs,
+                const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator!=(const sub_match<BiIter>& lhs,
                const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator<(const sub_match<BiIter>& lhs,
               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter, class ST, class SA>
-    bool operator>(const sub_match<BiIter>& lhs,
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
+    bool
+    operator>(const sub_match<BiIter>& lhs,
                    const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator>=(const sub_match<BiIter>& lhs,
                const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter, class ST, class SA>
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator<=(const sub_match<BiIter>& lhs,
                const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator==(typename iterator_traits<BiIter>::value_type const* lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<(typename iterator_traits<BiIter>::value_type const* lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>(typename iterator_traits<BiIter>::value_type const* lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
                const sub_match<BiIter>& rhs);
@@ -349,57 +362,62 @@ template <class BiIter>
     operator==(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Since C++20
+    auto
+    operator<=>(const sub_match<BiIter>& lhs,
+                typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter, class ST, class SA>                                  // Removed in C++20
     bool
     operator!=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<(const sub_match<BiIter>& lhs,
               typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>(const sub_match<BiIter>& lhs,
               typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const* rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator==(typename iterator_traits<BiIter>::value_type const& lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<(typename iterator_traits<BiIter>::value_type const& lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>(typename iterator_traits<BiIter>::value_type const& lhs,
               const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
                const sub_match<BiIter>& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
                const sub_match<BiIter>& rhs);
@@ -409,27 +427,32 @@ template <class BiIter>
     operator==(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Since C++20
+    auto
+    operator<=>(const sub_match<BiIter>& lhs,
+                typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator!=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<(const sub_match<BiIter>& lhs,
               typename iterator_traits<BiIter>::value_type const& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>(const sub_match<BiIter>& lhs,
               typename iterator_traits<BiIter>::value_type const& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator>=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const& rhs);
 
-template <class BiIter>
+template <class BiIter>                                                      // Removed in C++20
     bool
     operator<=(const sub_match<BiIter>& lhs,
                typename iterator_traits<BiIter>::value_type const& rhs);
@@ -520,7 +543,7 @@ template <class BidirectionalIterator, class Allocator>
     operator==(const match_results<BidirectionalIterator, Allocator>& m1,
                const match_results<BidirectionalIterator, Allocator>& m2);
 
-template <class BidirectionalIterator, class Allocator>
+template <class BidirectionalIterator, class Allocator>                    // Removed in C++20
     bool
     operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
                const match_results<BidirectionalIterator, Allocator>& m2);
@@ -687,7 +710,8 @@ public:
     regex_iterator& operator=(const regex_iterator&);
 
     bool operator==(const regex_iterator&) const;
-    bool operator!=(const regex_iterator&) const;
+    bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20
+    bool operator!=(const regex_iterator&) const;                                   // Removed in C++20
 
     const value_type& operator*() const;
     const value_type* operator->() const;
@@ -745,7 +769,8 @@ public:
     regex_token_iterator& operator=(const regex_token_iterator&);
 
     bool operator==(const regex_token_iterator&) const;
-    bool operator!=(const regex_token_iterator&) const;
+    bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20
+    bool operator!=(const regex_token_iterator&) const;                                   // Removed in C++20
 
     const value_type& operator*() const;
     const value_type* operator->() const;
@@ -765,15 +790,19 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #include <__algorithm/find.h>
 #include <__algorithm/search.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
+#include <__iterator/default_sentinel.h>
 #include <__iterator/wrap_iter.h>
 #include <__locale>
+#include <__memory/shared_ptr.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__type_traits/is_swappable.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
 #include <__utility/swap.h>
-#include <cstring>
+#include <__verbose_abort>
 #include <deque>
 #include <stdexcept>
 #include <string>
@@ -996,13 +1025,13 @@ enum error_type
 
 } // namespace regex_constants
 
-class _LIBCPP_EXCEPTION_ABI regex_error
+class _LIBCPP_EXPORTED_FROM_ABI regex_error
     : public runtime_error
 {
     regex_constants::error_type __code_;
 public:
     explicit regex_error(regex_constants::error_type __ecode);
-    regex_error(const regex_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
     ~regex_error() _NOEXCEPT override;
     _LIBCPP_INLINE_VISIBILITY
     regex_constants::error_type code() const {return __code_;}
@@ -1012,10 +1041,10 @@ template <regex_constants::error_type _Ev>
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_regex_error()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw regex_error(_Ev);
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode");
 #endif
 }
 
@@ -1221,7 +1250,7 @@ regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
 
 // lookup_collatename is very FreeBSD-specific
 
-_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s);
+_LIBCPP_EXPORTED_FROM_ABI string __get_collation_name(const char* __s);
 
 template <class _CharT>
 template <class _ForwardIterator>
@@ -1284,8 +1313,7 @@ regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
 
 // lookup_classname
 
-regex_traits<char>::char_class_type _LIBCPP_FUNC_VIS
-__get_classname(const char* __s, bool __icase);
+regex_traits<char>::char_class_type _LIBCPP_EXPORTED_FROM_ABI __get_classname(const char* __s, bool __icase);
 
 template <class _CharT>
 template <class _ForwardIterator>
@@ -1467,7 +1495,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     __end_state() {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1533,7 +1561,7 @@ public:
     explicit __empty_state(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1559,7 +1587,7 @@ public:
     explicit __empty_non_own_state(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1585,7 +1613,7 @@ public:
     explicit __repeat_one_loop(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1611,7 +1639,7 @@ public:
     explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
         : base(__s1), __second_(__s2) {}
 
-    virtual ~__owns_two_states();
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__owns_two_states();
 
     _LIBCPP_INLINE_VISIBILITY
     base*  second() const {return __second_;}
@@ -1654,8 +1682,8 @@ public:
           __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end),
           __greedy_(__greedy) {}
 
-    virtual void __exec(__state& __s) const;
-    virtual void __exec_split(bool __second, __state& __s) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
 
 private:
     _LIBCPP_INLINE_VISIBILITY
@@ -1747,8 +1775,8 @@ public:
                          __owns_one_state<_CharT>* __s2)
         : base(__s1, __s2) {}
 
-    virtual void __exec(__state& __s) const;
-    virtual void __exec_split(bool __second, __state& __s) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
 };
 
 template <class _CharT>
@@ -1785,7 +1813,7 @@ public:
     explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
         : base(__s), __mexp_(__mexp) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1813,7 +1841,7 @@ public:
     explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
         : base(__s), __mexp_(__mexp) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1842,7 +1870,7 @@ public:
     explicit __back_ref(unsigned __mexp, __node<_CharT>* __s)
         : base(__s), __mexp_(__mexp) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -1893,7 +1921,7 @@ public:
                               __node<_CharT>* __s)
         : base(__s), __traits_(__traits), __mexp_(__mexp) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -1948,7 +1976,7 @@ public:
                               __node<_CharT>* __s)
         : base(__s), __traits_(__traits), __mexp_(__mexp) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -2003,7 +2031,7 @@ public:
                              __node<_CharT>* __s)
         : base(__s), __traits_(__traits), __invert_(__invert) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -2079,7 +2107,7 @@ public:
     __l_anchor_multiline(bool __multiline, __node<_CharT>* __s)
         : base(__s), __multiline_(__multiline) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -2123,7 +2151,7 @@ public:
     __r_anchor_multiline(bool __multiline, __node<_CharT>* __s)
         : base(__s), __multiline_(__multiline) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -2163,7 +2191,7 @@ public:
     __match_any(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -2201,9 +2229,9 @@ public:
     void __exec(__state&) const override;
 };
 
-template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const;
+template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state&) const;
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const;
+template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state&) const;
 #endif
 
 // __match_char
@@ -2225,7 +2253,7 @@ public:
     __match_char(_CharT __c, __node<_CharT>* __s)
         : base(__s), __c_(__c) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT>
@@ -2265,7 +2293,7 @@ public:
     __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
         : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -2306,7 +2334,7 @@ public:
     __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
         : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -2361,7 +2389,7 @@ public:
           __negate_(__negate), __icase_(__icase), __collate_(__collate),
           __might_have_digraph_(__traits_.getloc().name() != "C") {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 
     _LIBCPP_INLINE_VISIBILITY
     bool __negated() const {return __negate_;}
@@ -2750,7 +2778,7 @@ public:
 
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
-        typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_regex&>::type
+        typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value, basic_regex&>::type
         assign(_InputIterator __first, _InputIterator __last,
                             flag_type __f = regex_constants::ECMAScript)
         {
@@ -2774,7 +2802,7 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         typename enable_if
         <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
+            __has_forward_iterator_category<_ForwardIterator>::value,
             basic_regex&
         >::type
         assign(_ForwardIterator __first, _ForwardIterator __last,
@@ -3082,7 +3110,7 @@ private:
 
 #if _LIBCPP_STD_VER >= 17
 template <class _ForwardIterator,
-          class = typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value, nullptr_t>::type
+          class = typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value, nullptr_t>::type
 >
 basic_regex(_ForwardIterator, _ForwardIterator,
             regex_constants::syntax_option_type = regex_constants::ECMAScript)
@@ -3153,7 +3181,7 @@ public:
     __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
         : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}
 
-    virtual void __exec(__state&) const;
+    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
 };
 
 template <class _CharT, class _Traits>
@@ -4131,9 +4159,9 @@ basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first
 {
     // Found [=
     //   This means =] must exist
-    value_type _Equal_close[2] = {'=', ']'};
-    _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close,
-                                                            _Equal_close+2);
+    value_type __equal_close[2] = {'=', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, __equal_close,
+                                                            __equal_close+2);
     if (__temp == __last)
         __throw_regex_error<regex_constants::error_brack>();
     // [__first, __temp) contains all text in [= ... =]
@@ -4173,9 +4201,9 @@ basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,
 {
     // Found [:
     //   This means :] must exist
-    value_type _Colon_close[2] = {':', ']'};
-    _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close,
-                                                            _Colon_close+2);
+    value_type __colon_close[2] = {':', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, __colon_close,
+                                                            __colon_close+2);
     if (__temp == __last)
         __throw_regex_error<regex_constants::error_brack>();
     // [__first, __temp) contains all text in [: ... :]
@@ -4198,9 +4226,9 @@ basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,
 {
     // Found [.
     //   This means .] must exist
-    value_type _Dot_close[2] = {'.', ']'};
-    _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close,
-                                                            _Dot_close+2);
+    value_type __dot_close[2] = {'.', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, __dot_close,
+                                                            __dot_close+2);
     if (__temp == __last)
         __throw_regex_error<regex_constants::error_brack>();
     // [__first, __temp) contains all text in [. ... .]
@@ -5009,6 +5037,16 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     int compare(const value_type* __s) const
         {return str().compare(__s);}
+
+    _LIBCPP_HIDE_FROM_ABI
+    void swap(sub_match& __s)
+#ifndef _LIBCPP_CXX03_LANG
+    _NOEXCEPT(__is_nothrow_swappable<_BidirectionalIterator>::value)
+#endif // _LIBCPP_CXX03_LANG
+    {
+        this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
+        std::swap(matched, __s.matched);
+    }
 };
 
 template <class _BiIter>
@@ -5019,6 +5057,15 @@ operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
     return __x.compare(__y) == 0;
 }
 
+#if _LIBCPP_STD_VER >= 20
+template<class _BiIter>
+using __sub_match_cat = compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>;
+
+template <class _BiIter>
+_LIBCPP_HIDE_FROM_ABI auto operator<=>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
+    return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
+}
+#else // _LIBCPP_STD_VER >= 20
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5111,6 +5158,7 @@ operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST
 {
     return !(__y < __x);
 }
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _BiIter, class _ST, class _SA>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5121,6 +5169,14 @@ operator==(const sub_match<_BiIter>& __x,
     return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0;
 }
 
+#if _LIBCPP_STD_VER >= 20
+template <class _BiIter, class _ST, class _SA>
+_LIBCPP_HIDE_FROM_ABI auto operator<=>(
+    const sub_match<_BiIter>& __x, const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
+    return static_cast<__sub_match_cat<_BiIter>>(
+        __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) <=> 0);
+}
+#else // _LIBCPP_STD_VER >= 20
 template <class _BiIter, class _ST, class _SA>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5218,6 +5274,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const* __x,
 {
     return !(__y < __x);
 }
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5228,6 +5285,13 @@ operator==(const sub_match<_BiIter>& __x,
     return __x.compare(__y) == 0;
 }
 
+#if _LIBCPP_STD_VER >= 20
+template <class _BiIter>
+_LIBCPP_HIDE_FROM_ABI auto
+operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
+    return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
+}
+#else // _LIBCPP_STD_VER >= 20
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5328,6 +5392,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const& __x,
 {
     return !(__y < __x);
 }
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5339,6 +5404,14 @@ operator==(const sub_match<_BiIter>& __x,
     return __x.compare(string_type(1, __y)) == 0;
 }
 
+#if _LIBCPP_STD_VER >= 20
+template <class _BiIter>
+_LIBCPP_HIDE_FROM_ABI auto
+operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
+    using string_type = basic_string<typename iterator_traits<_BiIter>::value_type>;
+    return static_cast<__sub_match_cat<_BiIter>>(__x.compare(string_type(1, __y)) <=> 0);
+}
+#else // _LIBCPP_STD_VER >= 20
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5384,6 +5457,7 @@ operator<=(const sub_match<_BiIter>& __x,
 {
     return !(__y < __x);
 }
+#endif // _LIBCPP_STD_VER >= 20
 
 template <class _CharT, class _ST, class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5460,38 +5534,38 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     difference_type length(size_type __sub = 0) const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::length() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::length() called when not ready");
         return (*this)[__sub].length();
         }
     _LIBCPP_INLINE_VISIBILITY
     difference_type position(size_type __sub = 0) const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::position() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::position() called when not ready");
         return _VSTD::distance(__position_start_, (*this)[__sub].first);
         }
     _LIBCPP_INLINE_VISIBILITY
     string_type str(size_type __sub = 0) const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::str() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::str() called when not ready");
         return (*this)[__sub].str();
         }
     _LIBCPP_INLINE_VISIBILITY
     const_reference operator[](size_type __n) const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::operator[]() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::operator[]() called when not ready");
         return __n < __matches_.size() ? __matches_[__n] : __unmatched_;
         }
 
     _LIBCPP_INLINE_VISIBILITY
     const_reference prefix() const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::prefix() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::prefix() called when not ready");
         return __prefix_;
         }
     _LIBCPP_INLINE_VISIBILITY
     const_reference suffix() const
         {
-        _LIBCPP_ASSERT(ready(), "match_results::suffix() called when not ready");
+        _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::suffix() called when not ready");
         return __suffix_;
         }
 
@@ -5631,7 +5705,7 @@ match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output_i
         const char_type* __fmt_first, const char_type* __fmt_last,
         regex_constants::match_flag_type __flags) const
 {
-    _LIBCPP_ASSERT(ready(), "match_results::format() called when not ready");
+    _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::format() called when not ready");
     if (__flags & regex_constants::format_sed)
     {
         for (; __fmt_first != __fmt_last; ++__fmt_first)
@@ -5747,6 +5821,7 @@ operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
            __x.__suffix_ == __y.__suffix_;
 }
 
+#if _LIBCPP_STD_VER < 20
 template <class _BidirectionalIterator, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5755,6 +5830,7 @@ operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
 {
     return !(__x == __y);
 }
+#endif
 
 template <class _BidirectionalIterator, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5861,7 +5937,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
 {
     deque<__state> __states;
     ptrdiff_t __highest_j = 0;
-    ptrdiff_t _Np = _VSTD::distance(__first, __last);
+    ptrdiff_t __np = _VSTD::distance(__first, __last);
     __node* __st = __start_.get();
     if (__st)
     {
@@ -5904,7 +5980,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
                 if (!__matched || __highest_j < __s.__current_ - __s.__first_)
                     __highest_j = __s.__current_ - __s.__first_;
                 __matched = true;
-                if (__highest_j == _Np)
+                if (__highest_j == __np)
                     __states.clear();
                 else
                     __states.pop_back();
@@ -5956,7 +6032,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
     vector<__state> __states;
     __state __best_state;
     ptrdiff_t __highest_j = 0;
-    ptrdiff_t _Np = _VSTD::distance(__first, __last);
+    ptrdiff_t __np = _VSTD::distance(__first, __last);
     __node* __st = __start_.get();
     if (__st)
     {
@@ -6008,7 +6084,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
                     __best_state = __s;
                 }
                 __matched = true;
-                if (__highest_j == _Np)
+                if (__highest_j == __np)
                     __states.clear();
                 else
                     __states.pop_back();
@@ -6214,7 +6290,7 @@ regex_search(const basic_string<_CharT, _ST, _SA>& __s,
     return __r;
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
 bool
 regex_search(const basic_string<_Cp, _ST, _SA>&& __s,
@@ -6277,7 +6353,7 @@ regex_match(const basic_string<_CharT, _ST, _SA>& __s,
     return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -6350,16 +6426,21 @@ public:
                    const regex_type& __re,
                    regex_constants::match_flag_type __m
                                               = regex_constants::match_default);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
                    const regex_type&& __re,
                    regex_constants::match_flag_type __m
                                      = regex_constants::match_default) = delete;
 #endif
 
-    bool operator==(const regex_iterator& __x) const;
+    _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_iterator& __x) const;
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
+#endif
+#if _LIBCPP_STD_VER < 20
     _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const regex_iterator& __x) const {return !(*this == __x);}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return  __match_;}
@@ -6482,7 +6563,7 @@ public:
                          const regex_type& __re, int __submatch = 0,
                          regex_constants::match_flag_type __m =
                                                 regex_constants::match_default);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
                          const regex_type&& __re, int __submatch = 0,
                          regex_constants::match_flag_type __m =
@@ -6493,7 +6574,7 @@ public:
                          const regex_type& __re, const vector<int>& __submatches,
                          regex_constants::match_flag_type __m =
                                                 regex_constants::match_default);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
                          const regex_type&& __re, const vector<int>& __submatches,
                          regex_constants::match_flag_type __m =
@@ -6507,7 +6588,7 @@ public:
                          regex_constants::match_flag_type __m =
                                                 regex_constants::match_default);
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
                          const regex_type&& __re,
                          initializer_list<int> __submatches,
@@ -6522,7 +6603,7 @@ public:
                              const int (&__submatches)[_Np],
                              regex_constants::match_flag_type __m =
                                                 regex_constants::match_default);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <size_t _Np>
         regex_token_iterator(_BidirectionalIterator __a,
                              _BidirectionalIterator __b,
@@ -6535,9 +6616,16 @@ public:
     regex_token_iterator(const regex_token_iterator&);
     regex_token_iterator& operator=(const regex_token_iterator&);
 
-    bool operator==(const regex_token_iterator& __x) const;
+    _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_token_iterator& __x) const;
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const {
+        return *this == regex_token_iterator();
+    }
+#endif
+#if _LIBCPP_STD_VER < 20
     _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     const value_type& operator*() const {return *__result_;}
@@ -6844,18 +6932,18 @@ regex_replace(const _CharT* __s,
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _BidirT>
-using match_results = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
+using match_results _LIBCPP_AVAILABILITY_PMR = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
 
-using cmatch  = match_results<const char*>;
-using smatch  = match_results<std::pmr::string::const_iterator>;
+using cmatch _LIBCPP_AVAILABILITY_PMR  = match_results<const char*>;
+using smatch _LIBCPP_AVAILABILITY_PMR  = match_results<std::pmr::string::const_iterator>;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wcmatch = match_results<const wchar_t*>;
-using wsmatch = match_results<std::pmr::wstring::const_iterator>;
+using wcmatch _LIBCPP_AVAILABILITY_PMR = match_results<const wchar_t*>;
+using wsmatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::wstring::const_iterator>;
 #endif
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
@@ -6866,9 +6954,11 @@ _LIBCPP_POP_MACROS
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iosfwd>
 #  include <iterator>
 #  include <new>
+#  include <type_traits>
 #  include <typeinfo>
 #  include <utility>
 #endif
lib/libcxx/include/scoped_allocator
@@ -103,7 +103,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
 template <class OuterA1, class OuterA2, class... InnerAllocs>
     bool
     operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
-               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
+               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20
 
 }  // std
 
@@ -130,6 +130,9 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !defined(_LIBCPP_CXX03_LANG)
@@ -531,7 +534,7 @@ public:
                          __p, _VSTD::forward<_Args>(__args)...);}
 
     template <class _T1, class _T2, class... _Args1, class... _Args2>
-    void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
+    _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
                        tuple<_Args1...> __x, tuple<_Args2...> __y)
     {
         typedef __outermost<outer_allocator_type> _OM;
@@ -555,25 +558,25 @@ public:
     }
 
     template <class _T1, class _T2>
-    void construct(pair<_T1, _T2>* __p)
+    _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p)
     { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
 
     template <class _T1, class _T2, class _Up, class _Vp>
-    void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
+    _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
         construct(__p, piecewise_construct,
                   _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
                   _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
     }
 
     template <class _T1, class _T2, class _Up, class _Vp>
-    void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
+    _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
         construct(__p, piecewise_construct,
                   _VSTD::forward_as_tuple(__x.first),
                   _VSTD::forward_as_tuple(__x.second));
     }
 
     template <class _T1, class _T2, class _Up, class _Vp>
-    void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
+    _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
         construct(__p, piecewise_construct,
                   _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
                   _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
@@ -678,7 +681,7 @@ private:
     template <class...> friend class __scoped_allocator_storage;
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _OuterAlloc, class... _InnerAllocs>
     scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
         -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
@@ -703,6 +706,8 @@ operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>&
            __a.inner_allocator() == __b.inner_allocator();
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -712,10 +717,14 @@ operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
     return !(__a == __b);
 }
 
+#endif // _LIBCPP_STD_VER <= 17
+
 #endif // !defined(_LIBCPP_CXX03_LANG)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
 #  include <climits>
lib/libcxx/include/semaphore
@@ -46,12 +46,15 @@ using binary_semaphore = counting_semaphore<1>;
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__atomic/atomic_base.h>
+#include <__atomic/atomic_sync.h>
+#include <__atomic/memory_order.h>
 #include <__availability>
 #include <__chrono/time_point.h>
 #include <__config>
 #include <__thread/timed_backoff_policy.h>
 #include <__threading_support>
-#include <atomic>
+#include <cstddef>
 #include <limits>
 #include <version>
 
@@ -78,6 +81,8 @@ functions. It avoids contention against users' own use of those facilities.
 
 */
 
+#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
+
 class __atomic_semaphore_base
 {
     __atomic_base<ptrdiff_t> __a_;
@@ -90,9 +95,14 @@ public:
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void release(ptrdiff_t __update = 1)
     {
-        if(0 < __a_.fetch_add(__update, memory_order_release))
-            ;
-        else if(__update > 1)
+        auto __old = __a_.fetch_add(__update, memory_order_release);
+        _LIBCPP_ASSERT_UNCATEGORIZED(__update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value");
+
+        if (__old > 0)
+        {
+            // Nothing to do
+        }
+        else if (__update > 1)
             __a_.notify_all();
         else
             __a_.notify_one();
@@ -106,11 +116,11 @@ public:
         };
         __cxx_atomic_wait(&__a_.__a_, __test_fn);
     }
-    template <class Rep, class Period>
+    template <class _Rep, class _Period>
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
+    bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time)
     {
-        if (__rel_time == chrono::duration<Rep, Period>::zero())
+        if (__rel_time == chrono::duration<_Rep, _Period>::zero())
             return try_acquire();
         auto const __test_fn = [this]() { return try_acquire(); };
         return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
@@ -128,20 +138,30 @@ public:
     }
 };
 
-#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
-
 template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
 class counting_semaphore
 {
     __atomic_semaphore_base __semaphore_;
 
 public:
+    static_assert(__least_max_value >= 0, "The least maximum value must be a positive number");
+
     static constexpr ptrdiff_t max() noexcept {
         return __least_max_value;
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) { }
+    constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __count >= 0,
+            "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
+            "initialized with a negative value");
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __count <= max(),
+            "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
+            "initialized with a value greater than max()");
+    }
     ~counting_semaphore() = default;
 
     counting_semaphore(const counting_semaphore&) = delete;
@@ -150,6 +170,7 @@ public:
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void release(ptrdiff_t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(__update >= 0, "counting_semaphore:release called with a negative value");
         __semaphore_.release(__update);
     }
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
@@ -157,9 +178,9 @@ public:
     {
         __semaphore_.acquire();
     }
-    template<class Rep, class Period>
+    template<class _Rep, class _Period>
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
+    bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time)
     {
         return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
     }
@@ -168,15 +189,15 @@ public:
     {
         return __semaphore_.try_acquire();
     }
-    template <class Clock, class Duration>
+    template <class _Clock, class _Duration>
     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
-    bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time)
+    bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time)
     {
-        auto const current = Clock::now();
-        if (current >= __abs_time)
+        auto const __current = _Clock::now();
+        if (__current >= __abs_time)
             return try_acquire();
         else
-            return try_acquire_for(__abs_time - current);
+            return try_acquire_for(__abs_time - __current);
     }
 };
 
@@ -188,4 +209,8 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <atomic>
+#endif
+
 #endif //_LIBCPP_SEMAPHORE
lib/libcxx/include/set
@@ -56,6 +56,8 @@ public:
     template <class InputIterator>
         set(InputIterator first, InputIterator last, const value_compare& comp,
             const allocator_type& a);
+    template<container-compatible-range<value_type> R>
+      set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
     set(const set& s);
     set(set&& s)
         noexcept(
@@ -70,6 +72,9 @@ public:
     template <class InputIterator>
         set(InputIterator first, InputIterator last, const allocator_type& a)
             : set(first, last, Compare(), a) {}  // C++14
+    template<container-compatible-range<value_type> R>
+      set(from_range_t, R&& rg, const Allocator& a))
+        : set(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
     set(initializer_list<value_type> il, const allocator_type& a)
         : set(il, Compare(), a) {}  // C++14
     ~set();
@@ -114,6 +119,8 @@ public:
     iterator insert(const_iterator position, value_type&& v);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                                      // C++23
     void insert(initializer_list<value_type> il);
 
     node_type extract(const_iterator position);                                       // C++17
@@ -190,6 +197,11 @@ set(InputIterator, InputIterator,
     Compare = Compare(), Allocator = Allocator())
   -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
 
+template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
+         class Allocator = allocator<ranges::range_value_t<R>>>
+  set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
+    -> set<ranges::range_value_t<R>, Compare, Allocator>; // C++23
+
 template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
 set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
   -> set<Key, Compare, Allocator>; // C++17
@@ -199,6 +211,10 @@ set(InputIterator, InputIterator, Allocator)
   -> set<typename iterator_traits<InputIterator>::value_type,
           less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  set(from_range_t, R&&, Allocator)
+    -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; // C++23
+
 template<class Key, class Allocator>
 set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17
 
@@ -210,27 +226,31 @@ operator==(const set<Key, Compare, Allocator>& x,
 template <class Key, class Compare, class Allocator>
 bool
 operator< (const set<Key, Compare, Allocator>& x,
-           const set<Key, Compare, Allocator>& y);
+           const set<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator!=(const set<Key, Compare, Allocator>& x,
-           const set<Key, Compare, Allocator>& y);
+           const set<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator> (const set<Key, Compare, Allocator>& x,
-           const set<Key, Compare, Allocator>& y);
+           const set<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator>=(const set<Key, Compare, Allocator>& x,
-           const set<Key, Compare, Allocator>& y);
+           const set<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator<=(const set<Key, Compare, Allocator>& x,
-           const set<Key, Compare, Allocator>& y);
+           const set<Key, Compare, Allocator>& y);                                // removed in C++20
+
+template<class Key, class Compare, class Allocator>
+  synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
+                                          const set<Key, Compare, Allocator>& y); // since C++20
 
 // specialized algorithms:
 template <class Key, class Compare, class Allocator>
@@ -280,6 +300,9 @@ public:
     template <class InputIterator>
         multiset(InputIterator first, InputIterator last,
                  const value_compare& comp, const allocator_type& a);
+    template<container-compatible-range<value_type> R>
+      multiset(from_range_t, R&& rg,
+               const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
     multiset(const multiset& s);
     multiset(multiset&& s)
         noexcept(
@@ -294,6 +317,9 @@ public:
     template <class InputIterator>
         multiset(InputIterator first, InputIterator last, const allocator_type& a)
             : set(first, last, Compare(), a) {}  // C++14
+    template<container-compatible-range<value_type> R>
+      multiset(from_range_t, R&& rg, const Allocator& a))
+        : multiset(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
     multiset(initializer_list<value_type> il, const allocator_type& a)
         : set(il, Compare(), a) {}  // C++14
     ~multiset();
@@ -338,6 +364,8 @@ public:
     iterator insert(const_iterator position, value_type&& v);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                                      // C++23
     void insert(initializer_list<value_type> il);
 
     node_type extract(const_iterator position);                                       // C++17
@@ -415,6 +443,11 @@ multiset(InputIterator, InputIterator,
     Compare = Compare(), Allocator = Allocator())
   -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
 
+template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
+          class Allocator = allocator<ranges::range_value_t<R>>>
+  multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
+    -> multiset<ranges::range_value_t<R>, Compare, Allocator>;
+
 template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
 multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
   -> multiset<Key, Compare, Allocator>; // C++17
@@ -424,6 +457,10 @@ multiset(InputIterator, InputIterator, Allocator)
   -> multiset<typename iterator_traits<InputIterator>::value_type,
           less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  multiset(from_range_t, R&&, Allocator)
+    -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
+
 template<class Key, class Allocator>
 multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17
 
@@ -435,27 +472,31 @@ operator==(const multiset<Key, Compare, Allocator>& x,
 template <class Key, class Compare, class Allocator>
 bool
 operator< (const multiset<Key, Compare, Allocator>& x,
-           const multiset<Key, Compare, Allocator>& y);
+           const multiset<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator!=(const multiset<Key, Compare, Allocator>& x,
-           const multiset<Key, Compare, Allocator>& y);
+           const multiset<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator> (const multiset<Key, Compare, Allocator>& x,
-           const multiset<Key, Compare, Allocator>& y);
+           const multiset<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator>=(const multiset<Key, Compare, Allocator>& x,
-           const multiset<Key, Compare, Allocator>& y);
+           const multiset<Key, Compare, Allocator>& y);                                // removed in C++20
 
 template <class Key, class Compare, class Allocator>
 bool
 operator<=(const multiset<Key, Compare, Allocator>& x,
-           const multiset<Key, Compare, Allocator>& y);
+           const multiset<Key, Compare, Allocator>& y);                                // removed in C++20
+
+template<class Key, class Compare, class Allocator>
+  synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
+                                          const multiset<Key, Compare, Allocator>& y); // since C++20
 
 // specialized algorithms:
 template <class Key, class Compare, class Allocator>
@@ -473,16 +514,22 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20
 
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
 #include <__functional/is_transparent.h>
 #include <__functional/operations.h>
 #include <__iterator/erase_if_container.h>
 #include <__iterator/iterator_traits.h>
+#include <__iterator/ranges_iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/allocator.h>
 #include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
 #include <__tree>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
@@ -547,7 +594,7 @@ public:
     typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
     typedef __insert_return_type<iterator, node_type> insert_return_type;
 #endif
@@ -593,13 +640,30 @@ public:
             insert(__f, __l);
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    set(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
+        const allocator_type& __a = allocator_type())
+      : __tree_(__comp, __a) {
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 14
         template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
             : set(__f, __l, key_compare(), __a) {}
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    set(from_range_t, _Range&& __range, const allocator_type& __a)
+      : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     set(const set& __s)
         : __tree_(__s.__tree_)
@@ -633,7 +697,7 @@ public:
         }
 
 #ifndef _LIBCPP_CXX03_LANG
-    set(set&& __s, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
 
     _LIBCPP_INLINE_VISIBILITY
     set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
@@ -650,7 +714,7 @@ public:
             insert(__il.begin(), __il.end());
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     set(initializer_list<value_type> __il, const allocator_type& __a)
         : set(__il, key_compare(), __a) {}
@@ -742,6 +806,17 @@ public:
                 __tree_.__insert_unique(__e, *__f);
         }
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      const_iterator __end = cend();
+      for (auto&& __element : __range) {
+        __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator,bool> insert(value_type&& __v)
@@ -767,11 +842,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {__tree_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     insert_return_type insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to set::insert()");
         return __tree_.template __node_handle_insert_unique<
             node_type, insert_return_type>(_VSTD::move(__nh));
@@ -779,7 +854,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to set::insert()");
         return __tree_.template __node_handle_insert_unique<node_type>(
             __hint, _VSTD::move(__nh));
@@ -798,7 +873,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(set<key_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
@@ -806,7 +881,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(set<key_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
@@ -814,7 +889,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(multiset<key_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
@@ -822,7 +897,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_unique(__source.__tree_);
     }
@@ -844,7 +919,7 @@ public:
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -858,21 +933,21 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_unique(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
     count(const _K2& __k) const                    {return __tree_.__count_multi(__k);}
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
     contains(const _K2& __k) const { return find(__k) != end(); }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     iterator lower_bound(const key_type& __k)
@@ -880,7 +955,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
         {return __tree_.lower_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -898,7 +973,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
         {return __tree_.upper_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -915,7 +990,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
         {return __tree_.__equal_range_unique(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
@@ -931,12 +1006,21 @@ public:
 template<class _InputIterator,
          class _Compare = less<__iter_value_type<_InputIterator>>,
          class _Allocator = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>>
 set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
   -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>,
+          class _Allocator = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>,
+          class = enable_if_t<!__is_allocator<_Compare>::value, void>>
+set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
+  -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
+#endif
+
 template<class _Key, class _Compare = less<_Key>,
          class _Allocator = allocator<_Key>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>,
@@ -945,12 +1029,19 @@ set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
   -> set<_Key, _Compare, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 set(_InputIterator, _InputIterator, _Allocator)
   -> set<__iter_value_type<_InputIterator>,
          less<__iter_value_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+set(from_range_t, _Range&&, _Allocator)
+  -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
+#endif
+
 template<class _Key, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 set(initializer_list<_Key>, _Allocator)
@@ -982,6 +1073,8 @@ operator==(const set<_Key, _Compare, _Allocator>& __x,
     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1027,6 +1120,17 @@ operator<=(const set<_Key, _Compare, _Allocator>& __x,
     return !(__y < __x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Key, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
+operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 // specialized algorithms:
 template <class _Key, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1038,7 +1142,7 @@ swap(set<_Key, _Compare, _Allocator>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Compare, class _Allocator, class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
     typename set<_Key, _Compare, _Allocator>::size_type
@@ -1084,7 +1188,7 @@ public:
     typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
 #endif
 
@@ -1121,7 +1225,7 @@ public:
             insert(__f, __l);
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
         template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
@@ -1137,6 +1241,21 @@ public:
             insert(__f, __l);
         }
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    multiset(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
+        const allocator_type& __a = allocator_type())
+      : __tree_(__comp, __a) {
+      insert_range(std::forward<_Range>(__range));
+    }
+
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    multiset(from_range_t, _Range&& __range, const allocator_type& __a)
+      : multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     multiset(const multiset& __s)
         : __tree_(__s.__tree_.value_comp(),
@@ -1158,7 +1277,7 @@ public:
         _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
         : __tree_(_VSTD::move(__s.__tree_)) {}
 
-    multiset(multiset&& __s, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
 #endif // _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     explicit multiset(const allocator_type& __a)
@@ -1186,7 +1305,7 @@ public:
             insert(__il.begin(), __il.end());
         }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     multiset(initializer_list<value_type> __il, const allocator_type& __a)
         : multiset(__il, key_compare(), __a) {}
@@ -1278,6 +1397,17 @@ public:
                 __tree_.__insert_multi(__e, *__f);
         }
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      const_iterator __end = cend();
+      for (auto&& __element : __range) {
+        __tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(value_type&& __v)
@@ -1302,11 +1432,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {__tree_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to multiset::insert()");
         return __tree_.template __node_handle_insert_multi<node_type>(
             _VSTD::move(__nh));
@@ -1314,7 +1444,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to multiset::insert()");
         return __tree_.template __node_handle_insert_multi<node_type>(
             __hint, _VSTD::move(__nh));
@@ -1333,7 +1463,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(multiset<key_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_multi(__source.__tree_);
     }
@@ -1341,7 +1471,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_multi(__source.__tree_);
     }
@@ -1349,7 +1479,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(set<key_type, _Compare2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_multi(__source.__tree_);
     }
@@ -1357,7 +1487,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(set<key_type, _Compare2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
                        "merging container with incompatible allocator");
         __tree_.__node_handle_merge_multi(__source.__tree_);
     }
@@ -1380,7 +1510,7 @@ public:
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -1394,21 +1524,21 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_multi(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
     count(const _K2& __k) const            {return __tree_.__count_multi(__k);}
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
     contains(const _K2& __k) const { return find(__k) != end(); }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     iterator lower_bound(const key_type& __k)
@@ -1416,7 +1546,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
             {return __tree_.lower_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -1434,7 +1564,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
             {return __tree_.upper_bound(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
@@ -1451,7 +1581,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
             {return __tree_.__equal_range_multi(__k);}
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
@@ -1467,12 +1597,21 @@ public:
 template<class _InputIterator,
          class _Compare = less<__iter_value_type<_InputIterator>>,
          class _Allocator = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>,
          class = enable_if_t<!__is_allocator<_Compare>::value, void>>
 multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
   -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>,
+          class _Allocator = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>,
+          class = enable_if_t<!__is_allocator<_Compare>::value, void>>
+multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
+  -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
+#endif
+
 template<class _Key, class _Compare = less<_Key>,
          class _Allocator = allocator<_Key>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>,
@@ -1481,12 +1620,19 @@ multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator(
   -> multiset<_Key, _Compare, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 multiset(_InputIterator, _InputIterator, _Allocator)
   -> multiset<__iter_value_type<_InputIterator>,
          less<__iter_value_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
+multiset(from_range_t, _Range&&, _Allocator)
+  -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
+#endif
+
 template<class _Key, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
 multiset(initializer_list<_Key>, _Allocator)
@@ -1518,6 +1664,8 @@ operator==(const multiset<_Key, _Compare, _Allocator>& __x,
     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1563,6 +1711,17 @@ operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
     return !(__y < __x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Key, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
+operator<=>(const multiset<_Key, _Allocator>& __x, const multiset<_Key, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Compare, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -1573,7 +1732,7 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Compare, class _Allocator, class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
     typename multiset<_Key, _Compare, _Allocator>::size_type
@@ -1584,22 +1743,24 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _KeyT, class _CompareT = std::less<_KeyT>>
-using set = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
+using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
 
 template <class _KeyT, class _CompareT = std::less<_KeyT>>
-using multiset = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
+using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_SET
lib/libcxx/include/shared_mutex
@@ -124,386 +124,343 @@ template <class Mutex>
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
+#include <__chrono/duration.h>
+#include <__chrono/steady_clock.h>
+#include <__chrono/time_point.h>
+#include <__condition_variable/condition_variable.h>
 #include <__config>
+#include <__memory/addressof.h>
+#include <__mutex/mutex.h>
+#include <__mutex/tag_types.h>
+#include <__mutex/unique_lock.h>
+#include <__system_error/system_error.h>
+#include <__utility/swap.h>
+#include <cerrno>
 #include <version>
 
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
+#if _LIBCPP_STD_VER >= 14
 
-#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY)
+#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#    pragma GCC system_header
+#  endif
 
-#include <__mutex_base>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-#ifdef _LIBCPP_HAS_NO_THREADS
-# error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
-#endif
+#  ifdef _LIBCPP_HAS_NO_THREADS
+#    error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
+#  endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex"))
-__shared_mutex_base
-{
-    mutex               __mut_;
-    condition_variable  __gate1_;
-    condition_variable  __gate2_;
-    unsigned            __state_;
+struct _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base {
+  mutex __mut_;
+  condition_variable __gate1_;
+  condition_variable __gate2_;
+  unsigned __state_;
 
-    static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
-    static const unsigned __n_readers_ = ~__write_entered_;
+  static const unsigned __write_entered_ = 1U << (sizeof(unsigned) * __CHAR_BIT__ - 1);
+  static const unsigned __n_readers_     = ~__write_entered_;
 
-    __shared_mutex_base();
-    _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;
+  __shared_mutex_base();
+  _LIBCPP_HIDE_FROM_ABI ~__shared_mutex_base() = default;
 
-    __shared_mutex_base(const __shared_mutex_base&) = delete;
-    __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
+  __shared_mutex_base(const __shared_mutex_base&)            = delete;
+  __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
 
-    // Exclusive ownership
-    void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking
-    bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
-    void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
+  // Exclusive ownership
+  void lock(); // blocking
+  bool try_lock();
+  void unlock();
 
-    // Shared ownership
-    void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking
-    bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true));
-    void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability());
+  // Shared ownership
+  void lock_shared(); // blocking
+  bool try_lock_shared();
+  void unlock_shared();
 
-//     typedef implementation-defined native_handle_type; // See 30.2.3
-//     native_handle_type native_handle(); // See 30.2.3
+  //     typedef implementation-defined native_handle_type; // See 30.2.3
+  //     native_handle_type native_handle(); // See 30.2.3
 };
 
+#  if _LIBCPP_STD_VER >= 17
+class _LIBCPP_EXPORTED_FROM_ABI
+    _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
+  __shared_mutex_base __base_;
 
-#if _LIBCPP_STD_VER > 14
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_mutex
-{
-    __shared_mutex_base __base_;
 public:
-    _LIBCPP_INLINE_VISIBILITY shared_mutex() : __base_() {}
-    _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
-
-    shared_mutex(const shared_mutex&) = delete;
-    shared_mutex& operator=(const shared_mutex&) = delete;
-
-    // Exclusive ownership
-    _LIBCPP_INLINE_VISIBILITY void lock()     { return __base_.lock(); }
-    _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base_.try_lock(); }
-    _LIBCPP_INLINE_VISIBILITY void unlock()   { return __base_.unlock(); }
-
-    // Shared ownership
-    _LIBCPP_INLINE_VISIBILITY void lock_shared()     { return __base_.lock_shared(); }
-    _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base_.try_lock_shared(); }
-    _LIBCPP_INLINE_VISIBILITY void unlock_shared()   { return __base_.unlock_shared(); }
-
-//     typedef __shared_mutex_base::native_handle_type native_handle_type;
-//     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }
+  _LIBCPP_HIDE_FROM_ABI shared_mutex() : __base_() {}
+  _LIBCPP_HIDE_FROM_ABI ~shared_mutex() = default;
+
+  shared_mutex(const shared_mutex&)            = delete;
+  shared_mutex& operator=(const shared_mutex&) = delete;
+
+  // Exclusive ownership
+  _LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()) {
+    return __base_.lock();
+  }
+  _LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
+    return __base_.try_lock();
+  }
+  _LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()) {
+    return __base_.unlock();
+  }
+
+  // Shared ownership
+  _LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()) {
+    return __base_.lock_shared();
+  }
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared()
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+    return __base_.try_lock_shared();
+  }
+  _LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()) {
+    return __base_.unlock_shared();
+  }
+
+  //     typedef __shared_mutex_base::native_handle_type native_handle_type;
+  //     _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); }
 };
-#endif
+#  endif
 
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(
+    __capability__("shared_timed_mutex")) shared_timed_mutex {
+  __shared_mutex_base __base_;
 
-class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_timed_mutex
-{
-    __shared_mutex_base __base_;
 public:
-    shared_timed_mutex();
-    _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
-
-    shared_timed_mutex(const shared_timed_mutex&) = delete;
-    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
-
-    // Exclusive ownership
-    void lock();
-    bool try_lock();
-    template <class _Rep, class _Period>
-        _LIBCPP_INLINE_VISIBILITY
-        bool
-        try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
-        {
-            return try_lock_until(chrono::steady_clock::now() + __rel_time);
-        }
-    template <class _Clock, class _Duration>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        bool
-        try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
-    void unlock();
-
-    // Shared ownership
-    void lock_shared();
-    bool try_lock_shared();
-    template <class _Rep, class _Period>
-        _LIBCPP_INLINE_VISIBILITY
-        bool
-        try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
-        {
-            return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
-        }
-    template <class _Clock, class _Duration>
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        bool
-        try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
-    void unlock_shared();
+  shared_timed_mutex();
+  _LIBCPP_HIDE_FROM_ABI ~shared_timed_mutex() = default;
+
+  shared_timed_mutex(const shared_timed_mutex&)            = delete;
+  shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+  // Exclusive ownership
+  void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__());
+  bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
+    return try_lock_until(chrono::steady_clock::now() + __rel_time);
+  }
+  template <class _Clock, class _Duration>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
+  try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
+  void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__());
+
+  // Shared ownership
+  void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__());
+  bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+    return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
+  }
+  template <class _Clock, class _Duration>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
+  try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
+  void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
 };
 
 template <class _Clock, class _Duration>
-bool
-shared_timed_mutex::try_lock_until(
-                        const chrono::time_point<_Clock, _Duration>& __abs_time)
-{
-    unique_lock<mutex> __lk(__base_.__mut_);
-    if (__base_.__state_ & __base_.__write_entered_)
-    {
-        while (true)
-        {
-            cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
-            if ((__base_.__state_ & __base_.__write_entered_) == 0)
-                break;
-            if (__status == cv_status::timeout)
-                return false;
-        }
+bool shared_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
+  unique_lock<mutex> __lk(__base_.__mut_);
+  if (__base_.__state_ & __base_.__write_entered_) {
+    while (true) {
+      cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
+      if ((__base_.__state_ & __base_.__write_entered_) == 0)
+        break;
+      if (__status == cv_status::timeout)
+        return false;
     }
-    __base_.__state_ |= __base_.__write_entered_;
-    if (__base_.__state_ & __base_.__n_readers_)
-    {
-        while (true)
-        {
-            cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
-            if ((__base_.__state_ & __base_.__n_readers_) == 0)
-                break;
-            if (__status == cv_status::timeout)
-            {
-                __base_.__state_ &= ~__base_.__write_entered_;
-                __base_.__gate1_.notify_all();
-                return false;
-            }
-        }
+  }
+  __base_.__state_ |= __base_.__write_entered_;
+  if (__base_.__state_ & __base_.__n_readers_) {
+    while (true) {
+      cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
+      if ((__base_.__state_ & __base_.__n_readers_) == 0)
+        break;
+      if (__status == cv_status::timeout) {
+        __base_.__state_ &= ~__base_.__write_entered_;
+        __base_.__gate1_.notify_all();
+        return false;
+      }
     }
-    return true;
+  }
+  return true;
 }
 
 template <class _Clock, class _Duration>
-bool
-shared_timed_mutex::try_lock_shared_until(
-                        const chrono::time_point<_Clock, _Duration>& __abs_time)
-{
-    unique_lock<mutex> __lk(__base_.__mut_);
-    if ((__base_.__state_ & __base_.__write_entered_) || (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_)
-    {
-        while (true)
-        {
-            cv_status status = __base_.__gate1_.wait_until(__lk, __abs_time);
-            if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
-                                       (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
-                break;
-            if (status == cv_status::timeout)
-                return false;
-        }
+bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
+  unique_lock<mutex> __lk(__base_.__mut_);
+  if ((__base_.__state_ & __base_.__write_entered_) ||
+      (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) {
+    while (true) {
+      cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
+      if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
+          (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
+        break;
+      if (__status == cv_status::timeout)
+        return false;
     }
-    unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
-    __base_.__state_ &= ~__base_.__n_readers_;
-    __base_.__state_ |= __num_readers;
-    return true;
+  }
+  unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
+  __base_.__state_ &= ~__base_.__n_readers_;
+  __base_.__state_ |= __num_readers;
+  return true;
 }
 
 template <class _Mutex>
-class shared_lock
-{
+class shared_lock {
 public:
-    typedef _Mutex mutex_type;
+  typedef _Mutex mutex_type;
 
 private:
-    mutex_type* __m_;
-    bool __owns_;
+  mutex_type* __m_;
+  bool __owns_;
 
 public:
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock() _NOEXCEPT
-        : __m_(nullptr),
-          __owns_(false)
-        {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    explicit shared_lock(mutex_type& __m)
-        : __m_(_VSTD::addressof(__m)),
-          __owns_(true)
-        {__m_->lock_shared();}
-
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
-        : __m_(_VSTD::addressof(__m)),
-          __owns_(false)
-        {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock(mutex_type& __m, try_to_lock_t)
-        : __m_(_VSTD::addressof(__m)),
-          __owns_(__m.try_lock_shared())
-        {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock(mutex_type& __m, adopt_lock_t)
-        : __m_(_VSTD::addressof(__m)),
-          __owns_(true)
-        {}
-
-    template <class _Clock, class _Duration>
-        _LIBCPP_INLINE_VISIBILITY
-        shared_lock(mutex_type& __m,
-                    const chrono::time_point<_Clock, _Duration>& __abs_time)
-            : __m_(_VSTD::addressof(__m)),
-              __owns_(__m.try_lock_shared_until(__abs_time))
-            {}
-
-    template <class _Rep, class _Period>
-        _LIBCPP_INLINE_VISIBILITY
-        shared_lock(mutex_type& __m,
-                    const chrono::duration<_Rep, _Period>& __rel_time)
-            : __m_(_VSTD::addressof(__m)),
-              __owns_(__m.try_lock_shared_for(__rel_time))
-            {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    ~shared_lock()
-    {
-        if (__owns_)
-            __m_->unlock_shared();
-    }
+  _LIBCPP_HIDE_FROM_ABI shared_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
 
-    shared_lock(shared_lock const&) = delete;
-    shared_lock& operator=(shared_lock const&) = delete;
+  _LIBCPP_HIDE_FROM_ABI explicit shared_lock(mutex_type& __m) : __m_(_VSTD::addressof(__m)), __owns_(true) {
+    __m_->lock_shared();
+  }
 
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock(shared_lock&& __u) _NOEXCEPT
-        : __m_(__u.__m_),
-          __owns_(__u.__owns_)
-        {
-            __u.__m_ = nullptr;
-            __u.__owns_ = false;
-        }
-
-    _LIBCPP_INLINE_VISIBILITY
-    shared_lock& operator=(shared_lock&& __u) _NOEXCEPT
-    {
-        if (__owns_)
-            __m_->unlock_shared();
-        __m_ = nullptr;
-        __owns_ = false;
-        __m_ = __u.__m_;
-        __owns_ = __u.__owns_;
-        __u.__m_ = nullptr;
-        __u.__owns_ = false;
-        return *this;
-    }
+  _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
+      : __m_(_VSTD::addressof(__m)),
+        __owns_(false) {}
 
-    void lock();
-    bool try_lock();
-    template <class Rep, class Period>
-        bool try_lock_for(const chrono::duration<Rep, Period>& __rel_time);
-    template <class Clock, class Duration>
-        bool try_lock_until(const chrono::time_point<Clock, Duration>& __abs_time);
-    void unlock();
+  _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, try_to_lock_t)
+      : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared()) {}
 
-    // Setters
-    _LIBCPP_INLINE_VISIBILITY
-    void swap(shared_lock& __u) _NOEXCEPT
-    {
-        _VSTD::swap(__m_, __u.__m_);
-        _VSTD::swap(__owns_, __u.__owns_);
-    }
+  _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, adopt_lock_t) : __m_(_VSTD::addressof(__m)), __owns_(true) {}
 
-    _LIBCPP_INLINE_VISIBILITY
-    mutex_type* release() _NOEXCEPT
-    {
-        mutex_type* __m = __m_;
-        __m_ = nullptr;
-        __owns_ = false;
-        return __m;
-    }
+  template <class _Clock, class _Duration>
+  _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time)
+      : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {}
 
-    // Getters
-    _LIBCPP_INLINE_VISIBILITY
-    bool owns_lock() const _NOEXCEPT {return __owns_;}
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time)
+      : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {}
 
-    _LIBCPP_INLINE_VISIBILITY
-    explicit operator bool () const _NOEXCEPT {return __owns_;}
+  _LIBCPP_HIDE_FROM_ABI ~shared_lock() {
+    if (__owns_)
+      __m_->unlock_shared();
+  }
+
+  shared_lock(shared_lock const&)            = delete;
+  shared_lock& operator=(shared_lock const&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI shared_lock(shared_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) {
+    __u.__m_    = nullptr;
+    __u.__owns_ = false;
+  }
 
-    _LIBCPP_INLINE_VISIBILITY
-    mutex_type* mutex() const _NOEXCEPT {return __m_;}
+  _LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT {
+    if (__owns_)
+      __m_->unlock_shared();
+    __m_        = nullptr;
+    __owns_     = false;
+    __m_        = __u.__m_;
+    __owns_     = __u.__owns_;
+    __u.__m_    = nullptr;
+    __u.__owns_ = false;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void lock();
+  _LIBCPP_HIDE_FROM_ABI bool try_lock();
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time);
+  template <class _Clock, class _Duration>
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
+  _LIBCPP_HIDE_FROM_ABI void unlock();
+
+  // Setters
+  _LIBCPP_HIDE_FROM_ABI void swap(shared_lock& __u) _NOEXCEPT {
+    _VSTD::swap(__m_, __u.__m_);
+    _VSTD::swap(__owns_, __u.__owns_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT {
+    mutex_type* __m = __m_;
+    __m_            = nullptr;
+    __owns_         = false;
+    return __m;
+  }
+
+  // Getters
+  _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; }
+
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; }
+
+  _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(shared_lock);
 
 template <class _Mutex>
-void
-shared_lock<_Mutex>::lock()
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
-    __m_->lock_shared();
-    __owns_ = true;
+void shared_lock<_Mutex>::lock() {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
+  __m_->lock_shared();
+  __owns_ = true;
 }
 
 template <class _Mutex>
-bool
-shared_lock<_Mutex>::try_lock()
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
-    __owns_ = __m_->try_lock_shared();
-    return __owns_;
+bool shared_lock<_Mutex>::try_lock() {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
+  __owns_ = __m_->try_lock_shared();
+  return __owns_;
 }
 
 template <class _Mutex>
 template <class _Rep, class _Period>
-bool
-shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
-    __owns_ = __m_->try_lock_shared_for(__d);
-    return __owns_;
+bool shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
+  __owns_ = __m_->try_lock_shared_for(__d);
+  return __owns_;
 }
 
 template <class _Mutex>
 template <class _Clock, class _Duration>
-bool
-shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
-{
-    if (__m_ == nullptr)
-        __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
-    if (__owns_)
-        __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
-    __owns_ = __m_->try_lock_shared_until(__t);
-    return __owns_;
+bool shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+  if (__m_ == nullptr)
+    __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
+  if (__owns_)
+    __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
+  __owns_ = __m_->try_lock_shared_until(__t);
+  return __owns_;
 }
 
 template <class _Mutex>
-void
-shared_lock<_Mutex>::unlock()
-{
-    if (!__owns_)
-        __throw_system_error(EPERM, "shared_lock::unlock: not locked");
-    __m_->unlock_shared();
-    __owns_ = false;
+void shared_lock<_Mutex>::unlock() {
+  if (!__owns_)
+    __throw_system_error(EPERM, "shared_lock::unlock: not locked");
+  __m_->unlock_shared();
+  __owns_ = false;
 }
 
 template <class _Mutex>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT
-    {__x.swap(__y);}
+inline _LIBCPP_HIDE_FROM_ABI void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT {
+  __x.swap(__y);
+}
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER > 11
+#endif // _LIBCPP_STD_VER >= 14
 
 _LIBCPP_POP_MACROS
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <system_error>
+#endif
+
 #endif // _LIBCPP_SHARED_MUTEX
lib/libcxx/include/span
@@ -71,7 +71,6 @@ public:
     constexpr span(const span& other) noexcept = default;
     template <class OtherElementType, size_t OtherExtent>
         constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
-    ~span() noexcept = default;
     constexpr span& operator=(const span& other) noexcept = default;
 
     // [span.sub], span subviews
@@ -129,7 +128,6 @@ template<class R>
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <__fwd/span.h>
 #include <__iterator/bounded_iter.h>
 #include <__iterator/concepts.h>
@@ -141,11 +139,14 @@ template<class R>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/enable_view.h>
 #include <__ranges/size.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <array>        // for array
 #include <cstddef>      // for byte
 #include <limits>
-#include <type_traits>  // for remove_cv, etc
 #include <version>
 
 // standard-mandated includes
@@ -166,7 +167,7 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _Tp>
 struct __is_std_array : false_type {};
@@ -211,7 +212,7 @@ public:
     using const_pointer          = const _Tp *;
     using reference              = _Tp &;
     using const_reference        = const _Tp &;
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
     using iterator               = __bounded_iter<pointer>;
 #else
     using iterator               = __wrap_iter<pointer>;
@@ -232,16 +233,18 @@ public:
     constexpr explicit span(_It __first, size_type __count)
         : __data_{_VSTD::to_address(__first)} {
       (void)__count;
-      _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
     }
 
     template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
     _LIBCPP_INLINE_VISIBILITY
     constexpr explicit span(_It __first, _End __last) : __data_{_VSTD::to_address(__first)} {
-      (void)__last;
-      _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)");
-      _LIBCPP_ASSERT(__last - __first == _Extent,
-                     "invalid range in span's constructor (iterator, sentinel): last - first != extent");
+      // [span.cons]/10
+      // Throws: When and what last - first throws.
+      [[maybe_unused]] auto __dist = __last - __first;
+      _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+          __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent");
     }
 
     _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {}
@@ -258,7 +261,8 @@ public:
     template <__span_compatible_range<element_type> _Range>
     _LIBCPP_INLINE_VISIBILITY
     constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} {
-      _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+          ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
     }
 
     template <__span_array_convertible<element_type> _OtherElementType>
@@ -269,10 +273,10 @@ public:
     template <__span_array_convertible<element_type> _OtherElementType>
     _LIBCPP_INLINE_VISIBILITY
         constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept
-        : __data_{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
-
-
-//  ~span() noexcept = default;
+        : __data_{__other.data()} {
+      _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+          _Extent == __other.size(), "size mismatch in span's constructor (other span)");
+        }
 
     template <size_t _Count>
     _LIBCPP_INLINE_VISIBILITY
@@ -293,14 +297,14 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
     {
-        _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");
         return {data(), __count};
     }
 
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept
     {
-        _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");
         return {data() + size() - __count, __count};
     }
 
@@ -321,11 +325,12 @@ public:
     constexpr span<element_type, dynamic_extent>
        subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
     {
-        _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
-        _LIBCPP_ASSERT(__count  <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            __offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
         if (__count == dynamic_extent)
             return {data() + __offset, size() - __offset};
-        _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
         return {data() + __offset, __count};
     }
 
@@ -335,19 +340,19 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
     {
-        _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");
         return __data_[__idx];
     }
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
     {
-        _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
         return __data_[0];
     }
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
     {
-        _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
         return __data_[size()-1];
     }
 
@@ -355,17 +360,17 @@ public:
 
 // [span.iter], span iterator support
     _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
         return std::__make_bounded_iter(data(), data(), data() + size());
 #else
-        return iterator(this, data());
+        return iterator(data());
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
         return std::__make_bounded_iter(data() + size(), data(), data() + size());
 #else
-        return iterator(this, data() + size());
+        return iterator(data() + size());
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }
@@ -394,7 +399,7 @@ public:
     using const_pointer          = const _Tp *;
     using reference              = _Tp &;
     using const_reference        = const _Tp &;
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
     using iterator               = __bounded_iter<pointer>;
 #else
     using iterator               = __wrap_iter<pointer>;
@@ -417,7 +422,8 @@ public:
     template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
     _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last)
         : __data_(_VSTD::to_address(__first)), __size_(__last - __first) {
-      _LIBCPP_ASSERT(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");
+        _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+            __last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");
     }
 
     template <size_t _Sz>
@@ -442,13 +448,11 @@ public:
         constexpr span(const span<_OtherElementType, _OtherExtent>& __other)  noexcept
         : __data_{__other.data()}, __size_{__other.size()} {}
 
-//    ~span() noexcept = default;
-
     template <size_t _Count>
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, _Count> first() const noexcept
     {
-        _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");
         return span<element_type, _Count>{data(), _Count};
     }
 
@@ -456,21 +460,21 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, _Count> last() const noexcept
     {
-        _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");
         return span<element_type, _Count>{data() + size() - _Count, _Count};
     }
 
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
     {
-        _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");
         return {data(), __count};
     }
 
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept
     {
-        _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");
         return {data() + size() - __count, __count};
     }
 
@@ -478,8 +482,10 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     constexpr span<element_type, _Count> subspan() const noexcept
     {
-        _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
-        _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            _Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,
+                                            "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
         return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
     }
 
@@ -487,11 +493,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
     {
-        _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
-        _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
         if (__count == dynamic_extent)
             return {data() + __offset, size() - __offset};
-        _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+            __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
         return {data() + __offset, __count};
     }
 
@@ -501,19 +507,19 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
     {
-        _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");
         return __data_[__idx];
     }
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
     {
-        _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
         return __data_[0];
     }
 
     _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
     {
-        _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");
         return __data_[size()-1];
     }
 
@@ -522,17 +528,17 @@ public:
 
 // [span.iter], span iterator support
     _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
         return std::__make_bounded_iter(data(), data(), data() + size());
 #else
-        return iterator(this, data());
+        return iterator(data());
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
-#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
         return std::__make_bounded_iter(data() + size(), data(), data() + size());
 #else
-        return iterator(this, data() + size());
+        return iterator(data() + size());
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }
@@ -566,10 +572,10 @@ _LIBCPP_INLINE_VISIBILITY
 auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
 { return __s.__as_writable_bytes(); }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template<contiguous_iterator _It, class _EndOrSize>
     span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 template<class _Tp, size_t _Sz>
     span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
@@ -583,7 +589,7 @@ template<class _Tp, size_t _Sz>
 template<ranges::contiguous_range _Range>
     span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
 
@@ -593,6 +599,7 @@ _LIBCPP_POP_MACROS
 #  include <concepts>
 #  include <functional>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_SPAN
lib/libcxx/include/sstream
@@ -30,17 +30,41 @@ public:
     explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
     basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
     explicit basic_stringbuf(ios_base::openmode which);                                // C++20
-    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
+    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
                              ios_base::openmode which = ios_base::in | ios_base::out);
+    explicit basic_stringbuf(const allocator_type& a)
+        : basic_stringbuf(ios_base::in | ios_base::out, a) {}                          // C++20
+    basic_stringbuf(ios_base::openmode which, const allocator_type& a);                // C++20
+    explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
+                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
+    template <class SAlloc>
+    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
+        : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}                       // C++20
+    template <class SAlloc>
+    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
+                    ios_base::openmode which, const allocator_type& a);                // C++20
+    template <class SAlloc>
+    explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
+                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
     basic_stringbuf(basic_stringbuf&& rhs);
+    basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a);                   // C++20
 
     // [stringbuf.assign] Assign and swap:
     basic_stringbuf& operator=(basic_stringbuf&& rhs);
-    void swap(basic_stringbuf& rhs);
+    void swap(basic_stringbuf& rhs) noexcept(see below);                               // conditionally noexcept since C++20
 
     // [stringbuf.members] Member functions:
-    basic_string<char_type, traits_type, allocator_type> str() const;
+    allocator_type get_allocator() const noexcept;                                     // C++20
+    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
+    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
+    template <class SAlloc>
+    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
+    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
+    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
     void str(const basic_string<char_type, traits_type, allocator_type>& s);
+    template <class SAlloc>
+    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
+    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
 
 protected:
     // [stringbuf.virtuals] Overridden virtual functions:
@@ -56,8 +80,8 @@ protected:
 
 // [stringbuf.assign] non member swap
 template <class charT, class traits, class Allocator>
-  void swap(basic_stringbuf<charT, traits, Allocator>& x,
-            basic_stringbuf<charT, traits, Allocator>& y);
+void swap(basic_stringbuf<charT, traits, Allocator>& x,
+          basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20
 
 typedef basic_stringbuf<char>    stringbuf;
 typedef basic_stringbuf<wchar_t> wstringbuf;
@@ -76,12 +100,23 @@ public:
     typedef Allocator                      allocator_type;
 
     // [istringstream.cons] Constructors:
-    explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
-    basic_istringstream() : basic_istringstream(ios_base::in) {}           // C++20
-    explicit basic_istringstream(ios_base::openmode which);                // C++20
-
-    explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
+    explicit basic_istringstream(ios_base::openmode which = ios_base::in);             // before C++20
+    basic_istringstream() : basic_istringstream(ios_base::in) {}                       // C++20
+    explicit basic_istringstream(ios_base::openmode which);                            // C++20
+    explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
                                  ios_base::openmode which = ios_base::in);
+    basic_istringstream(ios_base::openmode which, const allocator_type& a);            // C++20
+    explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s,
+                                 ios_base::openmode which = ios_base::in);             // C++20
+    template <class SAlloc>
+    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
+        : basic_istringstream(s, ios_base::in, a) {}                                   // C++20
+    template <class SAlloc>
+    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                        ios_base::openmode which, const allocator_type& a);            // C++20
+    template <class SAlloc>
+    explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                                 ios_base::openmode which = ios_base::in);             // C++20
     basic_istringstream(basic_istringstream&& rhs);
 
     // [istringstream.assign] Assign and swap:
@@ -90,13 +125,21 @@ public:
 
     // [istringstream.members] Member functions:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
-    basic_string<char_type, traits_type, allocator_type> str() const;
+    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
+    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
+    template <class SAlloc>
+    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
+    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
+    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
     void str(const basic_string<char_type, traits_type, allocator_type>& s);
+    template <class SAlloc>
+    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
+    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
 };
 
 template <class charT, class traits, class Allocator>
-  void swap(basic_istringstream<charT, traits, Allocator>& x,
-            basic_istringstream<charT, traits, Allocator>& y);
+void swap(basic_istringstream<charT, traits, Allocator>& x,
+          basic_istringstream<charT, traits, Allocator>& y);
 
 typedef basic_istringstream<char>    istringstream;
 typedef basic_istringstream<wchar_t> wistringstream;
@@ -116,12 +159,23 @@ public:
     typedef Allocator                      allocator_type;
 
     // [ostringstream.cons] Constructors:
-    explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
-    basic_ostringstream() : basic_ostringstream(ios_base::out) {}           // C++20
-    explicit basic_ostringstream(ios_base::openmode which);                 // C++20
-
-    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,
+    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);            // before C++20
+    basic_ostringstream() : basic_ostringstream(ios_base::out) {}                      // C++20
+    explicit basic_ostringstream(ios_base::openmode which);                            // C++20
+    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s,
                                  ios_base::openmode which = ios_base::out);
+    basic_ostringstream(ios_base::openmode which, const allocator_type& a);            // C++20
+    explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s,
+                                 ios_base::openmode which = ios_base::out);            // C++20
+    template <class SAlloc>
+    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
+        : basic_ostringstream(s, ios_base::out, a) {}                                  // C++20
+    template <class SAlloc>
+    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                        ios_base::openmode which, const allocator_type& a);            // C++20
+    template <class SAlloc>
+    explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                                 ios_base::openmode which = ios_base::out);            // C++20
     basic_ostringstream(basic_ostringstream&& rhs);
 
     // [ostringstream.assign] Assign and swap:
@@ -130,13 +184,21 @@ public:
 
     // [ostringstream.members] Member functions:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
-    basic_string<char_type, traits_type, allocator_type> str() const;
+    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
+    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
+    template <class SAlloc>
+    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
+    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
+    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
     void str(const basic_string<char_type, traits_type, allocator_type>& s);
+    template <class SAlloc>
+    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
+    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
 };
 
 template <class charT, class traits, class Allocator>
-  void swap(basic_ostringstream<charT, traits, Allocator>& x,
-            basic_ostringstream<charT, traits, Allocator>& y);
+void swap(basic_ostringstream<charT, traits, Allocator>& x,
+          basic_ostringstream<charT, traits, Allocator>& y);
 
 typedef basic_ostringstream<char>    ostringstream;
 typedef basic_ostringstream<wchar_t> wostringstream;
@@ -159,9 +221,20 @@ public:
     explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
     basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
     explicit basic_stringstream(ios_base::openmode which);                                // C++20
-
-    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,
-                                ios_base::openmode which = ios_base::out|ios_base::in);
+    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s,
+                                ios_base::openmode which = ios_base::out | ios_base::in);
+    basic_stringstream(ios_base::openmode which, const allocator_type& a);                // C++20
+    explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s,
+                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
+    template <class SAlloc>
+    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
+        : basic_stringstream(s, ios_base::out | ios_base::in, a) {}                       // C++20
+    template <class SAlloc>
+    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                       ios_base::openmode which, const allocator_type& a);                // C++20
+    template <class SAlloc>
+    explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
+                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
     basic_stringstream(basic_stringstream&& rhs);
 
     // [stringstream.assign] Assign and swap:
@@ -170,13 +243,21 @@ public:
 
     // [stringstream.members] Member functions:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
-    basic_string<char_type, traits_type, allocator_type> str() const;
-    void str(const basic_string<char_type, traits_type, allocator_type>& str);
+    basic_string<char_type, traits_type, allocator_type> str() const;                     // before C++20
+    basic_string<char_type, traits_type, allocator_type> str() const &;                   // C++20
+    template <class SAlloc>
+    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;             // C++20
+    basic_string<char_type, traits_type, allocator_type> str() &&;                        // C++20
+    basic_string_view<char_type, traits_type> view() const noexcept;                      // C++20
+    void str(const basic_string<char_type, traits_type, allocator_type>& s);
+    template <class SAlloc>
+    void str(const basic_string<char_type, traits_type, SAlloc>& s);                      // C++20
+    void str(basic_string<char_type, traits_type, allocator_type>&& s);                   // C++20
 };
 
 template <class charT, class traits, class Allocator>
-  void swap(basic_stringstream<charT, traits, Allocator>& x,
-            basic_stringstream<charT, traits, Allocator>& y);
+void swap(basic_stringstream<charT, traits, Allocator>& x,
+          basic_stringstream<charT, traits, Allocator>& y);
 
 typedef basic_stringstream<char>    stringstream;
 typedef basic_stringstream<wchar_t> wstringstream;
@@ -187,6 +268,7 @@ typedef basic_stringstream<wchar_t> wstringstream;
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__fwd/sstream.h>
 #include <__utility/swap.h>
 #include <istream>
 #include <ostream>
@@ -201,6 +283,14 @@ _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
 
+// TODO(LLVM-19): Remove this once we drop support for Clang 16,
+// which had this bug: https://github.com/llvm/llvm-project/issues/40363
+#ifdef _WIN32
+#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE
+#else
+#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI
+#endif
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Class template basic_stringbuf [stringbuf]
@@ -224,6 +314,8 @@ private:
     string_type __str_;
     mutable char_type* __hm_;
     ios_base::openmode __mode_;
+    _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
+    _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);
 
 public:
     // [stringbuf.cons] constructors:
@@ -243,15 +335,110 @@ public:
         str(__s);
     }
 
-    basic_stringbuf(basic_stringbuf&& __rhs);
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
+        : basic_stringbuf(ios_base::in | ios_base::out, __a) {}
+
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
+        : __str_(__a), __hm_(nullptr), __mode_(__wch) {}
+
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
+                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
+        : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI
+    basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a)
+        : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
+        const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
+        : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
+                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
+        : __str_(__s), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+#endif // _LIBCPP_STD_VER >= 20
+
+    basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
+        : basic_stringbuf(__rhs.__mode_, __a) {
+        __move_init(std::move(__rhs));
+    }
+#endif
 
     // [stringbuf.assign] Assign and swap:
     basic_stringbuf& operator=(basic_stringbuf&& __rhs);
-    void swap(basic_stringbuf& __rhs);
+    void swap(basic_stringbuf& __rhs)
+#if _LIBCPP_STD_VER >= 20
+        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+                 allocator_traits<allocator_type>::is_always_equal::value)
+#endif
+        ;
 
     // [stringbuf.members] Member functions:
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
+#endif
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
     string_type str() const;
-    void str(const string_type& __s);
+#else
+    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); }
+
+    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
+        string_type __result;
+        const basic_string_view<_CharT, _Traits> __view = view();
+        if (!__view.empty()) {
+            auto __pos = __view.data() - __str_.data();
+            __result.assign(std::move(__str_), __pos, __view.size());
+        }
+        __str_.clear();
+        __init_buf_ptrs();
+        return __result;
+    }
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+      requires __is_allocator<_SAlloc>::value
+    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+        return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
+#endif
+
+    void str(const string_type& __s) {
+        __str_ = __s;
+        __init_buf_ptrs();
+    }
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
+        __str_ = __s;
+        __init_buf_ptrs();
+    }
+
+    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
+        __str_ = std::move(__s);
+        __init_buf_ptrs();
+    }
+#endif // _LIBCPP_STD_VER >= 20
 
 protected:
     // [stringbuf.virtuals] Overridden virtual functions:
@@ -268,9 +455,7 @@ protected:
 };
 
 template <class _CharT, class _Traits, class _Allocator>
-basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
-    : __mode_(__rhs.__mode_)
-{
+_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
     char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
     ptrdiff_t __binp = -1;
     ptrdiff_t __ninp = -1;
@@ -359,6 +544,10 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
 template <class _CharT, class _Traits, class _Allocator>
 void
 basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
+#if _LIBCPP_STD_VER >= 20
+    noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value ||
+             allocator_traits<_Allocator>::is_always_equal::value)
+#endif
 {
     char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
     ptrdiff_t __rbinp = -1;
@@ -438,49 +627,42 @@ inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
      basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
+#if _LIBCPP_STD_VER >= 20
+    noexcept(noexcept(__x.swap(__y)))
+#endif
 {
     __x.swap(__y);
 }
 
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>
-basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
-{
-    if (__mode_ & ios_base::out)
-    {
+basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
+    if (__mode_ & ios_base::out) {
         if (__hm_ < this->pptr())
             __hm_ = this->pptr();
         return string_type(this->pbase(), __hm_, __str_.get_allocator());
-    }
-    else if (__mode_ & ios_base::in)
+    } else if (__mode_ & ios_base::in)
         return string_type(this->eback(), this->egptr(), __str_.get_allocator());
     return string_type(__str_.get_allocator());
 }
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
 
 template <class _CharT, class _Traits, class _Allocator>
-void
-basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
-{
-    __str_ = __s;
+_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
     __hm_ = nullptr;
-    if (__mode_ & ios_base::in)
-    {
-        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
-        this->setg(const_cast<char_type*>(__str_.data()),
-                   const_cast<char_type*>(__str_.data()),
-                   __hm_);
+    char_type* __data = const_cast<char_type*>(__str_.data());
+    typename string_type::size_type __sz = __str_.size();
+    if (__mode_ & ios_base::in) {
+        __hm_ = __data + __sz;
+        this->setg(__data, __data, __hm_);
     }
-    if (__mode_ & ios_base::out)
-    {
-        typename string_type::size_type __sz = __str_.size();
-        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
+    if (__mode_ & ios_base::out) {
+        __hm_ = __data + __sz;
         __str_.resize(__str_.capacity());
-        this->setp(const_cast<char_type*>(__str_.data()),
-                   const_cast<char_type*>(__str_.data()) + __str_.size());
-        if (__mode_ & (ios_base::app | ios_base::ate))
-        {
-            while (__sz > INT_MAX)
-            {
+        this->setp(__data, __data + __str_.size());
+        if (__mode_ & (ios_base::app | ios_base::ate)) {
+            while (__sz > INT_MAX) {
                 this->pbump(INT_MAX);
                 __sz -= INT_MAX;
             }
@@ -490,6 +672,20 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
     }
 }
 
+#if _LIBCPP_STD_VER >= 20
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits>
+basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept {
+    if (__mode_ & ios_base::out) {
+        if (__hm_ < this->pptr())
+            __hm_ = this->pptr();
+        return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_);
+    } else if (__mode_ & ios_base::in)
+        return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr());
+    return basic_string_view<_CharT, _Traits>();
+}
+#endif // _LIBCPP_STD_VER >= 20
+
 template <class _CharT, class _Traits, class _Allocator>
 typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
 basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
@@ -536,16 +732,16 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
 {
     if (!traits_type::eq_int_type(__c, traits_type::eof()))
     {
-        ptrdiff_t __ninp = this->gptr()  - this->eback();
+        ptrdiff_t __ninp = this->gptr() - this->eback();
         if (this->pptr() == this->epptr())
         {
             if (!(__mode_ & ios_base::out))
                 return traits_type::eof();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             try
             {
-#endif // _LIBCPP_NO_EXCEPTIONS
-                ptrdiff_t __nout = this->pptr()  - this->pbase();
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+                ptrdiff_t __nout = this->pptr() - this->pbase();
                 ptrdiff_t __hm = __hm_ - this->pbase();
                 __str_.push_back(char_type());
                 __str_.resize(__str_.capacity());
@@ -553,13 +749,13 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
                 this->setp(__p, __p + __str_.size());
                 this->__pbump(__nout);
                 __hm_ = this->pbase() + __hm;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             }
             catch (...)
             {
                 return traits_type::eof();
             }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         }
         __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
         if (__mode_ & ios_base::in)
@@ -619,7 +815,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
     if (__wch & ios_base::out)
     {
         this->setp(this->pbase(), this->epptr());
-        this->pbump(__noff);
+        this->__pbump(__noff);
     }
     return pos_type(__noff);
 }
@@ -660,6 +856,28 @@ public:
         , __sb_(__s, __wch | ios_base::in)
     { }
 
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
+        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}
+
+    _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in)
+        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
+        : basic_istringstream(__s, ios_base::in, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_istringstream(
+        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
+        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
+                                                       ios_base::openmode __wch = ios_base::in)
+        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
+#endif // _LIBCPP_STD_VER >= 20
+
     _LIBCPP_INLINE_VISIBILITY
     basic_istringstream(basic_istringstream&& __rhs)
         : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
@@ -685,14 +903,33 @@ public:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
         return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    string_type str() const {
-        return __sb_.str();
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); }
+
+    template <class _SAlloc>
+      requires __is_allocator<_SAlloc>::value
+    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+        return __sb_.str(__sa);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    void str(const string_type& __s) {
+
+    _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+
+    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+#else // _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+#endif // _LIBCPP_STD_VER >= 20
+
+    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
         __sb_.str(__s);
     }
+
+    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -740,6 +977,29 @@ public:
         , __sb_(__s, __wch | ios_base::out)
     { }
 
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a)
+        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {}
+
+    _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out)
+        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::out) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
+        : basic_ostringstream(__s, ios_base::out, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(
+        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
+        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {}
+
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
+                                                       ios_base::openmode __wch = ios_base::out)
+        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}
+#endif // _LIBCPP_STD_VER >= 20
+
     _LIBCPP_INLINE_VISIBILITY
     basic_ostringstream(basic_ostringstream&& __rhs)
         : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs))
@@ -766,14 +1026,33 @@ public:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
         return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    string_type str() const {
-        return __sb_.str();
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); }
+
+    template <class _SAlloc>
+      requires __is_allocator<_SAlloc>::value
+    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+        return __sb_.str(__sa);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    void str(const string_type& __s) {
+
+    _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+
+    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+#else // _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+#endif // _LIBCPP_STD_VER >= 20
+
+    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
         __sb_.str(__s);
     }
+
+    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -821,6 +1100,29 @@ public:
         , __sb_(__s, __wch)
     { }
 
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a)
+        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {}
+
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in)
+        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
+        : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_stringstream(
+        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
+        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {}
+
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
+                                                      ios_base::openmode __wch = ios_base::out | ios_base::in)
+        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}
+#endif // _LIBCPP_STD_VER >= 20
+
     _LIBCPP_INLINE_VISIBILITY
     basic_stringstream(basic_stringstream&& __rhs)
         : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs))
@@ -846,14 +1148,33 @@ public:
     basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
         return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    string_type str() const {
-        return __sb_.str();
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); }
+
+    template <class _SAlloc>
+      requires __is_allocator<_SAlloc>::value
+    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+        return __sb_.str(__sa);
     }
-    _LIBCPP_INLINE_VISIBILITY
-    void str(const string_type& __s) {
+
+    _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+
+    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+#else // _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+#endif // _LIBCPP_STD_VER >= 20
+
+    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
         __sb_.str(__s);
     }
+
+    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
+#endif // _LIBCPP_STD_VER >= 20
 };
 
 template <class _CharT, class _Traits, class _Allocator>
lib/libcxx/include/stack
@@ -42,6 +42,7 @@ public:
     explicit stack(const container_type& c);
     explicit stack(container_type&& c);
     template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23
+    template<container-compatible-range<T> R> stack(from_range_t, R&& rg); // since C++23
     template <class Alloc> explicit stack(const Alloc& a);
     template <class Alloc> stack(const container_type& c, const Alloc& a);
     template <class Alloc> stack(container_type&& c, const Alloc& a);
@@ -49,6 +50,8 @@ public:
     template <class Alloc> stack(stack&& c, const Alloc& a);
     template<class InputIterator, class Alloc>
     stack(InputIterator first, InputIterator last, const Alloc&); // since C++23
+    template<container-compatible-range<T> R, class Alloc>
+      stack(from_range_t, R&& rg, const Alloc&); // since C++23
 
     bool empty() const;
     size_type size() const;
@@ -57,6 +60,8 @@ public:
 
     void push(const value_type& x);
     void push(value_type&& x);
+    template<container-compatible-range<T> R>
+      void push_range(R&& rg); // C++23
     template <class... Args> reference emplace(Args&&... args); // reference in C++17
     void pop();
 
@@ -69,6 +74,9 @@ template<class Container>
 template<class InputIterator>
   stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23
 
+template<ranges::input_range R>
+  stack(from_range_t, R&&) -> stack<ranges::range_value_t<R>>; // since C++23
+
 template<class Container, class Allocator>
   stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
 
@@ -77,6 +85,10 @@ template<class InputIterator, class Allocator>
     -> stack<iter-value-type<InputIterator>,
              deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
 
+template<ranges::input_range R, class Allocator>
+  stack(from_range_t, R&&, Allocator)
+    -> stack<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
+
 template <class T, class Container>
   bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
 template <class T, class Container>
@@ -89,6 +101,9 @@ template <class T, class Container>
   bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
 template <class T, class Container>
   bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
+template<class T, three_way_comparable Container>
+  compare_three_way_result_t<Container>
+    operator<=>(const stack<T, Container>& x, const stack<T, Container>& y); // since C++20
 
 template <class T, class Container>
   void swap(stack<T, Container>& x, stack<T, Container>& y)
@@ -98,13 +113,19 @@ template <class T, class Container>
 
 */
 
+#include <__algorithm/ranges_copy.h>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__type_traits/is_same.h>
 #include <__utility/forward.h>
 #include <deque>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -204,18 +225,30 @@ public:
             : c(_VSTD::move(__s.c), __a) {}
 #endif // _LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class _InputIterator,
-              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+              class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
     _LIBCPP_HIDE_FROM_ABI
     stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
 
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    stack(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
+
     template <class _InputIterator,
               class _Alloc,
-              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+              class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
               class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
     _LIBCPP_HIDE_FROM_ABI
     stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {}
+
+    template <_ContainerCompatibleRange<_Tp> _Range,
+              class _Alloc,
+              class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    stack(from_range_t, _Range&& __range, const _Alloc& __alloc)
+        : c(from_range, std::forward<_Range>(__range), __alloc) {}
+
 #endif
 
     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
@@ -233,9 +266,23 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void push_range(_Range&& __range) {
+      if constexpr (requires (container_type& __c) {
+        __c.append_range(std::forward<_Range>(__range));
+      }) {
+        c.append_range(std::forward<_Range>(__range));
+      } else {
+        ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
+      }
+    }
+#endif
+
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         decltype(auto) emplace(_Args&&... __args)
         { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
 #else
@@ -257,18 +304,18 @@ public:
 
     _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
 
-    template <class T1, class _C1>
+    template <class _T1, class _OtherContainer>
     friend
     bool
-    operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
+    operator==(const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y);
 
-    template <class T1, class _C1>
+    template <class _T1, class _OtherContainer>
     friend
     bool
-    operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
+    operator< (const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y);
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Container,
          class = enable_if_t<!__is_allocator<_Container>::value>
 >
@@ -284,18 +331,28 @@ stack(_Container, _Alloc)
     -> stack<typename _Container::value_type, _Container>;
 #endif
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template<class _InputIterator,
-         class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+         class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
 stack(_InputIterator, _InputIterator)
     -> stack<__iter_value_type<_InputIterator>>;
 
+template <ranges::input_range _Range>
+stack(from_range_t, _Range&&) -> stack<ranges::range_value_t<_Range>>;
+
 template<class _InputIterator,
          class _Alloc,
-         class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = __enable_if_t<__is_allocator<_Alloc>::value>>
 stack(_InputIterator, _InputIterator, _Alloc)
     -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
+
+template <ranges::input_range _Range,
+          class _Alloc,
+          class = __enable_if_t<__is_allocator<_Alloc>::value>>
+stack(from_range_t, _Range&&, _Alloc)
+  -> stack<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
+
 #endif
 
 template <class _Tp, class _Container>
@@ -346,6 +403,17 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
     return !(__y < __x);
 }
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp, three_way_comparable _Container>
+_LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container>
+operator<=>(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) {
+    // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors
+    return __x.__get_container() <=> __y.__get_container();
+}
+
+#endif
+
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
 __enable_if_t<__is_swappable<_Container>::value, void>
@@ -366,6 +434,7 @@ _LIBCPP_END_NAMESPACE_STD
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
 #  include <functional>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_STACK
lib/libcxx/include/stdatomic.h
@@ -121,7 +121,7 @@ using std::atomic_signal_fence                         // see below
 #  pragma GCC system_header
 #endif
 
-#if defined(__cplusplus) && _LIBCPP_STD_VER > 20
+#if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
 
 #include <atomic>
 #include <version>
@@ -230,6 +230,6 @@ using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
 #   include_next <stdatomic.h>
 # endif
 
-#endif // defined(__cplusplus) && _LIBCPP_STD_VER > 20
+#endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
 
 #endif // _LIBCPP_STDATOMIC_H
lib/libcxx/include/stdexcept
@@ -43,8 +43,8 @@ public:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <cstdlib>
-#include <exception>
+#include <__exception/exception.h>
+#include <__verbose_abort>
 #include <iosfwd>  // for string forward decl
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -65,7 +65,7 @@ public:
     __libcpp_refstring& operator=(const __libcpp_refstring& __s) _NOEXCEPT;
     ~__libcpp_refstring();
 
-    const char* c_str() const _NOEXCEPT {return __imp_;}
+    _LIBCPP_HIDE_FROM_ABI const char* c_str() const _NOEXCEPT {return __imp_;}
 };
 #endif // !_LIBCPP_ABI_VCRUNTIME
 
@@ -74,7 +74,7 @@ _LIBCPP_END_NAMESPACE_STD
 namespace std  // purposefully not using versioning namespace
 {
 
-class _LIBCPP_EXCEPTION_ABI logic_error
+class _LIBCPP_EXPORTED_FROM_ABI logic_error
     : public exception
 {
 #ifndef _LIBCPP_ABI_VCRUNTIME
@@ -97,7 +97,7 @@ public:
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI runtime_error
+class _LIBCPP_EXPORTED_FROM_ABI runtime_error
     : public exception
 {
 #ifndef _LIBCPP_ABI_VCRUNTIME
@@ -120,7 +120,7 @@ public:
 #endif // _LIBCPP_ABI_VCRUNTIME
 };
 
-class _LIBCPP_EXCEPTION_ABI domain_error
+class _LIBCPP_EXPORTED_FROM_ABI domain_error
     : public logic_error
 {
 public:
@@ -128,12 +128,12 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s)   : logic_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    domain_error(const domain_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI domain_error(const domain_error&) _NOEXCEPT = default;
     ~domain_error() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI invalid_argument
+class _LIBCPP_EXPORTED_FROM_ABI invalid_argument
     : public logic_error
 {
 public:
@@ -141,24 +141,24 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s)   : logic_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    invalid_argument(const invalid_argument&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI invalid_argument(const invalid_argument&) _NOEXCEPT = default;
     ~invalid_argument() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI length_error
+class _LIBCPP_EXPORTED_FROM_ABI length_error
     : public logic_error
 {
 public:
     _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}
     _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s)   : logic_error(__s) {}
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    length_error(const length_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI length_error(const length_error&) _NOEXCEPT = default;
     ~length_error() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI out_of_range
+class _LIBCPP_EXPORTED_FROM_ABI out_of_range
     : public logic_error
 {
 public:
@@ -166,12 +166,12 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s)   : logic_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    out_of_range(const out_of_range&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI out_of_range(const out_of_range&) _NOEXCEPT = default;
     ~out_of_range() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI range_error
+class _LIBCPP_EXPORTED_FROM_ABI range_error
     : public runtime_error
 {
 public:
@@ -179,12 +179,12 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s)   : runtime_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    range_error(const range_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI range_error(const range_error&) _NOEXCEPT = default;
     ~range_error() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI overflow_error
+class _LIBCPP_EXPORTED_FROM_ABI overflow_error
     : public runtime_error
 {
 public:
@@ -192,12 +192,12 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s)   : runtime_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    overflow_error(const overflow_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI overflow_error(const overflow_error&) _NOEXCEPT = default;
     ~overflow_error() _NOEXCEPT override;
 #endif
 };
 
-class _LIBCPP_EXCEPTION_ABI underflow_error
+class _LIBCPP_EXPORTED_FROM_ABI underflow_error
     : public runtime_error
 {
 public:
@@ -205,7 +205,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s)   : runtime_error(__s) {}
 
 #ifndef _LIBCPP_ABI_VCRUNTIME
-    underflow_error(const underflow_error&) _NOEXCEPT = default;
+    _LIBCPP_HIDE_FROM_ABI underflow_error(const underflow_error&) _NOEXCEPT = default;
     ~underflow_error() _NOEXCEPT override;
 #endif
 };
@@ -215,96 +215,93 @@ public:
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // in the dylib
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
+_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_runtime_error(const char*);
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_logic_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw logic_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("logic_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_domain_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw domain_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("domain_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_invalid_argument(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw invalid_argument(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("invalid_argument was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_length_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw length_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("length_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_out_of_range(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw out_of_range(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("out_of_range was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_range_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw range_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("range_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_overflow_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw overflow_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("overflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_underflow_error(const char*__msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw underflow_error(__msg);
 #else
-    ((void)__msg);
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("underflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
 #endif
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
+#  include <exception>
+#endif
+
 #endif // _LIBCPP_STDEXCEPT
lib/libcxx/include/stdlib.h
@@ -109,16 +109,15 @@ extern "C++" {
 #endif
 
 // MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
-#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
+#if !defined(_LIBCPP_MSVCRT)
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
   return __builtin_labs(__x);
 }
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
   return __builtin_llabs(__x);
 }
-#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
+#endif // !defined(_LIBCPP_MSVCRT)
 
-#if !defined(__sun__)
 _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
   return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
 }
@@ -131,7 +130,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long double
 abs(long double __lcpp_x) _NOEXCEPT {
   return __builtin_fabsl(__lcpp_x);
 }
-#endif // !defined(__sun__)
 
 // div
 
@@ -146,7 +144,7 @@ abs(long double __lcpp_x) _NOEXCEPT {
 #endif
 
 // MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
-#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
+#if !defined(_LIBCPP_MSVCRT)
 inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
   return ::ldiv(__x, __y);
 }
@@ -156,7 +154,7 @@ inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
   return ::lldiv(__x, __y);
 }
 #endif
-#endif // _LIBCPP_MSVCRT / __sun__
+#endif // _LIBCPP_MSVCRT
 } // extern "C++"
 #endif // __cplusplus
 
lib/libcxx/include/stop_token
@@ -0,0 +1,49 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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_STOP_TOKEN
+#define _LIBCPP_STOP_TOKEN
+
+/*
+
+namespace std {
+  // [stoptoken], class stop_token
+  class stop_token;
+
+  // [stopsource], class stop_source
+  class stop_source;
+
+  // no-shared-stop-state indicator
+  struct nostopstate_t {
+    explicit nostopstate_t() = default;
+  };
+  inline constexpr nostopstate_t nostopstate{};
+
+  // [stopcallback], class template stop_callback
+  template<class Callback>
+    class stop_callback;
+
+*/
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__config>
+#include <__stop_token/stop_callback.h>
+#include <__stop_token/stop_source.h>
+#include <__stop_token/stop_token.h>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifdef _LIBCPP_HAS_NO_THREADS
+#  error "<stop_token> is not supported since libc++ has been configured without support for threads."
+#endif
+
+#endif // _LIBCPP_STOP_TOKEN
lib/libcxx/include/streambuf
@@ -109,6 +109,7 @@ protected:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+#include <__fwd/streambuf.h>
 #include <cstdint>
 #include <ios>
 #include <iosfwd>
@@ -489,11 +490,9 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type)
 }
 
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>;
-extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>;
-extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/string
@@ -119,11 +119,13 @@ public:
         explicit basic_string(const T& t, const Allocator& a = Allocator());                    // C++17, constexpr since C++20
     basic_string(const value_type* s, const allocator_type& a = allocator_type());              // constexpr since C++20
     basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
-    basic_string(nullptr_t) = delete; // C++2b
+    basic_string(nullptr_t) = delete; // C++23
     basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());        // constexpr since C++20
     template<class InputIterator>
         basic_string(InputIterator begin, InputIterator end,
                      const allocator_type& a = allocator_type());                               // constexpr since C++20
+    template<container-compatible-range<charT> R>
+      constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator());           // since C++23
     basic_string(initializer_list<value_type>, const Allocator& = Allocator());                 // constexpr since C++20
     basic_string(const basic_string&, const Allocator&);                                        // constexpr since C++20
     basic_string(basic_string&&, const Allocator&);                                             // constexpr since C++20
@@ -140,7 +142,7 @@ public:
              allocator_type::propagate_on_container_move_assignment::value ||
              allocator_type::is_always_equal::value );                                          // C++17, constexpr since C++20
     basic_string& operator=(const value_type* s);                                               // constexpr since C++20
-    basic_string& operator=(nullptr_t) = delete; // C++2b
+    basic_string& operator=(nullptr_t) = delete; // C++23
     basic_string& operator=(value_type c);                                                      // constexpr since C++20
     basic_string& operator=(initializer_list<value_type>);                                      // constexpr since C++20
 
@@ -200,6 +202,8 @@ public:
     basic_string& append(size_type n, value_type c);                                            // constexpr since C++20
     template<class InputIterator>
         basic_string& append(InputIterator first, InputIterator last);                          // constexpr since C++20
+    template<container-compatible-range<charT> R>
+      constexpr basic_string& append_range(R&& rg);                                             // C++23
     basic_string& append(initializer_list<value_type>);                                         // constexpr since C++20
 
     void push_back(value_type c);                                                               // constexpr since C++20
@@ -221,6 +225,8 @@ public:
     basic_string& assign(size_type n, value_type c);                                            // constexpr since C++20
     template<class InputIterator>
         basic_string& assign(InputIterator first, InputIterator last);                          // constexpr since C++20
+    template<container-compatible-range<charT> R>
+      constexpr basic_string& assign_range(R&& rg);                                             // C++23
     basic_string& assign(initializer_list<value_type>);                                         // constexpr since C++20
 
     basic_string& insert(size_type pos1, const basic_string& str);                              // constexpr since C++20
@@ -237,6 +243,8 @@ public:
     iterator      insert(const_iterator p, size_type n, value_type c);                          // constexpr since C++20
     template<class InputIterator>
         iterator insert(const_iterator p, InputIterator first, InputIterator last);             // constexpr since C++20
+    template<container-compatible-range<charT> R>
+      constexpr iterator insert_range(const_iterator p, R&& rg);                                // C++23
     iterator      insert(const_iterator p, initializer_list<value_type>);                       // constexpr since C++20
 
     basic_string& erase(size_type pos = 0, size_type n = npos);                                 // constexpr since C++20
@@ -262,6 +270,8 @@ public:
     basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);     // constexpr since C++20
     template<class InputIterator>
         basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
+    template<container-compatible-range<charT> R>
+      constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23
     basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);  // constexpr since C++20
 
     size_type copy(value_type* s, size_type n, size_type pos = 0) const;                        // constexpr since C++20
@@ -342,9 +352,9 @@ public:
     constexpr bool ends_with(charT c) const noexcept;                                           // C++20
     constexpr bool ends_with(const charT* s) const;                                             // C++20
 
-    constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept;                // C++2b
-    constexpr bool contains(charT c) const noexcept;                                            // C++2b
-    constexpr bool contains(const charT* s) const;                                              // C++2b
+    constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept;                // C++23
+    constexpr bool contains(charT c) const noexcept;                                            // C++23
+    constexpr bool contains(const charT* s) const;                                              // C++23
 };
 
 template<class InputIterator,
@@ -354,6 +364,26 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator())
                   char_traits<typename iterator_traits<InputIterator>::value_type>,
                   Allocator>;   // C++17
 
+template<ranges::input_range R,
+         class Allocator = allocator<ranges::range_value_t<R>>>
+  basic_string(from_range_t, R&&, Allocator = Allocator())
+    -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
+                    Allocator>; // C++23
+
+template<class charT,
+         class traits,
+         class Allocator = allocator<charT>>
+  explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
+    -> basic_string<charT, traits, Allocator>; // C++17
+
+template<class charT,
+         class traits,
+         class Allocator = allocator<charT>>
+  basic_string(basic_string_view<charT, traits>,
+                typename see below::size_type, typename see below::size_type,
+                const Allocator& = Allocator())
+    -> basic_string<charT, traits, Allocator>; // C++17
+
 template<class charT, class traits, class Allocator>
 basic_string<charT, traits, Allocator>
 operator+(const basic_string<charT, traits, Allocator>& lhs,
@@ -524,11 +554,11 @@ template <> struct hash<u16string>;
 template <> struct hash<u32string>;
 template <> struct hash<wstring>;
 
-basic_string<char>     operator "" s( const char *str,     size_t len );           // C++14, constexpr since C++20
-basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len );           // C++14, constexpr since C++20
-constexpr basic_string<char8_t>  operator "" s( const char8_t *str,  size_t len ); // C++20
-basic_string<char16_t> operator "" s( const char16_t *str, size_t len );           // C++14, constexpr since C++20
-basic_string<char32_t> operator "" s( const char32_t *str, size_t len );           // C++14, constexpr since C++20
+basic_string<char>     operator""s( const char *str,     size_t len );           // C++14, constexpr since C++20
+basic_string<wchar_t>  operator""s( const wchar_t *str,  size_t len );           // C++14, constexpr since C++20
+constexpr basic_string<char8_t>  operator""s( const char8_t *str,  size_t len ); // C++20
+basic_string<char16_t> operator""s( const char16_t *str, size_t len );           // C++14, constexpr since C++20
+basic_string<char32_t> operator""s( const char32_t *str, size_t len );           // C++14, constexpr since C++20
 
 }  // std
 
@@ -540,7 +570,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__algorithm/remove_if.h>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <__format/enable_insertable.h>
 #include <__functional/hash.h>
 #include <__functional/unary_function.h>
@@ -550,6 +579,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
 #include <__memory/allocator.h>
 #include <__memory/allocator_traits.h>
@@ -558,23 +588,38 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__ranges/size.h>
 #include <__string/char_traits.h>
 #include <__string/extern_template_lists.h>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_standard_layout.h>
+#include <__type_traits/is_trivial.h>
 #include <__type_traits/noexcept_move_assign_container.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/void_t.h>
 #include <__utility/auto_cast.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <__utility/is_pointer_in_range.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
 #include <__utility/unreachable.h>
 #include <climits>
 #include <cstdint>
 #include <cstdio>  // EOF
-#include <cstdlib>
 #include <cstring>
 #include <limits>
 #include <stdexcept>
 #include <string_view>
-#include <type_traits>
 #include <version>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -632,7 +677,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
 
-extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
+extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
+    <char, char_traits<char>, allocator<char> >(char const*, string const&);
 
 template <class _Iter>
 struct __string_is_trivial_iterator : public false_type {};
@@ -652,6 +698,7 @@ struct __can_be_converted_to_string_view : public _BoolConstant<
     > {};
 
 struct __uninitialized_size_tag {};
+struct __init_with_sentinel_tag {};
 
 template<class _CharT, class _Traits, class _Allocator>
 class basic_string
@@ -810,15 +857,21 @@ private:
             __set_long_pointer(__allocation);
             __set_long_size(__size);
         }
-        std::__debug_db_insert_c(this);
+    }
+
+    template <class _Iter, class _Sent>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a)
+        : __r_(__default_init_tag(), __a) {
+      __init_with_sentinel(std::move(__first), std::move(__last));
     }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) {
-        return iterator(this, __p);
+        return iterator(__p);
     }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const {
-        return const_iterator(this, __p);
+        return const_iterator(__p);
     }
 
 public:
@@ -827,7 +880,6 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
       _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
       : __r_(__default_init_tag(), __default_init_tag()) {
-    std::__debug_db_insert_c(this);
     __default_init();
   }
 
@@ -838,12 +890,24 @@ public:
       _NOEXCEPT
 #endif
       : __r_(__default_init_tag(), __a) {
-    std::__debug_db_insert_c(this);
     __default_init();
   }
 
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str);
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str)
+      : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
+    if (!__str.__is_long())
+      __r_.first() = __str.__r_.first();
+    else
+      __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a)
+      : __r_(__default_init_tag(), __a) {
+    if (!__str.__is_long())
+      __r_.first() = __str.__r_.first();
+    else
+      __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
+  }
 
 #ifndef _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
@@ -854,9 +918,6 @@ public:
 #  endif
       : __r_(std::move(__str.__r_)) {
     __str.__default_init();
-    std::__debug_db_insert_c(this);
-    if (__is_long())
-      std::__debug_db_swap(this, &__str);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
@@ -869,49 +930,47 @@ public:
       __r_.first() = __str.__r_.first();
       __str.__default_init();
     }
-    std::__debug_db_insert_c(this);
-    if (__is_long())
-      std::__debug_db_swap(this, &__str);
   }
 #endif // _LIBCPP_CXX03_LANG
 
-  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
+  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s)
       : __r_(__default_init_tag(), __default_init_tag()) {
-    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*) detected nullptr");
     __init(__s, traits_type::length(__s));
-    std::__debug_db_insert_c(this);
   }
 
-  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a);
+  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a)
+      : __r_(__default_init_tag(), __a) {
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
+    __init(__s, traits_type::length(__s));
+  }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   basic_string(nullptr_t) = delete;
 #endif
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
       : __r_(__default_init_tag(), __default_init_tag()) {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
     __init(__s, __n);
-    std::__debug_db_insert_c(this);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
   basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
       : __r_(__default_init_tag(), __a) {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr,
+                                 "basic_string(const char*, n, allocator) detected nullptr");
     __init(__s, __n);
-    std::__debug_db_insert_c(this);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c)
       : __r_(__default_init_tag(), __default_init_tag()) {
     __init(__n, __c);
-    std::__debug_db_insert_c(this);
   }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
   _LIBCPP_HIDE_FROM_ABI constexpr
   basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator())
       : basic_string(std::move(__str), __pos, npos, __alloc) {}
@@ -934,18 +993,23 @@ public:
       // Perform a copy because the allocators are not compatible.
       __init(__str.data() + __pos, __len);
     }
-
-    std::__debug_db_insert_c(this);
-    if (__is_long())
-      std::__debug_db_swap(this, &__str);
   }
 #endif
 
-  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a);
+  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a)
+      : __r_(__default_init_tag(), __a) {
+    __init(__n, __c);
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20
-  basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator());
+  basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator())
+      : __r_(__default_init_tag(), __a) {
+    size_type __str_sz = __str.size();
+    if (__pos > __str_sz)
+      __throw_out_of_range();
+    __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
+  }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
   basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
@@ -954,65 +1018,91 @@ public:
     if (__pos > __str_sz)
       __throw_out_of_range();
     __init(__str.data() + __pos, __str_sz - __pos);
-    std::__debug_db_insert_c(this);
   }
 
   template <class _Tp,
-            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                                  !__is_same_uncvref<_Tp, basic_string>::value> >
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
   _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-  basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type());
+  basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type())
+      : __r_(__default_init_tag(), __a) {
+    __self_view __sv0 = __t;
+    __self_view __sv  = __sv0.substr(__pos, __n);
+    __init(__sv.data(), __sv.size());
+  }
 
   template <class _Tp,
-            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                                  !__is_same_uncvref<_Tp, basic_string>::value> >
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
-      const _Tp& __t);
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t)
+      : __r_(__default_init_tag(), __default_init_tag()) {
+    __self_view __sv = __t;
+    __init(__sv.data(), __sv.size());
+  }
 
   template <class _Tp,
-            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                                  !__is_same_uncvref<_Tp, basic_string>::value> >
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
   _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
-      const _Tp& __t, const allocator_type& __a);
+      const _Tp& __t, const allocator_type& __a)
+      : __r_(__default_init_tag(), __a) {
+    __self_view __sv = __t;
+    __init(__sv.data(), __sv.size());
+  }
 
-  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
+  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last)
       : __r_(__default_init_tag(), __default_init_tag()) {
     __init(__first, __last);
-    std::__debug_db_insert_c(this);
   }
 
-  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
+  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
   basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
       : __r_(__default_init_tag(), __a) {
     __init(__first, __last);
-    std::__debug_db_insert_c(this);
   }
 
+#if _LIBCPP_STD_VER >= 23
+  template <_ContainerCompatibleRange<_CharT> _Range>
+  _LIBCPP_HIDE_FROM_ABI constexpr
+  basic_string(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
+      : __r_(__default_init_tag(), __a) {
+    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+      __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range));
+    } else {
+      __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
+    }
+  }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il)
       : __r_(__default_init_tag(), __default_init_tag()) {
     __init(__il.begin(), __il.end());
-    std::__debug_db_insert_c(this);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a)
       : __r_(__default_init_tag(), __a) {
     __init(__il.begin(), __il.end());
-    std::__debug_db_insert_c(this);
   }
 #endif // _LIBCPP_CXX03_LANG
 
-    inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string();
+  inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
+    if (__is_long())
+      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+  }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str);
 
-    template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                                               !__is_same_uncvref<_Tp, basic_string>::value> >
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                           !__is_same_uncvref<_Tp, basic_string>::value, int> = 0>
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
       __self_view __sv = __t;
       return assign(__sv);
@@ -1030,7 +1120,7 @@ public:
 #endif
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& operator=(const value_type* __s) {return assign(__s);}
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     basic_string& operator=(nullptr_t) = delete;
 #endif
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
@@ -1097,7 +1187,7 @@ public:
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class _Op>
     _LIBCPP_HIDE_FROM_ABI constexpr
     void resize_and_overwrite(size_type __n, _Op __op) {
@@ -1116,12 +1206,12 @@ public:
     bool empty() const _NOEXCEPT {return size() == 0;}
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
-    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
     return *(data() + __pos);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
-    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
     return *(__get_pointer() + __pos);
   }
 
@@ -1132,14 +1222,11 @@ public:
         return append(__str);
     }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-            && !__is_same_uncvref<_Tp, basic_string >::value,
-            basic_string&
-        >
+    template <class _Tp,
+              __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                !__is_same_uncvref<_Tp, basic_string >::value,
+                            int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
     operator+=(const _Tp& __t) {
         __self_view __sv = __t; return append(__sv);
     }
@@ -1162,25 +1249,27 @@ public:
         return append(__str.data(), __str.size());
   }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t<
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-            && !__is_same_uncvref<_Tp, basic_string>::value,
-            basic_string&
-        >
-                  append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
+  template <class _Tp,
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  append(const _Tp& __t) {
+        __self_view __sv = __t;
+        return append(__sv.data(), __sv.size());
+  }
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
 
-    template <class _Tp>
+    template <class _Tp,
+              __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                !__is_same_uncvref<_Tp, basic_string>::value,
+                            int> = 0>
     _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-            && !__is_same_uncvref<_Tp, basic_string>::value,
-            basic_string&
-        >
-                  append(const _Tp& __t, size_type __pos, size_type __n=npos);
+
+        basic_string&
+        append(const _Tp& __t, size_type __pos, size_type __n = npos);
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
@@ -1188,29 +1277,27 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     void __append_default_init(size_type __n);
 
-    template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    __enable_if_t
-        <
-            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-            basic_string&
-        >
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
     append(_InputIterator __first, _InputIterator __last) {
-      const basic_string __temp(__first, __last, __alloc());
-      append(__temp.data(), __temp.size());
-      return *this;
+        const basic_string __temp(__first, __last, __alloc());
+        append(__temp.data(), __temp.size());
+        return *this;
     }
-    template<class _ForwardIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    __enable_if_t
-        <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
-            basic_string&
-        >
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+
+    template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
     append(_ForwardIterator __first, _ForwardIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_CharT> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr basic_string& append_range(_Range&& __range) {
+      insert_range(end(), std::forward<_Range>(__range));
+      return *this;
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
@@ -1220,33 +1307,32 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
-    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
     return *__get_pointer();
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
-    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
     return *data();
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
-    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
     return *(__get_pointer() + size() - 1);
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
-    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
     return *(data() + size() - 1);
   }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            basic_string&
-        >
-                 assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
+  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  assign(const _Tp& __t) {
+    __self_view __sv = __t;
+    return assign(__sv.data(), __sv.size());
+  }
+
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& assign(const basic_string& __str) { return *this = __str; }
 #ifndef _LIBCPP_CXX03_LANG
@@ -1256,34 +1342,42 @@ public:
         {*this = std::move(__str); return *this;}
 #endif
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-            && !__is_same_uncvref<_Tp, basic_string>::value,
-            basic_string&
-        >
-                  assign(const _Tp & __t, size_type __pos, size_type __n=npos);
+
+    template <class _Tp,
+              __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                !__is_same_uncvref<_Tp, basic_string>::value,
+                            int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+    assign(const _Tp& __t, size_type __pos, size_type __n = npos);
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
-    template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-            basic_string&
-        >
-        assign(_InputIterator __first, _InputIterator __last);
-    template<class _ForwardIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
-            basic_string&
-        >
-        assign(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+    assign(_InputIterator __first, _InputIterator __last);
+
+    template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+    assign(_ForwardIterator __first, _ForwardIterator __last);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_CharT> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr basic_string& assign_range(_Range&& __range) {
+      if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value &&
+          (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) {
+        size_type __n = static_cast<size_type>(ranges::distance(__range));
+        __assign_trivial(ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+      }
+
+      return *this;
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
@@ -1294,56 +1388,57 @@ public:
     return insert(__pos1, __str.data(), __str.size());
   }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            basic_string&
-        >
-                 insert(size_type __pos1, const _Tp& __t)
-    { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
+  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  insert(size_type __pos1, const _Tp& __t) {
+    __self_view __sv = __t;
+    return insert(__pos1, __sv.data(), __sv.size());
+  }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
-            basic_string&
-        >
-                  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator      insert(const_iterator __pos, value_type __c);
+  template <class _Tp,
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_CharT> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
+        return insert(__position, __temp.data(), __temp.data() + __temp.size());
+      }
+    }
+#endif
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
   insert(const_iterator __pos, size_type __n, value_type __c) {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
-                         "string::insert(iterator, n, value) called with an iterator not referring to this string");
     difference_type __p = __pos - begin();
     insert(static_cast<size_type>(__p), __n, __c);
     return begin() + __p;
   }
 
-    template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-            iterator
-        >
-        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
-    template<class _ForwardIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
-            iterator
-        >
-        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
+  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
+  insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
+
+  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
+  insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     iterator insert(const_iterator __pos, initializer_list<value_type> __il)
@@ -1361,28 +1456,27 @@ public:
     return replace(__pos1, __n1, __str.data(), __str.size());
   }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            basic_string&
-        >
-                  replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
-    _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
-            basic_string&
-        >
-                  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
+  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(size_type __pos1, size_type __n1, const _Tp& __t) {
+    __self_view __sv = __t;
+    return replace(__pos1, __n1, __sv.data(), __sv.size());
+  }
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);
+
+  template <class _Tp,
+            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                              !__is_same_uncvref<_Tp, basic_string>::value,
+                          int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);
+
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
@@ -1390,14 +1484,12 @@ public:
         static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
   }
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            basic_string&
-        >
-                  replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
+  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
+    __self_view __sv = __t;
+    return replace(__i1 - begin(), __i2 - __i1, __sv);
+  }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
@@ -1414,14 +1506,19 @@ public:
     return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
   }
 
-    template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __is_cpp17_input_iterator<_InputIterator>::value,
-            basic_string&
-        >
-        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
+  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
+  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
+
+#if _LIBCPP_STD_VER >= 23
+  template <_ContainerCompatibleRange<_CharT> _Range>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr basic_string& replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) {
+    basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
+    return replace(__i1, __i2, __temp);
+  }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
@@ -1460,7 +1557,7 @@ public:
     const value_type* c_str() const _NOEXCEPT {return data();}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     const value_type* data() const _NOEXCEPT  {return std::__to_address(__get_pointer());}
-#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     value_type* data()             _NOEXCEPT  {return std::__to_address(__get_pointer());}
 #endif
@@ -1471,16 +1568,11 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
-    _LIBCPP_CONSTEXPR_SINCE_CXX20
-    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
     _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
@@ -1488,14 +1580,10 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1505,14 +1593,10 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1523,14 +1607,10 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1541,14 +1621,10 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1559,14 +1635,10 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            size_type
-        >
-              find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+    find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1577,23 +1649,13 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     int compare(const basic_string& __str) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            int
-        >
-        compare(const _Tp &__t) const _NOEXCEPT;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+    compare(const _Tp& __t) const _NOEXCEPT;
 
-    template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-            int
-        >
-         compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
+    template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+    compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
@@ -1601,20 +1663,19 @@ public:
     int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
                 size_type __n2 = npos) const;
 
-    template <class _Tp>
-    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-        __enable_if_t
-        <
-            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
-            int
-        >
-        compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
+    template <class _Tp,
+              __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                                !__is_same_uncvref<_Tp, basic_string>::value,
+                            int> = 0>
+    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+    compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const;
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT;
     _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     constexpr _LIBCPP_HIDE_FROM_ABI
     bool starts_with(__self_view __sv) const noexcept
     { return __self_view(data(), size()).starts_with(__sv); }
@@ -1640,7 +1701,7 @@ public:
     { return ends_with(__self_view(__s)); }
 #endif
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     constexpr _LIBCPP_HIDE_FROM_ABI
     bool contains(__self_view __sv) const noexcept
     { return __self_view(data(), size()).contains(__sv); }
@@ -1658,15 +1719,6 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT;
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const;
-    bool __decrementable(const const_iterator* __i) const;
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 private:
     template<class _Alloc>
     inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1683,7 +1735,7 @@ private:
     }
 
     static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
         if (__libcpp_is_constant_evaluated()) {
             for (size_type __i = 0; __i != __n; ++__i)
                 std::construct_at(std::addressof(__begin[__i]));
@@ -1691,7 +1743,7 @@ private:
 #else
         (void)__begin;
         (void)__n;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
     }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __default_init() {
@@ -1716,9 +1768,17 @@ private:
         return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
     }
 
-    template <class _ForwardIterator>
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
+
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
+
+    template <class _ForwardIterator, class _Sentinel>
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-    iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
+    iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {
         size_type __sz = size();
         size_type __cap = capacity();
         value_type* __p;
@@ -1731,7 +1791,7 @@ private:
         }
         else
         {
-            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
+            __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
             __p = std::__to_address(__get_long_pointer());
         }
         __sz += __n;
@@ -1743,19 +1803,25 @@ private:
         return begin() + __ip;
     }
 
+    template<class _Iterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20
+    iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);
+
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     void __set_short_size(size_type __s) _NOEXCEPT {
-        _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
+        _LIBCPP_ASSERT_INTERNAL(
+            __s < __min_cap, "__s should never be greater than or equal to the short string capacity");
         __r_.first().__s.__size_ = __s;
         __r_.first().__s.__is_long_ = false;
     }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     size_type __get_short_size() const _NOEXCEPT {
-        _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
+        _LIBCPP_ASSERT_INTERNAL(
+            !__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
         return __r_.first().__s.__size_;
     }
 
@@ -1839,25 +1905,29 @@ private:
     // to only inline the fast path code directly in the ctor.
     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
 
-    template <class _InputIterator>
-    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-    <
-        __is_exactly_cpp17_input_iterator<_InputIterator>::value
-    >
-    __init(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+    inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last);
 
-    template <class _ForwardIterator>
-    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-    <
-        __is_cpp17_forward_iterator<_ForwardIterator>::value
-    >
-    __init(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+    inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last);
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    void __init_with_sentinel(_InputIterator __first, _Sentinel __last);
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz);
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20
+#if _LIBCPP_ABI_VERSION >= 2 //  We want to use the function in the dylib in ABIv1
+    _LIBCPP_HIDE_FROM_ABI
+#endif
+    _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
     void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                    size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __grow_by_without_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
+                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                                size_type __n_copy,  size_type __n_del,
@@ -1918,7 +1988,7 @@ private:
         _NOEXCEPT_(__alloc_traits::is_always_equal::value);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     void __move_assign(basic_string& __str, true_type)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         _NOEXCEPT;
 #else
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
@@ -1962,21 +2032,13 @@ private:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
       __set_size(__newsz);
-      __invalidate_iterators_past(__newsz);
       traits_type::assign(__p[__newsz], value_type());
       return *this;
     }
 
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __invalidate_iterators_past(size_type);
-
-    template<class _Tp>
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    bool __addr_in_range(_Tp&& __t) const {
-        // assume that the ranges overlap, because we can't check during constant evaluation
-        if (__libcpp_is_constant_evaluated())
-          return true;
-        const volatile void *__p = std::addressof(__t);
-        return data() <= __p && __p <= data() + size();
+    template <class _Tp>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const {
+      return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v));
     }
 
     _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
@@ -2017,7 +2079,7 @@ private:
 template<class _InputIterator,
          class _CharT = __iter_value_type<_InputIterator>,
          class _Allocator = allocator<_CharT>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>
          >
 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
@@ -2041,35 +2103,14 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _
   -> basic_string<_CharT, _Traits, _Allocator>;
 #endif
 
-template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_CONSTEXPR_SINCE_CXX20
-void
-basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
-{
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-    if (!__libcpp_is_constant_evaluated()) {
-        __c_node* __c = __get_db()->__find_c_and_lock(this);
-        if (__c)
-        {
-            const_pointer __new_last = __get_pointer() + __pos;
-            for (__i_node** __p = __c->end_; __p != __c->beg_; )
-            {
-                --__p;
-                const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-                if (__i->base() > __new_last)
-                {
-                    (*__p)->__c_ = nullptr;
-                    if (--__c->end_ != __p)
-                        std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-                }
-            }
-            __get_db()->unlock();
-        }
-    }
-#else
-    (void)__pos;
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-}
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Allocator = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>
+          >
+basic_string(from_range_t, _Range&&, _Allocator = _Allocator())
+  -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>;
+#endif
 
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -2128,44 +2169,6 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
     traits_type::assign(__p[__sz], value_type());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
-    : __r_(__default_init_tag(), __a)
-{
-    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
-    __init(__s, traits_type::length(__s));
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
-    : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
-{
-    if (!__str.__is_long())
-        __r_.first() = __str.__r_.first();
-    else
-        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
-                                  __str.__get_long_size());
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(
-    const basic_string& __str, const allocator_type& __a)
-    : __r_(__default_init_tag(), __a)
-{
-    if (!__str.__is_long())
-        __r_.first() = __str.__r_.first();
-    else
-        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
-                                  __str.__get_long_size());
-    std::__debug_db_insert_c(this);
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
@@ -2220,81 +2223,26 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
-    : __r_(__default_init_tag(), __a)
-{
-    __init(__n, __c);
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
-                                                        size_type __pos, size_type __n,
-                                                        const _Allocator& __a)
-    : __r_(__default_init_tag(), __a)
-{
-    size_type __str_sz = __str.size();
-    if (__pos > __str_sz)
-        __throw_out_of_range();
-    __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, class>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(
-             const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
-    : __r_(__default_init_tag(), __a)
-{
-    __self_view __sv0 = __t;
-    __self_view __sv = __sv0.substr(__pos, __n);
-    __init(__sv.data(), __sv.size());
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, class>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
-     : __r_(__default_init_tag(), __default_init_tag())
-{
-    __self_view __sv = __t;
-    __init(__sv.data(), __sv.size());
-    std::__debug_db_insert_c(this);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, class>
+template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
-    : __r_(__default_init_tag(), __a)
+void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
 {
-    __self_view __sv = __t;
-    __init(__sv.data(), __sv.size());
-    std::__debug_db_insert_c(this);
+  __init_with_sentinel(std::move(__first), std::move(__last));
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_exactly_cpp17_input_iterator<_InputIterator>::value
->
-basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
-{
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+void basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
     __default_init();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     for (; __first != __last; ++__first)
         push_back(*__first);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -2302,28 +2250,35 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
             __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
         throw;
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _ForwardIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_cpp17_forward_iterator<_ForwardIterator>::value
->
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void
 basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
 {
+  size_type __sz = static_cast<size_type>(std::distance(__first, __last));
+  __init_with_size(__first, __last, __sz);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+void basic_string<_CharT, _Traits, _Allocator>::__init_with_size(
+    _InputIterator __first, _Sentinel __last, size_type __sz) {
     if (__libcpp_is_constant_evaluated())
         __r_.first() = __rep();
-    size_type __sz = static_cast<size_type>(std::distance(__first, __last));
+
     if (__sz > max_size())
         __throw_length_error();
+
     pointer __p;
     if (__fits_in_sso(__sz))
     {
         __set_short_size(__sz);
         __p = __get_short_pointer();
+
     }
     else
     {
@@ -2335,14 +2290,14 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
         __set_long_size(__sz);
     }
 
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif  // _LIBCPP_HAS_NO_EXCEPTIONS
     for (; __first != __last; ++__first, (void) ++__p)
         traits_type::assign(*__p, *__first);
     traits_type::assign(*__p, value_type());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -2350,16 +2305,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
             __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
         throw;
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-basic_string<_CharT, _Traits, _Allocator>::~basic_string()
-{
-    std::__debug_db_erase_c(this);
-    if (__is_long())
-        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+#endif  // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2379,7 +2325,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
     auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
     pointer __p = __allocation.ptr;
     __begin_lifetime(__p, __allocation.count);
-    std::__debug_db_invalidate_all(this);
     if (__n_copy != 0)
         traits_type::copy(std::__to_address(__p),
                           std::__to_address(__old_p), __n_copy);
@@ -2398,9 +2343,16 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
     traits_type::assign(__p[__old_sz], value_type());
 }
 
+// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
+// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is
+// not removed or changed to avoid breaking the ABI.
 template <class _CharT, class _Traits, class _Allocator>
 void
 _LIBCPP_CONSTEXPR_SINCE_CXX20
+#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
+    _LIBCPP_HIDE_FROM_ABI
+#endif
+    _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                                                      size_type __n_copy,  size_type __n_del,     size_type __n_add)
 {
@@ -2414,7 +2366,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
     auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
     pointer __p = __allocation.ptr;
     __begin_lifetime(__p, __allocation.count);
-    std::__debug_db_invalidate_all(this);
     if (__n_copy != 0)
         traits_type::copy(std::__to_address(__p),
                           std::__to_address(__old_p), __n_copy);
@@ -2429,6 +2380,21 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
     __set_long_cap(__allocation.count);
 }
 
+template <class _CharT, class _Traits, class _Allocator>
+void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
+    size_type __old_cap,
+    size_type __delta_cap,
+    size_type __old_sz,
+    size_type __n_copy,
+    size_type __n_del,
+    size_type __n_add) {
+    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+    __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
+    _LIBCPP_SUPPRESS_DEPRECATED_POP
+    __set_long_size(__old_sz - __n_del + __n_add);
+}
+
 // assign
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2443,7 +2409,6 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
     __is_short ? __set_short_size(__n) : __set_long_size(__n);
     traits_type::copy(std::__to_address(__p), __s, __n);
     traits_type::assign(__p[__n], value_type());
-    __invalidate_iterators_past(__n);
   } else {
     size_type __sz = __is_short ? __get_short_size() : __get_long_size();
     __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
@@ -2473,7 +2438,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::assign received nullptr");
     return (__builtin_constant_p(__n) && __fits_in_sso(__n))
                ? __assign_short(__s, __n)
                : __assign_external(__s, __n);
@@ -2488,7 +2453,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
     if (__cap < __n)
     {
         size_type __sz = size();
-        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
+        __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
     }
     value_type* __p = std::__to_address(__get_pointer());
     traits_type::assign(__p, __n, __c);
@@ -2513,7 +2478,6 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
     }
     traits_type::assign(*__p, __c);
     traits_type::assign(*++__p, value_type());
-    __invalidate_iterators_past(1);
     return *this;
 }
 
@@ -2522,7 +2486,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
 {
-  if (this != &__str) {
+  if (this != std::addressof(__str)) {
     __copy_assign_alloc(__str);
     if (!__is_long()) {
       if (!__str.__is_long()) {
@@ -2555,7 +2519,7 @@ template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _NOEXCEPT
 #else
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
@@ -2584,55 +2548,62 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
 #endif
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-     __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
+template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
-    const basic_string __temp(__first, __last, __alloc());
-    assign(__temp.data(), __temp.size());
-    return *this;
+  __assign_with_sentinel(__first, __last);
+  return *this;
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _ForwardIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+void
+basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) {
+  const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc());
+  assign(__temp.data(), __temp.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
 {
-    size_type __cap = capacity();
-    size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
-        static_cast<size_type>(std::distance(__first, __last)) : 0;
+  if (__string_is_trivial_iterator<_ForwardIterator>::value) {
+    size_type __n = static_cast<size_type>(std::distance(__first, __last));
+    __assign_trivial(__first, __last, __n);
+  } else {
+    __assign_with_sentinel(__first, __last);
+  }
 
-    if (__string_is_trivial_iterator<_ForwardIterator>::value &&
-        (__cap >= __n || !__addr_in_range(*__first)))
-    {
-        if (__cap < __n)
-        {
-            size_type __sz = size();
-            __grow_by(__cap, __n - __cap, __sz, 0, __sz);
-        }
-        pointer __p = __get_pointer();
-        for (; __first != __last; ++__p, (void) ++__first)
-            traits_type::assign(*__p, *__first);
-        traits_type::assign(*__p, value_type());
-        __set_size(__n);
-        __invalidate_iterators_past(__n);
-    }
-    else
-    {
-        const basic_string __temp(__first, __last, __alloc());
-        assign(__temp.data(), __temp.size());
+  return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+void
+basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
+  _LIBCPP_ASSERT_INTERNAL(
+      __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
+
+  size_type __cap = capacity();
+  if (__cap < __n) {
+    // Unlike `append` functions, if the input range points into the string itself, there is no case that the input
+    // range could get invalidated by reallocation:
+    // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string,
+    //    thus no reallocation would happen.
+    // 2. In the exotic case where the input range is the byte representation of the string itself, the string
+    //    object itself stays valid even if reallocation happens.
+    size_type __sz = size();
+    __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
     }
-    return *this;
+    pointer __p = __get_pointer();
+    for (; __first != __last; ++__p, (void) ++__first)
+        traits_type::assign(*__p, *__first);
+    traits_type::assign(*__p, value_type());
+    __set_size(__n);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2647,16 +2618,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
-basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
-{
+template <class _Tp,
+          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
+                        int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {
     __self_view __sv = __t;
     size_type __sz = __sv.size();
     if (__pos > __sz)
@@ -2664,7 +2631,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p
     return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
 }
 
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
@@ -2677,7 +2643,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::assign received nullptr");
     return __builtin_constant_p(*__s)
                ? (__fits_in_sso(traits_type::length(__s))
                       ? __assign_short(__s, traits_type::length(__s))
@@ -2691,7 +2657,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::append received nullptr");
     size_type __cap = capacity();
     size_type __sz = size();
     if (__cap - __sz >= __n)
@@ -2720,7 +2686,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
         size_type __cap = capacity();
         size_type __sz = size();
         if (__cap - __sz < __n)
-            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+            __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
         pointer __p = __get_pointer();
         traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
         __sz += __n;
@@ -2739,7 +2705,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
         size_type __cap = capacity();
         size_type __sz = size();
         if (__cap - __sz < __n)
-            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+            __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
         pointer __p = __get_pointer();
         __sz += __n;
         __set_size(__sz);
@@ -2767,7 +2733,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
     }
     if (__sz == __cap)
     {
-        __grow_by(__cap, 1, __sz, __sz, 0);
+        __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
         __is_short = false; // the string is always long after __grow_by
     }
     pointer __p = __get_pointer();
@@ -2786,13 +2752,8 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _ForwardIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
+template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(
     _ForwardIterator __first, _ForwardIterator __last)
 {
@@ -2805,7 +2766,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(
             !__addr_in_range(*__first))
         {
             if (__cap - __sz < __n)
-                __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+              __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
             pointer __p = __get_pointer() + __sz;
             for (; __first != __last; ++__p, (void) ++__first)
                 traits_type::assign(*__p, *__first);
@@ -2833,15 +2794,12 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-    __enable_if_t
-    <
-        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-        basic_string<_CharT, _Traits, _Allocator>&
-    >
-basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
-{
+template <class _Tp,
+          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
+                        int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {
     __self_view __sv = __t;
     size_type __sz = __sv.size();
     if (__pos > __sz)
@@ -2854,7 +2812,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::append received nullptr");
     return append(__s, traits_type::length(__s));
 }
 
@@ -2865,7 +2823,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::insert received nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         __throw_out_of_range();
@@ -2921,7 +2879,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
         }
         else
         {
-            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
+            __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
             __p = std::__to_address(__get_long_pointer());
         }
         traits_type::assign(__p + __pos, __n, __c);
@@ -2933,47 +2891,40 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-   __is_exactly_cpp17_input_iterator<_InputIterator>::value,
-   typename basic_string<_CharT, _Traits, _Allocator>::iterator
->
+template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
-  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
-                       "string::insert(iterator, range) called with an iterator not"
-                       " referring to this string");
   const basic_string __temp(__first, __last, __alloc());
   return insert(__pos, __temp.data(), __temp.data() + __temp.size());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _ForwardIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::iterator
->
+template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
-                         "string::insert(iterator, range) called with an iterator not referring to this string");
+    auto __n = static_cast<size_type>(std::distance(__first, __last));
+    return __insert_with_size(__pos, __first, __last, __n);
+}
 
+template <class _CharT, class _Traits, class _Allocator>
+template<class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20
+typename basic_string<_CharT, _Traits, _Allocator>::iterator
+basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(
+    const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) {
     size_type __ip = static_cast<size_type>(__pos - begin());
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
     if (__n == 0)
         return begin() + __ip;
 
-    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
+    if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first))
     {
         return __insert_from_safe_copy(__n, __ip, __first, __last);
     }
     else
     {
-        const basic_string __temp(__first, __last, __alloc());
+        const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc());
         return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
     }
 }
@@ -2991,16 +2942,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
-                                                  size_type __pos2, size_type __n)
-{
+template <class _Tp,
+          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
+                        int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {
     __self_view __sv = __t;
     size_type __str_sz = __sv.size();
     if (__pos2 > __str_sz)
@@ -3013,7 +2960,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::insert received nullptr");
     return insert(__pos, __s, traits_type::length(__s));
 }
 
@@ -3022,17 +2969,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
-                         "string::insert(iterator, character) called with an iterator not"
-                         " referring to this string");
-
     size_type __ip = static_cast<size_type>(__pos - begin());
     size_type __sz = size();
     size_type __cap = capacity();
     value_type* __p;
     if (__cap == __sz)
     {
-        __grow_by(__cap, 1, __sz, __ip, 0, 1);
+        __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
         __p = std::__to_address(__get_long_pointer());
     }
     else
@@ -3056,7 +2999,7 @@ basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 {
-    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         __throw_out_of_range();
@@ -3064,10 +3007,6 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
     size_type __cap = capacity();
     if (__cap - __sz + __n1 >= __n2)
     {
-        if (__libcpp_is_constant_evaluated()) {
-            __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
-            return *this;
-        }
         value_type* __p = std::__to_address(__get_pointer());
         if (__n1 != __n2)
         {
@@ -3080,7 +3019,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
                     traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
                     return __null_terminate_at(__p, __sz + (__n2 - __n1));
                 }
-                if (__p + __pos < __s && __s < __p + __sz)
+                if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s))
                 {
                     if (__p + __pos + __n1 <= __s)
                         __s += __n2 - __n1;
@@ -3127,7 +3066,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
     }
     else
     {
-        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
+        __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
         __p = std::__to_address(__get_long_pointer());
     }
     traits_type::assign(__p + __pos, __n2, __c);
@@ -3135,13 +3074,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template<class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __is_cpp17_input_iterator<_InputIterator>::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
+template<class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
                                                    _InputIterator __j1, _InputIterator __j2)
 {
@@ -3162,16 +3096,13 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-    basic_string<_CharT, _Traits, _Allocator>&
->
-basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
-                                                   size_type __pos2, size_type __n2)
-{
+template <class _Tp,
+          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
+                        int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(
+    size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {
     __self_view __sv = __t;
     size_type __str_sz = __sv.size();
     if (__pos2 > __str_sz)
@@ -3184,7 +3115,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::replace received nullptr");
     return replace(__pos, __n1, __s, traits_type::length(__s));
 }
 
@@ -3230,11 +3161,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
 {
-  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
-                       "string::erase(iterator) called with an iterator not"
-                       " referring to this string");
-
-  _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
+  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+      __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
   iterator __b = begin();
   size_type __r = static_cast<size_type>(__pos - __b);
   erase(__r, 1);
@@ -3246,11 +3174,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
-  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
-                       "string::erase(iterator,  iterator) called with an iterator not"
-                       " referring to this string");
-
-  _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
+  _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");
   iterator __b = begin();
   size_type __r = static_cast<size_type>(__first - __b);
   erase(__r, static_cast<size_type>(__last - __first));
@@ -3262,7 +3186,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
 void
 basic_string<_CharT, _Traits, _Allocator>::pop_back()
 {
-    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");
     __erase_to_end(size() - 1);
 }
 
@@ -3271,7 +3195,6 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
 void
 basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
 {
-    std::__debug_db_invalidate_all(this);
     if (__is_long())
     {
         traits_type::assign(*__get_long_pointer(), value_type());
@@ -3365,23 +3288,23 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
         }
         else
         {
-        #ifndef _LIBCPP_NO_EXCEPTIONS
+        #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             try
             {
-        #endif // _LIBCPP_NO_EXCEPTIONS
+        #endif // _LIBCPP_HAS_NO_EXCEPTIONS
                 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
                 __new_data = __allocation.ptr;
                 __target_capacity = __allocation.count - 1;
-        #ifndef _LIBCPP_NO_EXCEPTIONS
+        #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             }
             catch (...)
             {
                 return;
             }
-        #else  // _LIBCPP_NO_EXCEPTIONS
+        #else  // _LIBCPP_HAS_NO_EXCEPTIONS
             if (__new_data == nullptr)
                 return;
-        #endif // _LIBCPP_NO_EXCEPTIONS
+        #endif // _LIBCPP_HAS_NO_EXCEPTIONS
         }
         __begin_lifetime(__new_data, __target_capacity + 1);
         __now_long = true;
@@ -3400,7 +3323,6 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
     }
     else
         __set_short_size(__sz);
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3447,13 +3369,7 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
                     __is_nothrow_swappable<allocator_type>::value)
 #endif
 {
-    if (!__is_long())
-        std::__debug_db_invalidate_all(this);
-    if (!__str.__is_long())
-        std::__debug_db_invalidate_all(&__str);
-    std::__debug_db_swap(this, &__str);
-
-    _LIBCPP_ASSERT(
+    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
         __alloc_traits::propagate_on_container_swap::value ||
         __alloc_traits::is_always_equal::value ||
         __alloc() == __str.__alloc(), "swapping non-equal allocators");
@@ -3479,7 +3395,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos,
                                                 size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find(): received nullptr");
     return std::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3495,13 +3411,8 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3516,7 +3427,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find(): received nullptr");
     return std::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3540,7 +3451,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos,
                                                  size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
     return std::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3556,13 +3467,8 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3577,7 +3483,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::rfind(): received nullptr");
     return std::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3601,7 +3507,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos,
                                                          size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
     return std::__str_find_first_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3617,13 +3523,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3638,7 +3539,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_of(): received nullptr");
     return std::__str_find_first_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3661,7 +3562,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos,
                                                         size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
     return std::__str_find_last_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3677,13 +3578,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3698,7 +3594,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_of(): received nullptr");
     return std::__str_find_last_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3721,7 +3617,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
                                                              size_type __pos,
                                                              size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3737,13 +3633,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3758,7 +3649,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_not_of(): received nullptr");
     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3782,7 +3673,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
                                                             size_type __pos,
                                                             size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
@@ -3798,13 +3689,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::size_type
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
                                                 size_type __pos) const _NOEXCEPT
 {
@@ -3819,7 +3705,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_not_of(): received nullptr");
     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
@@ -3837,13 +3723,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
 // compare
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    int
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
 {
     __self_view __sv = __t;
@@ -3876,7 +3757,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    const value_type* __s,
                                                    size_type __n2) const
 {
-    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
     size_type __sz = size();
     if (__pos1 > __sz || __n2 == npos)
         __throw_out_of_range();
@@ -3893,13 +3774,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
-    int
->
+template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
                                                    const _Tp& __t) const
@@ -3919,20 +3795,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-__enable_if_t
-<
-    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
-    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-    int
->
-basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
-                                                   size_type __n1,
-                                                   const _Tp& __t,
-                                                   size_type __pos2,
-                                                   size_type __n2) const
-{
+template <class _Tp,
+          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
+                        int> >
+_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(
+    size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const {
     __self_view __sv = __t;
     return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
 }
@@ -3954,7 +3822,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
     return compare(0, npos, __s, traits_type::length(__s));
 }
 
@@ -3965,7 +3833,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
                                                    const value_type* __s) const
 {
-    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
     return compare(__pos1, __n1, __s, traits_type::length(__s));
 }
 
@@ -3982,7 +3850,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const
         return false;
     if (data() == nullptr)
         return false;
-    if (data()[size()] != value_type())
+    if (!_Traits::eq(data()[size()], value_type()))
         return false;
     return true;
 }
@@ -4010,7 +3878,7 @@ bool
 operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
 {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
 #else
     size_t __lhs_sz = __lhs.size();
@@ -4047,7 +3915,7 @@ operator==(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
 {
     typedef basic_string<_CharT, _Traits, _Allocator> _String;
-    _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
     size_t __lhs_len = _Traits::length(__lhs);
     if (__lhs_len != __rhs.size()) return false;
     return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
@@ -4060,18 +3928,18 @@ bool
 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
 {
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
 #else
     typedef basic_string<_CharT, _Traits, _Allocator> _String;
-    _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
     size_t __rhs_len = _Traits::length(__rhs);
     if (__rhs_len != __lhs.size()) return false;
     return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
 #endif
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
@@ -4086,7 +3954,7 @@ operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT
     return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
 }
 
-#else // _LIBCPP_STD_VER > 17
+#else // _LIBCPP_STD_VER >= 20
 
 template<class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI
@@ -4230,7 +4098,7 @@ operator>=(const _CharT* __lhs,
 {
     return !(__lhs < __rhs);
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 // operator +
 
@@ -4397,46 +4265,46 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
     __lhs.swap(__rhs);
 }
 
-_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI int                stoi  (const string& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI long               stol  (const string& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI unsigned long      stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI long long          stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
 
-_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = nullptr);
-_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = nullptr);
-_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI float       stof (const string& __str, size_t* __idx = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI double      stod (const string& __str, size_t* __idx = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
 
-_LIBCPP_FUNC_VIS string to_string(int __val);
-_LIBCPP_FUNC_VIS string to_string(unsigned __val);
-_LIBCPP_FUNC_VIS string to_string(long __val);
-_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
-_LIBCPP_FUNC_VIS string to_string(long long __val);
-_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
-_LIBCPP_FUNC_VIS string to_string(float __val);
-_LIBCPP_FUNC_VIS string to_string(double __val);
-_LIBCPP_FUNC_VIS string to_string(long double __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
+_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-
-_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = nullptr);
-_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = nullptr);
-_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr);
-
-_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
-_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
+_LIBCPP_EXPORTED_FROM_ABI int                stoi  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI long               stol  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI unsigned long      stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI long long          stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+
+_LIBCPP_EXPORTED_FROM_ABI float       stof (const wstring& __str, size_t* __idx = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI double      stod (const wstring& __str, size_t* __idx = nullptr);
+_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
+
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
+_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
 template<class _CharT, class _Traits, class _Allocator>
@@ -4445,11 +4313,11 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type
                basic_string<_CharT, _Traits, _Allocator>::npos;
 
 template <class _CharT, class _Allocator>
-struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
-{
-    size_t
-    operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
-    { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); }
+struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
+    _LIBCPP_HIDE_FROM_ABI size_t
+    operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
+        return std::__do_string_hash(__val.data(), __val.data() + __val.size());
+    }
 };
 
 template <class _Allocator>
@@ -4504,7 +4372,7 @@ basic_istream<_CharT, _Traits>&
 getline(basic_istream<_CharT, _Traits>&& __is,
         basic_string<_CharT, _Traits, _Allocator>& __str);
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _CharT, class _Traits, class _Allocator, class _Up>
 inline _LIBCPP_HIDE_FROM_ABI
     typename basic_string<_CharT, _Traits, _Allocator>::size_type
@@ -4526,57 +4394,21 @@ inline _LIBCPP_HIDE_FROM_ABI
 }
 #endif
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-template<class _CharT, class _Traits, class _Allocator>
-bool
-basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
-{
-    return data() <= std::__to_address(__i->base()) &&
-           std::__to_address(__i->base()) < data() + size();
-}
-
-template<class _CharT, class _Traits, class _Allocator>
-bool
-basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
-{
-    return data() < std::__to_address(__i->base()) &&
-           std::__to_address(__i->base()) <= data() + size();
-}
-
-template<class _CharT, class _Traits, class _Allocator>
-bool
-basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
-{
-    const value_type* __p = std::__to_address(__i->base()) + __n;
-    return data() <= __p && __p <= data() + size();
-}
-
-template<class _CharT, class _Traits, class _Allocator>
-bool
-basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-{
-    const value_type* __p = std::__to_address(__i->base()) + __n;
-    return data() <= __p && __p < data() + size();
-}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 // Literal suffixes for basic_string [basic.string.literals]
 inline namespace literals
 {
   inline namespace string_literals
   {
     inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string<char> operator "" s( const char *__str, size_t __len )
+    basic_string<char> operator""s( const char *__str, size_t __len )
     {
         return basic_string<char> (__str, __len);
     }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
     inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
+    basic_string<wchar_t> operator""s( const wchar_t *__str, size_t __len )
     {
         return basic_string<wchar_t> (__str, __len);
     }
@@ -4584,27 +4416,27 @@ inline namespace literals
 
 #ifndef _LIBCPP_HAS_NO_CHAR8_T
     inline _LIBCPP_HIDE_FROM_ABI constexpr
-    basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len)
+    basic_string<char8_t> operator""s(const char8_t *__str, size_t __len)
     {
         return basic_string<char8_t> (__str, __len);
     }
 #endif
 
     inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
+    basic_string<char16_t> operator""s( const char16_t *__str, size_t __len )
     {
         return basic_string<char16_t> (__str, __len);
     }
 
     inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
+    basic_string<char32_t> operator""s( const char32_t *__str, size_t __len )
     {
         return basic_string<char32_t> (__str, __len);
     }
   } // namespace string_literals
 } // namespace literals
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <>
 inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -4622,12 +4454,12 @@ _LIBCPP_POP_MACROS
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <algorithm>
 #  include <concepts>
-#  include <functional>
+#  include <cstdlib>
 #  include <iterator>
 #  include <new>
+#  include <type_traits>
 #  include <typeinfo>
 #  include <utility>
-#  include <vector>
 #endif
 
 #endif // _LIBCPP_STRING
lib/libcxx/include/string.h
@@ -64,8 +64,7 @@ size_t strlen(const char* s);
 // MSVCRT, GNU libc and its derivates may already have the correct prototype in
 // <string.h>. This macro can be defined by users if their C library provides
 // the right signature.
-#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || \
-    defined(__sun__) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
+#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
 #define _LIBCPP_STRING_H_HAS_CONST_OVERLOADS
 #endif
 
lib/libcxx/include/string_view
@@ -90,7 +90,7 @@ namespace std {
       basic_string_view& operator=(const basic_string_view&) noexcept = default;
       template<class Allocator>
       constexpr basic_string_view(const charT* str);
-      basic_string_view(nullptr_t) = delete; // C++2b
+      basic_string_view(nullptr_t) = delete; // C++23
       constexpr basic_string_view(const charT* str, size_type len);
       template <class It, class End>
       constexpr basic_string_view(It begin, End end); // C++20
@@ -168,9 +168,9 @@ namespace std {
       constexpr bool ends_with(charT c) const noexcept;               // C++20
       constexpr bool ends_with(const charT* s) const;                 // C++20
 
-      constexpr bool contains(basic_string_view s) const noexcept; // C++2b
-      constexpr bool contains(charT c) const noexcept;             // C++2b
-      constexpr bool contains(const charT* s) const;               // C++2b
+      constexpr bool contains(basic_string_view s) const noexcept; // C++23
+      constexpr bool contains(charT c) const noexcept;             // C++23
+      constexpr bool contains(const charT* s) const;               // C++23
 
      private:
       const_pointer data_;  // exposition only
@@ -191,11 +191,11 @@ namespace std {
   template <> struct hash<u32string_view>;
   template <> struct hash<wstring_view>;
 
-  constexpr basic_string_view<char>     operator "" sv(const char *str,     size_t len) noexcept;
-  constexpr basic_string_view<wchar_t>  operator "" sv(const wchar_t *str,  size_t len) noexcept;
-  constexpr basic_string_view<char8_t>  operator "" sv(const char8_t *str,  size_t len) noexcept; // C++20
-  constexpr basic_string_view<char16_t> operator "" sv(const char16_t *str, size_t len) noexcept;
-  constexpr basic_string_view<char32_t> operator "" sv(const char32_t *str, size_t len) noexcept;
+  constexpr basic_string_view<char>     operator""sv(const char *str,     size_t len) noexcept;
+  constexpr basic_string_view<wchar_t>  operator""sv(const wchar_t *str,  size_t len) noexcept;
+  constexpr basic_string_view<char8_t>  operator""sv(const char8_t *str,  size_t len) noexcept; // C++20
+  constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept;
+  constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept;
 
 }  // namespace std
 
@@ -208,8 +208,9 @@ namespace std {
 #include <__functional/hash.h>
 #include <__functional/unary_function.h>
 #include <__fwd/string_view.h>
+#include <__iterator/bounded_iter.h>
 #include <__iterator/concepts.h>
-#include <__iterator/readable_traits.h>
+#include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/pointer_traits.h>
 #include <__ranges/concepts.h>
@@ -218,10 +219,18 @@ namespace std {
 #include <__ranges/enable_view.h>
 #include <__ranges/size.h>
 #include <__string/char_traits.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_standard_layout.h>
+#include <__type_traits/is_trivial.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__type_traits/type_identity.h>
+#include <cstddef>
 #include <iosfwd>
 #include <limits>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -252,7 +261,9 @@ template <class _Traits>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
 inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
   // This needs to be a single statement for C++11 constexpr
-  return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s);
+  return _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr,
+                                      "null pointer passed to non-null argument of char_traits<...>::length"),
+      _Traits::length(__s);
 }
 
 template<class _CharT, class _Traits>
@@ -265,7 +276,11 @@ public:
     using const_pointer          = const _CharT*;
     using reference              = _CharT&;
     using const_reference        = const _CharT&;
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
+    using const_iterator         = __bounded_iter<const_pointer>;
+#else
     using const_iterator         = const_pointer; // See [string.view.iterators]
+#endif
     using iterator               = const_iterator;
     using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
     using reverse_iterator       = const_reverse_iterator;
@@ -293,22 +308,27 @@ public:
     basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
         : __data_(__s), __size_(__len)
     {
-#if _LIBCPP_STD_VER > 11
-    _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __len <= static_cast<size_type>(numeric_limits<difference_type>::max()),
+        "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__len == 0 || __s != nullptr,
+                                 "string_view::string_view(_CharT *, size_t): received nullptr");
 #endif
     }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
       requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
     constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
        : __data_(_VSTD::to_address(__begin)), __size_(__end - __begin)
     {
-      _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
+      _LIBCPP_ASSERT_VALID_INPUT_RANGE((__end - __begin) >= 0,
+                                       "std::string_view::string_view(iterator, sentinel) received invalid range");
     }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class _Range>
       requires (
         !is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
@@ -318,20 +338,17 @@ public:
         !is_convertible_v<_Range, const _CharT*> &&
         (!requires(remove_cvref_t<_Range>& __d) {
           __d.operator _VSTD::basic_string_view<_CharT, _Traits>();
-        }) &&
-        (!requires {
-         typename remove_reference_t<_Range>::traits_type;
-        } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>)
+        })
       )
     constexpr explicit _LIBCPP_HIDE_FROM_ABI
     basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
     basic_string_view(const _CharT* __s)
         : __data_(__s), __size_(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     basic_string_view(nullptr_t) = delete;
 #endif
 
@@ -343,10 +360,22 @@ public:
     const_iterator end()    const _NOEXCEPT { return cend(); }
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
-    const_iterator cbegin() const _NOEXCEPT { return __data_; }
+    const_iterator cbegin() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
+        return std::__make_bounded_iter(data(), data(), data() + size());
+#else
+        return __data_;
+#endif
+    }
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
-    const_iterator cend()   const _NOEXCEPT { return __data_ + __size_; }
+    const_iterator cend()   const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
+        return std::__make_bounded_iter(data() + size(), data(), data() + size());
+#else
+        return __data_ + __size_;
+#endif
+    }
 
     _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY
     const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
@@ -376,7 +405,7 @@ public:
     // [string.view.access], element access
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
     const_reference operator[](size_type __pos) const _NOEXCEPT {
-      return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
+      return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
     }
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
@@ -390,13 +419,14 @@ public:
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
     const_reference front() const _NOEXCEPT
     {
-        return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data_[0];
+        return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
     }
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
     const_reference back() const _NOEXCEPT
     {
-        return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data_[__size_-1];
+        return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"),
+               __data_[__size_ - 1];
     }
 
     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
@@ -406,7 +436,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     void remove_prefix(size_type __n) _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");
         __data_ += __n;
         __size_ -= __n;
     }
@@ -414,7 +444,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     void remove_suffix(size_type __n) _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()");
         __size_ -= __n;
     }
 
@@ -492,7 +522,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
         return std::__str_find<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -507,7 +537,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
         return std::__str_find<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -515,7 +545,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find(): received nullptr");
         return std::__str_find<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
@@ -524,7 +554,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
         return std::__str_rfind<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -539,7 +569,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
         return std::__str_rfind<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -547,7 +577,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::rfind(): received nullptr");
         return std::__str_rfind<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
@@ -556,7 +586,8 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
+                                     "string_view::find_first_of(): received nullptr");
         return std::__str_find_first_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -568,7 +599,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
         return std::__str_find_first_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -576,7 +607,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_of(): received nullptr");
         return std::__str_find_first_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
@@ -585,7 +616,8 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
+                                     "string_view::find_last_of(): received nullptr");
         return std::__str_find_last_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -597,7 +629,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
         return std::__str_find_last_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -605,7 +637,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_of(): received nullptr");
         return std::__str_find_last_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
@@ -614,7 +646,8 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
+                                     "string_view::find_first_not_of(): received nullptr");
         return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -629,7 +662,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
         return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -637,7 +670,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
         return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
@@ -646,7 +679,8 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
+                                     "string_view::find_last_not_of(): received nullptr");
         return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s.data(), __pos, __s.size());
     }
@@ -661,7 +695,7 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
         return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, __n);
     }
@@ -669,12 +703,12 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
         return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     constexpr _LIBCPP_INLINE_VISIBILITY
     bool starts_with(basic_string_view __s) const noexcept
     { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
@@ -700,7 +734,7 @@ public:
     { return ends_with(basic_string_view(__s)); }
 #endif
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     constexpr _LIBCPP_INLINE_VISIBILITY
     bool contains(basic_string_view __sv) const noexcept
     { return find(__sv) != npos; }
@@ -720,23 +754,23 @@ private:
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _CharT, class _Traits>
 inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
 
 template <class _CharT, class _Traits>
 inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 // [string.view.deduct]
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
   basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <ranges::contiguous_range _Range>
   basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
 #endif
@@ -773,11 +807,11 @@ bool operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
     if (__lhs.size() != __rhs.size()) return false;
     return __lhs.compare(__rhs) == 0;
 }
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 // operator <=>
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 template <class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI constexpr auto
@@ -807,7 +841,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
     }
 }
 
-#else //  _LIBCPP_STD_VER > 17
+#else //  _LIBCPP_STD_VER >= 20
 
 // operator !=
 template<class _CharT, class _Traits>
@@ -940,7 +974,7 @@ bool operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
     return __lhs.compare(__rhs) >= 0;
 }
 
-#endif //  _LIBCPP_STD_VER > 17
+#endif //  _LIBCPP_STD_VER >= 20
 
 template<class _CharT, class _Traits>
 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
@@ -976,20 +1010,20 @@ template <>
 struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
 #endif
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 inline namespace literals
 {
   inline namespace string_view_literals
   {
     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
+    basic_string_view<char> operator""sv(const char *__str, size_t __len) _NOEXCEPT
     {
         return basic_string_view<char> (__str, __len);
     }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
+    basic_string_view<wchar_t> operator""sv(const wchar_t *__str, size_t __len) _NOEXCEPT
     {
         return basic_string_view<wchar_t> (__str, __len);
     }
@@ -997,20 +1031,20 @@ inline namespace literals
 
 #ifndef _LIBCPP_HAS_NO_CHAR8_T
     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
+    basic_string_view<char8_t> operator""sv(const char8_t *__str, size_t __len) _NOEXCEPT
     {
         return basic_string_view<char8_t> (__str, __len);
     }
 #endif
 
     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
+    basic_string_view<char16_t> operator""sv(const char16_t *__str, size_t __len) _NOEXCEPT
     {
         return basic_string_view<char16_t> (__str, __len);
     }
 
     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
+    basic_string_view<char32_t> operator""sv(const char32_t *__str, size_t __len) _NOEXCEPT
     {
         return basic_string_view<char32_t> (__str, __len);
     }
@@ -1024,8 +1058,9 @@ _LIBCPP_POP_MACROS
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <algorithm>
 #  include <concepts>
-#  include <functional>
+#  include <cstdlib>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_STRING_VIEW
lib/libcxx/include/strstream
@@ -141,12 +141,12 @@ private:
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS strstreambuf
+class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstreambuf
     : public streambuf
 {
 public:
 #ifndef _LIBCPP_CXX03_LANG
-    strstreambuf() : strstreambuf(0) {}
+    _LIBCPP_HIDE_FROM_ABI strstreambuf() : strstreambuf(0) {}
     explicit strstreambuf(streamsize __alsize);
 #else
     explicit strstreambuf(streamsize __alsize = 0);
@@ -237,7 +237,7 @@ strstreambuf::operator=(strstreambuf&& __rhs)
 
 #endif // _LIBCPP_CXX03_LANG
 
-class _LIBCPP_TYPE_VIS istrstream
+class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI istrstream
     : public istream
 {
 public:
@@ -256,8 +256,8 @@ public:
 
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    istrstream(istrstream&& __rhs)
-        : istream(_VSTD::move(__rhs)),
+    istrstream(istrstream&& __rhs)  // extension
+        : istream(_VSTD::move(static_cast<istream&>(__rhs))),
           __sb_(_VSTD::move(__rhs.__sb_))
     {
         istream::set_rdbuf(&__sb_);
@@ -290,7 +290,7 @@ private:
     strstreambuf __sb_;
 };
 
-class _LIBCPP_TYPE_VIS ostrstream
+class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI ostrstream
     : public ostream
 {
 public:
@@ -305,8 +305,8 @@ public:
 
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    ostrstream(ostrstream&& __rhs)
-        : ostream(_VSTD::move(__rhs)),
+    ostrstream(ostrstream&& __rhs)  // extension
+        : ostream(_VSTD::move(static_cast<ostream&>(__rhs))),
           __sb_(_VSTD::move(__rhs.__sb_))
     {
         ostream::set_rdbuf(&__sb_);
@@ -343,7 +343,7 @@ private:
     strstreambuf __sb_; // exposition only
 };
 
-class _LIBCPP_TYPE_VIS strstream
+class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstream
     : public iostream
 {
 public:
@@ -365,8 +365,8 @@ public:
 
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    strstream(strstream&& __rhs)
-        : iostream(_VSTD::move(__rhs)),
+    strstream(strstream&& __rhs)  // extension
+        : iostream(_VSTD::move(static_cast<iostream&>(__rhs))),
           __sb_(_VSTD::move(__rhs.__sb_))
     {
         iostream::set_rdbuf(&__sb_);
lib/libcxx/include/system_error
@@ -146,13 +146,11 @@ template <> struct hash<std::error_condition>;
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__errc>
-#include <__functional/hash.h>
-#include <__functional/unary_function.h>
-#include <__memory/addressof.h>
-#include <stdexcept>
-#include <string>
-#include <type_traits>
+#include <__system_error/errc.h>
+#include <__system_error/error_category.h>
+#include <__system_error/error_code.h>
+#include <__system_error/error_condition.h>
+#include <__system_error/system_error.h>
 #include <version>
 
 // standard-mandated includes
@@ -164,385 +162,11 @@ template <> struct hash<std::error_condition>;
 #  pragma GCC system_header
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// is_error_code_enum
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_error_code_enum
-    : public false_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value;
-#endif
-
-// is_error_condition_enum
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum
-    : public false_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
-#endif
-
-template <>
-struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc>
-    : true_type { };
-
-#ifdef _LIBCPP_CXX03_LANG
-template <>
-struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx>
-    : true_type { };
-#endif
-
-class _LIBCPP_TYPE_VIS error_condition;
-class _LIBCPP_TYPE_VIS error_code;
-
-// class error_category
-
-class _LIBCPP_HIDDEN __do_message;
-
-class _LIBCPP_TYPE_VIS error_category
-{
-public:
-    virtual ~error_category() _NOEXCEPT;
-
-#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS)
-    error_category() noexcept;
-#else
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default;
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdint>
+#  include <cstring>
+#  include <limits>
+#  include <type_traits>
 #endif
-    error_category(const error_category&) = delete;
-    error_category& operator=(const error_category&) = delete;
-
-    virtual const char* name() const _NOEXCEPT = 0;
-    virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
-    virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
-    virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
-    virtual string message(int __ev) const = 0;
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}
-
-#if _LIBCPP_STD_VER > 17
-
-    _LIBCPP_HIDE_FROM_ABI
-    strong_ordering operator<=>(const error_category& __rhs) const noexcept {return compare_three_way()(this, std::addressof(__rhs));}
-
-#else // _LIBCPP_STD_VER > 17
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}
-
-#endif // _LIBCPP_STD_VER > 17
-
-    friend class _LIBCPP_HIDDEN __do_message;
-};
-
-class _LIBCPP_HIDDEN __do_message
-    : public error_category
-{
-public:
-    string message(int __ev) const override;
-};
-
-_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
-_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
-
-namespace __adl_only {
-    // Those cause ADL to trigger but they are not viable candidates,
-    // so they are never actually selected.
-    void make_error_condition() = delete;
-    void make_error_code() = delete;
-} // namespace __adl_only
-
-class _LIBCPP_TYPE_VIS error_condition
-{
-    int __val_;
-    const error_category* __cat_;
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    error_condition(int __val, const error_category& __cat) _NOEXCEPT
-        : __val_(__val), __cat_(&__cat) {}
-
-    template <class _Ep>
-        _LIBCPP_INLINE_VISIBILITY
-        error_condition(_Ep __e,
-              typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr
-                                                                     ) _NOEXCEPT
-            {
-                using __adl_only::make_error_condition;
-                *this = make_error_condition(__e);
-            }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void assign(int __val, const error_category& __cat) _NOEXCEPT
-    {
-        __val_ = __val;
-        __cat_ = &__cat;
-    }
-
-    template <class _Ep>
-        _LIBCPP_INLINE_VISIBILITY
-        typename enable_if
-        <
-            is_error_condition_enum<_Ep>::value,
-            error_condition&
-        >::type
-        operator=(_Ep __e) _NOEXCEPT
-            {
-                using __adl_only::make_error_condition;
-                *this = make_error_condition(__e);
-                return *this;
-            }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void clear() _NOEXCEPT
-    {
-        __val_ = 0;
-        __cat_ = &generic_category();
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    int value() const _NOEXCEPT {return __val_;}
-
-    _LIBCPP_INLINE_VISIBILITY
-    const error_category& category() const _NOEXCEPT {return *__cat_;}
-    string message() const;
-
-    _LIBCPP_INLINE_VISIBILITY
-    explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
-};
-
-inline _LIBCPP_INLINE_VISIBILITY
-error_condition
-make_error_condition(errc __e) _NOEXCEPT
-{
-    return error_condition(static_cast<int>(__e), generic_category());
-}
-
-// error_code
-
-class _LIBCPP_TYPE_VIS error_code
-{
-    int __val_;
-    const error_category* __cat_;
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    error_code(int __val, const error_category& __cat) _NOEXCEPT
-        : __val_(__val), __cat_(&__cat) {}
-
-    template <class _Ep>
-        _LIBCPP_INLINE_VISIBILITY
-        error_code(_Ep __e,
-                   typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr
-                                                                     ) _NOEXCEPT
-            {
-                using __adl_only::make_error_code;
-                *this = make_error_code(__e);
-            }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void assign(int __val, const error_category& __cat) _NOEXCEPT
-    {
-        __val_ = __val;
-        __cat_ = &__cat;
-    }
-
-    template <class _Ep>
-        _LIBCPP_INLINE_VISIBILITY
-        typename enable_if
-        <
-            is_error_code_enum<_Ep>::value,
-            error_code&
-        >::type
-        operator=(_Ep __e) _NOEXCEPT
-            {
-                using __adl_only::make_error_code;
-                *this = make_error_code(__e);
-                return *this;
-            }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void clear() _NOEXCEPT
-    {
-        __val_ = 0;
-        __cat_ = &system_category();
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    int value() const _NOEXCEPT {return __val_;}
-
-    _LIBCPP_INLINE_VISIBILITY
-    const error_category& category() const _NOEXCEPT {return *__cat_;}
-
-    _LIBCPP_INLINE_VISIBILITY
-    error_condition default_error_condition() const _NOEXCEPT
-        {return __cat_->default_error_condition(__val_);}
-
-    string message() const;
-
-    _LIBCPP_INLINE_VISIBILITY
-    explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
-};
-
-inline _LIBCPP_INLINE_VISIBILITY
-error_code
-make_error_code(errc __e) _NOEXCEPT
-{
-    return error_code(static_cast<int>(__e), generic_category());
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
-{
-    return __x.category() == __y.category() && __x.value() == __y.value();
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
-{
-    return __x.category().equivalent(__x.value(), __y)
-        || __y.category().equivalent(__x, __y.value());
-}
-
-#if _LIBCPP_STD_VER <= 17
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
-{
-    return __y == __x;
-}
-#endif
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
-{
-    return __x.category() == __y.category() && __x.value() == __y.value();
-}
-
-#if _LIBCPP_STD_VER <= 17
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
-{return !(__x == __y);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT
-{return !(__x == __y);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT
-{return !(__x == __y);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
-{return !(__x == __y);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
-{
-    return __x.category() < __y.category()
-        || (__x.category() == __y.category() && __x.value() < __y.value());
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
-{
-    return __x.category() < __y.category()
-        || (__x.category() == __y.category() && __x.value() < __y.value());
-}
-
-#else // _LIBCPP_STD_VER <= 17
-
-inline _LIBCPP_HIDE_FROM_ABI strong_ordering
-operator<=>(const error_code& __x, const error_code& __y) noexcept
-{
-    if (auto __c = __x.category() <=> __y.category(); __c != 0)
-        return __c;
-    return __x.value() <=> __y.value();
-}
-
-inline _LIBCPP_HIDE_FROM_ABI strong_ordering
-operator<=>(const error_condition& __x, const error_condition& __y) noexcept
-{
-    if (auto __c = __x.category() <=> __y.category(); __c != 0)
-       return __c;
-    return __x.value() <=> __y.value();
-}
-
-#endif // _LIBCPP_STD_VER <= 17
-
-template <>
-struct _LIBCPP_TEMPLATE_VIS hash<error_code>
-    : public __unary_function<error_code, size_t>
-{
-    _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(const error_code& __ec) const _NOEXCEPT
-    {
-        return static_cast<size_t>(__ec.value());
-    }
-};
-
-template <>
-struct _LIBCPP_TEMPLATE_VIS hash<error_condition>
-    : public __unary_function<error_condition, size_t>
-{
-    _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(const error_condition& __ec) const _NOEXCEPT
-    {
-        return static_cast<size_t>(__ec.value());
-    }
-};
-
-// system_error
-
-class _LIBCPP_TYPE_VIS system_error
-    : public runtime_error
-{
-    error_code __ec_;
-public:
-    system_error(error_code __ec, const string& __what_arg);
-    system_error(error_code __ec, const char* __what_arg);
-    system_error(error_code __ec);
-    system_error(int __ev, const error_category& __ecat, const string& __what_arg);
-    system_error(int __ev, const error_category& __ecat, const char* __what_arg);
-    system_error(int __ev, const error_category& __ecat);
-    system_error(const system_error&) _NOEXCEPT = default;
-    ~system_error() _NOEXCEPT override;
-
-    _LIBCPP_INLINE_VISIBILITY
-    const error_code& code() const _NOEXCEPT {return __ec_;}
-
-private:
-    static string __init(const error_code&, string);
-};
-
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
-void __throw_system_error(int __ev, const char* __what_arg);
-
-_LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_SYSTEM_ERROR
lib/libcxx/include/thread
@@ -64,6 +64,9 @@ template<class charT, class traits>
 basic_ostream<charT, traits>&
 operator<<(basic_ostream<charT, traits>& out, thread::id id);
 
+template<class charT>
+struct formatter<thread::id, charT>;
+
 namespace this_thread
 {
 
@@ -84,19 +87,12 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
-#include <__functional/hash.h>
-#include <__memory/unique_ptr.h>
-#include <__mutex_base>
-#include <__thread/poll_with_backoff.h>
-#include <__thread/timed_backoff_policy.h>
+#include <__thread/formatter.h>
+#include <__thread/this_thread.h>
+#include <__thread/thread.h>
 #include <__threading_support>
-#include <__utility/forward.h>
-#include <cstddef>
-#include <iosfwd>
-#include <system_error>
-#include <tuple>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -108,314 +104,27 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
 #  pragma GCC system_header
 #endif
 
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
 #ifdef _LIBCPP_HAS_NO_THREADS
 # error "<thread> is not supported since libc++ has been configured without support for threads."
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp> class __thread_specific_ptr;
-class _LIBCPP_TYPE_VIS __thread_struct;
-class _LIBCPP_HIDDEN __thread_struct_imp;
-class __assoc_sub_state;
-
-_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
-
-class _LIBCPP_TYPE_VIS __thread_struct
-{
-    __thread_struct_imp* __p_;
-
-    __thread_struct(const __thread_struct&);
-    __thread_struct& operator=(const __thread_struct&);
-public:
-    __thread_struct();
-    ~__thread_struct();
-
-    void notify_all_at_thread_exit(condition_variable*, mutex*);
-    void __make_ready_at_thread_exit(__assoc_sub_state*);
-};
-
-template <class _Tp>
-class __thread_specific_ptr
-{
-    __libcpp_tls_key __key_;
-
-     // Only __thread_local_data() may construct a __thread_specific_ptr
-     // and only with _Tp == __thread_struct.
-    static_assert((is_same<_Tp, __thread_struct>::value), "");
-    __thread_specific_ptr();
-    friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
-
-    __thread_specific_ptr(const __thread_specific_ptr&);
-    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
-
-    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
-
-public:
-    typedef _Tp* pointer;
-
-    ~__thread_specific_ptr();
-
-    _LIBCPP_INLINE_VISIBILITY
-    pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
-    _LIBCPP_INLINE_VISIBILITY
-    pointer operator*() const {return *get();}
-    _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return get();}
-    void set_pointer(pointer __p);
-};
-
-template <class _Tp>
-void _LIBCPP_TLS_DESTRUCTOR_CC
-__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
-{
-    delete static_cast<pointer>(__p);
-}
-
-template <class _Tp>
-__thread_specific_ptr<_Tp>::__thread_specific_ptr()
-{
-  int __ec =
-      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
-  if (__ec)
-    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
-}
-
-template <class _Tp>
-__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
-{
-    // __thread_specific_ptr is only created with a static storage duration
-    // so this destructor is only invoked during program termination. Invoking
-    // pthread_key_delete(__key_) may prevent other threads from deleting their
-    // thread local data. For this reason we leak the key.
-}
-
-template <class _Tp>
-void
-__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
-{
-    _LIBCPP_ASSERT(get() == nullptr,
-                   "Attempting to overwrite thread local data");
-    std::__libcpp_tls_set(__key_, __p);
-}
-
-template<>
-struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
-    : public __unary_function<__thread_id, size_t>
-{
-    _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(__thread_id __v) const _NOEXCEPT
-    {
-        return hash<__libcpp_thread_id>()(__v.__id_);
-    }
-};
-
-template<class _CharT, class _Traits>
-_LIBCPP_INLINE_VISIBILITY
-basic_ostream<_CharT, _Traits>&
-operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
-{return __os << __id.__id_;}
-
-class _LIBCPP_TYPE_VIS thread
-{
-    __libcpp_thread_t __t_;
-
-    thread(const thread&);
-    thread& operator=(const thread&);
-public:
-    typedef __thread_id id;
-    typedef __libcpp_thread_t native_handle_type;
-
-    _LIBCPP_INLINE_VISIBILITY
-    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
-#ifndef _LIBCPP_CXX03_LANG
-    template <class _Fp, class ..._Args,
-              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-        explicit thread(_Fp&& __f, _Args&&... __args);
-#else  // _LIBCPP_CXX03_LANG
-    template <class _Fp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-    explicit thread(_Fp __f);
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
+#  include <cstddef>
+#  include <ctime>
+#  include <iosfwd>
+#  include <ratio>
 #endif
-    ~thread();
-
-    _LIBCPP_INLINE_VISIBILITY
-    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
-        __t.__t_ = _LIBCPP_NULL_THREAD;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    thread& operator=(thread&& __t) _NOEXCEPT {
-        if (!__libcpp_thread_isnull(&__t_))
-            terminate();
-        __t_ = __t.__t_;
-        __t.__t_ = _LIBCPP_NULL_THREAD;
-        return *this;
-    }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
-    void join();
-    void detach();
-    _LIBCPP_INLINE_VISIBILITY
-    id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
-    _LIBCPP_INLINE_VISIBILITY
-    native_handle_type native_handle() _NOEXCEPT {return __t_;}
-
-    static unsigned hardware_concurrency() _NOEXCEPT;
-};
-
-#ifndef _LIBCPP_CXX03_LANG
-
-template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
-{
-    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
-}
-
-template <class _Fp>
-_LIBCPP_INLINE_VISIBILITY
-void* __thread_proxy(void* __vp)
-{
-    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
-    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
-    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
-    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
-    _VSTD::__thread_execute(*__p.get(), _Index());
-    return nullptr;
-}
-
-template <class _Fp, class ..._Args,
-          class
-         >
-thread::thread(_Fp&& __f, _Args&&... __args)
-{
-    typedef unique_ptr<__thread_struct> _TSPtr;
-    _TSPtr __tsp(new __thread_struct);
-    typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
-    unique_ptr<_Gp> __p(
-            new _Gp(_VSTD::move(__tsp),
-                    _VSTD::forward<_Fp>(__f),
-                    _VSTD::forward<_Args>(__args)...));
-    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
-    if (__ec == 0)
-        __p.release();
-    else
-        __throw_system_error(__ec, "thread constructor failed");
-}
-
-#else  // _LIBCPP_CXX03_LANG
-
-template <class _Fp>
-struct __thread_invoke_pair {
-    // This type is used to pass memory for thread local storage and a functor
-    // to a newly created thread because std::pair doesn't work with
-    // std::unique_ptr in C++03.
-    __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
-    unique_ptr<__thread_struct> __tsp_;
-    _Fp __fn_;
-};
-
-template <class _Fp>
-_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
-{
-    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
-    __thread_local_data().set_pointer(__p->__tsp_.release());
-    (__p->__fn_)();
-    return nullptr;
-}
-
-template <class _Fp>
-thread::thread(_Fp __f)
-{
-
-    typedef __thread_invoke_pair<_Fp> _InvokePair;
-    typedef unique_ptr<_InvokePair> _PairPtr;
-    _PairPtr __pp(new _InvokePair(__f));
-    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
-    if (__ec == 0)
-        __pp.release();
-    else
-        __throw_system_error(__ec, "thread constructor failed");
-}
-
-#endif // _LIBCPP_CXX03_LANG
-
-inline _LIBCPP_INLINE_VISIBILITY
-void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
-
-namespace this_thread
-{
-
-_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);
-
-template <class _Rep, class _Period>
-_LIBCPP_HIDE_FROM_ABI void
-sleep_for(const chrono::duration<_Rep, _Period>& __d)
-{
-    if (__d > chrono::duration<_Rep, _Period>::zero())
-    {
-        // The standard guarantees a 64bit signed integer resolution for nanoseconds,
-        // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
-        // and issues with long double folding on PowerPC with GCC.
-        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
-            chrono::duration<long double>(9223372036.0L);
-        chrono::nanoseconds __ns;
-        if (__d < _Max)
-        {
-            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
-            if (__ns < __d)
-                ++__ns;
-        }
-        else
-            __ns = chrono::nanoseconds::max();
-        this_thread::sleep_for(__ns);
-    }
-}
-
-template <class _Clock, class _Duration>
-_LIBCPP_HIDE_FROM_ABI void
-sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
-{
-    mutex __mut;
-    condition_variable __cv;
-    unique_lock<mutex> __lk(__mut);
-    while (_Clock::now() < __t)
-        __cv.wait_until(__lk, __t);
-}
-
-template <class _Duration>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
-{
-    this_thread::sleep_for(__t - chrono::steady_clock::now());
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void yield() _NOEXCEPT {__libcpp_thread_yield();}
-
-} // namespace this_thread
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
 #  include <chrono>
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstring>
 #  include <functional>
+#  include <new>
+#  include <system_error>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_THREAD
lib/libcxx/include/tuple
@@ -206,10 +206,18 @@ template <class... Types>
 #include <__compare/synth_three_way.h>
 #include <__config>
 #include <__functional/invoke.h>
-#include <__functional/unwrap_ref.h>
 #include <__fwd/array.h>
+#include <__fwd/get.h>
+#include <__fwd/tuple.h>
 #include <__memory/allocator_arg_t.h>
 #include <__memory/uses_allocator.h>
+#include <__tuple/make_tuple_types.h>
+#include <__tuple/sfinae_helpers.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_indices.h>
+#include <__tuple/tuple_like_ext.h>
+#include <__tuple/tuple_size.h>
+#include <__tuple/tuple_types.h>
 #include <__type_traits/apply_cv.h>
 #include <__type_traits/common_reference.h>
 #include <__type_traits/common_type.h>
@@ -244,6 +252,7 @@ template <class... Types>
 #include <__type_traits/negation.h>
 #include <__type_traits/remove_cvref.h>
 #include <__type_traits/remove_reference.h>
+#include <__type_traits/unwrap_ref.h>
 #include <__utility/forward.h>
 #include <__utility/integer_sequence.h>
 #include <__utility/move.h>
@@ -262,6 +271,9 @@ template <class... Types>
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -295,7 +307,7 @@ class __tuple_leaf
     _Hp __value_;
 
     template <class _Tp>
-    static constexpr bool __can_bind_reference() {
+    static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
 #if __has_keyword(__reference_binds_to_temporary)
       return !__reference_binds_to_temporary(_Hp, _Tp);
 #else
@@ -367,8 +379,8 @@ public:
         {static_assert(!is_reference<_Hp>::value,
            "Attempted to uses-allocator construct a reference element in a tuple");}
 
-    __tuple_leaf(const __tuple_leaf& __t) = default;
-    __tuple_leaf(__tuple_leaf&& __t) = default;
+    _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default;
+    _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default;
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
     int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
@@ -865,7 +877,7 @@ public:
         : __base_(allocator_arg_t(), __a, __t)
     { }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
 
     template <class... _Up, enable_if_t<
@@ -879,7 +891,7 @@ public:
     _LIBCPP_HIDE_FROM_ABI constexpr
         explicit(!(is_convertible_v<_Up&, _Tp> && ...))
     tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
 
@@ -929,7 +941,7 @@ public:
         : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
     { }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
 
     template <class... _Up, enable_if_t<
@@ -944,17 +956,17 @@ public:
         explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
     tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
         : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
 
-    template <template <class...> class Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
+    template <template <class...> class _Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
     struct _CtorPredicateFromPair : false_type{};
 
-    template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
-    struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
-        Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
-        Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
+    template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
+    struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
+        _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
+        _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
     > {};
 
     template <class _Pair>
@@ -1018,7 +1030,7 @@ public:
         : __base_(allocator_arg_t(), __a, __p)
     { }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
 
     template <class _U1, class _U2, enable_if_t<
@@ -1082,7 +1094,7 @@ public:
         : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
     { }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
 
     template <class _U1, class _U2, enable_if_t<
@@ -1097,7 +1109,7 @@ public:
         explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
     tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
         : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     // [tuple.assign]
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1109,7 +1121,7 @@ public:
         return *this;
     }
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr
     const tuple& operator=(tuple const& __tuple) const
       requires (_And<is_copy_assignable<const _Tp>...>::value) {
@@ -1126,7 +1138,7 @@ public:
                                          typename __make_tuple_indices<sizeof...(_Tp)>::type());
         return *this;
     }
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
@@ -1170,7 +1182,7 @@ public:
     }
 
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class... _UTypes, enable_if_t<
         _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
              is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
@@ -1193,17 +1205,17 @@ public:
                                          typename __make_tuple_indices<sizeof...(_Tp)>::type());
         return *this;
     }
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
-    template <template<class...> class Pred, bool _Const,
+    template <template<class...> class _Pred, bool _Const,
               class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
     struct _AssignPredicateFromPair : false_type {};
 
-    template <template<class...> class Pred, bool _Const,
+    template <template<class...> class _Pred, bool _Const,
               class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
-    struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
-        _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
-             Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
+    struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
+        _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
+             _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
             > {};
 
     template <bool _Const, class _Pair>
@@ -1212,7 +1224,7 @@ public:
     template <bool _Const, class _Pair>
     struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     template <class _U1, class _U2, enable_if_t<
         _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
     _LIBCPP_HIDE_FROM_ABI constexpr
@@ -1232,7 +1244,7 @@ public:
         std::get<1>(*this) = std::move(__pair.second);
         return *this;
     }
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
     template<class _Up1, class _Up2, __enable_if_t<
         _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
@@ -1296,20 +1308,19 @@ public:
     void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
         {__base_.swap(__t.__base_);}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr
     void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
         __base_.swap(__t.__base_);
     }
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 };
 
 template <>
 class _LIBCPP_TEMPLATE_VIS tuple<>
 {
 public:
-    _LIBCPP_INLINE_VISIBILITY constexpr
-        tuple() _NOEXCEPT = default;
+    constexpr tuple() _NOEXCEPT = default;
     template <class _Alloc>
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
         tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
@@ -1324,12 +1335,12 @@ public:
         tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     void swap(tuple&) _NOEXCEPT {}
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
     _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
 #endif
 };
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
     requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
 struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
@@ -1341,9 +1352,9 @@ template <class... _TTypes, class... _UTypes>
 struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
     using type = tuple<common_type_t<_TTypes, _UTypes>...>;
 };
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class ..._Tp>
 tuple(_Tp...) -> tuple<_Tp...>;
 template <class _Tp1, class _Tp2>
@@ -1363,7 +1374,7 @@ swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
                  _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
     {__t.swap(__u);}
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 template <class... _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr
 enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
@@ -1413,7 +1424,7 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
              static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 
 namespace __find_detail {
 
@@ -1501,9 +1512,13 @@ struct __ignore_t
     const __ignore_t& operator=(_Tp&&) const {return *this;}
 };
 
+#  if _LIBCPP_STD_VER >= 17
+inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
+#  else
 namespace {
   constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
 } // namespace
+#  endif
 
 template <class... _Tp>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
@@ -1552,7 +1567,7 @@ operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
     return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 
 // operator<=>
 
@@ -1574,7 +1589,7 @@ operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
     return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
 }
 
-#else // _LIBCPP_STD_VER > 17
+#else // _LIBCPP_STD_VER >= 20
 
 template <class ..._Tp, class ..._Up>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
@@ -1644,7 +1659,7 @@ operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
     return !(__y < __x);
 }
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
 // tuple_cat
 
@@ -1712,17 +1727,15 @@ template <class ..._Types, size_t ..._I0, class _Tuple0>
 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
 {
     typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
-    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
-                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
+    typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type;
 };
 
 template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
                                   _Tuple0, _Tuple1, _Tuples...>
     : public __tuple_cat_return_ref_imp<
-         tuple<_Types..., typename __apply_cv<_Tuple0,
-               typename tuple_element<_I0,
-                  __libcpp_remove_reference_t<_Tuple0> >::type>::type&&...>,
+         tuple<_Types..., __apply_cv_t<_Tuple0,
+                                       typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>,
          typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
          _Tuple1, _Tuples...>
 {
@@ -1762,13 +1775,9 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
         (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
         typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
         typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1;
-        return __tuple_cat<
-            tuple<_Types...,
-                  typename __apply_cv<_Tuple0, typename tuple_element<
-                                                   _J0, _T0>::type>::type&&...>,
-            typename __make_tuple_indices<sizeof...(_Types) +
-                                          tuple_size<_T0>::value>::type,
-            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
+        return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>,
+                           typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type,
+                           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
             _VSTD::forward_as_tuple(
                 _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
                 _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
@@ -1803,7 +1812,7 @@ pair<_T1, _T2>::pair(piecewise_construct_t,
 {
 }
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template <class _Tp>
 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
 
@@ -1845,12 +1854,14 @@ _LIBCPP_NOEXCEPT_RETURN(
 
 #undef _LIBCPP_NOEXCEPT_RETURN
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 #endif // !defined(_LIBCPP_CXX03_LANG)
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <exception>
 #  include <iosfwd>
lib/libcxx/include/type_traits
@@ -51,7 +51,7 @@ namespace std
     template <class T> struct is_arithmetic;
     template <class T> struct is_fundamental;
     template <class T> struct is_member_pointer;
-    template <class T> struct is_scoped_enum; // C++2b
+    template <class T> struct is_scoped_enum; // C++23
     template <class T> struct is_scalar;
     template <class T> struct is_object;
     template <class T> struct is_compound;
@@ -286,7 +286,7 @@ namespace std
       template <class T> inline constexpr bool is_member_pointer_v
         = is_member_pointer<T>::value;                                   // C++17
       template <class T> inline constexpr bool is_scoped_enum_v
-        = is_scoped_enum<T>::value;                                      // C++2b
+        = is_scoped_enum<T>::value;                                      // C++23
 
       // See C++14 20.10.4.3, type properties
       template <class T> inline constexpr bool is_const_v
@@ -418,7 +418,6 @@ namespace std
 */
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__functional/invoke.h>
 #include <__fwd/hash.h> // This is https://llvm.org/PR56938
 #include <__type_traits/add_const.h>
 #include <__type_traits/add_cv.h>
@@ -443,6 +442,7 @@ namespace std
 #include <__type_traits/has_unique_object_representation.h>
 #include <__type_traits/has_virtual_destructor.h>
 #include <__type_traits/integral_constant.h>
+#include <__type_traits/invoke.h>
 #include <__type_traits/is_abstract.h>
 #include <__type_traits/is_aggregate.h>
 #include <__type_traits/is_arithmetic.h>
@@ -532,6 +532,7 @@ namespace std
 #include <__type_traits/result_of.h>
 #include <__type_traits/type_identity.h>
 #include <__type_traits/underlying_type.h>
+#include <__type_traits/unwrap_ref.h>
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
 #include <cstddef>
lib/libcxx/include/typeindex
@@ -87,7 +87,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     bool operator>=(const type_index& __y) const _NOEXCEPT
         {return !__t_->before(*__y.__t_);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_HIDE_FROM_ABI
     strong_ordering operator<=>(const type_index& __y) const noexcept {
       if (*__t_ == *__y.__t_)
lib/libcxx/include/typeinfo
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef __LIBCPP_TYPEINFO
-#define __LIBCPP_TYPEINFO
+#ifndef _LIBCPP_TYPEINFO
+#define _LIBCPP_TYPEINFO
 
 /*
 
@@ -21,7 +21,7 @@ class type_info
 public:
     virtual ~type_info();
 
-    bool operator==(const type_info& rhs) const noexcept;
+    bool operator==(const type_info& rhs) const noexcept; // constexpr since C++23
     bool operator!=(const type_info& rhs) const noexcept; // removed in C++20
 
     bool before(const type_info& rhs) const noexcept;
@@ -59,11 +59,11 @@ public:
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
+#include <__exception/exception.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__verbose_abort>
 #include <cstddef>
 #include <cstdint>
-#include <cstdlib>
-#include <exception>
-#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -79,7 +79,7 @@ namespace std  // purposefully not using versioning namespace
 
 #if defined(_LIBCPP_ABI_MICROSOFT)
 
-class _LIBCPP_EXCEPTION_ABI type_info
+class _LIBCPP_EXPORTED_FROM_ABI type_info
 {
     type_info& operator=(const type_info&);
     type_info(const type_info&);
@@ -104,8 +104,13 @@ public:
 
     size_t hash_code() const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
     bool operator==(const type_info& __arg) const _NOEXCEPT {
+      // When evaluated in a constant expression, both type infos simply can't come
+      // from different translation units, so it is sufficient to compare their addresses.
+      if (__libcpp_is_constant_evaluated()) {
+        return this == &__arg;
+      }
       return __compare(__arg) == 0;
     }
 
@@ -294,7 +299,7 @@ struct __type_info_implementations {
      __impl;
 };
 
-class _LIBCPP_EXCEPTION_ABI type_info
+class _LIBCPP_EXPORTED_FROM_ABI type_info
 {
   type_info& operator=(const type_info&);
   type_info(const type_info&);
@@ -330,9 +335,14 @@ public:
       return __impl::__hash(__type_name);
     }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
     bool operator==(const type_info& __arg) const _NOEXCEPT
     {
+      // When evaluated in a constant expression, both type infos simply can't come
+      // from different translation units, so it is sufficient to compare their addresses.
+      if (__libcpp_is_constant_evaluated()) {
+        return this == &__arg;
+      }
       return __impl::__eq(__type_name, __arg.__type_name);
     }
 
@@ -344,17 +354,17 @@ public:
 };
 #endif // defined(_LIBCPP_ABI_MICROSOFT)
 
-class _LIBCPP_EXCEPTION_ABI bad_cast
+class _LIBCPP_EXPORTED_FROM_ABI bad_cast
     : public exception
 {
  public:
   bad_cast() _NOEXCEPT;
-  bad_cast(const bad_cast&) _NOEXCEPT = default;
+  _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default;
   ~bad_cast() _NOEXCEPT override;
   const char* what() const _NOEXCEPT override;
 };
 
-class _LIBCPP_EXCEPTION_ABI bad_typeid
+class _LIBCPP_EXPORTED_FROM_ABI bad_typeid
     : public exception
 {
  public:
@@ -395,12 +405,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
 void __throw_bad_cast()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw bad_cast();
 #else
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode");
 #endif
 }
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // __LIBCPP_TYPEINFO
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
+#  include <exception>
+#  include <type_traits>
+#endif
+
+#endif // _LIBCPP_TYPEINFO
lib/libcxx/include/uchar.h
@@ -42,10 +42,12 @@ size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
 
 // Some platforms don't implement <uchar.h> and we don't want to give a hard
 // error on those platforms. When the platform doesn't provide <uchar.h>, at
-// least include <stddef.h> so we get the declaration for size_t.
+// least include <stddef.h> so we get the declaration for size_t, and try to
+// get the declaration of mbstate_t too.
 #if __has_include_next(<uchar.h>)
 # include_next <uchar.h>
 #else
+# include <__mbstate_t.h>
 # include <stddef.h>
 #endif
 
lib/libcxx/include/unordered_map
@@ -59,6 +59,11 @@ public:
                       size_type n = 0, const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
+    template<container-compatible-range<value_type> R>
+      unordered_map(from_range_t, R&& rg, size_type n = see below,
+        const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+        const allocator_type& a = allocator_type()); // C++23
+
     explicit unordered_map(const allocator_type&);
     unordered_map(const unordered_map&);
     unordered_map(const unordered_map&, const Allocator&);
@@ -82,6 +87,12 @@ public:
       unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
         const allocator_type& a)
       : unordered_map(f, l, n, hf, key_equal(), a) {}  // C++14
+    template<container-compatible-range<value_type> R>
+      unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a)
+        : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
+    template<container-compatible-range<value_type> R>
+      unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
+        : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }       // C++23
     unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
       : unordered_map(il, n, hasher(), key_equal(), a) {}  // C++14
     unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
@@ -122,6 +133,8 @@ public:
         iterator insert(const_iterator hint, P&& obj);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                                      // C++23
     void insert(initializer_list<value_type>);
 
     node_type extract(const_iterator position);                                       // C++17
@@ -224,6 +237,13 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type = see
   -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
     Allocator>; // C++17
 
+template<ranges::input_range R, class Hash = hash<range-key-type<R>>,
+         class Pred = equal_to<range-key-type<R>>,
+         class Allocator = allocator<range-to-alloc-type<R>>>
+  unordered_map(from_range_t, R&&, typename see below::size_type = see below,
+                Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+    -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23
+
 template<class Key, class T, class Hash = hash<Key>,
     class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
 unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type = see below,
@@ -245,6 +265,21 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash,
   -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
           equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  unordered_map(from_range_t, R&&, typename see below::size_type, Allocator)
+    -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
+template<ranges::input_range R, class Allocator>
+  unordered_map(from_range_t, R&&, Allocator)
+    -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
+template<ranges::input_range R, class Hash, class Allocator>
+  unordered_map(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
+    -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
 template<class Key, class T, typename Allocator>
 unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator)
   -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17
@@ -270,7 +305,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 template <class Key, class T, class Hash, class Pred, class Alloc>
     bool
     operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
-               const unordered_map<Key, T, Hash, Pred, Alloc>& y);
+               const unordered_map<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20
 
 template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
           class Alloc = allocator<pair<const Key, T>>>
@@ -311,6 +346,10 @@ public:
                       size_type n = 0, const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
+    template<container-compatible-range<value_type> R>
+      unordered_multimap(from_range_t, R&& rg, size_type n = see below,
+        const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+        const allocator_type& a = allocator_type()); // C++23
     explicit unordered_multimap(const allocator_type&);
     unordered_multimap(const unordered_multimap&);
     unordered_multimap(const unordered_multimap&, const Allocator&);
@@ -334,6 +373,12 @@ public:
       unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
         const allocator_type& a)
       : unordered_multimap(f, l, n, hf, key_equal(), a) {}  // C++14
+    template<container-compatible-range<value_type> R>
+      unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a)
+        : unordered_multimap(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
+    template<container-compatible-range<value_type> R>
+      unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
+        : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }       // C++23
     unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
       : unordered_multimap(il, n, hasher(), key_equal(), a) {}  // C++14
     unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
@@ -374,6 +419,8 @@ public:
         iterator insert(const_iterator hint, P&& obj);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                               // C++23
     void insert(initializer_list<value_type>);
 
     node_type extract(const_iterator position);                // C++17
@@ -453,6 +500,13 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type =
   -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
     Allocator>; // C++17
 
+template<ranges::input_range R, class Hash = hash<range-key-type<R>>,
+         class Pred = equal_to<range-key-type<R>>,
+         class Allocator = allocator<range-to-alloc-type<R>>>
+  unordered_multimap(from_range_t, R&&, typename see below::size_type = see below,
+                Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+    -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23
+
 template<class Key, class T, class Hash = hash<Key>,
     class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
 unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type = see below,
@@ -474,6 +528,21 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type,
   -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
           equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  unordered_multimap(from_range_t, R&&, typename see below::size_type, Allocator)
+    -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
+template<ranges::input_range R, class Allocator>
+  unordered_multimap(from_range_t, R&&, Allocator)
+    -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
+template<ranges::input_range R, class Hash, class Allocator>
+  unordered_multimap(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
+    -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash,
+                      equal_to<range-key-type<R>>, Allocator>;   // C++23
+
 template<class Key, class T, typename Allocator>
 unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator)
   -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17
@@ -508,7 +577,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 template <class Key, class T, class Hash, class Pred, class Alloc>
     bool
     operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
-               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
+               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20
 
 }  // std
 
@@ -516,19 +585,24 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 
 #include <__algorithm/is_permutation.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
-#include <__debug>
 #include <__functional/is_transparent.h>
 #include <__functional/operations.h>
 #include <__hash_table>
 #include <__iterator/distance.h>
 #include <__iterator/erase_if_container.h>
 #include <__iterator/iterator_traits.h>
+#include <__iterator/ranges_iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/allocator.h>
 #include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <stdexcept>
 #include <tuple>
@@ -575,7 +649,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Key& __x) const
         {return static_cast<const _Hash&>(*this)(__x);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _K2& __x) const
@@ -611,7 +685,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Key& __x) const
         {return __hash_(__x);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _K2& __x) const
@@ -661,7 +735,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _Cp& __y) const
         {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _K2& __y) const
@@ -712,7 +786,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _Cp& __y) const
         {return __pred_(__x, __y.__get_value().first);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _K2& __y) const
@@ -825,7 +899,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     value_type& __get_value()
     {
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         return *_VSTD::launder(_VSTD::addressof(__cc_));
 #else
         return __cc_;
@@ -835,7 +909,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const value_type& __get_value() const
     {
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         return *_VSTD::launder(_VSTD::addressof(__cc_));
 #else
         return __cc_;
@@ -953,9 +1027,11 @@ public:
     friend _LIBCPP_INLINE_VISIBILITY
         bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
         {return __x.__i_ == __y.__i_;}
+#if _LIBCPP_STD_VER <= 17
     friend _LIBCPP_INLINE_VISIBILITY
         bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
         {return __x.__i_ != __y.__i_;}
+#endif
 
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
@@ -1007,9 +1083,11 @@ public:
     friend _LIBCPP_INLINE_VISIBILITY
         bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
         {return __x.__i_ == __y.__i_;}
+#if _LIBCPP_STD_VER <= 17
     friend _LIBCPP_INLINE_VISIBILITY
         bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
         {return __x.__i_ != __y.__i_;}
+#endif
 
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
@@ -1035,7 +1113,7 @@ public:
     typedef value_type&                                    reference;
     typedef const value_type&                              const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
-                  "Invalid allocator::value_type");
+                  "Allocator::value_type must be same type as value_type");
 
 private:
     typedef __hash_value_type<key_type, mapped_type>                          __value_type;
@@ -1075,7 +1153,7 @@ public:
     typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
     typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __map_node_handle<__node, allocator_type> node_type;
     typedef __insert_return_type<iterator, node_type> insert_return_type;
 #endif
@@ -1089,41 +1167,55 @@ public:
     unordered_map()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
-    explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
-    unordered_map(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf,
                   const key_equal& __eql,
                   const allocator_type& __a);
     template <class _InputIterator>
-        unordered_map(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        unordered_map(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        unordered_map(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf,
                       const key_equal& __eql,
                       const allocator_type& __a);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_map(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
+                  const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
+                  const allocator_type& __a = allocator_type())
+        : __table_(__hf, __eql, typename __table::allocator_type(__a)) {
+      if (__n > 0) {
+        __table_.__rehash_unique(__n);
+      }
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     explicit unordered_map(const allocator_type& __a);
-    unordered_map(const unordered_map& __u);
-    unordered_map(const unordered_map& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u);
+    _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     unordered_map(unordered_map&& __u)
         _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
-    unordered_map(unordered_map&& __u, const allocator_type& __a);
-    unordered_map(initializer_list<value_type> __il);
-    unordered_map(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n,
                   const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
-    unordered_map(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n,
                   const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
 #endif // _LIBCPP_CXX03_LANG
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     unordered_map(size_type __n, const allocator_type& __a)
       : unordered_map(__n, hasher(), key_equal(), __a) {}
@@ -1139,6 +1231,19 @@ public:
       unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
         const allocator_type& __a)
       : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_map(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
+        : unordered_map(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
+
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_map(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_map(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
       : unordered_map(__il, __n, hasher(), key_equal(), __a) {}
@@ -1205,11 +1310,7 @@ public:
     pair<iterator, bool> insert(const value_type& __x)
         {return __table_.__insert_unique(__x);}
 
-    iterator insert(const_iterator __p, const value_type& __x) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                             "unordered_map::insert(const_iterator, const value_type&) called with an iterator not "
-                             "referring to this unordered_map");
-        ((void)__p);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) {
         return insert(__x).first;
     }
 
@@ -1217,6 +1318,16 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         void insert(_InputIterator __first, _InputIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      for (auto&& __element : __range) {
+        __table_.__insert_unique(std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     void insert(initializer_list<value_type> __il)
@@ -1226,11 +1337,7 @@ public:
     pair<iterator, bool> insert(value_type&& __x)
         {return __table_.__insert_unique(_VSTD::move(__x));}
 
-    iterator insert(const_iterator __p, value_type&& __x) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                             "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
-                             " referring to this unordered_map");
-        ((void)__p);
+    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, value_type&& __x) {
         return __table_.__insert_unique(_VSTD::move(__x)).first;
     }
 
@@ -1243,12 +1350,8 @@ public:
     template <class _Pp,
               class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
         _LIBCPP_INLINE_VISIBILITY
-        iterator insert(const_iterator __p, _Pp&& __x)
+        iterator insert(const_iterator, _Pp&& __x)
         {
-            _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                                 "unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
-                                 " referring to this unordered_map");
-          ((void)__p);
             return insert(_VSTD::forward<_Pp>(__x)).first;
         }
 
@@ -1260,17 +1363,13 @@ public:
 
     template <class... _Args>
     _LIBCPP_INLINE_VISIBILITY
-    iterator emplace_hint(const_iterator __p, _Args&&... __args) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                             "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
-                             " referring to this unordered_map");
-          ((void)__p);
+    iterator emplace_hint(const_iterator, _Args&&... __args) {
         return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
     }
 
 #endif // _LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
         pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
@@ -1291,23 +1390,15 @@ public:
 
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
-        iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
+        iterator try_emplace(const_iterator, const key_type& __k, _Args&&... __args)
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this,
-                             "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
-                             " referring to this unordered_map");
-        ((void)__h);
         return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first;
     }
 
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
-        iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
+        iterator try_emplace(const_iterator, key_type&& __k, _Args&&... __args)
     {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this,
-                             "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
-                             " referring to this unordered_map");
-        ((void)__h);
         return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first;
     }
 
@@ -1339,7 +1430,6 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v)
      {
-          // FIXME: Add debug mode checking for the iterator input
           return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first;
      }
 
@@ -1347,10 +1437,9 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v)
      {
-        // FIXME: Add debug mode checking for the iterator input
         return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first;
      }
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
     _LIBCPP_INLINE_VISIBILITY
     iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
@@ -1364,11 +1453,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
         void clear() _NOEXCEPT {__table_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     insert_return_type insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_map::insert()");
         return __table_.template __node_handle_insert_unique<
             node_type, insert_return_type>(_VSTD::move(__nh));
@@ -1376,7 +1465,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_map::insert()");
         return __table_.template __node_handle_insert_unique<node_type>(
             __hint.__i_, _VSTD::move(__nh));
@@ -1397,32 +1486,32 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_unique(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_unique(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_unique(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_unique(__source.__table_);
     }
 #endif
@@ -1443,31 +1532,31 @@ public:
     iterator       find(const key_type& __k)       {return __table_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __table_.find(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     iterator       find(const _K2& __k)            {return __table_.find(__k);}
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const _K2& __k) const      {return __table_.find(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const _K2& __k) const      {return __table_.__count_unique(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
 
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const _K2& __k) const      {return find(__k) != end();}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const key_type& __k)
@@ -1475,7 +1564,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
         {return __table_.__equal_range_unique(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const _K2& __k)
@@ -1484,15 +1573,15 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
         {return __table_.__equal_range_unique(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-    mapped_type& operator[](const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
 #ifndef _LIBCPP_CXX03_LANG
-    mapped_type& operator[](key_type&& __k);
+    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
 #endif
 
-    mapped_type&       at(const key_type& __k);
-    const mapped_type& at(const key_type& __k) const;
+    _LIBCPP_HIDE_FROM_ABI mapped_type&       at(const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
@@ -1529,23 +1618,10 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.__reserve_unique(__n);}
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const
-        {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
-    bool __decrementable(const const_iterator* __i) const
-        {return __table_.__decrementable(_VSTD::addressof(__i->__i_));}
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 private:
 
 #ifdef _LIBCPP_CXX03_LANG
-    __node_holder __construct_node_with_key(const key_type& __k);
+    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
 #endif
 };
 
@@ -1554,7 +1630,7 @@ template<class _InputIterator,
          class _Hash = hash<__iter_key_type<_InputIterator>>,
          class _Pred = equal_to<__iter_key_type<_InputIterator>>,
          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<!__is_allocator<_Pred>::value>,
@@ -1563,6 +1639,20 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
               _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
   -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Hash = hash<__range_key_type<_Range>>,
+          class _Pred = equal_to<__range_key_type<_Range>>,
+          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<!__is_allocator<_Pred>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>; // C++23
+#endif
+
 template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>,
          class _Pred = equal_to<remove_const_t<_Key>>,
          class _Allocator = allocator<pair<const _Key, _Tp>>,
@@ -1575,21 +1665,21 @@ unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allo
   -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
   -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                    hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_map(_InputIterator, _InputIterator, _Allocator)
   -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                    hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
 template<class _InputIterator, class _Hash, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
@@ -1597,6 +1687,30 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
   -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                    _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_map(from_range_t, _Range&&, _Allocator)
+  -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Hash, class _Allocator,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+#endif
+
 template<class _Key, class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
@@ -1625,7 +1739,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
 }
 
@@ -1635,7 +1748,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
 }
 
@@ -1645,7 +1757,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const allocator_type& __a)
     : __table_(typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1653,7 +1764,6 @@ template <class _InputIterator>
 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         _InputIterator __first, _InputIterator __last)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__first, __last);
 }
 
@@ -1664,7 +1774,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__first, __last);
 }
@@ -1676,7 +1785,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__first, __last);
 }
@@ -1686,7 +1794,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const unordered_map& __u)
     : __table_(__u.__table_)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1696,7 +1803,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const unordered_map& __u, const allocator_type& __a)
     : __table_(__u.__table_, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1710,8 +1816,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
-    _VSTD::__debug_db_insert_c(this);
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1719,7 +1823,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         unordered_map&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
@@ -1728,15 +1831,12 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
                 __u.__table_.remove((__i++).__i_)->__value_.__move());
         }
     }
-    else
-        std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         initializer_list<value_type> __il)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__il.begin(), __il.end());
 }
 
@@ -1746,7 +1846,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1757,7 +1856,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1874,7 +1972,7 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1904,6 +2002,8 @@ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     return true;
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1913,6 +2013,8 @@ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     return !(__x == __y);
 }
 
+#endif
+
 template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
           class _Alloc = allocator<pair<const _Key, _Tp> > >
 class _LIBCPP_TEMPLATE_VIS unordered_multimap
@@ -1928,7 +2030,7 @@ public:
     typedef value_type&                                    reference;
     typedef const value_type&                              const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
-                  "Invalid allocator::value_type");
+                  "Allocator::value_type must be same type as value_type");
 
 private:
     typedef __hash_value_type<key_type, mapped_type>                          __value_type;
@@ -1967,7 +2069,7 @@ private:
     typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
     typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __map_node_handle<__node, allocator_type> node_type;
 #endif
 
@@ -1980,42 +2082,56 @@ private:
     unordered_multimap()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
-    explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
-    unordered_multimap(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf,
                                 const key_equal& __eql,
                                 const allocator_type& __a);
     template <class _InputIterator>
-        unordered_multimap(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        unordered_multimap(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        unordered_multimap(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf,
                       const key_equal& __eql,
                       const allocator_type& __a);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multimap(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
+                       const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
+                       const allocator_type& __a = allocator_type())
+        : __table_(__hf, __eql, typename __table::allocator_type(__a)) {
+      if (__n > 0) {
+        __table_.__rehash_multi(__n);
+      }
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     explicit unordered_multimap(const allocator_type& __a);
-    unordered_multimap(const unordered_multimap& __u);
-    unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u);
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     unordered_multimap(unordered_multimap&& __u)
         _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
-    unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
-    unordered_multimap(initializer_list<value_type> __il);
-    unordered_multimap(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n,
                        const hasher& __hf = hasher(),
                        const key_equal& __eql = key_equal());
-    unordered_multimap(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n,
                        const hasher& __hf, const key_equal& __eql,
                        const allocator_type& __a);
 #endif // _LIBCPP_CXX03_LANG
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_INLINE_VISIBILITY
     unordered_multimap(size_type __n, const allocator_type& __a)
       : unordered_multimap(__n, hasher(), key_equal(), __a) {}
@@ -2031,6 +2147,19 @@ private:
       unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
         const allocator_type& __a)
       : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multimap(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
+        : unordered_multimap(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
+
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multimap(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multimap(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
       : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}
@@ -2104,6 +2233,16 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void insert(_InputIterator __first, _InputIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      for (auto&& __element : __range) {
+        __table_.__insert_multi(std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     void insert(initializer_list<value_type> __il)
@@ -2128,12 +2267,12 @@ private:
         {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
 
     template <class... _Args>
-    iterator emplace(_Args&&... __args) {
+    _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
         return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
     }
 
     template <class... _Args>
-    iterator emplace_hint(const_iterator __p, _Args&&... __args) {
+    _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
         return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
     }
 #endif // _LIBCPP_CXX03_LANG
@@ -2151,11 +2290,11 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {__table_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_multimap::insert()");
         return __table_.template __node_handle_insert_multi<node_type>(
             _VSTD::move(__nh));
@@ -2163,7 +2302,7 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_multimap::insert()");
         return __table_.template __node_handle_insert_multi<node_type>(
             __hint.__i_, _VSTD::move(__nh));
@@ -2184,32 +2323,32 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
 #endif
@@ -2230,31 +2369,31 @@ private:
     iterator       find(const key_type& __k)       {return __table_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __table_.find(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     iterator       find(const _K2& __k)            {return __table_.find(__k);}
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const _K2& __k) const      {return __table_.find(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const _K2& __k) const      {return __table_.__count_multi(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
 
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const _K2& __k) const      {return find(__k) != end();}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const key_type& __k)
@@ -2262,7 +2401,7 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
         {return __table_.__equal_range_multi(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const _K2& __k)
@@ -2271,7 +2410,7 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
         {return __table_.__equal_range_multi(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
@@ -2308,21 +2447,6 @@ private:
     void rehash(size_type __n) {__table_.__rehash_multi(__n);}
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.__reserve_multi(__n);}
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const
-        {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
-    bool __decrementable(const const_iterator* __i) const
-        {return __table_.__decrementable(_VSTD::addressof(__i->__i_));}
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
-
 };
 
 #if _LIBCPP_STD_VER >= 17
@@ -2330,7 +2454,7 @@ template<class _InputIterator,
          class _Hash = hash<__iter_key_type<_InputIterator>>,
          class _Pred = equal_to<__iter_key_type<_InputIterator>>,
          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<!__is_allocator<_Pred>::value>,
@@ -2339,6 +2463,20 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
                    _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
   -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Hash = hash<__range_key_type<_Range>>,
+          class _Pred = equal_to<__range_key_type<_Range>>,
+          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<!__is_allocator<_Pred>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>;
+#endif
+
 template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>,
          class _Pred = equal_to<remove_const_t<_Key>>,
          class _Allocator = allocator<pair<const _Key, _Tp>>,
@@ -2351,21 +2489,21 @@ unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<
   -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
   -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                         hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_multimap(_InputIterator, _InputIterator, _Allocator)
   -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                         hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
 template<class _InputIterator, class _Hash, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
@@ -2373,6 +2511,30 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
   -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
                         _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multimap(from_range_t, _Range&&, _Allocator)
+  -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Hash, class _Allocator,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash,
+                   equal_to<__range_key_type<_Range>>, _Allocator>;
+
+#endif
+
 template<class _Key, class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
@@ -2401,7 +2563,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
 }
 
@@ -2411,7 +2572,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
 }
 
@@ -2420,7 +2580,6 @@ template <class _InputIterator>
 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         _InputIterator __first, _InputIterator __last)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__first, __last);
 }
 
@@ -2431,7 +2590,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__first, __last);
 }
@@ -2443,7 +2601,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__first, __last);
 }
@@ -2454,7 +2611,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const allocator_type& __a)
     : __table_(typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2462,7 +2618,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const unordered_multimap& __u)
     : __table_(__u.__table_)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -2472,7 +2627,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const unordered_multimap& __u, const allocator_type& __a)
     : __table_(__u.__table_, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -2486,8 +2640,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
-    _VSTD::__debug_db_insert_c(this);
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2495,7 +2647,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         unordered_multimap&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
@@ -2505,15 +2656,12 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
                 __u.__table_.remove((__i++).__i_)->__value_.__move());
         }
     }
-    else
-        std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         initializer_list<value_type> __il)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__il.begin(), __il.end());
 }
 
@@ -2523,7 +2671,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__il.begin(), __il.end());
 }
@@ -2534,7 +2681,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, typename __table::allocator_type(__a))
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__il.begin(), __il.end());
 }
@@ -2584,7 +2730,7 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -2618,6 +2764,8 @@ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     return true;
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -2627,17 +2775,19 @@ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     return !(__x == __y);
 }
 
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
-using unordered_map =
+using unordered_map _LIBCPP_AVAILABILITY_PMR =
     std::unordered_map<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
 
 template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
-using unordered_multimap =
+using unordered_multimap _LIBCPP_AVAILABILITY_PMR =
     std::unordered_multimap<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
@@ -2647,7 +2797,9 @@ _LIBCPP_END_NAMESPACE_STD
 #  include <algorithm>
 #  include <bit>
 #  include <concepts>
+#  include <cstdlib>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_UNORDERED_MAP
lib/libcxx/include/unordered_set
@@ -58,6 +58,10 @@ public:
                       size_type n = 0, const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
+    template<container-compatible-range<value_type> R>
+      unordered_set(from_range_t, R&& rg, size_type n = see below,
+        const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+        const allocator_type& a = allocator_type()); // C++23
     explicit unordered_set(const allocator_type&);
     unordered_set(const unordered_set&);
     unordered_set(const unordered_set&, const Allocator&);
@@ -77,6 +81,12 @@ public:
     template <class InputIterator>
       unordered_set(InputIterator f, InputIterator l, size_type n,
                     const hasher& hf,  const allocator_type& a); // C++14
+    template<container-compatible-range<value_type> R>
+      unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a)
+        : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
+    template<container-compatible-range<value_type> R>
+      unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
+        : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }       // C++23
     unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
     unordered_set(initializer_list<value_type> il, size_type n,
                   const hasher& hf,  const allocator_type& a); // C++14
@@ -113,6 +123,8 @@ public:
     iterator insert(const_iterator hint, value_type&& obj);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                                      // C++23
     void insert(initializer_list<value_type>);
 
     node_type extract(const_iterator position);                       // C++17
@@ -191,6 +203,13 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type = see
   -> unordered_set<typename iterator_traits<InputIterator>::value_type,
         Hash, Pred, Allocator>; // C++17
 
+template<ranges::input_range R,
+         class Hash = hash<ranges::range_value_t<R>>,
+         class Pred = equal_to<ranges::range_value_t<R>>,
+         class Allocator = allocator<ranges::range_value_t<R>>>
+  unordered_set(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+    -> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23
+
 template<class T, class Hash = hash<T>,
           class Pred = equal_to<T>, class Allocator = allocator<T>>
 unordered_set(initializer_list<T>, typename see below::size_type = see below,
@@ -211,6 +230,21 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type,
         equal_to<typename iterator_traits<InputIterator>::value_type>,
         Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  unordered_set(from_range_t, R&&, typename see below::size_type, Allocator)
+    -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
+template<ranges::input_range R, class Allocator>
+  unordered_set(from_range_t, R&&, Allocator)
+    -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
+template<ranges::input_range R, class Hash, class Allocator>
+  unordered_set(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
+    -> unordered_set<ranges::range_value_t<R>, Hash,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
 template<class T, class Allocator>
 unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
   -> unordered_set<T, hash<T>, equal_to<T>, Allocator>; // C++17
@@ -232,7 +266,7 @@ template <class Value, class Hash, class Pred, class Alloc>
 template <class Value, class Hash, class Pred, class Alloc>
     bool
     operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,
-               const unordered_set<Value, Hash, Pred, Alloc>& y);
+               const unordered_set<Value, Hash, Pred, Alloc>& y); // removed in C++20
 
 template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
           class Alloc = allocator<Value>>
@@ -272,6 +306,10 @@ public:
                       size_type n = 0, const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
+    template<container-compatible-range<value_type> R>
+      unordered_multiset(from_range_t, R&& rg, size_type n = see below,
+        const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+        const allocator_type& a = allocator_type()); // C++23
     explicit unordered_multiset(const allocator_type&);
     unordered_multiset(const unordered_multiset&);
     unordered_multiset(const unordered_multiset&, const Allocator&);
@@ -291,6 +329,12 @@ public:
     template <class InputIterator>
       unordered_multiset(InputIterator f, InputIterator l, size_type n,
                          const hasher& hf, const allocator_type& a); // C++14
+    template<container-compatible-range<value_type> R>
+      unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a)
+        : unordered_multiset(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
+    template<container-compatible-range<value_type> R>
+      unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
+        : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }       // C++23
     unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
     unordered_multiset(initializer_list<value_type> il, size_type n,
                        const hasher& hf,  const allocator_type& a); // C++14
@@ -327,6 +371,8 @@ public:
     iterator insert(const_iterator hint, value_type&& obj);
     template <class InputIterator>
         void insert(InputIterator first, InputIterator last);
+    template<container-compatible-range<value_type> R>
+      void insert_range(R&& rg);                            // C++23
     void insert(initializer_list<value_type>);
 
     node_type extract(const_iterator position);             // C++17
@@ -405,6 +451,13 @@ unordered_multiset(InputIterator, InputIterator, see below::size_type = see belo
   -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
         Hash, Pred, Allocator>; // C++17
 
+template<ranges::input_range R,
+         class Hash = hash<ranges::range_value_t<R>>,
+         class Pred = equal_to<ranges::range_value_t<R>>,
+         class Allocator = allocator<ranges::range_value_t<R>>>
+  unordered_multiset(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+    -> unordered_multiset<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23
+
 template<class T, class Hash = hash<T>,
           class Pred = equal_to<T>, class Allocator = allocator<T>>
 unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
@@ -424,6 +477,21 @@ unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
   -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash,
         equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator>
+  unordered_multiset(from_range_t, R&&, typename see below::size_type, Allocator)
+    -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
+template<ranges::input_range R, class Allocator>
+  unordered_multiset(from_range_t, R&&, Allocator)
+    -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
+template<ranges::input_range R, class Hash, class Allocator>
+  unordered_multiset(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
+    -> unordered_multiset<ranges::range_value_t<R>, Hash,
+                      equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
+
 template<class T, class Allocator>
 unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
   -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>; // C++17
@@ -454,25 +522,29 @@ template <class Value, class Hash, class Pred, class Alloc>
 template <class Value, class Hash, class Pred, class Alloc>
     bool
     operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
-               const unordered_multiset<Value, Hash, Pred, Alloc>& y);
+               const unordered_multiset<Value, Hash, Pred, Alloc>& y); // removed in C++20
 }  // std
 
 */
 
 #include <__algorithm/is_permutation.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__config>
-#include <__debug>
 #include <__functional/is_transparent.h>
 #include <__functional/operations.h>
 #include <__hash_table>
 #include <__iterator/distance.h>
 #include <__iterator/erase_if_container.h>
 #include <__iterator/iterator_traits.h>
+#include <__iterator/ranges_iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/allocator.h>
 #include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
 #include <version>
@@ -513,7 +585,7 @@ public:
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
-                  "Invalid allocator::value_type");
+                  "Allocator::value_type must be same type as value_type");
 
     static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
                   "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
@@ -535,7 +607,7 @@ public:
     typedef typename __table::const_local_iterator local_iterator;
     typedef typename __table::const_local_iterator const_local_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
     typedef __insert_return_type<iterator, node_type> insert_return_type;
 #endif
@@ -549,11 +621,10 @@ public:
     unordered_set()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
-    explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     inline _LIBCPP_INLINE_VISIBILITY
     unordered_set(size_type __n, const allocator_type& __a)
         : unordered_set(__n, hasher(), key_equal(), __a) {}
@@ -561,46 +632,74 @@ public:
     unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)
         : unordered_set(__n, __hf, key_equal(), __a) {}
 #endif
-    unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
     template <class _InputIterator>
-        unordered_set(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        unordered_set(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        unordered_set(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf, const key_equal& __eql,
                       const allocator_type& __a);
-#if _LIBCPP_STD_VER > 11
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_set(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
+                  const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
+                  const allocator_type& __a = allocator_type())
+    : __table_(__hf, __eql, __a) {
+      if (__n > 0) {
+        __table_.__rehash_unique(__n);
+      }
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 14
     template <class _InputIterator>
     inline _LIBCPP_INLINE_VISIBILITY
         unordered_set(_InputIterator __first, _InputIterator __last,
                     size_type __n, const allocator_type& __a)
             : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}
     template <class _InputIterator>
-        unordered_set(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf, const allocator_type& __a)
             : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}
 #endif
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_set(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
+        : unordered_set(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
+
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_set(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_set(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     explicit unordered_set(const allocator_type& __a);
-    unordered_set(const unordered_set& __u);
-    unordered_set(const unordered_set& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u);
+    _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     unordered_set(unordered_set&& __u)
         _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
-    unordered_set(unordered_set&& __u, const allocator_type& __a);
-    unordered_set(initializer_list<value_type> __il);
-    unordered_set(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n,
                   const hasher& __hf = hasher(),
                   const key_equal& __eql = key_equal());
-    unordered_set(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n,
                   const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     inline _LIBCPP_INLINE_VISIBILITY
     unordered_set(initializer_list<value_type> __il, size_type __n,
                                                       const allocator_type& __a)
@@ -661,11 +760,7 @@ public:
             {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
     template <class... _Args>
     _LIBCPP_INLINE_VISIBILITY
-    iterator emplace_hint(const_iterator __p, _Args&&... __args) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
-            "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
-            " referring to this unordered_set");
-        (void)__p;
+    iterator emplace_hint(const_iterator, _Args&&... __args) {
         return __table_.__emplace_unique(std::forward<_Args>(__args)...).first;
     }
 
@@ -673,11 +768,7 @@ public:
     pair<iterator, bool> insert(value_type&& __x)
         {return __table_.__insert_unique(_VSTD::move(__x));}
     _LIBCPP_INLINE_VISIBILITY
-    iterator insert(const_iterator __p, value_type&& __x) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
-            "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
-            " referring to this unordered_set");
-        (void)__p;
+    iterator insert(const_iterator, value_type&& __x) {
         return insert(std::move(__x)).first;
     }
 
@@ -690,17 +781,23 @@ public:
         {return __table_.__insert_unique(__x);}
 
     _LIBCPP_INLINE_VISIBILITY
-    iterator insert(const_iterator __p, const value_type& __x) {
-        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
-            "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
-            " referring to this unordered_set");
-        (void)__p;
+    iterator insert(const_iterator, const value_type& __x) {
         return insert(__x).first;
     }
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         void insert(_InputIterator __first, _InputIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      for (auto&& __element : __range) {
+        __table_.__insert_unique(std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator erase(const_iterator __p) {return __table_.erase(__p);}
     _LIBCPP_INLINE_VISIBILITY
@@ -711,11 +808,11 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT {__table_.clear();}
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     insert_return_type insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_set::insert()");
         return __table_.template __node_handle_insert_unique<
             node_type, insert_return_type>(_VSTD::move(__nh));
@@ -723,7 +820,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __h, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_set::insert()");
         return __table_.template __node_handle_insert_unique<node_type>(
             __h, _VSTD::move(__nh));
@@ -743,32 +840,32 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __table_.__node_handle_merge_unique(__source.__table_);
     }
     template<class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+          _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                              "merging container with incompatible allocator");
         __table_.__node_handle_merge_unique(__source.__table_);
     }
     template<class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __table_.__node_handle_merge_unique(__source.__table_);
     }
     template<class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         __table_.__node_handle_merge_unique(__source.__table_);
     }
 #endif
@@ -787,31 +884,31 @@ public:
     iterator       find(const key_type& __k)       {return __table_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __table_.find(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     iterator       find(const _K2& __k)            {return __table_.find(__k);}
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const _K2& __k) const      {return __table_.find(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const _K2& __k) const      {return __table_.__count_unique(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
 
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const _K2& __k) const      {return find(__k) != end();}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const key_type& __k)
@@ -819,7 +916,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
         {return __table_.__equal_range_unique(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const _K2& __k)
@@ -828,7 +925,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
         {return __table_.__equal_range_unique(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
@@ -863,20 +960,6 @@ public:
     void rehash(size_type __n) {__table_.__rehash_unique(__n);}
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.__reserve_unique(__n);}
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const
-        {return __table_.__dereferenceable(__i);}
-    bool __decrementable(const const_iterator* __i) const
-        {return __table_.__decrementable(__i);}
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(__i, __n);}
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(__i, __n);}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 };
 
 #if _LIBCPP_STD_VER >= 17
@@ -884,7 +967,7 @@ template<class _InputIterator,
          class _Hash = hash<__iter_value_type<_InputIterator>>,
          class _Pred = equal_to<__iter_value_type<_InputIterator>>,
          class _Allocator = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<!__is_allocator<_Pred>::value>,
@@ -893,6 +976,20 @@ unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
               _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
   -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Hash = hash<ranges::range_value_t<_Range>>,
+          class _Pred = equal_to<ranges::range_value_t<_Range>>,
+          class _Allocator = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<!__is_allocator<_Pred>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
+#endif
+
 template<class _Tp, class _Hash = hash<_Tp>,
          class _Pred = equal_to<_Tp>,
          class _Allocator = allocator<_Tp>,
@@ -905,7 +1002,7 @@ unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size
   -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_set(_InputIterator, _InputIterator,
               typename allocator_traits<_Allocator>::size_type, _Allocator)
@@ -915,7 +1012,7 @@ unordered_set(_InputIterator, _InputIterator,
                    _Allocator>;
 
 template<class _InputIterator, class _Hash, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
@@ -925,6 +1022,29 @@ unordered_set(_InputIterator, _InputIterator,
                    equal_to<__iter_value_type<_InputIterator>>,
                    _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
+                   equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_set(from_range_t, _Range&&, _Allocator)
+  -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
+                   equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Hash, class _Allocator,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_set<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+#endif
+
 template<class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
@@ -943,7 +1063,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
 }
 
@@ -952,7 +1071,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
 }
 
@@ -961,7 +1079,6 @@ template <class _InputIterator>
 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         _InputIterator __first, _InputIterator __last)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__first, __last);
 }
 
@@ -972,7 +1089,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__first, __last);
 }
@@ -984,7 +1100,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__first, __last);
 }
@@ -995,7 +1110,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const allocator_type& __a)
     : __table_(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1003,7 +1117,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const unordered_set& __u)
     : __table_(__u.__table_)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1013,7 +1126,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const unordered_set& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1027,8 +1139,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
-    _VSTD::__debug_db_insert_c(this);
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1036,22 +1146,18 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         unordered_set&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
         while (__u.size() != 0)
             __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
     }
-    else
-        std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         initializer_list<value_type> __il)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__il.begin(), __il.end());
 }
 
@@ -1061,7 +1167,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1072,7 +1177,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_unique(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1120,7 +1224,7 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Value, class _Hash, class _Pred, class _Alloc,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1150,6 +1254,8 @@ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
     return true;
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1159,6 +1265,8 @@ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
     return !(__x == __y);
 }
 
+#endif
+
 template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
 class _LIBCPP_TEMPLATE_VIS unordered_multiset
@@ -1173,7 +1281,7 @@ public:
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
-                  "Invalid allocator::value_type");
+                  "Allocator::value_type must be same type as value_type");
 
 private:
     typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
@@ -1191,7 +1299,7 @@ public:
     typedef typename __table::const_local_iterator local_iterator;
     typedef typename __table::const_local_iterator const_local_iterator;
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
 #endif
 
@@ -1204,13 +1312,12 @@ public:
     unordered_multiset()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
     {
-        _VSTD::__debug_db_insert_c(this);
     }
-    explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
+    explicit _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
-    unordered_multiset(size_type __n, const hasher& __hf,
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf,
                        const key_equal& __eql, const allocator_type& __a);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     inline _LIBCPP_INLINE_VISIBILITY
     unordered_multiset(size_type __n, const allocator_type& __a)
         : unordered_multiset(__n, hasher(), key_equal(), __a) {}
@@ -1219,16 +1326,31 @@ public:
         : unordered_multiset(__n, __hf, key_equal(), __a) {}
 #endif
     template <class _InputIterator>
-        unordered_multiset(_InputIterator __first, _InputIterator __last);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
-        unordered_multiset(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf = hasher(),
                       const key_equal& __eql = key_equal());
     template <class _InputIterator>
-        unordered_multiset(_InputIterator __first, _InputIterator __last,
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last,
                       size_type __n , const hasher& __hf,
                       const key_equal& __eql, const allocator_type& __a);
-#if _LIBCPP_STD_VER > 11
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multiset(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
+                  const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
+                  const allocator_type& __a = allocator_type())
+    : __table_(__hf, __eql, __a) {
+      if (__n > 0) {
+        __table_.__rehash_multi(__n);
+      }
+      insert_range(std::forward<_Range>(__range));
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 14
     template <class _InputIterator>
     inline _LIBCPP_INLINE_VISIBILITY
     unordered_multiset(_InputIterator __first, _InputIterator __last,
@@ -1240,23 +1362,36 @@ public:
                        size_type __n, const hasher& __hf, const allocator_type& __a)
         : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
 #endif
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multiset(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
+        : unordered_multiset(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
+
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    unordered_multiset(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multiset(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     explicit unordered_multiset(const allocator_type& __a);
-    unordered_multiset(const unordered_multiset& __u);
-    unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     unordered_multiset(unordered_multiset&& __u)
         _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
-    unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
-    unordered_multiset(initializer_list<value_type> __il);
-    unordered_multiset(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n,
                        const hasher& __hf = hasher(),
                        const key_equal& __eql = key_equal());
-    unordered_multiset(initializer_list<value_type> __il, size_type __n,
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n,
                        const hasher& __hf, const key_equal& __eql,
                        const allocator_type& __a);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     inline _LIBCPP_INLINE_VISIBILITY
     unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
       : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
@@ -1280,7 +1415,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     unordered_multiset& operator=(unordered_multiset&& __u)
         _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
-    unordered_multiset& operator=(initializer_list<value_type> __il);
+    _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
 #endif // _LIBCPP_CXX03_LANG
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1338,11 +1473,21 @@ public:
         _LIBCPP_INLINE_VISIBILITY
         void insert(_InputIterator __first, _InputIterator __last);
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<value_type> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    void insert_range(_Range&& __range) {
+      for (auto&& __element : __range) {
+        __table_.__insert_multi(std::forward<decltype(__element)>(__element));
+      }
+    }
+#endif
+
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_multiset::insert()");
         return __table_.template __node_handle_insert_multi<node_type>(
             _VSTD::move(__nh));
@@ -1350,7 +1495,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const_iterator __hint, node_type&& __nh)
     {
-        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
             "node_type with incompatible allocator passed to unordered_multiset::insert()");
         return __table_.template __node_handle_insert_multi<node_type>(
             __hint, _VSTD::move(__nh));
@@ -1371,32 +1516,32 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
     template <class _H2, class _P2>
     _LIBCPP_INLINE_VISIBILITY
     void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
     {
-        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
-                       "merging container with incompatible allocator");
+        _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
+                                            "merging container with incompatible allocator");
         return __table_.__node_handle_merge_multi(__source.__table_);
     }
 #endif
@@ -1425,31 +1570,31 @@ public:
     iterator       find(const key_type& __k)       {return __table_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __table_.find(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     iterator       find(const _K2& __k)            {return __table_.find(__k);}
     template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const _K2& __k) const      {return __table_.find(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     size_type count(const _K2& __k) const      {return __table_.__count_multi(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
 
     template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const _K2& __k) const      {return find(__k) != end();}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const key_type& __k)
@@ -1457,7 +1602,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
         {return __table_.__equal_range_multi(__k);}
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
     template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, iterator>             equal_range(const _K2& __k)
@@ -1466,7 +1611,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
         {return __table_.__equal_range_multi(__k);}
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
     _LIBCPP_INLINE_VISIBILITY
     size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
@@ -1501,20 +1646,6 @@ public:
     void rehash(size_type __n) {__table_.__rehash_multi(__n);}
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.__reserve_multi(__n);}
-
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const
-        {return __table_.__dereferenceable(__i);}
-    bool __decrementable(const const_iterator* __i) const
-        {return __table_.__decrementable(__i);}
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(__i, __n);}
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-        {return __table_.__addable(__i, __n);}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 };
 
 #if _LIBCPP_STD_VER >= 17
@@ -1522,7 +1653,7 @@ template<class _InputIterator,
          class _Hash = hash<__iter_value_type<_InputIterator>>,
          class _Pred = equal_to<__iter_value_type<_InputIterator>>,
          class _Allocator = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<!__is_allocator<_Pred>::value>,
@@ -1531,6 +1662,20 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
               _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
   -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Hash = hash<ranges::range_value_t<_Range>>,
+          class _Pred = equal_to<ranges::range_value_t<_Range>>,
+          class _Allocator = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<!__is_allocator<_Pred>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
+#endif
+
 template<class _Tp, class _Hash = hash<_Tp>,
          class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
@@ -1542,7 +1687,7 @@ unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>:
   -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
 
 template<class _InputIterator, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
   -> unordered_multiset<__iter_value_type<_InputIterator>,
@@ -1551,7 +1696,7 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
                    _Allocator>;
 
 template<class _InputIterator, class _Hash, class _Allocator,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<!__is_allocator<_Hash>::value>,
          class = enable_if_t<!is_integral<_Hash>::value>,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
@@ -1561,6 +1706,29 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
                    equal_to<__iter_value_type<_InputIterator>>,
                    _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
+                   equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Allocator,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multiset(from_range_t, _Range&&, _Allocator)
+  -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
+                   equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+template <ranges::input_range _Range, class _Hash, class _Allocator,
+          class = enable_if_t<!__is_allocator<_Hash>::value>,
+          class = enable_if_t<!is_integral<_Hash>::value>,
+          class = enable_if_t<__is_allocator<_Allocator>::value>>
+unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
+
+#endif
+
 template<class _Tp, class _Allocator,
          class = enable_if_t<__is_allocator<_Allocator>::value>>
 unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
@@ -1579,7 +1747,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
 }
 
@@ -1589,7 +1756,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
 }
 
@@ -1598,7 +1764,6 @@ template <class _InputIterator>
 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         _InputIterator __first, _InputIterator __last)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__first, __last);
 }
 
@@ -1609,7 +1774,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__first, __last);
 }
@@ -1621,7 +1785,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__first, __last);
 }
@@ -1632,7 +1795,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const allocator_type& __a)
     : __table_(__a)
 {
-    _VSTD::__debug_db_insert_c(this);
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1640,7 +1802,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const unordered_multiset& __u)
     : __table_(__u.__table_)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1650,7 +1811,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const unordered_multiset& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1664,8 +1824,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
-    _VSTD::__debug_db_insert_c(this);
-    std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1673,22 +1831,18 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         unordered_multiset&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
         while (__u.size() != 0)
             __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
     }
-    else
-        std::__debug_db_swap(this, std::addressof(__u));
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         initializer_list<value_type> __il)
 {
-    _VSTD::__debug_db_insert_c(this);
     insert(__il.begin(), __il.end());
 }
 
@@ -1698,7 +1852,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1709,7 +1862,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
-    _VSTD::__debug_db_insert_c(this);
     __table_.__rehash_multi(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1758,7 +1910,7 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Value, class _Hash, class _Pred, class _Alloc,
           class _Predicate>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1792,6 +1944,8 @@ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
     return true;
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -1801,24 +1955,28 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
     return !(__x == __y);
 }
 
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
-using unordered_set = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
+using unordered_set _LIBCPP_AVAILABILITY_PMR = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
 
 template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
-using unordered_multiset = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
+using unordered_multiset _LIBCPP_AVAILABILITY_PMR = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <concepts>
+#  include <cstdlib>
 #  include <functional>
 #  include <iterator>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_UNORDERED_SET
lib/libcxx/include/utility
@@ -84,14 +84,15 @@ struct pair
     explicit(see-below) constexpr pair();
     explicit(see-below) pair(const T1& x, const T2& y);                          // constexpr in C++14
     template <class U = T1, class V = T2> explicit(see-below) pair(U&&, V&&);    // constexpr in C++14
-    template <class U, class V> constexpr explicit(see below) pair(pair<U, V>&); // since C++23
+    template <class U, class V> constexpr explicit(see-below) pair(pair<U, V>&); // since C++23
     template <class U, class V> explicit(see-below) pair(const pair<U, V>& p);   // constexpr in C++14
     template <class U, class V> explicit(see-below) pair(pair<U, V>&& p);        // constexpr in C++14
     template <class U, class V>
-    constexpr explicit(see below) pair(const pair<U, V>&&);                      // since C++23
+    constexpr explicit(see-below) pair(const pair<U, V>&&);                      // since C++23
+    template <pair-like P> constexpr explicit(see-below) pair(P&&);              // since C++23
     template <class... Args1, class... Args2>
-        pair(piecewise_construct_t, tuple<Args1...> first_args,
-             tuple<Args2...> second_args);                                       // constexpr in C++20
+        pair(piecewise_construct_t, tuple<Args1...> first_args,                  // constexpr in C++20
+                                    tuple<Args2...> second_args);
 
     constexpr const pair& operator=(const pair& p) const;                        // since C++23
     template <class U, class V> pair& operator=(const pair<U, V>& p);            // constexpr in C++20
@@ -103,6 +104,8 @@ struct pair
     template <class U, class V> pair& operator=(pair<U, V>&& p);                 // constexpr in C++20
     template <class U, class V>
     constexpr const pair& operator=(pair<U, V>&& p) const;                       // since C++23
+    template <pair-like P> constexpr pair& operator=(P&&);                       // since C++23
+    template <pair-like P> constexpr const pair& operator=(P&&) const;           // since C++23
 
     void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
                                 is_nothrow_swappable_v<T2>);                     // constexpr in C++20
@@ -117,24 +120,30 @@ struct common_type<pair<T1, T2>, pair<U1, U2>>;
 
 template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>;
 
-template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
-template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
-template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
-template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
-template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
-template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
-template <class T1, class T2>
-  constexpr common_comparison_type_t<synth-three-way-result<T1>,
-                                     synth-three-way-result<T2>>
-    operator<=>(const pair<T1,T2>&, const pair<T1,T2>&);                               // C++20
+template <class T1, class T2, class U1, class U2>
+bool operator==(const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14
+template <class T1, class T2, class U1, class U2>
+bool operator!=(const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14, removed in C++20
+template <class T1, class T2, class U1, class U2>
+bool operator< (const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14, removed in C++20
+template <class T1, class T2, class U1, class U2>
+bool operator> (const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14, removed in C++20
+template <class T1, class T2, class U1, class U2>
+bool operator>=(const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14, removed in C++20
+template <class T1, class T2, class U1, class U2>
+bool operator<=(const pair<T1,T2>&, const pair<U1,U2>&);                         // constexpr in C++14, removed in C++20
+template <class T1, class T2, class U1, class U2>
+  constexpr common_comparison_type_t<synth-three-way-result<T1,U1>,
+                                     synth-three-way-result<T2,U2>>
+    operator<=>(const pair<T1,T2>&, const pair<U1,U2>&);                         // C++20
 
 template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);                // constexpr in C++14
 template <class T1, class T2>
 void
 swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));            // constexpr in C++20
 
-template<class T1, class T2>
-constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));    // since C++23
+template<class T1, class T2>                                                     // since C++23
+constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
 
 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
 inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
@@ -208,8 +217,8 @@ template<class... T>
   using index_sequence_for = make_index_sequence<sizeof...(T)>;
 
 template<class T, class U=T>
-    constexpr T exchange(T& obj, U&& new_value)
-      noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value); // constexpr in C++17, noexcept in C++23
+    constexpr T exchange(T& obj, U&& new_value)                                 // constexpr in C++17, noexcept in C++23
+      noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value);
 
 // 20.2.7, in-place construction // C++17
 struct in_place_t {
@@ -231,7 +240,7 @@ template <size_t I>
 
 // [utility.underlying], to_underlying
 template <class T>
-    constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++2b
+    constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++23
 
 }  // std
 
@@ -266,8 +275,8 @@ template <class T>
 #include <initializer_list>
 
 // [tuple.helper]
-#include <__tuple_dir/tuple_element.h>
-#include <__tuple_dir/tuple_size.h>
+#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_size.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
lib/libcxx/include/valarray
@@ -116,6 +116,8 @@ public:
     size_t start()  const;
     size_t size()   const;
     size_t stride() const;
+
+    friend bool operator==(const slice& x, const slice& y); // since C++20
 };
 
 template <class T>
@@ -351,8 +353,10 @@ template <class T> unspecified2 end(const valarray<T>& v);
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/operations.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator.h>
 #include <__memory/uninitialized_algorithms.h>
+#include <__type_traits/decay.h>
 #include <__type_traits/remove_reference.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
@@ -400,10 +404,18 @@ public:
     _LIBCPP_INLINE_VISIBILITY size_t start()  const {return __start_;}
     _LIBCPP_INLINE_VISIBILITY size_t size()   const {return __size_;}
     _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;}
+
+#if _LIBCPP_STD_VER >= 20
+
+    _LIBCPP_HIDE_FROM_ABI friend bool operator==(const slice& __x, const slice& __y) {
+      return __x.start() == __y.start() && __x.size() == __y.size() && __x.stride() == __y.stride();
+    }
+
+#endif
 };
 
 template <class _Tp> class _LIBCPP_TEMPLATE_VIS slice_array;
-class _LIBCPP_TYPE_VIS gslice;
+class _LIBCPP_EXPORTED_FROM_ABI gslice;
 template <class _Tp> class _LIBCPP_TEMPLATE_VIS gslice_array;
 template <class _Tp> class _LIBCPP_TEMPLATE_VIS mask_array;
 template <class _Tp> class _LIBCPP_TEMPLATE_VIS indirect_array;
@@ -432,7 +444,7 @@ template <class _Op, class _A0>
 struct _UnaryOp
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     _A0 __a0_;
@@ -451,7 +463,7 @@ template <class _Op, class _A0, class _A1>
 struct _BinaryOp
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     _A0 __a0_;
@@ -1104,18 +1116,18 @@ private:
     valarray& __assign_range(const value_type* __f, const value_type* __l);
 };
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 template<class _Tp, size_t _Size>
 valarray(const _Tp(&)[_Size], size_t) -> valarray<_Tp>;
 #endif
 
-extern template _LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t);
+extern template _LIBCPP_EXPORTED_FROM_ABI void valarray<size_t>::resize(size_t, size_t);
 
 template <class _Op, class _Tp>
 struct _UnaryOp<_Op, valarray<_Tp> >
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     const valarray<_Tp>& __a0_;
@@ -1134,7 +1146,7 @@ template <class _Op, class _Tp, class _A1>
 struct _BinaryOp<_Op, valarray<_Tp>, _A1>
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     const valarray<_Tp>& __a0_;
@@ -1155,7 +1167,7 @@ template <class _Op, class _A0, class _Tp>
 struct _BinaryOp<_Op, _A0, valarray<_Tp> >
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     _A0 __a0_;
@@ -1176,7 +1188,7 @@ template <class _Op, class _Tp>
 struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
 {
     typedef typename _Op::__result_type __result_type;
-    typedef typename decay<__result_type>::type value_type;
+    using value_type = __decay_t<__result_type>;
 
     _Op __op_;
     const valarray<_Tp>& __a0_;
@@ -1326,7 +1338,6 @@ private:
         {}
 
     template <class> friend class valarray;
-    template <class> friend class sliceExpr;
 };
 
 template <class _Tp>
@@ -1527,7 +1538,7 @@ slice_array<_Tp>::operator=(const value_type& __x) const
 
 // gslice
 
-class _LIBCPP_TYPE_VIS gslice
+class _LIBCPP_EXPORTED_FROM_ABI gslice
 {
     valarray<size_t> __size_;
     valarray<size_t> __stride_;
@@ -2818,20 +2829,20 @@ valarray<_Tp>::valarray(size_t __n)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
                 ::new ((void*)__end_) value_type();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2852,20 +2863,20 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
                 ::new ((void*)__end_) value_type(*__p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2877,20 +2888,20 @@ valarray<_Tp>::valarray(const valarray& __v)
     if (__v.size())
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__v.size());
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
                 ::new ((void*)__end_) value_type(*__p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__v.size());
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2914,21 +2925,21 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             size_t __n_left = __n;
             for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
                 ::new ((void*)__end_) value_type(*__p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2943,21 +2954,21 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             size_t __n_left = __n;
             for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
                 ::new ((void*)__end_) value_type(*__p);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2970,23 +2981,23 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef const size_t* _Ip;
             const value_type* __s = __ga.__vp_;
             for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
                     __i != __e; ++__i, ++__end_)
                 ::new ((void*)__end_) value_type(__s[*__i]);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -2999,23 +3010,23 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef const size_t* _Ip;
             const value_type* __s = __ma.__vp_;
             for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
                     __i != __e; ++__i, ++__end_)
                 ::new ((void*)__end_) value_type(__s[*__i]);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -3028,23 +3039,23 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             typedef const size_t* _Ip;
             const value_type* __s = __ia.__vp_;
             for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
                     __i != __e; ++__i, ++__end_)
                 ::new ((void*)__end_) value_type(__s[*__i]);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -3753,20 +3764,20 @@ valarray<_Tp>::resize(size_t __n, value_type __x)
     if (__n)
     {
         __begin_ = __end_ = allocator<value_type>().allocate(__n);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
                 ::new ((void*)__end_) value_type(__x);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             __clear(__n);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -4933,8 +4944,11 @@ _LIBCPP_POP_MACROS
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <algorithm>
 #  include <concepts>
+#  include <cstdlib>
 #  include <cstring>
 #  include <functional>
+#  include <stdexcept>
+#  include <type_traits>
 #endif
 
 #endif // _LIBCPP_VALARRAY
lib/libcxx/include/variant
@@ -210,10 +210,12 @@ namespace std {
 #include <__compare/compare_three_way_result.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
+#include <__exception/exception.h>
 #include <__functional/hash.h>
 #include <__functional/invoke.h>
 #include <__functional/operations.h>
 #include <__functional/unary_function.h>
+#include <__memory/addressof.h>
 #include <__type_traits/add_const.h>
 #include <__type_traits/add_cv.h>
 #include <__type_traits/add_pointer.h>
@@ -231,12 +233,13 @@ namespace std {
 #include <__type_traits/remove_const.h>
 #include <__type_traits/type_identity.h>
 #include <__type_traits/void_t.h>
+#include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>
 #include <__variant/monostate.h>
-#include <exception>
+#include <__verbose_abort>
 #include <initializer_list>
 #include <limits>
 #include <new>
@@ -257,7 +260,7 @@ _LIBCPP_PUSH_MACROS
 
 namespace std { // explicitly not using versioning namespace
 
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
 public:
    const char* what() const _NOEXCEPT override;
 };
@@ -266,7 +269,7 @@ public:
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 
 // Light N-dimensional array of function pointers. Used in place of std::array to avoid
 // adding a dependency.
@@ -285,10 +288,10 @@ _LIBCPP_NORETURN
 inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
 void __throw_bad_variant_access() {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         throw bad_variant_access();
 #else
-        _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode");
 #endif
 }
 
@@ -547,7 +550,7 @@ private:
   }
 
   template <class _Fp, class... _Fs>
-  static constexpr void __std_visit_visitor_return_type_check() {
+  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() {
     static_assert(
         __all<is_same_v<_Fp, _Fs>...>::value,
         "`std::visit` requires the visitor to have a single return type.");
@@ -594,9 +597,9 @@ private:
   template <class _Fp, class _Vp, class... _Vs>
   _LIBCPP_HIDE_FROM_ABI
   static constexpr auto __make_fdiagonal() {
-    constexpr size_t _Np = __remove_cvref_t<_Vp>::__size();
-    static_assert(__all<(_Np == __remove_cvref_t<_Vs>::__size())...>::value);
-    return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
+    constexpr size_t __np = __remove_cvref_t<_Vp>::__size();
+    static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value);
+    return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{});
   }
 
   template <class _Fp, class... _Vs, size_t... _Is>
@@ -660,7 +663,7 @@ struct __variant {
         _VSTD::forward<_Vs>(__vs)...);
   }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   template <class _Rp, class _Visitor, class... _Vs>
   _LIBCPP_HIDE_FROM_ABI
   static constexpr _Rp __visit_value(_Visitor&& __visitor,
@@ -673,7 +676,7 @@ struct __variant {
 
 private:
   template <class _Visitor, class... _Values>
-  static constexpr void __std_visit_exhaustive_visitor_check() {
+  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() {
     static_assert(is_invocable_v<_Visitor, _Values...>,
                   "`std::visit` requires the visitor to be exhaustive.");
   }
@@ -692,7 +695,7 @@ private:
     _Visitor&& __visitor;
   };
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   template <class _Rp, class _Visitor>
   struct __value_visitor_return_type {
     template <class... _Alts>
@@ -721,7 +724,7 @@ private:
     return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
   }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
   template <class _Rp, class _Visitor>
   _LIBCPP_HIDE_FROM_ABI
   static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
@@ -1034,10 +1037,10 @@ protected:
       __a.__value = _VSTD::forward<_Arg>(__arg);
     } else {
       struct {
-        void operator()(true_type) const {
+        _LIBCPP_HIDE_FROM_ABI void operator()(true_type) const {
           __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
         }
-        void operator()(false_type) const {
+        _LIBCPP_HIDE_FROM_ABI void operator()(false_type) const {
           __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
         }
         __assignment* __this;
@@ -1155,10 +1158,10 @@ class _LIBCPP_TEMPLATE_VIS __impl
 
 public:
   using __base_type::__base_type; // get in_place_index_t constructor & friends
-  __impl(__impl const&) = default;
-  __impl(__impl&&) = default;
-  __impl& operator=(__impl const&) = default;
-  __impl& operator=(__impl&&) = default;
+  _LIBCPP_HIDE_FROM_ABI __impl(__impl const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __impl(__impl&&) = default;
+  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default;
 
   template <size_t _Ip, class _Arg>
   _LIBCPP_HIDE_FROM_ABI
@@ -1187,7 +1190,7 @@ public:
         _VSTD::swap(__lhs, __rhs);
       }
       __impl __tmp(_VSTD::move(*__rhs));
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
       if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
         this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
       } else {
@@ -1271,7 +1274,7 @@ struct __all_overloads : _Bases... {
   using _Bases::operator()...;
 };
 
-template <class IdxSeq>
+template <class _IdxSeq>
 struct __make_overloads_imp;
 
 template <size_t ..._Idx>
@@ -1291,7 +1294,7 @@ using __best_match_t =
 } // namespace __variant_detail
 
 template <class... _Types>
-class _LIBCPP_TEMPLATE_VIS variant
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
     : private __sfinae_ctor_base<
           __all<is_copy_constructible_v<_Types>...>::value,
           __all<is_move_constructible_v<_Types>...>::value>,
@@ -1323,8 +1326,8 @@ public:
   constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
       : __impl_(in_place_index<0>) {}
 
-  constexpr variant(const variant&) = default;
-  constexpr variant(variant&&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default;
 
   template <
       class _Arg,
@@ -1393,10 +1396,10 @@ public:
       is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
       : __impl_(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
 
-  ~variant() = default;
+  _LIBCPP_HIDE_FROM_ABI ~variant() = default;
 
-  constexpr variant& operator=(const variant&) = default;
-  constexpr variant& operator=(variant&&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&) = default;
 
   template <
       class _Arg,
@@ -1652,7 +1655,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs,
   return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
 }
 
-#  if _LIBCPP_STD_VER > 17
+#  if _LIBCPP_STD_VER >= 20
 
 template <class... _Types> requires (three_way_comparable<_Types> && ...)
 _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
@@ -1671,7 +1674,7 @@ operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
   return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
 }
 
-#  endif // _LIBCPP_STD_VER > 17
+#  endif // _LIBCPP_STD_VER >= 20
 
 template <class... _Types>
 _LIBCPP_HIDE_FROM_ABI
@@ -1757,7 +1760,7 @@ constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
                                   _VSTD::forward<_Vs>(__vs)...);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <
     class _Rp, class _Visitor, class... _Vs,
     typename = void_t<decltype(_VSTD::__as_variant(std::declval<_Vs>()))...> >
@@ -1824,13 +1827,14 @@ constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
   return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
 }
 
-#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <exception>
 #  include <type_traits>
 #  include <typeinfo>
 #  include <utility>
lib/libcxx/include/vector
@@ -41,6 +41,8 @@ public:
     vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
     template <class InputIterator>
         vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
+    template<container-compatible-range<T> R>
+      constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
     vector(const vector& x);
     vector(vector&& x)
         noexcept(is_nothrow_move_constructible<allocator_type>::value);
@@ -55,6 +57,8 @@ public:
     vector& operator=(initializer_list<value_type> il);
     template <class InputIterator>
         void assign(InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      constexpr void assign_range(R&& rg); // C++23
     void assign(size_type n, const value_type& u);
     void assign(initializer_list<value_type> il);
 
@@ -99,6 +103,8 @@ public:
     void push_back(value_type&& x);
     template <class... Args>
         reference emplace_back(Args&&... args); // reference in C++17
+    template<container-compatible-range<T> R>
+      constexpr void append_range(R&& rg); // C++23
     void pop_back();
 
     template <class... Args> iterator emplace(const_iterator position, Args&&... args);
@@ -107,6 +113,8 @@ public:
     iterator insert(const_iterator position, size_type n, const value_type& x);
     template <class InputIterator>
         iterator insert(const_iterator position, InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
     iterator insert(const_iterator position, initializer_list<value_type> il);
 
     iterator erase(const_iterator position);
@@ -165,6 +173,8 @@ public:
     vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
     template <class InputIterator>
         vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
+    template<container-compatible-range<bool> R>
+      constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
     vector(const vector& x);
     vector(vector&& x)
         noexcept(is_nothrow_move_constructible<allocator_type>::value);
@@ -179,6 +189,8 @@ public:
     vector& operator=(initializer_list<value_type> il);
     template <class InputIterator>
         void assign(InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      constexpr void assign_range(R&& rg); // C++23
     void assign(size_type n, const value_type& u);
     void assign(initializer_list<value_type> il);
 
@@ -218,6 +230,8 @@ public:
 
     void push_back(const value_type& x);
     template <class... Args> reference emplace_back(Args&&... args);  // C++14; reference in C++17
+    template<container-compatible-range<T> R>
+      constexpr void append_range(R&& rg); // C++23
     void pop_back();
 
     template <class... Args> iterator emplace(const_iterator position, Args&&... args);  // C++14
@@ -225,6 +239,8 @@ public:
     iterator insert(const_iterator position, size_type n, const value_type& x);
     template <class InputIterator>
         iterator insert(const_iterator position, InputIterator first, InputIterator last);
+    template<container-compatible-range<T> R>
+      constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
     iterator insert(const_iterator position, initializer_list<value_type> il);
 
     iterator erase(const_iterator position);
@@ -247,14 +263,21 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
    vector(InputIterator, InputIterator, Allocator = Allocator())
    -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
 
+template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
+  vector(from_range_t, R&&, Allocator = Allocator())
+    -> vector<ranges::range_value_t<R>, Allocator>; // C++23
+
 template <class Allocator> struct hash<std::vector<bool, Allocator>>;
 
-template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
-template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
-template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
-template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
-template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
-template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // constexpr since C++20
+template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // removed in C++20
+template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // removed in C++20
+template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // removed in C++20
+template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // removed in C++20
+template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);   // removed in C++20
+template <class T, class Allocator> constexpr
+  constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x,
+                                                  const vector<T, Allocator>& y);                                  // since C++20
 
 template <class T, class Allocator>
 void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
@@ -262,10 +285,10 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
 
 template <class T, class Allocator, class U>
 typename vector<T, Allocator>::size_type
-erase(vector<T, Allocator>& c, const U& value);       // C++20
+erase(vector<T, Allocator>& c, const U& value);       // since C++20
 template <class T, class Allocator, class Predicate>
 typename vector<T, Allocator>::size_type
-erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20
+erase_if(vector<T, Allocator>& c, Predicate pred);    // since C++20
 
 
 template<class T>
@@ -281,44 +304,57 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
 #include <__algorithm/copy.h>
 #include <__algorithm/equal.h>
 #include <__algorithm/fill_n.h>
+#include <__algorithm/iterator_operations.h>
 #include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lexicographical_compare_three_way.h>
 #include <__algorithm/remove.h>
 #include <__algorithm/remove_if.h>
 #include <__algorithm/rotate.h>
 #include <__algorithm/unwrap_iter.h>
 #include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
 #include <__bit_reference>
 #include <__concepts/same_as.h>
 #include <__config>
-#include <__debug>
 #include <__format/enable_insertable.h>
 #include <__format/formatter.h>
+#include <__format/formatter_bool.h>
 #include <__functional/hash.h>
 #include <__functional/unary_function.h>
 #include <__iterator/advance.h>
+#include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
+#include <__memory/allocator_traits.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/temp_value.h>
 #include <__memory/uninitialized_algorithms.h>
 #include <__memory_resource/polymorphic_allocator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/from_range.h>
+#include <__ranges/size.h>
 #include <__split_buffer>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
 #include <__type_traits/noexcept_move_assign_container.h>
+#include <__type_traits/type_identity.h>
 #include <__utility/exception_guard.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
+#include <__utility/pair.h>
 #include <__utility/swap.h>
 #include <climits>
-#include <cstdlib>
 #include <cstring>
 #include <iosfwd> // for forward declaration of vector
 #include <limits>
 #include <stdexcept>
-#include <type_traits>
 #include <version>
 
 // standard-mandated includes
@@ -341,7 +377,6 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
@@ -376,7 +411,6 @@ public:
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
     {
-        std::__debug_db_insert_c(this);
     }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)
 #if _LIBCPP_STD_VER <= 14
@@ -386,10 +420,9 @@ public:
 #endif
         : __end_cap_(nullptr, __a)
     {
-        std::__debug_db_insert_c(this);
     }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a);
 #endif
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x);
@@ -399,7 +432,6 @@ public:
     vector(size_type __n, const value_type& __x, const allocator_type& __a)
         : __end_cap_(nullptr, __a)
     {
-      std::__debug_db_insert_c(this);
       if (__n > 0)
       {
           __vallocate(__n);
@@ -408,12 +440,12 @@ public:
     }
 
   template <class _InputIterator,
-            __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+            __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_InputIterator __first, _InputIterator __last);
   template <class _InputIterator,
-            __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+            __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
@@ -421,29 +453,41 @@ public:
 
   template <
       class _ForwardIterator,
-      __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+      __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_ForwardIterator __first, _ForwardIterator __last);
 
   template <class _ForwardIterator,
-      __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+      __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
   vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a);
 
+#if _LIBCPP_STD_VER >= 23
+  template <_ContainerCompatibleRange<_Tp> _Range>
+  _LIBCPP_HIDE_FROM_ABI constexpr vector(from_range_t, _Range&& __range,
+      const allocator_type& __alloc = allocator_type()) : __end_cap_(nullptr, __alloc) {
+    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+      auto __n = static_cast<size_type>(ranges::distance(__range));
+      __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
+
+    } else {
+      __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
+    }
+  }
+#endif
+
 private:
   class __destroy_vector {
     public:
-      _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
+      _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
 
       _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
-          __vec_.__annotate_delete();
-          std::__debug_db_erase_c(std::addressof(__vec_));
-
           if (__vec_.__begin_ != nullptr) {
             __vec_.__clear();
+            __vec_.__annotate_delete();
             __alloc_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.capacity());
           }
       }
@@ -474,7 +518,7 @@ public:
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     vector(vector&& __x)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         noexcept;
 #else
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
@@ -487,17 +531,31 @@ public:
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 
   template <class _InputIterator,
-            __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+            __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_InputIterator __first, _InputIterator __last);
   template <
       class _ForwardIterator,
-      __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+      __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void assign_range(_Range&& __range) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const_reference __u);
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -561,22 +619,22 @@ public:
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference       front() _NOEXCEPT
     {
-        _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
         return *this->__begin_;
     }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
         return *this->__begin_;
     }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference       back() _NOEXCEPT
     {
-        _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
         return *(this->__end_ - 1);
     }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back()  const _NOEXCEPT
     {
-        _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
+        _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
         return *(this->__end_ - 1);
     }
 
@@ -594,12 +652,20 @@ public:
 
     template <class... _Args>
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         reference emplace_back(_Args&&... __args);
 #else
         void      emplace_back(_Args&&... __args);
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void append_range(_Range&& __range) {
+      insert_range(end(), std::forward<_Range>(__range));
+    }
+#endif
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     void pop_back();
 
@@ -613,15 +679,29 @@ public:
     iterator insert(const_iterator __position, size_type __n, const_reference __x);
 
   template <class _InputIterator,
-            __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+            __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible< value_type, typename iterator_traits<_InputIterator>::reference>::value,
                           int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
   insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<_Tp> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
+
   template <
       class _ForwardIterator,
-      __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+      __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible< value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> = 0>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
@@ -642,7 +722,6 @@ public:
         size_type __old_size = size();
         __clear();
         __annotate_shrink(__old_size);
-        std::__debug_db_invalidate_all(this);
     }
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
@@ -658,23 +737,12 @@ public:
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-    bool __dereferenceable(const const_iterator* __i) const;
-    bool __decrementable(const const_iterator* __i) const;
-    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
-    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
 private:
     pointer __begin_ = nullptr;
     pointer __end_ = nullptr;
     __compressed_pair<pointer, allocator_type> __end_cap_ =
         __compressed_pair<pointer, allocator_type>(nullptr, __default_init_tag());
 
-    _LIBCPP_HIDE_FROM_ABI void __invalidate_iterators_past(pointer __new_last);
-
     //  Allocate space for __n objects
     //  throws length_error if __n > max_size()
     //  throws (probably bad_alloc) if memory run out
@@ -698,16 +766,56 @@ private:
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     void __construct_at_end(size_type __n, const_reference __x);
 
-  template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> = 0>
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-  __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) {
+      auto __guard = std::__make_exception_guard(__destroy_vector(*this));
+
+      if (__n > 0) {
+        __vallocate(__n);
+        __construct_at_end(__first, __last, __n);
+      }
+
+      __guard.__complete();
+    }
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __init_with_sentinel(_InputIterator __first, _Sentinel __last) {
+      auto __guard = std::__make_exception_guard(__destroy_vector(*this));
+
+      for (; __first != __last; ++__first)
+        emplace_back(*__first);
+
+      __guard.__complete();
+    }
+
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
+
+    template <class _ForwardIterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n);
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
+
+    template <class _Iterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+    void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
 
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    iterator       __make_iter(pointer __p) _NOEXCEPT { return iterator(this, __p); }
+    iterator       __make_iter(pointer __p) _NOEXCEPT { return iterator(__p); }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
-    const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(this, __p); }
+    const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(__p); }
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __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);
@@ -718,8 +826,6 @@ private:
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     void __destruct_at_end(pointer __new_last) _NOEXCEPT
     {
-        if (!__libcpp_is_constant_evaluated())
-            __invalidate_iterators_past(__new_last);
         size_type __old_size = size();
         __base_destruct_at_end(__new_last);
         __annotate_shrink(__old_size);
@@ -734,17 +840,19 @@ private:
     inline void __emplace_back_slow_path(_Args&&... __args);
 
     // The following functions are no-ops outside of AddressSanitizer mode.
-    // We call annotatations only for the default Allocator because other allocators
-    // may not meet the AddressSanitizer alignment constraints.
-    // See the documentation for __sanitizer_annotate_contiguous_container for more details.
+    // We call annotations for every allocator, unless explicitly disabled.
+    //
+    // To disable annotations for a particular allocator, change value of
+    // __asan_annotate_container_with_allocator to false.
+    // For more details, see the "Using libc++" documentation page or
+    // the documentation for __sanitizer_annotate_contiguous_container.
 #ifndef _LIBCPP_HAS_NO_ASAN
     _LIBCPP_CONSTEXPR_SINCE_CXX20
     void __annotate_contiguous_container(const void *__beg, const void *__end,
                                          const void *__old_mid,
                                          const void *__new_mid) const
     {
-
-      if (!__libcpp_is_constant_evaluated() && __beg && is_same<allocator_type, __default_allocator_type>::value)
+      if (!__libcpp_is_constant_evaluated() && __beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
         __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
     }
 #else
@@ -866,6 +974,7 @@ private:
     if (__alloc() != __c.__alloc())
     {
       __clear();
+      __annotate_delete();
       __alloc_traits::deallocate(__alloc(), this->__begin_, capacity());
       this->__begin_ = this->__end_ = __end_cap() = nullptr;
     }
@@ -892,7 +1001,7 @@ private:
 #if _LIBCPP_STD_VER >= 17
 template<class _InputIterator,
          class _Alloc = allocator<__iter_value_type<_InputIterator>>,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 vector(_InputIterator, _InputIterator)
@@ -900,13 +1009,22 @@ vector(_InputIterator, _InputIterator)
 
 template<class _InputIterator,
          class _Alloc,
-         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
          class = enable_if_t<__is_allocator<_Alloc>::value>
          >
 vector(_InputIterator, _InputIterator, _Alloc)
   -> vector<__iter_value_type<_InputIterator>, _Alloc>;
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+template <ranges::input_range _Range,
+          class _Alloc = allocator<ranges::range_value_t<_Range>>,
+          class = enable_if_t<__is_allocator<_Alloc>::value>
+          >
+vector(from_range_t, _Range&&, _Alloc = _Alloc())
+  -> vector<ranges::range_value_t<_Range>, _Alloc>;
+#endif
+
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 void
@@ -922,7 +1040,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
     std::swap(this->__end_cap(), __v.__end_cap());
     __v.__first_ = __v.__begin_;
     __annotate_new(size());
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Tp, class _Allocator>
@@ -942,7 +1059,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
     std::swap(this->__end_cap(), __v.__end_cap());
     __v.__first_ = __v.__begin_;
     __annotate_new(size());
-    std::__debug_db_invalidate_all(this);
     return __r;
 }
 
@@ -954,6 +1070,7 @@ vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
     if (this->__begin_ != nullptr)
     {
         clear();
+        __annotate_delete();
         __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
         this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
     }
@@ -1021,10 +1138,9 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 }
 
 template <class _Tp, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> >
+template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
-{
+vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
   _ConstructTransaction __tx(*this, __n);
   __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
 }
@@ -1074,7 +1190,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(size_type __n)
 {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
     if (__n > 0)
     {
         __vallocate(__n);
@@ -1083,14 +1198,13 @@ vector<_Tp, _Allocator>::vector(size_type __n)
     __guard.__complete();
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
     : __end_cap_(nullptr, __a)
 {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
     if (__n > 0)
     {
         __vallocate(__n);
@@ -1105,7 +1219,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
 {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
     if (__n > 0)
     {
         __vallocate(__n);
@@ -1115,69 +1228,47 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
 }
 
 template <class _Tp, class _Allocator>
-template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
                           int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last)
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    for (; __first != __last; ++__first)
-        emplace_back(*__first);
-    __guard.__complete();
+  __init_with_sentinel(__first, __last);
 }
 
 template <class _Tp, class _Allocator>
-template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
                           int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
     : __end_cap_(nullptr, __a)
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    for (; __first != __last; ++__first)
-        emplace_back(*__first);
-    __guard.__complete();
+  __init_with_sentinel(__first, __last);
 }
 
 template <class _Tp, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last)
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__first, __last, __n);
-    }
-    __guard.__complete();
+  size_type __n = static_cast<size_type>(std::distance(__first, __last));
+  __init_with_size(__first, __last, __n);
 }
 
 template <class _Tp, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
     : __end_cap_(nullptr, __a)
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__first, __last, __n);
-    }
-    __guard.__complete();
+  size_type __n = static_cast<size_type>(std::distance(__first, __last));
+  __init_with_size(__first, __last, __n);
 }
 
 template <class _Tp, class _Allocator>
@@ -1185,15 +1276,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(const vector& __x)
     : __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    size_type __n = __x.size();
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__x.__begin_, __x.__end_, __n);
-    }
-    __guard.__complete();
+  __init_with_size(__x.__begin_, __x.__end_, __x.size());
 }
 
 template <class _Tp, class _Allocator>
@@ -1201,30 +1284,20 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
     : __end_cap_(nullptr, __a)
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
-    size_type __n = __x.size();
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__x.__begin_, __x.__end_, __n);
-    }
-    __guard.__complete();
+  __init_with_size(__x.__begin_, __x.__end_, __x.size());
 }
 
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 vector<_Tp, _Allocator>::vector(vector&& __x)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         noexcept
 #else
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
 #endif
     : __end_cap_(nullptr, std::move(__x.__alloc()))
 {
-    std::__debug_db_insert_c(this);
-    std::__debug_db_swap(this, std::addressof(__x));
     this->__begin_ = __x.__begin_;
     this->__end_ = __x.__end_;
     this->__end_cap() = __x.__end_cap();
@@ -1237,14 +1310,12 @@ inline _LIBCPP_HIDE_FROM_ABI
 vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
     : __end_cap_(nullptr, __a)
 {
-    std::__debug_db_insert_c(this);
     if (__a == __x.__alloc())
     {
         this->__begin_ = __x.__begin_;
         this->__end_ = __x.__end_;
         this->__end_cap() = __x.__end_cap();
         __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
-        std::__debug_db_swap(this, std::addressof(__x));
     }
     else
     {
@@ -1263,7 +1334,6 @@ inline _LIBCPP_HIDE_FROM_ABI
 vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
 {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
     if (__il.size() > 0)
     {
         __vallocate(__il.size());
@@ -1279,7 +1349,6 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocat
     : __end_cap_(nullptr, __a)
 {
     auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    std::__debug_db_insert_c(this);
     if (__il.size() > 0)
     {
         __vallocate(__il.size());
@@ -1329,7 +1398,6 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
     this->__end_ = __c.__end_;
     this->__end_cap() = __c.__end_cap();
     __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
-    std::__debug_db_swap(this, std::addressof(__c));
 }
 
 template <class _Tp, class _Allocator>
@@ -1347,40 +1415,52 @@ vector<_Tp, _Allocator>::operator=(const vector& __x)
 }
 
 template <class _Tp, class _Allocator>
-template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
                           int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
+  __assign_with_sentinel(__first, __last);
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+void vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
     clear();
     for (; __first != __last; ++__first)
         emplace_back(*__first);
 }
 
 template <class _Tp, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
 {
-    size_type __new_size = static_cast<size_type>(std::distance(__first, __last));
+  __assign_with_size(__first, __last, std::distance(__first, __last));
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+void vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
+    size_type __new_size = static_cast<size_type>(__n);
     if (__new_size <= capacity())
     {
-        _ForwardIterator __mid = __last;
-        bool __growing = false;
         if (__new_size > size())
         {
-            __growing = true;
-            __mid =  __first;
-            std::advance(__mid, size());
-        }
-        pointer __m = std::copy(__first, __mid, this->__begin_);
-        if (__growing)
+            _ForwardIterator __mid = std::next(__first, size());
+            std::copy(__first, __mid, this->__begin_);
             __construct_at_end(__mid, __last, __new_size - size());
+        }
         else
+        {
+            pointer __m = std::__copy<_ClassicAlgPolicy>(__first, __last, this->__begin_).second;
             this->__destruct_at_end(__m);
+        }
     }
     else
     {
@@ -1388,7 +1468,6 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las
         __vallocate(__recommend(__new_size));
         __construct_at_end(__first, __last, __new_size);
     }
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Tp, class _Allocator>
@@ -1411,7 +1490,6 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
         __vallocate(__recommend(static_cast<size_type>(__n)));
         __construct_at_end(__n, __u);
     }
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Tp, class _Allocator>
@@ -1456,7 +1534,7 @@ inline _LIBCPP_HIDE_FROM_ABI
 typename vector<_Tp, _Allocator>::reference
 vector<_Tp, _Allocator>::operator[](size_type __n) _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
     return this->__begin_[__n];
 }
 
@@ -1466,7 +1544,7 @@ inline _LIBCPP_HIDE_FROM_ABI
 typename vector<_Tp, _Allocator>::const_reference
 vector<_Tp, _Allocator>::operator[](size_type __n) const _NOEXCEPT
 {
-    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
     return this->__begin_[__n];
 }
 
@@ -1512,19 +1590,19 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
 {
     if (capacity() > size())
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             allocator_type& __a = this->__alloc();
             __split_buffer<value_type, allocator_type&> __v(size(), size(), __a);
             __swap_out_circular_buffer(__v);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -1588,7 +1666,7 @@ template <class _Tp, class _Allocator>
 template <class... _Args>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 inline
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 typename vector<_Tp, _Allocator>::reference
 #else
 void
@@ -1601,7 +1679,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
     }
     else
         __emplace_back_slow_path(std::forward<_Args>(__args)...);
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     return this->back();
 #endif
 }
@@ -1612,7 +1690,7 @@ inline
 void
 vector<_Tp, _Allocator>::pop_back()
 {
-    _LIBCPP_ASSERT(!empty(), "vector::pop_back called on an empty vector");
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector");
     this->__destruct_at_end(this->__end_ - 1);
 }
 
@@ -1622,15 +1700,11 @@ inline _LIBCPP_HIDE_FROM_ABI
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __position)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::erase(iterator) called with an iterator not referring to this vector");
-    _LIBCPP_ASSERT(__position != end(),
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__position != end(),
         "vector::erase(iterator) called with a non-dereferenceable iterator");
     difference_type __ps = __position - cbegin();
     pointer __p = this->__begin_ + __ps;
     this->__destruct_at_end(std::move(__p + 1, this->__end_, __p));
-    if (!__libcpp_is_constant_evaluated())
-        this->__invalidate_iterators_past(__p - 1);
     return __make_iter(__p);
 }
 
@@ -1639,17 +1713,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__first)) == this,
-                         "vector::erase(iterator, iterator) called with an iterator not referring to this vector");
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__last)) == this,
-                         "vector::erase(iterator, iterator) called with an iterator not referring to this vector");
-
-    _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
     pointer __p = this->__begin_ + (__first - begin());
     if (__first != __last) {
         this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p));
-        if (!__libcpp_is_constant_evaluated())
-            this->__invalidate_iterators_past(__p - 1);
     }
     return __make_iter(__p);
 }
@@ -1679,8 +1746,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::insert(iterator, x) called with an iterator not referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     // We can't compare unrelated pointers inside constant expressions
     if (!__libcpp_is_constant_evaluated() && this->__end_ < this->__end_cap())
@@ -1713,8 +1778,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::insert(iterator, x) called with an iterator not referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
@@ -1744,8 +1807,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::emplace(iterator, x) called with an iterator not referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
@@ -1775,8 +1836,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::insert(iterator, n, x) called with an iterator not referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (__n > 0)
     {
@@ -1810,16 +1869,21 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
     }
     return __make_iter(__p);
 }
-
 template <class _Tp, class _Allocator>
-template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
+template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
                               is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
                           int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::insert(iterator, range) called with an iterator not referring to this vector");
+  return __insert_with_sentinel(__position, __first, __last);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
     difference_type __off = __position - begin();
     pointer __p = this->__begin_ + __off;
     allocator_type& __a = this->__alloc();
@@ -1831,24 +1895,24 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
     __split_buffer<value_type, allocator_type&> __v(__a);
     if (__first != __last)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
-            __v.__construct_at_end(__first, __last);
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+            __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
             difference_type __old_size = __old_last - this->__begin_;
             difference_type __old_p = __p - this->__begin_;
             reserve(__recommend(size() + __v.size()));
             __p = this->__begin_ + __old_p;
             __old_last = this->__begin_ + __old_size;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             erase(__make_iter(__old_last), end());
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     __p = std::rotate(__p, __old_last, this->__end_);
     insert(__make_iter(__p), std::make_move_iterator(__v.begin()),
@@ -1857,23 +1921,30 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
 }
 
 template <class _Tp, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
                         is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
                     int> >
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
 {
-    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
-                         "vector::insert(iterator, range) called with an iterator not referring to this vector");
+  return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
+}
+
+template <class _Tp, class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last,
+                                            difference_type __n) {
+    auto __insertion_size = __n;
     pointer __p = this->__begin_ + (__position - begin());
-    difference_type __n = std::distance(__first, __last);
     if (__n > 0)
     {
         if (__n <= this->__end_cap() - this->__end_)
         {
             size_type __old_n = __n;
             pointer __old_last = this->__end_;
-            _ForwardIterator __m = __last;
+            _Iterator __m = std::next(__first, __n);
             difference_type __dx = this->__end_ - __p;
             if (__n > __dx)
             {
@@ -1893,7 +1964,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi
         {
             allocator_type& __a = this->__alloc();
             __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
-            __v.__construct_at_end(__first, __last);
+            __v.__construct_at_end_with_size(__first, __insertion_size);
             __p = __swap_out_circular_buffer(__v, __p);
         }
     }
@@ -1935,16 +2006,15 @@ vector<_Tp, _Allocator>::swap(vector& __x)
                 __is_nothrow_swappable<allocator_type>::value)
 #endif
 {
-    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
-                   this->__alloc() == __x.__alloc(),
-                   "vector::swap: Either propagate_on_container_swap must be true"
-                   " or the allocators must compare equal");
+    _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"
+                                        " or the allocators must compare equal");
     std::swap(this->__begin_, __x.__begin_);
     std::swap(this->__end_, __x.__end_);
     std::swap(this->__end_cap(), __x.__end_cap());
     std::__swap_allocator(this->__alloc(), __x.__alloc(),
         integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
-    std::__debug_db_swap(this, std::addressof(__x));
 }
 
 template <class _Tp, class _Allocator>
@@ -1969,61 +2039,6 @@ vector<_Tp, _Allocator>::__invariants() const
     return true;
 }
 
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-
-template <class _Tp, class _Allocator>
-bool
-vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
-{
-    return this->__begin_ <= __i->base() && __i->base() < this->__end_;
-}
-
-template <class _Tp, class _Allocator>
-bool
-vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
-{
-    return this->__begin_ < __i->base() && __i->base() <= this->__end_;
-}
-
-template <class _Tp, class _Allocator>
-bool
-vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
-{
-    const_pointer __p = __i->base() + __n;
-    return this->__begin_ <= __p && __p <= this->__end_;
-}
-
-template <class _Tp, class _Allocator>
-bool
-vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
-{
-    const_pointer __p = __i->base() + __n;
-    return this->__begin_ <= __p && __p < this->__end_;
-}
-
-#endif // _LIBCPP_ENABLE_DEBUG_MODE
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI
-void
-vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) {
-#ifdef _LIBCPP_ENABLE_DEBUG_MODE
-  __c_node* __c = __get_db()->__find_c_and_lock(this);
-  for (__i_node** __p = __c->end_; __p != __c->beg_; ) {
-    --__p;
-    const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-    if (__i->base() > __new_last) {
-      (*__p)->__c_ = nullptr;
-      if (--__c->end_ != __p)
-        std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
-    }
-  }
-  __get_db()->unlock();
-#else
-  ((void)__new_last);
-#endif
-}
-
 // vector<bool>
 
 template <class _Allocator> class vector<bool, _Allocator>;
@@ -2107,12 +2122,11 @@ public:
 private:
   class __destroy_vector {
     public:
-      _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
+      _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
 
       _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
         if (__vec_.__begin_ != nullptr)
             __storage_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.__cap());
-        std::__debug_db_invalidate_all(this);
       }
 
     private:
@@ -2123,23 +2137,40 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector(*this)(); }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a);
 #endif
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a);
     template <class _InputIterator>
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last,
-               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
+               typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0);
     template <class _InputIterator>
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
+               typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0);
     template <class _ForwardIterator>
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last,
-               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
+               typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
     template <class _ForwardIterator>
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
-               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
+               typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
+
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<bool> _Range>
+    _LIBCPP_HIDE_FROM_ABI constexpr
+    vector(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a)) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a);
@@ -2157,7 +2188,7 @@ public:
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     vector(vector&& __v)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         noexcept;
 #else
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
@@ -2168,18 +2199,32 @@ public:
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 
     template <class _InputIterator>
-        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
+        typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
            void
         >::type
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last);
     template <class _ForwardIterator>
         typename enable_if
         <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
+            __has_forward_iterator_category<_ForwardIterator>::value,
            void
         >::type
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<bool> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void assign_range(_Range&& __range) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x);
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -2254,24 +2299,32 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back()  const {return __make_ref(__size_ - 1);}
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x);
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <class... _Args>
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference emplace_back(_Args&&... __args)
 #else
     _LIBCPP_HIDE_FROM_ABI void      emplace_back(_Args&&... __args)
 #endif
     {
         push_back ( value_type ( std::forward<_Args>(__args)... ));
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
         return this->back();
 #endif
     }
 #endif
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<bool> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void append_range(_Range&& __range) {
+      insert_range(end(), std::forward<_Range>(__range));
+    }
+#endif
+
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() {--__size_;}
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
     template <class... _Args>
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator emplace(const_iterator __position, _Args&&... __args)
         { return insert ( __position, value_type ( std::forward<_Args>(__args)... )); }
@@ -2280,18 +2333,32 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, const value_type& __x);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, size_type __n, const value_type& __x);
     template <class _InputIterator>
-        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
+        typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
             iterator
         >::type
         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
     template <class _ForwardIterator>
         typename enable_if
         <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
+            __has_forward_iterator_category<_ForwardIterator>::value,
             iterator
         >::type
         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
 
+#if _LIBCPP_STD_VER >= 23
+    template <_ContainerCompatibleRange<bool> _Range>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
+      if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
+        auto __n = static_cast<size_type>(ranges::distance(__range));
+        return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
+
+      } else {
+        return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
+      }
+    }
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     iterator insert(const_iterator __position, initializer_list<value_type> __il)
@@ -2304,7 +2371,7 @@ public:
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     void clear() _NOEXCEPT {__size_ = 0;}
 
-    _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
 #if _LIBCPP_STD_VER >= 14
         _NOEXCEPT;
 #else
@@ -2329,6 +2396,52 @@ private:
         std::__throw_out_of_range("vector");
     }
 
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) {
+      auto __guard = std::__make_exception_guard(__destroy_vector(*this));
+
+      if (__n > 0) {
+        __vallocate(__n);
+        __construct_at_end(std::move(__first), std::move(__last), __n);
+      }
+
+      __guard.__complete();
+    }
+
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    void __init_with_sentinel(_InputIterator __first, _Sentinel __last) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+      try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+        for (; __first != __last; ++__first)
+            push_back(*__first);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+      } catch (...) {
+        if (__begin_ != nullptr)
+          __storage_traits::deallocate(__alloc(), __begin_, __cap());
+        throw;
+      }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+    }
+
+  template <class _Iterator, class _Sentinel>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
+
+  template <class _ForwardIterator, class _Sentinel>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns);
+
+  template <class _InputIterator, class _Sentinel>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
+
+  template <class _Iterator, class _Sentinel>
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+  iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
+
     //  Allocate space for __n objects
     //  throws length_error if __n > max_size()
     //  throws (probably bad_alloc) if memory run out
@@ -2355,13 +2468,9 @@ private:
         {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20  size_type __recommend(size_type __new_size) const;
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x);
-    template <class _ForwardIterator>
-        typename enable_if
-        <
-            __is_cpp17_forward_iterator<_ForwardIterator>::value,
-            void
-        >::type
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _InputIterator, class _Sentinel>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+    void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x);
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
     reference __make_ref(size_type __pos) _NOEXCEPT
@@ -2436,7 +2545,6 @@ vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
     if (this->__begin_ != nullptr)
     {
         __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
-        std::__debug_db_invalidate_all(this);
         this->__begin_ = nullptr;
         this->__size_ = this->__cap() = 0;
     }
@@ -2491,17 +2599,11 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
 }
 
 template <class _Allocator>
-template <class _ForwardIterator>
+template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
-typename enable_if
-<
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
-    void
->::type
-vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
-{
+void vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
     size_type __old_size = this->__size_;
-    this->__size_ += std::distance(__first, __last);
+    this->__size_ += __n;
     if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word))
     {
         if (this->__size_ <= __bits_per_word)
@@ -2509,7 +2611,7 @@ vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardI
         else
             this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
     }
-    std::copy(__first, __last, __make_iter(__old_size));
+    std::__copy<_ClassicAlgPolicy>(__first, __last, __make_iter(__old_size));
 }
 
 template <class _Allocator>
@@ -2550,7 +2652,7 @@ vector<bool, _Allocator>::vector(size_type __n)
     }
 }
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 template <class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
@@ -2598,92 +2700,50 @@ template <class _Allocator>
 template <class _InputIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
-       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
+       typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __default_init_tag())
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
-    {
-#endif // _LIBCPP_NO_EXCEPTIONS
-        for (; __first != __last; ++__first)
-            push_back(*__first);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        if (__begin_ != nullptr)
-            __storage_traits::deallocate(__alloc(), __begin_, __cap());
-        std::__debug_db_invalidate_all(this);
-        throw;
-    }
-#endif // _LIBCPP_NO_EXCEPTIONS
+  __init_with_sentinel(__first, __last);
 }
 
 template <class _Allocator>
 template <class _InputIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
+       typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
-    {
-#endif // _LIBCPP_NO_EXCEPTIONS
-        for (; __first != __last; ++__first)
-            push_back(*__first);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        if (__begin_ != nullptr)
-            __storage_traits::deallocate(__alloc(), __begin_, __cap());
-        std::__debug_db_invalidate_all(this);
-        throw;
-    }
-#endif // _LIBCPP_NO_EXCEPTIONS
+  __init_with_sentinel(__first, __last);
 }
 
 template <class _Allocator>
 template <class _ForwardIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
-                                typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
+                                typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __default_init_tag())
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__first, __last);
-    }
-    __guard.__complete();
+  auto __n = static_cast<size_type>(std::distance(__first, __last));
+  __init_with_size(__first, __last, __n);
 }
 
 template <class _Allocator>
 template <class _ForwardIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
-                                typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
+                                typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
-    if (__n > 0)
-    {
-        __vallocate(__n);
-        __construct_at_end(__first, __last);
-    }
-    __guard.__complete();
+  auto __n = static_cast<size_type>(std::distance(__first, __last));
+  __init_with_size(__first, __last, __n);
 }
 
 #ifndef _LIBCPP_CXX03_LANG
@@ -2699,7 +2759,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
     if (__n > 0)
     {
         __vallocate(__n);
-        __construct_at_end(__il.begin(), __il.end());
+        __construct_at_end(__il.begin(), __il.end(), __n);
     }
 }
 
@@ -2714,7 +2774,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
     if (__n > 0)
     {
         __vallocate(__n);
-        __construct_at_end(__il.begin(), __il.end());
+        __construct_at_end(__il.begin(), __il.end(), __n);
     }
 }
 
@@ -2730,7 +2790,7 @@ vector<bool, _Allocator>::vector(const vector& __v)
     if (__v.size() > 0)
     {
         __vallocate(__v.size());
-        __construct_at_end(__v.begin(), __v.end());
+        __construct_at_end(__v.begin(), __v.end(), __v.size());
     }
 }
 
@@ -2744,7 +2804,7 @@ vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
     if (__v.size() > 0)
     {
         __vallocate(__v.size());
-        __construct_at_end(__v.begin(), __v.end());
+        __construct_at_end(__v.begin(), __v.end(), __v.size());
     }
 }
 
@@ -2772,7 +2832,7 @@ vector<bool, _Allocator>::operator=(const vector& __v)
 
 template <class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v)
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
     _NOEXCEPT
 #else
     _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
@@ -2803,7 +2863,7 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
     else if (__v.size() > 0)
     {
         __vallocate(__v.size());
-        __construct_at_end(__v.begin(), __v.end());
+        __construct_at_end(__v.begin(), __v.end(), __v.size());
     }
 }
 
@@ -2861,16 +2921,22 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
         }
         std::fill_n(begin(), __n, __x);
     }
-    std::__debug_db_invalidate_all(this);
 }
 
 template <class _Allocator>
 template <class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
    void
 >::type
 vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
+  __assign_with_sentinel(__first, __last);
+}
+
+template <class _Allocator>
+template <class _Iterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+void vector<bool, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
     clear();
     for (; __first != __last; ++__first)
         push_back(*__first);
@@ -2881,14 +2947,22 @@ template <class _ForwardIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
+    __has_forward_iterator_category<_ForwardIterator>::value,
    void
 >::type
 vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
 {
+  __assign_with_size(__first, __last, std::distance(__first, __last));
+}
+
+template <class _Allocator>
+template <class _ForwardIterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+void vector<bool, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns) {
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns >= 0, "invalid range specified");
+
     clear();
-    difference_type __ns = std::distance(__first, __last);
-    _LIBCPP_ASSERT(__ns >= 0, "invalid range specified");
+
     const size_t __n = static_cast<size_type>(__ns);
     if (__n)
     {
@@ -2897,7 +2971,7 @@ vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __la
             __vdeallocate();
             __vallocate(__n);
         }
-        __construct_at_end(__first, __last);
+        __construct_at_end(__first, __last, __n);
     }
 }
 
@@ -2911,9 +2985,8 @@ vector<bool, _Allocator>::reserve(size_type __n)
             this->__throw_length_error();
         vector __v(this->get_allocator());
         __v.__vallocate(__n);
-        __v.__construct_at_end(this->begin(), this->end());
+        __v.__construct_at_end(this->begin(), this->end(), this->size());
         swap(__v);
-        std::__debug_db_invalidate_all(this);
     }
 }
 
@@ -2923,17 +2996,17 @@ vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT
 {
     if (__external_cap_to_internal(size()) > __cap())
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             vector(*this, allocator_type(__alloc())).swap(*this);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 }
 
@@ -3018,11 +3091,19 @@ vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const
 
 template <class _Allocator>
 template <class _InputIterator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
+_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
     typename vector<bool, _Allocator>::iterator
 >::type
 vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
 {
+  return __insert_with_sentinel(__position, __first, __last);
+}
+
+template <class _Allocator>
+template <class _InputIterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
     difference_type __off = __position - begin();
     iterator __p = __const_iterator_cast(__position);
     iterator __old_end = end();
@@ -3034,24 +3115,24 @@ vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __fir
     vector __v(get_allocator());
     if (__first != __last)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
-            __v.assign(__first, __last);
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+            __v.__assign_with_sentinel(std::move(__first), std::move(__last));
             difference_type __old_size = static_cast<difference_type>(__old_end - begin());
             difference_type __old_p = __p - begin();
             reserve(__recommend(size() + __v.size()));
             __p = begin() + __old_p;
             __old_end = begin() + __old_size;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             erase(__old_end, end());
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     __p = std::rotate(__p, __old_end, end());
     insert(__p, __v.begin(), __v.end());
@@ -3063,13 +3144,21 @@ template <class _ForwardIterator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 typename enable_if
 <
-    __is_cpp17_forward_iterator<_ForwardIterator>::value,
+    __has_forward_iterator_category<_ForwardIterator>::value,
     typename vector<bool, _Allocator>::iterator
 >::type
 vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
 {
-    const difference_type __n_signed = std::distance(__first, __last);
-    _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified");
+  return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
+}
+
+template <class _Allocator>
+template <class _ForwardIterator, class _Sentinel>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last,
+                                             difference_type __n_signed) {
+    _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed >= 0, "invalid range specified");
     const size_type __n = static_cast<size_type>(__n_signed);
     iterator __r;
     size_type __c = capacity();
@@ -3089,7 +3178,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __f
         std::copy_backward(__position, cend(), __v.end());
         swap(__v);
     }
-    std::copy(__first, __last, __r);
+    std::__copy<_ClassicAlgPolicy>(__first, __last, __r);
     return __r;
 }
 
@@ -3238,8 +3327,9 @@ operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
     return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
 }
 
+#if _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 bool
 operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
@@ -3248,7 +3338,6 @@ operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 bool
 operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
@@ -3257,7 +3346,6 @@ operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 bool
 operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
@@ -3266,7 +3354,6 @@ operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 bool
 operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
@@ -3275,7 +3362,6 @@ operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
 bool
 operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
@@ -3283,6 +3369,17 @@ operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
     return !(__y < __x);
 }
 
+#else // _LIBCPP_STD_VER <= 17
+
+template <class _Tp, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
+operator<=>(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) {
+    return std::lexicographical_compare_three_way(
+        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
 template <class _Tp, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI
@@ -3293,7 +3390,7 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
     __x.swap(__y);
 }
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Up>
 _LIBCPP_CONSTEXPR_SINCE_CXX20
 inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type
@@ -3319,15 +3416,15 @@ template <>
 inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
 #endif
 
-#endif // _LIBCPP_STD_VER > 17
+#endif // _LIBCPP_STD_VER >= 20
 
-#if _LIBCPP_STD_VER > 20
-template <class _Tp, class CharT>
+#if _LIBCPP_STD_VER >= 23
+template <class _Tp, class _CharT>
 // Since is-vector-bool-reference is only used once it's inlined here.
   requires same_as<typename _Tp::__container, vector<bool, typename _Tp::__container::allocator_type>>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<_Tp, _CharT> {
 private:
-  formatter<bool, CharT> __underlying_;
+  formatter<bool, _CharT> __underlying_;
 
 public:
   template <class _ParseContext>
@@ -3340,15 +3437,15 @@ public:
         return __underlying_.format(__ref, __ctx);
   }
 };
-#endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace pmr {
 template <class _ValueT>
-using vector = std::vector<_ValueT, polymorphic_allocator<_ValueT>>;
+using vector _LIBCPP_AVAILABILITY_PMR = std::vector<_ValueT, polymorphic_allocator<_ValueT>>;
 } // namespace pmr
 _LIBCPP_END_NAMESPACE_STD
 #endif
@@ -3359,6 +3456,8 @@ _LIBCPP_POP_MACROS
 #  include <algorithm>
 #  include <atomic>
 #  include <concepts>
+#  include <cstdlib>
+#  include <type_traits>
 #  include <typeinfo>
 #  include <utility>
 #endif
lib/libcxx/include/version
@@ -28,6 +28,8 @@ __cpp_lib_array_constexpr                               201811L <array> <iterato
 __cpp_lib_as_const                                      201510L <utility>
 __cpp_lib_associative_heterogeneous_erasure             202110L <map> <set> <unordered_map>
                                                                 <unordered_set>
+__cpp_lib_associative_heterogeneous_insertion           202306L <map> <set> <unordered_map>
+                                                                <unordered_set>
 __cpp_lib_assume_aligned                                201811L <memory>
 __cpp_lib_atomic_flag_test                              201907L <atomic>
 __cpp_lib_atomic_float                                  201711L <atomic>
@@ -38,10 +40,13 @@ __cpp_lib_atomic_shared_ptr                             201711L <atomic>
 __cpp_lib_atomic_value_initialization                   201911L <atomic> <memory>
 __cpp_lib_atomic_wait                                   201907L <atomic>
 __cpp_lib_barrier                                       201907L <barrier>
-__cpp_lib_bind_back                                     202202L <functional>
-__cpp_lib_bind_front                                    201907L <functional>
+__cpp_lib_bind_back                                     202306L <functional>
+                                                        202202L // C++23
+__cpp_lib_bind_front                                    202306L <functional>
+                                                        201907L // C++20
 __cpp_lib_bit_cast                                      201806L <bit>
 __cpp_lib_bitops                                        201907L <bit>
+__cpp_lib_bitset                                        202306L <bitset>
 __cpp_lib_bool_constant                                 201505L <type_traits>
 __cpp_lib_bounded_array_traits                          201902L <type_traits>
 __cpp_lib_boyer_moore_searcher                          201603L <functional>
@@ -72,6 +77,7 @@ __cpp_lib_constexpr_tuple                               201811L <tuple>
 __cpp_lib_constexpr_typeinfo                            202106L <typeinfo>
 __cpp_lib_constexpr_utility                             201811L <utility>
 __cpp_lib_constexpr_vector                              201907L <vector>
+__cpp_lib_copyable_function                             202306L <functional>
 __cpp_lib_coroutine                                     201902L <coroutine>
 __cpp_lib_destroying_delete                             201806L <new>
 __cpp_lib_enable_shared_from_this                       201603L <memory>
@@ -82,15 +88,20 @@ __cpp_lib_erase_if                                      202002L <deque> <forward
 __cpp_lib_exchange_function                             201304L <utility>
 __cpp_lib_execution                                     201902L <execution>
                                                         201603L // C++17
-__cpp_lib_expected                                      202202L <expected>
+__cpp_lib_expected                                      202211L <expected>
 __cpp_lib_filesystem                                    201703L <filesystem>
 __cpp_lib_format                                        202106L <format>
+__cpp_lib_format_ranges                                 202207L <format>
+__cpp_lib_formatters                                    202302L <stacktrace> <thread>
 __cpp_lib_forward_like                                  202207L <utility>
+__cpp_lib_fstream_native_handle                         202306L <fstream>
+__cpp_lib_function_ref                                  202306L <functional>
 __cpp_lib_gcd_lcm                                       201606L <numeric>
 __cpp_lib_generic_associative_lookup                    201304L <map> <set>
 __cpp_lib_generic_unordered_lookup                      201811L <unordered_map> <unordered_set>
 __cpp_lib_hardware_interference_size                    201703L <new>
 __cpp_lib_has_unique_object_representations             201606L <type_traits>
+__cpp_lib_hazard_pointer                                202306L <hazard_pointer>
 __cpp_lib_hypot                                         201603L <cmath>
 __cpp_lib_incomplete_container_elements                 201505L <forward_list> <list> <vector>
 __cpp_lib_int_pow2                                      202002L <bit>
@@ -121,7 +132,9 @@ __cpp_lib_make_unique                                   201304L <memory>
 __cpp_lib_map_try_emplace                               201411L <map>
 __cpp_lib_math_constants                                201907L <numbers>
 __cpp_lib_math_special_functions                        201603L <cmath>
+__cpp_lib_mdspan                                        202207L <mdspan>
 __cpp_lib_memory_resource                               201603L <memory_resource>
+__cpp_lib_move_iterator_concept                         202207L <iterator>
 __cpp_lib_move_only_function                            202110L <functional>
 __cpp_lib_node_extract                                  201606L <map> <set> <unordered_map>
                                                                 <unordered_set>
@@ -136,22 +149,26 @@ __cpp_lib_optional                                      202110L <optional>
 __cpp_lib_out_ptr                                       202106L <memory>
 __cpp_lib_parallel_algorithm                            201603L <algorithm> <numeric>
 __cpp_lib_polymorphic_allocator                         201902L <memory_resource>
+__cpp_lib_print                                         202207L <ostream> <print>
 __cpp_lib_quoted_string_io                              201304L <iomanip>
-__cpp_lib_ranges                                        202106L <algorithm> <functional> <iterator>
+__cpp_lib_ranges                                        202207L <algorithm> <functional> <iterator>
                                                                 <memory> <ranges>
 __cpp_lib_ranges_as_rvalue                              202207L <ranges>
 __cpp_lib_ranges_chunk                                  202202L <ranges>
 __cpp_lib_ranges_chunk_by                               202202L <ranges>
 __cpp_lib_ranges_iota                                   202202L <numeric>
 __cpp_lib_ranges_join_with                              202202L <ranges>
+__cpp_lib_ranges_repeat                                 202207L <ranges>
 __cpp_lib_ranges_slide                                  202202L <ranges>
 __cpp_lib_ranges_starts_ends_with                       202106L <algorithm>
 __cpp_lib_ranges_to_container                           202202L <deque> <forward_list> <list>
-                                                                <map> <priority_queue> <queue>
+                                                                <map> <queue> <ranges>
                                                                 <set> <stack> <string>
                                                                 <unordered_map> <unordered_set> <vector>
 __cpp_lib_ranges_zip                                    202110L <ranges> <tuple> <utility>
+__cpp_lib_ratio                                         202306L <ratio>
 __cpp_lib_raw_memory_algorithms                         201606L <memory>
+__cpp_lib_rcu                                           202306L <rcu>
 __cpp_lib_reference_from_temporary                      202202L <type_traits>
 __cpp_lib_remove_cvref                                  201711L <type_traits>
 __cpp_lib_result_of_sfinae                              201210L <functional> <type_traits>
@@ -166,10 +183,12 @@ __cpp_lib_shared_ptr_weak_type                          201606L <memory>
 __cpp_lib_shared_timed_mutex                            201402L <shared_mutex>
 __cpp_lib_shift                                         201806L <algorithm>
 __cpp_lib_smart_ptr_for_overwrite                       202002L <memory>
+__cpp_lib_smart_ptr_owner_equality                      202306L <memory>
 __cpp_lib_source_location                               201907L <source_location>
 __cpp_lib_span                                          202002L <span>
 __cpp_lib_spanstream                                    202106L <spanstream>
 __cpp_lib_ssize                                         201902L <iterator>
+__cpp_lib_sstream_from_string_view                      202306L <sstream>
 __cpp_lib_stacktrace                                    202011L <stacktrace>
 __cpp_lib_starts_ends_with                              201711L <string> <string_view>
 __cpp_lib_stdatomic_h                                   202011L <stdatomic.h>
@@ -178,11 +197,14 @@ __cpp_lib_string_resize_and_overwrite                   202110L <string>
 __cpp_lib_string_udls                                   201304L <string>
 __cpp_lib_string_view                                   201803L <string> <string_view>
                                                         201606L // C++17
+__cpp_lib_submdspan                                     202306L <mdspan>
 __cpp_lib_syncbuf                                       201803L <syncstream>
+__cpp_lib_text_encoding                                 202306L <text_encoding>
 __cpp_lib_three_way_comparison                          201907L <compare>
 __cpp_lib_to_address                                    201711L <memory>
 __cpp_lib_to_array                                      201907L <array>
 __cpp_lib_to_chars                                      201611L <charconv>
+__cpp_lib_to_string                                     202306L <string>
 __cpp_lib_to_underlying                                 202102L <utility>
 __cpp_lib_transformation_trait_aliases                  201304L <type_traits>
 __cpp_lib_transparent_operators                         201510L <functional> <memory>
@@ -197,6 +219,7 @@ __cpp_lib_unreachable                                   202202L <utility>
 __cpp_lib_unwrap_ref                                    201811L <functional>
 __cpp_lib_variant                                       202102L <variant>
 __cpp_lib_void_t                                        201411L <type_traits>
+__cpp_lib_within_lifetime                               202306L <type_traits>
 
 */
 
@@ -209,7 +232,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 
 // clang-format off
 
-#if _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 14
 # define __cpp_lib_chrono_udls                          201304L
 # define __cpp_lib_complex_udls                         201309L
 # define __cpp_lib_exchange_function                    201304L
@@ -224,7 +247,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_quoted_string_io                     201304L
 # define __cpp_lib_result_of_sfinae                     201210L
 # define __cpp_lib_robust_nonmodifying_seq_ops          201304L
-# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX)
 #   define __cpp_lib_shared_timed_mutex                 201402L
 # endif
 # define __cpp_lib_string_udls                          201304L
@@ -234,7 +257,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_tuples_by_type                       201304L
 #endif
 
-#if _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER >= 17
 # define __cpp_lib_addressof_constexpr                  201603L
 # define __cpp_lib_allocator_traits_is_always_equal     201411L
 # define __cpp_lib_any                                  201606L
@@ -249,7 +272,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_clamp                                201603L
 # define __cpp_lib_enable_shared_from_this              201603L
 // # define __cpp_lib_execution                            201603L
-# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
+# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY)
 #   define __cpp_lib_filesystem                         201703L
 # endif
 # define __cpp_lib_gcd_lcm                              201606L
@@ -268,7 +291,9 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_make_from_tuple                      201606L
 # define __cpp_lib_map_try_emplace                      201411L
 // # define __cpp_lib_math_special_functions               201603L
-# define __cpp_lib_memory_resource                      201603L
+# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR)
+#   define __cpp_lib_memory_resource                    201603L
+# endif
 # define __cpp_lib_node_extract                         201606L
 # define __cpp_lib_nonmember_container_access           201411L
 # define __cpp_lib_not_fn                               201603L
@@ -277,7 +302,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_raw_memory_algorithms                201606L
 # define __cpp_lib_sample                               201603L
 # define __cpp_lib_scoped_lock                          201703L
-# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX)
 #   define __cpp_lib_shared_mutex                       201505L
 # endif
 # define __cpp_lib_shared_ptr_arrays                    201611L
@@ -293,7 +318,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_void_t                               201411L
 #endif
 
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
 # undef  __cpp_lib_array_constexpr
 # define __cpp_lib_array_constexpr                      201811L
 # define __cpp_lib_assume_aligned                       201811L
@@ -303,15 +328,15 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_atomic_ref                           201806L
 // # define __cpp_lib_atomic_shared_ptr                    201711L
 # define __cpp_lib_atomic_value_initialization          201911L
-# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
+# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
 #   define __cpp_lib_atomic_wait                        201907L
 # endif
-# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
 #   define __cpp_lib_barrier                            201907L
 # endif
 # define __cpp_lib_bind_front                           201907L
 # define __cpp_lib_bit_cast                             201806L
-// # define __cpp_lib_bitops                               201907L
+# define __cpp_lib_bitops                               201907L
 # define __cpp_lib_bounded_array_traits                 201902L
 # if !defined(_LIBCPP_HAS_NO_CHAR8_T)
 #   define __cpp_lib_char8_t                            201907L
@@ -330,16 +355,14 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_constexpr_utility                    201811L
 # define __cpp_lib_constexpr_vector                     201907L
 # define __cpp_lib_coroutine                            201902L
-# if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
+# if _LIBCPP_STD_VER >= 20 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
 #   define __cpp_lib_destroying_delete                  201806L
 # endif
 # define __cpp_lib_endian                               201907L
 # define __cpp_lib_erase_if                             202002L
 # undef  __cpp_lib_execution
 // # define __cpp_lib_execution                            201902L
-# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-// #   define __cpp_lib_format                             202106L
-# endif
+// # define __cpp_lib_format                               202106L
 # define __cpp_lib_generic_unordered_lookup             201811L
 # define __cpp_lib_int_pow2                             202002L
 # define __cpp_lib_integer_comparison_functions         202002L
@@ -351,15 +374,18 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # if !defined(_LIBCPP_HAS_NO_THREADS)
 // #   define __cpp_lib_jthread                            201911L
 # endif
-# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
 #   define __cpp_lib_latch                              201907L
 # endif
 # define __cpp_lib_list_remove_return_type              201806L
 # define __cpp_lib_math_constants                       201907L
-# define __cpp_lib_polymorphic_allocator                201902L
-# define __cpp_lib_ranges                               202106L
+# define __cpp_lib_move_iterator_concept                202207L
+# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR)
+#   define __cpp_lib_polymorphic_allocator              201902L
+# endif
+# define __cpp_lib_ranges                               202207L
 # define __cpp_lib_remove_cvref                         201711L
-# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
 #   define __cpp_lib_semaphore                          201907L
 # endif
 # undef  __cpp_lib_shared_ptr_arrays
@@ -382,7 +408,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_unwrap_ref                           201811L
 #endif
 
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
 # define __cpp_lib_adaptor_iterator_pair_constructor    202106L
 # define __cpp_lib_allocate_at_least                    202106L
 // # define __cpp_lib_associative_heterogeneous_erasure    202110L
@@ -393,23 +419,28 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_constexpr_cmath                      202202L
 # undef  __cpp_lib_constexpr_memory
 # define __cpp_lib_constexpr_memory                     202202L
-// # define __cpp_lib_constexpr_typeinfo                   202106L
-# define __cpp_lib_expected                             202202L
+# define __cpp_lib_constexpr_typeinfo                   202106L
+# define __cpp_lib_expected                             202211L
+# define __cpp_lib_format_ranges                        202207L
+// # define __cpp_lib_formatters                           202302L
 # define __cpp_lib_forward_like                         202207L
-// # define __cpp_lib_invoke_r                             202106L
+# define __cpp_lib_invoke_r                             202106L
 # define __cpp_lib_is_scoped_enum                       202011L
+// # define __cpp_lib_mdspan                               202207L
 // # define __cpp_lib_move_only_function                   202110L
 # undef  __cpp_lib_optional
 # define __cpp_lib_optional                             202110L
 // # define __cpp_lib_out_ptr                              202106L
+// # define __cpp_lib_print                                202207L
 # define __cpp_lib_ranges_as_rvalue                     202207L
 // # define __cpp_lib_ranges_chunk                         202202L
 // # define __cpp_lib_ranges_chunk_by                      202202L
 // # define __cpp_lib_ranges_iota                          202202L
 // # define __cpp_lib_ranges_join_with                     202202L
+# define __cpp_lib_ranges_repeat                        202207L
 // # define __cpp_lib_ranges_slide                         202202L
 // # define __cpp_lib_ranges_starts_ends_with              202106L
-// # define __cpp_lib_ranges_to_container                  202202L
+# define __cpp_lib_ranges_to_container                  202202L
 // # define __cpp_lib_ranges_zip                           202110L
 // # define __cpp_lib_reference_from_temporary             202202L
 // # define __cpp_lib_spanstream                           202106L
@@ -417,10 +448,31 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_stdatomic_h                          202011L
 # define __cpp_lib_string_contains                      202011L
 # define __cpp_lib_string_resize_and_overwrite          202110L
+// # define __cpp_lib_to_string                            202306L
 # define __cpp_lib_to_underlying                        202102L
 # define __cpp_lib_unreachable                          202202L
 #endif
 
+#if _LIBCPP_STD_VER >= 26
+// # define __cpp_lib_associative_heterogeneous_insertion  202306L
+# undef  __cpp_lib_bind_back
+// # define __cpp_lib_bind_back                            202306L
+# undef  __cpp_lib_bind_front
+# define __cpp_lib_bind_front                           202306L
+// # define __cpp_lib_bitset                               202306L
+// # define __cpp_lib_copyable_function                    202306L
+// # define __cpp_lib_fstream_native_handle                202306L
+// # define __cpp_lib_function_ref                         202306L
+// # define __cpp_lib_hazard_pointer                       202306L
+# define __cpp_lib_ratio                                202306L
+// # define __cpp_lib_rcu                                  202306L
+// # define __cpp_lib_smart_ptr_owner_equality             202306L
+// # define __cpp_lib_sstream_from_string_view             202306L
+// # define __cpp_lib_submdspan                            202306L
+// # define __cpp_lib_text_encoding                        202306L
+// # define __cpp_lib_within_lifetime                      202306L
+#endif
+
 // clang-format on
 
 #endif // _LIBCPP_VERSIONH
lib/libcxx/include/wchar.h
@@ -116,12 +116,16 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 #  pragma GCC system_header
 #endif
 
+// We define this here to support older versions of glibc <wchar.h> that do
+// not define this for clang.
 #ifdef __cplusplus
 #define __CORRECT_ISO_CPP_WCHAR_H_PROTO
 #endif
 
 #  if __has_include_next(<wchar.h>)
 #    include_next <wchar.h>
+#  else
+#    include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of <wchar.h>
 #  endif
 
 // Determine whether we have const-correct overloads for wcschr and friends.
lib/libcxx/src/experimental/memory_resource.cpp
@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
 
 // new_delete_resource()
 
-class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
+class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp
     : public memory_resource
 {
     void *do_allocate(size_t size, size_t align) override {
@@ -51,7 +51,7 @@ public:
 
 // null_memory_resource()
 
-class _LIBCPP_TYPE_VIS __null_memory_resource_imp
+class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp
     : public memory_resource
 {
 public:
lib/libcxx/src/filesystem/directory_entry.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <cstdint>
+#include <filesystem>
+#include <system_error>
+
+#include "file_descriptor.h"
+#include "posix_compat.h"
+#include "time_utils.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+error_code directory_entry::__do_refresh() noexcept {
+  __data_.__reset();
+  error_code failure_ec;
+
+  detail::StatT full_st;
+  file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
+  if (!status_known(st)) {
+    __data_.__reset();
+    return failure_ec;
+  }
+
+  if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
+    __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+  } else { // we have a symlink
+    __data_.__sym_perms_ = st.permissions();
+    // Get the information about the linked entity.
+    // Ignore errors from stat, since we don't want errors regarding symlink
+    // resolution to be reported to the user.
+    error_code ignored_ec;
+    st = detail::posix_stat(__p_, full_st, &ignored_ec);
+
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+
+    // If we failed to resolve the link, then only partially populate the
+    // cache.
+    if (!status_known(st)) {
+      __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
+      return error_code{};
+    }
+    // Otherwise, we resolved the link, potentially as not existing.
+    // That's OK.
+    __data_.__cache_type_ = directory_entry::_RefreshSymlink;
+  }
+
+  if (_VSTD_FS::is_regular_file(st))
+    __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
+
+  if (_VSTD_FS::exists(st)) {
+    __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
+
+    // Attempt to extract the mtime, and fail if it's not representable using
+    // file_time_type. For now we ignore the error, as we'll report it when
+    // the value is actually used.
+    error_code ignored_ec;
+    __data_.__write_time_ =
+        detail::__extract_last_write_time(__p_, full_st, &ignored_ec);
+  }
+
+  return failure_ec;
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/directory_iterator.cpp
@@ -11,8 +11,18 @@
 #include <errno.h>
 #include <filesystem>
 #include <stack>
+#include <utility>
 
-#include "filesystem_common.h"
+#include "error.h"
+#include "file_descriptor.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#else
+# include <dirent.h>   // for DIR & friends
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
@@ -182,7 +192,7 @@ directory_iterator::directory_iterator(const path& p, error_code* ec,
 }
 
 directory_iterator& directory_iterator::__increment(error_code* ec) {
-  _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to increment an invalid iterator");
   ErrorHandler<void> err("directory_iterator::operator++()", ec);
 
   error_code m_ec;
@@ -196,7 +206,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) {
 }
 
 directory_entry const& directory_iterator::__dereference() const {
-  _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to dereference an invalid iterator");
   return __imp_->__entry_;
 }
 
@@ -225,7 +235,7 @@ recursive_directory_iterator::recursive_directory_iterator(
 }
 
 void recursive_directory_iterator::__pop(error_code* ec) {
-  _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Popping the end iterator");
   if (ec)
     ec->clear();
   __imp_->__stack_.pop();
lib/libcxx/src/filesystem/error.h
@@ -0,0 +1,238 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_ERROR_H
+#define FILESYSTEM_ERROR_H
+
+#include <__assert>
+#include <__config>
+#include <cerrno>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <string>
+#include <system_error>
+#include <utility> // __libcpp_unreachable
+
+#include "format_string.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h> // ERROR_* macros
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+#if defined(_LIBCPP_WIN32API)
+
+inline errc __win_err_to_errc(int err) {
+  constexpr struct {
+    DWORD win;
+    errc errc;
+  } win_error_mapping[] = {
+      {ERROR_ACCESS_DENIED, errc::permission_denied},
+      {ERROR_ALREADY_EXISTS, errc::file_exists},
+      {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
+      {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
+      {ERROR_BAD_UNIT, errc::no_such_device},
+      {ERROR_BROKEN_PIPE, errc::broken_pipe},
+      {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
+      {ERROR_BUSY, errc::device_or_resource_busy},
+      {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
+      {ERROR_CANNOT_MAKE, errc::permission_denied},
+      {ERROR_CANTOPEN, errc::io_error},
+      {ERROR_CANTREAD, errc::io_error},
+      {ERROR_CANTWRITE, errc::io_error},
+      {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
+      {ERROR_DEV_NOT_EXIST, errc::no_such_device},
+      {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
+      {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
+      {ERROR_DIRECTORY, errc::invalid_argument},
+      {ERROR_DISK_FULL, errc::no_space_on_device},
+      {ERROR_FILE_EXISTS, errc::file_exists},
+      {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
+      {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
+      {ERROR_INVALID_ACCESS, errc::permission_denied},
+      {ERROR_INVALID_DRIVE, errc::no_such_device},
+      {ERROR_INVALID_FUNCTION, errc::function_not_supported},
+      {ERROR_INVALID_HANDLE, errc::invalid_argument},
+      {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
+      {ERROR_INVALID_PARAMETER, errc::invalid_argument},
+      {ERROR_LOCK_VIOLATION, errc::no_lock_available},
+      {ERROR_LOCKED, errc::no_lock_available},
+      {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
+      {ERROR_NOACCESS, errc::permission_denied},
+      {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
+      {ERROR_NOT_READY, errc::resource_unavailable_try_again},
+      {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
+      {ERROR_NOT_SUPPORTED, errc::not_supported},
+      {ERROR_OPEN_FAILED, errc::io_error},
+      {ERROR_OPEN_FILES, errc::device_or_resource_busy},
+      {ERROR_OPERATION_ABORTED, errc::operation_canceled},
+      {ERROR_OUTOFMEMORY, errc::not_enough_memory},
+      {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
+      {ERROR_READ_FAULT, errc::io_error},
+      {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
+      {ERROR_RETRY, errc::resource_unavailable_try_again},
+      {ERROR_SEEK, errc::io_error},
+      {ERROR_SHARING_VIOLATION, errc::permission_denied},
+      {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
+      {ERROR_WRITE_FAULT, errc::io_error},
+      {ERROR_WRITE_PROTECT, errc::permission_denied},
+  };
+
+  for (const auto &pair : win_error_mapping)
+    if (pair.win == static_cast<DWORD>(err))
+      return pair.errc;
+  return errc::invalid_argument;
+}
+
+#endif // _LIBCPP_WIN32API
+
+inline error_code capture_errno() {
+  _LIBCPP_ASSERT_UNCATEGORIZED(errno != 0, "Expected errno to be non-zero");
+  return error_code(errno, generic_category());
+}
+
+#if defined(_LIBCPP_WIN32API)
+inline error_code make_windows_error(int err) {
+  return make_error_code(__win_err_to_errc(err));
+}
+#endif
+
+template <class T>
+T error_value();
+template <>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
+template <>
+inline bool error_value<bool>() {
+  return false;
+}
+#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
+template <>
+inline size_t error_value<size_t>() {
+  return size_t(-1);
+}
+#endif
+template <>
+inline uintmax_t error_value<uintmax_t>() {
+  return uintmax_t(-1);
+}
+template <>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
+  return file_time_type::min();
+}
+template <>
+inline path error_value<path>() {
+  return {};
+}
+
+template <class T>
+struct ErrorHandler {
+  const char* func_name_;
+  error_code* ec_ = nullptr;
+  const path* p1_ = nullptr;
+  const path* p2_ = nullptr;
+
+  ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
+               const path* p2 = nullptr)
+      : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
+    if (ec_)
+      ec_->clear();
+  }
+
+  T report(const error_code& ec) const {
+    if (ec_) {
+      *ec_ = ec;
+      return error_value<T>();
+    }
+    string what = string("in ") + func_name_;
+    switch (bool(p1_) + bool(p2_)) {
+    case 0:
+      __throw_filesystem_error(what, ec);
+    case 1:
+      __throw_filesystem_error(what, *p1_, ec);
+    case 2:
+      __throw_filesystem_error(what, *p1_, *p2_, ec);
+    }
+    __libcpp_unreachable();
+  }
+
+  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
+  void report_impl(const error_code& ec, const char* msg, va_list ap) const {
+    if (ec_) {
+      *ec_ = ec;
+      return;
+    }
+    string what =
+        string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap);
+    switch (bool(p1_) + bool(p2_)) {
+    case 0:
+      __throw_filesystem_error(what, ec);
+    case 1:
+      __throw_filesystem_error(what, *p1_, ec);
+    case 2:
+      __throw_filesystem_error(what, *p1_, *p2_, ec);
+    }
+    __libcpp_unreachable();
+  }
+
+  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
+  T report(const error_code& ec, const char* msg, ...) const {
+    va_list ap;
+    va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+    try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+      report_impl(ec, msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+    } catch (...) {
+      va_end(ap);
+      throw;
+    }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+    va_end(ap);
+    return error_value<T>();
+  }
+
+  T report(errc const& err) const {
+    return report(make_error_code(err));
+  }
+
+  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
+  T report(errc const& err, const char* msg, ...) const {
+    va_list ap;
+    va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+    try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+      report_impl(make_error_code(err), msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+    } catch (...) {
+      va_end(ap);
+      throw;
+    }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+    va_end(ap);
+    return error_value<T>();
+  }
+
+private:
+  ErrorHandler(ErrorHandler const&) = delete;
+  ErrorHandler& operator=(ErrorHandler const&) = delete;
+};
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_ERROR_H
lib/libcxx/src/filesystem/file_descriptor.h
@@ -0,0 +1,298 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_FILE_DESCRIPTOR_H
+#define FILESYSTEM_FILE_DESCRIPTOR_H
+
+#include <__config>
+#include <cstdint>
+#include <filesystem>
+#include <string_view>
+#include <system_error>
+#include <utility>
+
+#include "error.h"
+#include "posix_compat.h"
+#include "time_utils.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#else
+# include <dirent.h>   // for DIR & friends
+# include <fcntl.h>    // values for fchmodat
+# include <sys/stat.h>
+# include <sys/statvfs.h>
+# include <unistd.h>
+#endif // defined(_LIBCPP_WIN32API)
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+#if !defined(_LIBCPP_WIN32API)
+
+#if defined(DT_BLK)
+template <class DirEntT, class = decltype(DirEntT::d_type)>
+file_type get_file_type(DirEntT* ent, int) {
+  switch (ent->d_type) {
+  case DT_BLK:
+    return file_type::block;
+  case DT_CHR:
+    return file_type::character;
+  case DT_DIR:
+    return file_type::directory;
+  case DT_FIFO:
+    return file_type::fifo;
+  case DT_LNK:
+    return file_type::symlink;
+  case DT_REG:
+    return file_type::regular;
+  case DT_SOCK:
+    return file_type::socket;
+  // Unlike in lstat, hitting "unknown" here simply means that the underlying
+  // filesystem doesn't support d_type. Report is as 'none' so we correctly
+  // set the cache to empty.
+  case DT_UNKNOWN:
+    break;
+  }
+  return file_type::none;
+}
+#endif // defined(DT_BLK)
+
+template <class DirEntT>
+file_type get_file_type(DirEntT*, long) {
+  return file_type::none;
+}
+
+inline pair<string_view, file_type> posix_readdir(DIR* dir_stream,
+                                                  error_code& ec) {
+  struct dirent* dir_entry_ptr = nullptr;
+  errno = 0; // zero errno in order to detect errors
+  ec.clear();
+  if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
+    if (errno)
+      ec = capture_errno();
+    return {};
+  } else {
+    return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
+  }
+}
+
+#else // _LIBCPP_WIN32API
+
+inline file_type get_file_type(const WIN32_FIND_DATAW& data) {
+  if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
+      data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+    return file_type::symlink;
+  if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+    return file_type::directory;
+  return file_type::regular;
+}
+inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
+  return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
+}
+inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
+  ULARGE_INTEGER tmp;
+  const FILETIME& time = data.ftLastWriteTime;
+  tmp.u.LowPart = time.dwLowDateTime;
+  tmp.u.HighPart = time.dwHighDateTime;
+  return file_time_type(file_time_type::duration(tmp.QuadPart));
+}
+
+#endif // !_LIBCPP_WIN32API
+
+//                       POSIX HELPERS
+
+using value_type = path::value_type;
+using string_type = path::string_type;
+
+struct FileDescriptor {
+  const path& name;
+  int fd = -1;
+  StatT m_stat;
+  file_status m_status;
+
+  template <class... Args>
+  static FileDescriptor create(const path* p, error_code& ec, Args... args) {
+    ec.clear();
+    int fd;
+#ifdef _LIBCPP_WIN32API
+    // TODO: most of the filesystem implementation uses native Win32 calls
+    // (mostly via posix_compat.h). However, here we use the C-runtime APIs to
+    // open a file, because we subsequently pass the C-runtime fd to
+    // `std::[io]fstream::__open(int fd)` in order to implement copy_file.
+    //
+    // Because we're calling the windows C-runtime, win32 error codes are
+    // translated into C error numbers by the C runtime, and returned in errno,
+    // rather than being accessible directly via GetLastError.
+    //
+    // Ideally copy_file should be calling the Win32 CopyFile2 function, which
+    // works on paths, not open files -- at which point this FileDescriptor type
+    // will no longer be needed on windows at all.
+    fd = ::_wopen(p->c_str(), args...);
+#else
+    fd = open(p->c_str(), args...);
+#endif
+
+    if (fd == -1) {
+      ec = capture_errno();
+      return FileDescriptor{p};
+    }
+    return FileDescriptor(p, fd);
+  }
+
+  template <class... Args>
+  static FileDescriptor create_with_status(const path* p, error_code& ec,
+                                           Args... args) {
+    FileDescriptor fd = create(p, ec, args...);
+    if (!ec)
+      fd.refresh_status(ec);
+
+    return fd;
+  }
+
+  file_status get_status() const { return m_status; }
+  StatT const& get_stat() const { return m_stat; }
+
+  bool status_known() const { return _VSTD_FS::status_known(m_status); }
+
+  file_status refresh_status(error_code& ec);
+
+  void close() noexcept {
+    if (fd != -1) {
+#ifdef _LIBCPP_WIN32API
+      ::_close(fd);
+#else
+      ::close(fd);
+#endif
+      // FIXME: shouldn't this return an error_code?
+    }
+    fd = -1;
+  }
+
+  FileDescriptor(FileDescriptor&& other)
+      : name(other.name), fd(other.fd), m_stat(other.m_stat),
+        m_status(other.m_status) {
+    other.fd = -1;
+    other.m_status = file_status{};
+  }
+
+  ~FileDescriptor() { close(); }
+
+  FileDescriptor(FileDescriptor const&) = delete;
+  FileDescriptor& operator=(FileDescriptor const&) = delete;
+
+private:
+  explicit FileDescriptor(const path* p, int descriptor = -1) : name(*p), fd(descriptor) {}
+};
+
+inline perms posix_get_perms(const StatT& st) noexcept {
+  return static_cast<perms>(st.st_mode) & perms::mask;
+}
+
+inline file_status create_file_status(error_code& m_ec, path const& p,
+                                      const StatT& path_stat, error_code* ec) {
+  if (ec)
+    *ec = m_ec;
+  if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
+    return file_status(file_type::not_found);
+  } else if (m_ec) {
+    ErrorHandler<void> err("posix_stat", ec, &p);
+    err.report(m_ec, "failed to determine attributes for the specified path");
+    return file_status(file_type::none);
+  }
+  // else
+
+  file_status fs_tmp;
+  auto const mode = path_stat.st_mode;
+  if (S_ISLNK(mode))
+    fs_tmp.type(file_type::symlink);
+  else if (S_ISREG(mode))
+    fs_tmp.type(file_type::regular);
+  else if (S_ISDIR(mode))
+    fs_tmp.type(file_type::directory);
+  else if (S_ISBLK(mode))
+    fs_tmp.type(file_type::block);
+  else if (S_ISCHR(mode))
+    fs_tmp.type(file_type::character);
+  else if (S_ISFIFO(mode))
+    fs_tmp.type(file_type::fifo);
+  else if (S_ISSOCK(mode))
+    fs_tmp.type(file_type::socket);
+  else
+    fs_tmp.type(file_type::unknown);
+
+  fs_tmp.permissions(detail::posix_get_perms(path_stat));
+  return fs_tmp;
+}
+
+inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
+  error_code m_ec;
+  if (detail::stat(p.c_str(), &path_stat) == -1)
+    m_ec = detail::capture_errno();
+  return create_file_status(m_ec, p, path_stat, ec);
+}
+
+inline file_status posix_stat(path const& p, error_code* ec) {
+  StatT path_stat;
+  return posix_stat(p, path_stat, ec);
+}
+
+inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
+  error_code m_ec;
+  if (detail::lstat(p.c_str(), &path_stat) == -1)
+    m_ec = detail::capture_errno();
+  return create_file_status(m_ec, p, path_stat, ec);
+}
+
+inline file_status posix_lstat(path const& p, error_code* ec) {
+  StatT path_stat;
+  return posix_lstat(p, path_stat, ec);
+}
+
+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
+inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
+  if (detail::ftruncate(fd.fd, to_size) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  ec.clear();
+  return false;
+}
+
+inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
+  if (detail::fchmod(fd.fd, st.st_mode) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  ec.clear();
+  return false;
+}
+
+inline bool stat_equivalent(const StatT& st1, const StatT& st2) {
+  return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+}
+
+inline file_status FileDescriptor::refresh_status(error_code& ec) {
+  // FD must be open and good.
+  m_status = file_status{};
+  m_stat = {};
+  error_code m_ec;
+  if (detail::fstat(fd, &m_stat) == -1)
+    m_ec = capture_errno();
+  m_status = create_file_status(m_ec, name, m_stat, &ec);
+  return m_status;
+}
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_FILE_DESCRIPTOR_H
lib/libcxx/src/filesystem/filesystem_clock.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <chrono>
+#include <filesystem>
+#include <time.h>
+
+#if defined(_LIBCPP_WIN32API)
+#  include "time_utils.h"
+#endif
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#endif
+
+#if __has_include(<unistd.h>)
+# include <unistd.h> // _POSIX_TIMERS
+#endif
+
+#if __has_include(<sys/time.h>)
+# include <sys/time.h> // for gettimeofday and timeval
+#endif
+
+#if defined(__APPLE__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
+# define _LIBCPP_HAS_CLOCK_GETTIME
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+const bool _FilesystemClock::is_steady;
+
+_FilesystemClock::time_point _FilesystemClock::now() noexcept {
+  typedef chrono::duration<rep> __secs;
+#if defined(_LIBCPP_WIN32API)
+  typedef chrono::duration<rep, nano> __nsecs;
+  FILETIME time;
+  GetSystemTimeAsFileTime(&time);
+  detail::TimeSpec tp = detail::filetime_to_timespec(time);
+  return time_point(__secs(tp.tv_sec) +
+                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
+  typedef chrono::duration<rep, nano> __nsecs;
+  struct timespec tp;
+  if (0 != clock_gettime(CLOCK_REALTIME, &tp))
+    __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
+  return time_point(__secs(tp.tv_sec) +
+                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#else
+  typedef chrono::duration<rep, micro> __microsecs;
+  timeval tv;
+  gettimeofday(&tv, 0);
+  return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/filesystem_error.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <__utility/unreachable.h>
+#include <filesystem>
+#include <system_error>
+
+#include "format_string.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+filesystem_error::~filesystem_error() {}
+
+void filesystem_error::__create_what(int __num_paths) {
+  const char* derived_what = system_error::what();
+  __storage_->__what_ = [&]() -> string {
+    switch (__num_paths) {
+    case 0:
+      return detail::format_string("filesystem error: %s", derived_what);
+    case 1:
+      return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
+                                   derived_what, path1().c_str());
+    case 2:
+      return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
+                                   derived_what, path1().c_str(), path2().c_str());
+    }
+    __libcpp_unreachable();
+  }();
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/format_string.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_FORMAT_STRING_H
+#define FILESYSTEM_FORMAT_STRING_H
+
+#include <__assert>
+#include <__config>
+#include <array>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdio>
+#include <string>
+
+#if defined(_LIBCPP_WIN32API)
+#  define PATHSTR(x) (L##x)
+#  define PATH_CSTR_FMT "\"%ls\""
+#else
+#  define PATHSTR(x) (x)
+#  define PATH_CSTR_FMT "\"%s\""
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
+  array<char, 256> buf;
+
+  va_list apcopy;
+  va_copy(apcopy, ap);
+  int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
+  va_end(apcopy);
+
+  string result;
+  if (static_cast<size_t>(ret) < buf.size()) {
+    result.assign(buf.data(), static_cast<size_t>(ret));
+  } else {
+    // we did not provide a long enough buffer on our first attempt. The
+    // return value is the number of bytes (excluding the null byte) that are
+    // needed for formatting.
+    size_t size_with_null = static_cast<size_t>(ret) + 1;
+    result.__resize_default_init(size_with_null - 1);
+    ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
+    _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
+  }
+  return result;
+}
+
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
+  string ret;
+  va_list ap;
+  va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+    ret = detail::vformat_string(msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  } catch (...) {
+    va_end(ap);
+    throw;
+  }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+  va_end(ap);
+  return ret;
+}
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_FORMAT_STRING_H
lib/libcxx/src/filesystem/int128_builtins.cpp
@@ -18,7 +18,7 @@
 
 #if !defined(_LIBCPP_HAS_NO_INT128)
 
-extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS
+extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_EXPORTED_FROM_ABI
 __int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) {
   const int N = (int)(sizeof(__int128_t) * CHAR_BIT);
   const __int128_t MIN = (__int128_t)1 << (N - 1);
lib/libcxx/src/filesystem/operations.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <__assert>
+#include <__config>
 #include <__utility/unreachable.h>
 #include <array>
 #include <climits>
@@ -17,9 +18,11 @@
 #include <type_traits>
 #include <vector>
 
-#include "filesystem_common.h"
-
+#include "error.h"
+#include "file_descriptor.h"
+#include "path_parser.h"
 #include "posix_compat.h"
+#include "time_utils.h"
 
 #if defined(_LIBCPP_WIN32API)
 # define WIN32_LEAN_AND_MEAN
@@ -45,595 +48,12 @@
 # define _LIBCPP_FILESYSTEM_USE_FSTREAM
 #endif
 
-#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API)
-# include <sys/time.h> // for gettimeofday and timeval
-#endif
-
 #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
 # pragma comment(lib, "rt")
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
-namespace {
-
-bool isSeparator(path::value_type C) {
-  if (C == '/')
-    return true;
-#if defined(_LIBCPP_WIN32API)
-  if (C == '\\')
-    return true;
-#endif
-  return false;
-}
-
-bool isDriveLetter(path::value_type C) {
-  return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
-}
-
-namespace parser {
-
-using string_view_t = path::__string_view;
-using string_view_pair = pair<string_view_t, string_view_t>;
-using PosPtr = path::value_type const*;
-
-struct PathParser {
-  enum ParserState : unsigned char {
-    // Zero is a special sentinel value used by default constructed iterators.
-    PS_BeforeBegin = path::iterator::_BeforeBegin,
-    PS_InRootName = path::iterator::_InRootName,
-    PS_InRootDir = path::iterator::_InRootDir,
-    PS_InFilenames = path::iterator::_InFilenames,
-    PS_InTrailingSep = path::iterator::_InTrailingSep,
-    PS_AtEnd = path::iterator::_AtEnd
-  };
-
-  const string_view_t Path;
-  string_view_t RawEntry;
-  ParserState State;
-
-private:
-  PathParser(string_view_t P, ParserState State) noexcept : Path(P),
-                                                            State(State) {}
-
-public:
-  PathParser(string_view_t P, string_view_t E, unsigned char S)
-      : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
-    // S cannot be '0' or PS_BeforeBegin.
-  }
-
-  static PathParser CreateBegin(string_view_t P) noexcept {
-    PathParser PP(P, PS_BeforeBegin);
-    PP.increment();
-    return PP;
-  }
-
-  static PathParser CreateEnd(string_view_t P) noexcept {
-    PathParser PP(P, PS_AtEnd);
-    return PP;
-  }
-
-  PosPtr peek() const noexcept {
-    auto TkEnd = getNextTokenStartPos();
-    auto End = getAfterBack();
-    return TkEnd == End ? nullptr : TkEnd;
-  }
-
-  void increment() noexcept {
-    const PosPtr End = getAfterBack();
-    const PosPtr Start = getNextTokenStartPos();
-    if (Start == End)
-      return makeState(PS_AtEnd);
-
-    switch (State) {
-    case PS_BeforeBegin: {
-      PosPtr TkEnd = consumeRootName(Start, End);
-      if (TkEnd)
-        return makeState(PS_InRootName, Start, TkEnd);
-    }
-      _LIBCPP_FALLTHROUGH();
-    case PS_InRootName: {
-      PosPtr TkEnd = consumeAllSeparators(Start, End);
-      if (TkEnd)
-        return makeState(PS_InRootDir, Start, TkEnd);
-      else
-        return makeState(PS_InFilenames, Start, consumeName(Start, End));
-    }
-    case PS_InRootDir:
-      return makeState(PS_InFilenames, Start, consumeName(Start, End));
-
-    case PS_InFilenames: {
-      PosPtr SepEnd = consumeAllSeparators(Start, End);
-      if (SepEnd != End) {
-        PosPtr TkEnd = consumeName(SepEnd, End);
-        if (TkEnd)
-          return makeState(PS_InFilenames, SepEnd, TkEnd);
-      }
-      return makeState(PS_InTrailingSep, Start, SepEnd);
-    }
-
-    case PS_InTrailingSep:
-      return makeState(PS_AtEnd);
-
-    case PS_AtEnd:
-      __libcpp_unreachable();
-    }
-  }
-
-  void decrement() noexcept {
-    const PosPtr REnd = getBeforeFront();
-    const PosPtr RStart = getCurrentTokenStartPos() - 1;
-    if (RStart == REnd) // we're decrementing the begin
-      return makeState(PS_BeforeBegin);
-
-    switch (State) {
-    case PS_AtEnd: {
-      // Try to consume a trailing separator or root directory first.
-      if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
-        if (SepEnd == REnd)
-          return makeState(PS_InRootDir, Path.data(), RStart + 1);
-        PosPtr TkStart = consumeRootName(SepEnd, REnd);
-        if (TkStart == REnd)
-          return makeState(PS_InRootDir, RStart, RStart + 1);
-        return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
-      } else {
-        PosPtr TkStart = consumeRootName(RStart, REnd);
-        if (TkStart == REnd)
-          return makeState(PS_InRootName, TkStart + 1, RStart + 1);
-        TkStart = consumeName(RStart, REnd);
-        return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
-      }
-    }
-    case PS_InTrailingSep:
-      return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
-                       RStart + 1);
-    case PS_InFilenames: {
-      PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
-      if (SepEnd == REnd)
-        return makeState(PS_InRootDir, Path.data(), RStart + 1);
-      PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
-      if (TkStart == REnd) {
-        if (SepEnd)
-          return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
-        return makeState(PS_InRootName, TkStart + 1, RStart + 1);
-      }
-      TkStart = consumeName(SepEnd, REnd);
-      return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
-    }
-    case PS_InRootDir:
-      return makeState(PS_InRootName, Path.data(), RStart + 1);
-    case PS_InRootName:
-    case PS_BeforeBegin:
-      __libcpp_unreachable();
-    }
-  }
-
-  /// \brief Return a view with the "preferred representation" of the current
-  ///   element. For example trailing separators are represented as a '.'
-  string_view_t operator*() const noexcept {
-    switch (State) {
-    case PS_BeforeBegin:
-    case PS_AtEnd:
-      return PATHSTR("");
-    case PS_InRootDir:
-      if (RawEntry[0] == '\\')
-        return PATHSTR("\\");
-      else
-        return PATHSTR("/");
-    case PS_InTrailingSep:
-      return PATHSTR("");
-    case PS_InRootName:
-    case PS_InFilenames:
-      return RawEntry;
-    }
-    __libcpp_unreachable();
-  }
-
-  explicit operator bool() const noexcept {
-    return State != PS_BeforeBegin && State != PS_AtEnd;
-  }
-
-  PathParser& operator++() noexcept {
-    increment();
-    return *this;
-  }
-
-  PathParser& operator--() noexcept {
-    decrement();
-    return *this;
-  }
-
-  bool atEnd() const noexcept {
-    return State == PS_AtEnd;
-  }
-
-  bool inRootDir() const noexcept {
-    return State == PS_InRootDir;
-  }
-
-  bool inRootName() const noexcept {
-    return State == PS_InRootName;
-  }
-
-  bool inRootPath() const noexcept {
-    return inRootName() || inRootDir();
-  }
-
-private:
-  void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
-    State = NewState;
-    RawEntry = string_view_t(Start, End - Start);
-  }
-  void makeState(ParserState NewState) noexcept {
-    State = NewState;
-    RawEntry = {};
-  }
-
-  PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
-
-  PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
-
-  /// \brief Return a pointer to the first character after the currently
-  ///   lexed element.
-  PosPtr getNextTokenStartPos() const noexcept {
-    switch (State) {
-    case PS_BeforeBegin:
-      return Path.data();
-    case PS_InRootName:
-    case PS_InRootDir:
-    case PS_InFilenames:
-      return &RawEntry.back() + 1;
-    case PS_InTrailingSep:
-    case PS_AtEnd:
-      return getAfterBack();
-    }
-    __libcpp_unreachable();
-  }
-
-  /// \brief Return a pointer to the first character in the currently lexed
-  ///   element.
-  PosPtr getCurrentTokenStartPos() const noexcept {
-    switch (State) {
-    case PS_BeforeBegin:
-    case PS_InRootName:
-      return &Path.front();
-    case PS_InRootDir:
-    case PS_InFilenames:
-    case PS_InTrailingSep:
-      return &RawEntry.front();
-    case PS_AtEnd:
-      return &Path.back() + 1;
-    }
-    __libcpp_unreachable();
-  }
-
-  // Consume all consecutive separators.
-  PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
-    if (P == nullptr || P == End || !isSeparator(*P))
-      return nullptr;
-    const int Inc = P < End ? 1 : -1;
-    P += Inc;
-    while (P != End && isSeparator(*P))
-      P += Inc;
-    return P;
-  }
-
-  // Consume exactly N separators, or return nullptr.
-  PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
-    PosPtr Ret = consumeAllSeparators(P, End);
-    if (Ret == nullptr)
-      return nullptr;
-    if (P < End) {
-      if (Ret == P + N)
-        return Ret;
-    } else {
-      if (Ret == P - N)
-        return Ret;
-    }
-    return nullptr;
-  }
-
-  PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
-    PosPtr Start = P;
-    if (P == nullptr || P == End || isSeparator(*P))
-      return nullptr;
-    const int Inc = P < End ? 1 : -1;
-    P += Inc;
-    while (P != End && !isSeparator(*P))
-      P += Inc;
-    if (P == End && Inc < 0) {
-      // Iterating backwards and consumed all the rest of the input.
-      // Check if the start of the string would have been considered
-      // a root name.
-      PosPtr RootEnd = consumeRootName(End + 1, Start);
-      if (RootEnd)
-        return RootEnd - 1;
-    }
-    return P;
-  }
-
-  PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
-    if (P == End)
-      return nullptr;
-    if (P < End) {
-      if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
-        return nullptr;
-      return P + 2;
-    } else {
-      if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
-        return nullptr;
-      return P - 2;
-    }
-  }
-
-  PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
-    if (P == End)
-      return nullptr;
-    if (P < End)
-      return consumeName(consumeNSeparators(P, End, 2), End);
-    else
-      return consumeNSeparators(consumeName(P, End), End, 2);
-  }
-
-  PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
-#if defined(_LIBCPP_WIN32API)
-    if (PosPtr Ret = consumeDriveLetter(P, End))
-      return Ret;
-    if (PosPtr Ret = consumeNetworkRoot(P, End))
-      return Ret;
-#endif
-    return nullptr;
-  }
-};
-
-string_view_pair separate_filename(string_view_t const& s) {
-  if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
-    return string_view_pair{s, PATHSTR("")};
-  auto pos = s.find_last_of('.');
-  if (pos == string_view_t::npos || pos == 0)
-    return string_view_pair{s, string_view_t{}};
-  return string_view_pair{s.substr(0, pos), s.substr(pos)};
-}
-
-string_view_t createView(PosPtr S, PosPtr E) noexcept {
-  return {S, static_cast<size_t>(E - S) + 1};
-}
-
-} // namespace parser
-} // namespace
-
-//                       POSIX HELPERS
-
-#if defined(_LIBCPP_WIN32API)
-namespace detail {
-
-errc __win_err_to_errc(int err) {
-  constexpr struct {
-    DWORD win;
-    errc errc;
-  } win_error_mapping[] = {
-      {ERROR_ACCESS_DENIED, errc::permission_denied},
-      {ERROR_ALREADY_EXISTS, errc::file_exists},
-      {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
-      {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
-      {ERROR_BAD_UNIT, errc::no_such_device},
-      {ERROR_BROKEN_PIPE, errc::broken_pipe},
-      {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
-      {ERROR_BUSY, errc::device_or_resource_busy},
-      {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
-      {ERROR_CANNOT_MAKE, errc::permission_denied},
-      {ERROR_CANTOPEN, errc::io_error},
-      {ERROR_CANTREAD, errc::io_error},
-      {ERROR_CANTWRITE, errc::io_error},
-      {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
-      {ERROR_DEV_NOT_EXIST, errc::no_such_device},
-      {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
-      {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
-      {ERROR_DIRECTORY, errc::invalid_argument},
-      {ERROR_DISK_FULL, errc::no_space_on_device},
-      {ERROR_FILE_EXISTS, errc::file_exists},
-      {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
-      {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
-      {ERROR_INVALID_ACCESS, errc::permission_denied},
-      {ERROR_INVALID_DRIVE, errc::no_such_device},
-      {ERROR_INVALID_FUNCTION, errc::function_not_supported},
-      {ERROR_INVALID_HANDLE, errc::invalid_argument},
-      {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
-      {ERROR_INVALID_PARAMETER, errc::invalid_argument},
-      {ERROR_LOCK_VIOLATION, errc::no_lock_available},
-      {ERROR_LOCKED, errc::no_lock_available},
-      {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
-      {ERROR_NOACCESS, errc::permission_denied},
-      {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
-      {ERROR_NOT_READY, errc::resource_unavailable_try_again},
-      {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
-      {ERROR_NOT_SUPPORTED, errc::not_supported},
-      {ERROR_OPEN_FAILED, errc::io_error},
-      {ERROR_OPEN_FILES, errc::device_or_resource_busy},
-      {ERROR_OPERATION_ABORTED, errc::operation_canceled},
-      {ERROR_OUTOFMEMORY, errc::not_enough_memory},
-      {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
-      {ERROR_READ_FAULT, errc::io_error},
-      {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
-      {ERROR_RETRY, errc::resource_unavailable_try_again},
-      {ERROR_SEEK, errc::io_error},
-      {ERROR_SHARING_VIOLATION, errc::permission_denied},
-      {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
-      {ERROR_WRITE_FAULT, errc::io_error},
-      {ERROR_WRITE_PROTECT, errc::permission_denied},
-  };
-
-  for (const auto &pair : win_error_mapping)
-    if (pair.win == static_cast<DWORD>(err))
-      return pair.errc;
-  return errc::invalid_argument;
-}
-
-} // namespace detail
-#endif
-
-namespace detail {
-namespace {
-
-using value_type = path::value_type;
-using string_type = path::string_type;
-
-struct FileDescriptor {
-  const path& name;
-  int fd = -1;
-  StatT m_stat;
-  file_status m_status;
-
-  template <class... Args>
-  static FileDescriptor create(const path* p, error_code& ec, Args... args) {
-    ec.clear();
-    int fd;
-    if ((fd = detail::open(p->c_str(), args...)) == -1) {
-      ec = capture_errno();
-      return FileDescriptor{p};
-    }
-    return FileDescriptor(p, fd);
-  }
-
-  template <class... Args>
-  static FileDescriptor create_with_status(const path* p, error_code& ec,
-                                           Args... args) {
-    FileDescriptor fd = create(p, ec, args...);
-    if (!ec)
-      fd.refresh_status(ec);
-
-    return fd;
-  }
-
-  file_status get_status() const { return m_status; }
-  StatT const& get_stat() const { return m_stat; }
-
-  bool status_known() const { return _VSTD_FS::status_known(m_status); }
-
-  file_status refresh_status(error_code& ec);
-
-  void close() noexcept {
-    if (fd != -1)
-      detail::close(fd);
-    fd = -1;
-  }
-
-  FileDescriptor(FileDescriptor&& other)
-      : name(other.name), fd(other.fd), m_stat(other.m_stat),
-        m_status(other.m_status) {
-    other.fd = -1;
-    other.m_status = file_status{};
-  }
-
-  ~FileDescriptor() { close(); }
-
-  FileDescriptor(FileDescriptor const&) = delete;
-  FileDescriptor& operator=(FileDescriptor const&) = delete;
-
-private:
-  explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {}
-};
-
-perms posix_get_perms(const StatT& st) noexcept {
-  return static_cast<perms>(st.st_mode) & perms::mask;
-}
-
-file_status create_file_status(error_code& m_ec, path const& p,
-                               const StatT& path_stat, error_code* ec) {
-  if (ec)
-    *ec = m_ec;
-  if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
-    return file_status(file_type::not_found);
-  } else if (m_ec) {
-    ErrorHandler<void> err("posix_stat", ec, &p);
-    err.report(m_ec, "failed to determine attributes for the specified path");
-    return file_status(file_type::none);
-  }
-  // else
-
-  file_status fs_tmp;
-  auto const mode = path_stat.st_mode;
-  if (S_ISLNK(mode))
-    fs_tmp.type(file_type::symlink);
-  else if (S_ISREG(mode))
-    fs_tmp.type(file_type::regular);
-  else if (S_ISDIR(mode))
-    fs_tmp.type(file_type::directory);
-  else if (S_ISBLK(mode))
-    fs_tmp.type(file_type::block);
-  else if (S_ISCHR(mode))
-    fs_tmp.type(file_type::character);
-  else if (S_ISFIFO(mode))
-    fs_tmp.type(file_type::fifo);
-  else if (S_ISSOCK(mode))
-    fs_tmp.type(file_type::socket);
-  else
-    fs_tmp.type(file_type::unknown);
-
-  fs_tmp.permissions(detail::posix_get_perms(path_stat));
-  return fs_tmp;
-}
-
-file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
-  error_code m_ec;
-  if (detail::stat(p.c_str(), &path_stat) == -1)
-    m_ec = detail::capture_errno();
-  return create_file_status(m_ec, p, path_stat, ec);
-}
-
-file_status posix_stat(path const& p, error_code* ec) {
-  StatT path_stat;
-  return posix_stat(p, path_stat, ec);
-}
-
-file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
-  error_code m_ec;
-  if (detail::lstat(p.c_str(), &path_stat) == -1)
-    m_ec = detail::capture_errno();
-  return create_file_status(m_ec, p, path_stat, ec);
-}
-
-file_status posix_lstat(path const& p, error_code* ec) {
-  StatT path_stat;
-  return posix_lstat(p, path_stat, ec);
-}
-
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
-bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
-  if (detail::ftruncate(fd.fd, to_size) == -1) {
-    ec = capture_errno();
-    return true;
-  }
-  ec.clear();
-  return false;
-}
-
-bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
-  if (detail::fchmod(fd.fd, st.st_mode) == -1) {
-    ec = capture_errno();
-    return true;
-  }
-  ec.clear();
-  return false;
-}
-
-bool stat_equivalent(const StatT& st1, const StatT& st2) {
-  return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
-}
-
-file_status FileDescriptor::refresh_status(error_code& ec) {
-  // FD must be open and good.
-  m_status = file_status{};
-  m_stat = {};
-  error_code m_ec;
-  if (detail::fstat(fd, &m_stat) == -1)
-    m_ec = capture_errno();
-  m_status = create_file_status(m_ec, name, m_stat, &ec);
-  return m_status;
-}
-} // namespace
-} // end namespace detail
-
 using detail::capture_errno;
 using detail::ErrorHandler;
 using detail::StatT;
@@ -642,51 +62,6 @@ using parser::createView;
 using parser::PathParser;
 using parser::string_view_t;
 
-const bool _FilesystemClock::is_steady;
-
-_FilesystemClock::time_point _FilesystemClock::now() noexcept {
-  typedef chrono::duration<rep> __secs;
-#if defined(_LIBCPP_WIN32API)
-  typedef chrono::duration<rep, nano> __nsecs;
-  FILETIME time;
-  GetSystemTimeAsFileTime(&time);
-  TimeSpec tp = detail::filetime_to_timespec(time);
-  return time_point(__secs(tp.tv_sec) +
-                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
-#elif defined(CLOCK_REALTIME)
-  typedef chrono::duration<rep, nano> __nsecs;
-  struct timespec tp;
-  if (0 != clock_gettime(CLOCK_REALTIME, &tp))
-    __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
-  return time_point(__secs(tp.tv_sec) +
-                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
-#else
-  typedef chrono::duration<rep, micro> __microsecs;
-  timeval tv;
-  gettimeofday(&tv, 0);
-  return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
-#endif // CLOCK_REALTIME
-}
-
-filesystem_error::~filesystem_error() {}
-
-void filesystem_error::__create_what(int __num_paths) {
-  const char* derived_what = system_error::what();
-  __storage_->__what_ = [&]() -> string {
-    switch (__num_paths) {
-    case 0:
-      return detail::format_string("filesystem error: %s", derived_what);
-    case 1:
-      return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
-                                   derived_what, path1().c_str());
-    case 2:
-      return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
-                                   derived_what, path1().c_str(), path2().c_str());
-    }
-    __libcpp_unreachable();
-  }();
-}
-
 static path __do_absolute(const path& p, path* cwd, error_code* ec) {
   if (ec)
     ec->clear();
@@ -975,7 +350,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
       return err.report(m_ec);
   }
 
-  if (!copy_file_impl(from_fd, to_fd, m_ec)) {
+  if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) {
     // FIXME: Remove the dest file if we failed, and it didn't exist previously.
     return err.report(m_ec);
   }
@@ -1104,7 +479,7 @@ path __current_path(error_code* ec) {
   Deleter deleter = &::free;
 #else
   auto size = ::pathconf(".", _PC_PATH_MAX);
-  _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
+  _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size");
 
   auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
   path::value_type* ptr = buff.get();
@@ -1193,18 +568,6 @@ bool __fs_is_empty(const path& p, error_code* ec) {
   __libcpp_unreachable();
 }
 
-static file_time_type __extract_last_write_time(const path& p, const StatT& st,
-                                                error_code* ec) {
-  using detail::fs_time;
-  ErrorHandler<file_time_type> err("last_write_time", ec, &p);
-
-  auto ts = detail::extract_mtime(st);
-  if (!fs_time::is_representable(ts))
-    return err.report(errc::value_too_large);
-
-  return fs_time::convert_from_timespec(ts);
-}
-
 file_time_type __last_write_time(const path& p, error_code* ec) {
   using namespace chrono;
   ErrorHandler<file_time_type> err("last_write_time", ec, &p);
@@ -1214,7 +577,7 @@ file_time_type __last_write_time(const path& p, error_code* ec) {
   detail::posix_stat(p, st, &m_ec);
   if (m_ec)
     return err.report(m_ec);
-  return __extract_last_write_time(p, st, ec);
+  return detail::__extract_last_write_time(p, st, ec);
 }
 
 void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
@@ -1264,7 +627,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
   const bool resolve_symlinks = !has_opt(perm_options::nofollow);
   const bool add_perms = has_opt(perm_options::add);
   const bool remove_perms = has_opt(perm_options::remove);
-  _LIBCPP_ASSERT(
+  _LIBCPP_ASSERT_UNCATEGORIZED(
       (add_perms + remove_perms + has_opt(perm_options::replace)) == 1,
       "One and only one of the perm_options constants replace, add, or remove "
       "is present in opts");
@@ -1278,7 +641,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
     set_sym_perms = is_symlink(st);
     if (m_ec)
       return err.report(m_ec);
-    _LIBCPP_ASSERT(st.permissions() != perms::unknown,
+    _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown,
                    "Permissions unexpectedly unknown");
     if (add_perms)
       prms |= st.permissions();
@@ -1324,7 +687,7 @@ path __read_symlink(const path& p, error_code* ec) {
   detail::SSizeT ret;
   if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1)
     return err.report(capture_errno());
-  _LIBCPP_ASSERT(ret > 0, "TODO");
+  _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO");
   if (static_cast<size_t>(ret) >= size)
     return err.report(errc::value_too_large);
   buff[ret] = 0;
@@ -1550,8 +913,13 @@ path __temp_directory_path(error_code* ec) {
   for (auto& ep : env_paths)
     if ((ret = getenv(ep)))
       break;
-  if (ret == nullptr)
+  if (ret == nullptr) {
+#if defined(__ANDROID__)
+    ret = "/data/local/tmp";
+#else
     ret = "/tmp";
+#endif
+  }
 
   path p(ret);
 #endif
@@ -1604,500 +972,4 @@ path __weakly_canonical(const path& p, error_code* ec) {
   return result.lexically_normal();
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//                            path definitions
-///////////////////////////////////////////////////////////////////////////////
-
-constexpr path::value_type path::preferred_separator;
-
-path& path::replace_extension(path const& replacement) {
-  path p = extension();
-  if (not p.empty()) {
-    __pn_.erase(__pn_.size() - p.native().size());
-  }
-  if (!replacement.empty()) {
-    if (replacement.native()[0] != '.') {
-      __pn_ += PATHSTR(".");
-    }
-    __pn_.append(replacement.__pn_);
-  }
-  return *this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// path.decompose
-
-string_view_t path::__root_name() const {
-  auto PP = PathParser::CreateBegin(__pn_);
-  if (PP.State == PathParser::PS_InRootName)
-    return *PP;
-  return {};
-}
-
-string_view_t path::__root_directory() const {
-  auto PP = PathParser::CreateBegin(__pn_);
-  if (PP.State == PathParser::PS_InRootName)
-    ++PP;
-  if (PP.State == PathParser::PS_InRootDir)
-    return *PP;
-  return {};
-}
-
-string_view_t path::__root_path_raw() const {
-  auto PP = PathParser::CreateBegin(__pn_);
-  if (PP.State == PathParser::PS_InRootName) {
-    auto NextCh = PP.peek();
-    if (NextCh && isSeparator(*NextCh)) {
-      ++PP;
-      return createView(__pn_.data(), &PP.RawEntry.back());
-    }
-    return PP.RawEntry;
-  }
-  if (PP.State == PathParser::PS_InRootDir)
-    return *PP;
-  return {};
-}
-
-static bool ConsumeRootName(PathParser *PP) {
-  static_assert(PathParser::PS_BeforeBegin == 1 &&
-      PathParser::PS_InRootName == 2,
-      "Values for enums are incorrect");
-  while (PP->State <= PathParser::PS_InRootName)
-    ++(*PP);
-  return PP->State == PathParser::PS_AtEnd;
-}
-
-static bool ConsumeRootDir(PathParser* PP) {
-  static_assert(PathParser::PS_BeforeBegin == 1 &&
-                PathParser::PS_InRootName == 2 &&
-                PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
-  while (PP->State <= PathParser::PS_InRootDir)
-    ++(*PP);
-  return PP->State == PathParser::PS_AtEnd;
-}
-
-string_view_t path::__relative_path() const {
-  auto PP = PathParser::CreateBegin(__pn_);
-  if (ConsumeRootDir(&PP))
-    return {};
-  return createView(PP.RawEntry.data(), &__pn_.back());
-}
-
-string_view_t path::__parent_path() const {
-  if (empty())
-    return {};
-  // Determine if we have a root path but not a relative path. In that case
-  // return *this.
-  {
-    auto PP = PathParser::CreateBegin(__pn_);
-    if (ConsumeRootDir(&PP))
-      return __pn_;
-  }
-  // Otherwise remove a single element from the end of the path, and return
-  // a string representing that path
-  {
-    auto PP = PathParser::CreateEnd(__pn_);
-    --PP;
-    if (PP.RawEntry.data() == __pn_.data())
-      return {};
-    --PP;
-    return createView(__pn_.data(), &PP.RawEntry.back());
-  }
-}
-
-string_view_t path::__filename() const {
-  if (empty())
-    return {};
-  {
-    PathParser PP = PathParser::CreateBegin(__pn_);
-    if (ConsumeRootDir(&PP))
-      return {};
-  }
-  return *(--PathParser::CreateEnd(__pn_));
-}
-
-string_view_t path::__stem() const {
-  return parser::separate_filename(__filename()).first;
-}
-
-string_view_t path::__extension() const {
-  return parser::separate_filename(__filename()).second;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.gen
-
-enum PathPartKind : unsigned char {
-  PK_None,
-  PK_RootSep,
-  PK_Filename,
-  PK_Dot,
-  PK_DotDot,
-  PK_TrailingSep
-};
-
-static PathPartKind ClassifyPathPart(string_view_t Part) {
-  if (Part.empty())
-    return PK_TrailingSep;
-  if (Part == PATHSTR("."))
-    return PK_Dot;
-  if (Part == PATHSTR(".."))
-    return PK_DotDot;
-  if (Part == PATHSTR("/"))
-    return PK_RootSep;
-#if defined(_LIBCPP_WIN32API)
-  if (Part == PATHSTR("\\"))
-    return PK_RootSep;
-#endif
-  return PK_Filename;
-}
-
-path path::lexically_normal() const {
-  if (__pn_.empty())
-    return *this;
-
-  using PartKindPair = pair<string_view_t, PathPartKind>;
-  vector<PartKindPair> Parts;
-  // Guess as to how many elements the path has to avoid reallocating.
-  Parts.reserve(32);
-
-  // Track the total size of the parts as we collect them. This allows the
-  // resulting path to reserve the correct amount of memory.
-  size_t NewPathSize = 0;
-  auto AddPart = [&](PathPartKind K, string_view_t P) {
-    NewPathSize += P.size();
-    Parts.emplace_back(P, K);
-  };
-  auto LastPartKind = [&]() {
-    if (Parts.empty())
-      return PK_None;
-    return Parts.back().second;
-  };
-
-  bool MaybeNeedTrailingSep = false;
-  // Build a stack containing the remaining elements of the path, popping off
-  // elements which occur before a '..' entry.
-  for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
-    auto Part = *PP;
-    PathPartKind Kind = ClassifyPathPart(Part);
-    switch (Kind) {
-    case PK_Filename:
-    case PK_RootSep: {
-      // Add all non-dot and non-dot-dot elements to the stack of elements.
-      AddPart(Kind, Part);
-      MaybeNeedTrailingSep = false;
-      break;
-    }
-    case PK_DotDot: {
-      // Only push a ".." element if there are no elements preceding the "..",
-      // or if the preceding element is itself "..".
-      auto LastKind = LastPartKind();
-      if (LastKind == PK_Filename) {
-        NewPathSize -= Parts.back().first.size();
-        Parts.pop_back();
-      } else if (LastKind != PK_RootSep)
-        AddPart(PK_DotDot, PATHSTR(".."));
-      MaybeNeedTrailingSep = LastKind == PK_Filename;
-      break;
-    }
-    case PK_Dot:
-    case PK_TrailingSep: {
-      MaybeNeedTrailingSep = true;
-      break;
-    }
-    case PK_None:
-      __libcpp_unreachable();
-    }
-  }
-  // [fs.path.generic]p6.8: If the path is empty, add a dot.
-  if (Parts.empty())
-    return PATHSTR(".");
-
-  // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
-  // trailing directory-separator.
-  bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
-
-  path Result;
-  Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
-  for (auto& PK : Parts)
-    Result /= PK.first;
-
-  if (NeedTrailingSep)
-    Result /= PATHSTR("");
-
-  Result.make_preferred();
-  return Result;
-}
-
-static int DetermineLexicalElementCount(PathParser PP) {
-  int Count = 0;
-  for (; PP; ++PP) {
-    auto Elem = *PP;
-    if (Elem == PATHSTR(".."))
-      --Count;
-    else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
-      ++Count;
-  }
-  return Count;
-}
-
-path path::lexically_relative(const path& base) const {
-  { // perform root-name/root-directory mismatch checks
-    auto PP = PathParser::CreateBegin(__pn_);
-    auto PPBase = PathParser::CreateBegin(base.__pn_);
-    auto CheckIterMismatchAtBase = [&]() {
-      return PP.State != PPBase.State &&
-             (PP.inRootPath() || PPBase.inRootPath());
-    };
-    if (PP.inRootName() && PPBase.inRootName()) {
-      if (*PP != *PPBase)
-        return {};
-    } else if (CheckIterMismatchAtBase())
-      return {};
-
-    if (PP.inRootPath())
-      ++PP;
-    if (PPBase.inRootPath())
-      ++PPBase;
-    if (CheckIterMismatchAtBase())
-      return {};
-  }
-
-  // Find the first mismatching element
-  auto PP = PathParser::CreateBegin(__pn_);
-  auto PPBase = PathParser::CreateBegin(base.__pn_);
-  while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
-    ++PP;
-    ++PPBase;
-  }
-
-  // If there is no mismatch, return ".".
-  if (!PP && !PPBase)
-    return ".";
-
-  // Otherwise, determine the number of elements, 'n', which are not dot or
-  // dot-dot minus the number of dot-dot elements.
-  int ElemCount = DetermineLexicalElementCount(PPBase);
-  if (ElemCount < 0)
-    return {};
-
-  // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
-  if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
-    return PATHSTR(".");
-
-  // return a path constructed with 'n' dot-dot elements, followed by the
-  // elements of '*this' after the mismatch.
-  path Result;
-  // FIXME: Reserve enough room in Result that it won't have to re-allocate.
-  while (ElemCount--)
-    Result /= PATHSTR("..");
-  for (; PP; ++PP)
-    Result /= *PP;
-  return Result;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.comparisons
-static int CompareRootName(PathParser *LHS, PathParser *RHS) {
-  if (!LHS->inRootName() && !RHS->inRootName())
-    return 0;
-
-  auto GetRootName = [](PathParser *Parser) -> string_view_t {
-    return Parser->inRootName() ? **Parser : PATHSTR("");
-  };
-  int res = GetRootName(LHS).compare(GetRootName(RHS));
-  ConsumeRootName(LHS);
-  ConsumeRootName(RHS);
-  return res;
-}
-
-static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
-  if (!LHS->inRootDir() && RHS->inRootDir())
-    return -1;
-  else if (LHS->inRootDir() && !RHS->inRootDir())
-    return 1;
-  else {
-    ConsumeRootDir(LHS);
-    ConsumeRootDir(RHS);
-    return 0;
-  }
-}
-
-static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
-  auto &LHS = *LHSPtr;
-  auto &RHS = *RHSPtr;
-
-  int res;
-  while (LHS && RHS) {
-    if ((res = (*LHS).compare(*RHS)) != 0)
-      return res;
-    ++LHS;
-    ++RHS;
-  }
-  return 0;
-}
-
-static int CompareEndState(PathParser *LHS, PathParser *RHS) {
-  if (LHS->atEnd() && !RHS->atEnd())
-    return -1;
-  else if (!LHS->atEnd() && RHS->atEnd())
-    return 1;
-  return 0;
-}
-
-int path::__compare(string_view_t __s) const {
-  auto LHS = PathParser::CreateBegin(__pn_);
-  auto RHS = PathParser::CreateBegin(__s);
-  int res;
-
-  if ((res = CompareRootName(&LHS, &RHS)) != 0)
-    return res;
-
-  if ((res = CompareRootDir(&LHS, &RHS)) != 0)
-    return res;
-
-  if ((res = CompareRelative(&LHS, &RHS)) != 0)
-    return res;
-
-  return CompareEndState(&LHS, &RHS);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.nonmembers
-size_t hash_value(const path& __p) noexcept {
-  auto PP = PathParser::CreateBegin(__p.native());
-  size_t hash_value = 0;
-  hash<string_view_t> hasher;
-  while (PP) {
-    hash_value = __hash_combine(hash_value, hasher(*PP));
-    ++PP;
-  }
-  return hash_value;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.itr
-path::iterator path::begin() const {
-  auto PP = PathParser::CreateBegin(__pn_);
-  iterator it;
-  it.__path_ptr_ = this;
-  it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
-  it.__entry_ = PP.RawEntry;
-  it.__stashed_elem_.__assign_view(*PP);
-  return it;
-}
-
-path::iterator path::end() const {
-  iterator it{};
-  it.__state_ = path::iterator::_AtEnd;
-  it.__path_ptr_ = this;
-  return it;
-}
-
-path::iterator& path::iterator::__increment() {
-  PathParser PP(__path_ptr_->native(), __entry_, __state_);
-  ++PP;
-  __state_ = static_cast<_ParserState>(PP.State);
-  __entry_ = PP.RawEntry;
-  __stashed_elem_.__assign_view(*PP);
-  return *this;
-}
-
-path::iterator& path::iterator::__decrement() {
-  PathParser PP(__path_ptr_->native(), __entry_, __state_);
-  --PP;
-  __state_ = static_cast<_ParserState>(PP.State);
-  __entry_ = PP.RawEntry;
-  __stashed_elem_.__assign_view(*PP);
-  return *this;
-}
-
-#if defined(_LIBCPP_WIN32API)
-////////////////////////////////////////////////////////////////////////////
-// Windows path conversions
-size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
-  if (str.empty())
-    return 0;
-  ErrorHandler<size_t> err("__wide_to_char", nullptr);
-  UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
-  BOOL used_default = FALSE;
-  int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
-                                outlen, nullptr, &used_default);
-  if (ret <= 0 || used_default)
-    return err.report(errc::illegal_byte_sequence);
-  return ret;
-}
-
-size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
-  if (str.empty())
-    return 0;
-  ErrorHandler<size_t> err("__char_to_wide", nullptr);
-  UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
-  int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
-                                str.size(), out, outlen);
-  if (ret <= 0)
-    return err.report(errc::illegal_byte_sequence);
-  return ret;
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////
-//                           directory entry definitions
-///////////////////////////////////////////////////////////////////////////////
-
-error_code directory_entry::__do_refresh() noexcept {
-  __data_.__reset();
-  error_code failure_ec;
-
-  StatT full_st;
-  file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
-  if (!status_known(st)) {
-    __data_.__reset();
-    return failure_ec;
-  }
-
-  if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
-    __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
-    __data_.__type_ = st.type();
-    __data_.__non_sym_perms_ = st.permissions();
-  } else { // we have a symlink
-    __data_.__sym_perms_ = st.permissions();
-    // Get the information about the linked entity.
-    // Ignore errors from stat, since we don't want errors regarding symlink
-    // resolution to be reported to the user.
-    error_code ignored_ec;
-    st = detail::posix_stat(__p_, full_st, &ignored_ec);
-
-    __data_.__type_ = st.type();
-    __data_.__non_sym_perms_ = st.permissions();
-
-    // If we failed to resolve the link, then only partially populate the
-    // cache.
-    if (!status_known(st)) {
-      __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
-      return error_code{};
-    }
-    // Otherwise, we resolved the link, potentially as not existing.
-    // That's OK.
-    __data_.__cache_type_ = directory_entry::_RefreshSymlink;
-  }
-
-  if (_VSTD_FS::is_regular_file(st))
-    __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
-
-  if (_VSTD_FS::exists(st)) {
-    __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
-
-    // Attempt to extract the mtime, and fail if it's not representable using
-    // file_time_type. For now we ignore the error, as we'll report it when
-    // the value is actually used.
-    error_code ignored_ec;
-    __data_.__write_time_ =
-        __extract_last_write_time(__p_, full_st, &ignored_ec);
-  }
-
-  return failure_ec;
-}
-
 _LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/path.cpp
@@ -0,0 +1,460 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <filesystem>
+#include <vector>
+
+#include "error.h"
+#include "path_parser.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+using detail::ErrorHandler;
+using parser::createView;
+using parser::PathParser;
+using parser::string_view_t;
+
+///////////////////////////////////////////////////////////////////////////////
+//                            path definitions
+///////////////////////////////////////////////////////////////////////////////
+
+constexpr path::value_type path::preferred_separator;
+
+path& path::replace_extension(path const& replacement) {
+  path p = extension();
+  if (not p.empty()) {
+    __pn_.erase(__pn_.size() - p.native().size());
+  }
+  if (!replacement.empty()) {
+    if (replacement.native()[0] != '.') {
+      __pn_ += PATHSTR(".");
+    }
+    __pn_.append(replacement.__pn_);
+  }
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// path.decompose
+
+string_view_t path::__root_name() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName)
+    return *PP;
+  return {};
+}
+
+string_view_t path::__root_directory() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName)
+    ++PP;
+  if (PP.State == PathParser::PS_InRootDir)
+    return *PP;
+  return {};
+}
+
+string_view_t path::__root_path_raw() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName) {
+    auto NextCh = PP.peek();
+    if (NextCh && isSeparator(*NextCh)) {
+      ++PP;
+      return createView(__pn_.data(), &PP.RawEntry.back());
+    }
+    return PP.RawEntry;
+  }
+  if (PP.State == PathParser::PS_InRootDir)
+    return *PP;
+  return {};
+}
+
+static bool ConsumeRootName(PathParser *PP) {
+  static_assert(PathParser::PS_BeforeBegin == 1 &&
+      PathParser::PS_InRootName == 2,
+      "Values for enums are incorrect");
+  while (PP->State <= PathParser::PS_InRootName)
+    ++(*PP);
+  return PP->State == PathParser::PS_AtEnd;
+}
+
+static bool ConsumeRootDir(PathParser* PP) {
+  static_assert(PathParser::PS_BeforeBegin == 1 &&
+                PathParser::PS_InRootName == 2 &&
+                PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
+  while (PP->State <= PathParser::PS_InRootDir)
+    ++(*PP);
+  return PP->State == PathParser::PS_AtEnd;
+}
+
+string_view_t path::__relative_path() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (ConsumeRootDir(&PP))
+    return {};
+  return createView(PP.RawEntry.data(), &__pn_.back());
+}
+
+string_view_t path::__parent_path() const {
+  if (empty())
+    return {};
+  // Determine if we have a root path but not a relative path. In that case
+  // return *this.
+  {
+    auto PP = PathParser::CreateBegin(__pn_);
+    if (ConsumeRootDir(&PP))
+      return __pn_;
+  }
+  // Otherwise remove a single element from the end of the path, and return
+  // a string representing that path
+  {
+    auto PP = PathParser::CreateEnd(__pn_);
+    --PP;
+    if (PP.RawEntry.data() == __pn_.data())
+      return {};
+    --PP;
+    return createView(__pn_.data(), &PP.RawEntry.back());
+  }
+}
+
+string_view_t path::__filename() const {
+  if (empty())
+    return {};
+  {
+    PathParser PP = PathParser::CreateBegin(__pn_);
+    if (ConsumeRootDir(&PP))
+      return {};
+  }
+  return *(--PathParser::CreateEnd(__pn_));
+}
+
+string_view_t path::__stem() const {
+  return parser::separate_filename(__filename()).first;
+}
+
+string_view_t path::__extension() const {
+  return parser::separate_filename(__filename()).second;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.gen
+
+enum PathPartKind : unsigned char {
+  PK_None,
+  PK_RootSep,
+  PK_Filename,
+  PK_Dot,
+  PK_DotDot,
+  PK_TrailingSep
+};
+
+static PathPartKind ClassifyPathPart(string_view_t Part) {
+  if (Part.empty())
+    return PK_TrailingSep;
+  if (Part == PATHSTR("."))
+    return PK_Dot;
+  if (Part == PATHSTR(".."))
+    return PK_DotDot;
+  if (Part == PATHSTR("/"))
+    return PK_RootSep;
+#if defined(_LIBCPP_WIN32API)
+  if (Part == PATHSTR("\\"))
+    return PK_RootSep;
+#endif
+  return PK_Filename;
+}
+
+path path::lexically_normal() const {
+  if (__pn_.empty())
+    return *this;
+
+  using PartKindPair = pair<string_view_t, PathPartKind>;
+  vector<PartKindPair> Parts;
+  // Guess as to how many elements the path has to avoid reallocating.
+  Parts.reserve(32);
+
+  // Track the total size of the parts as we collect them. This allows the
+  // resulting path to reserve the correct amount of memory.
+  size_t NewPathSize = 0;
+  auto AddPart = [&](PathPartKind K, string_view_t P) {
+    NewPathSize += P.size();
+    Parts.emplace_back(P, K);
+  };
+  auto LastPartKind = [&]() {
+    if (Parts.empty())
+      return PK_None;
+    return Parts.back().second;
+  };
+
+  bool MaybeNeedTrailingSep = false;
+  // Build a stack containing the remaining elements of the path, popping off
+  // elements which occur before a '..' entry.
+  for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
+    auto Part = *PP;
+    PathPartKind Kind = ClassifyPathPart(Part);
+    switch (Kind) {
+    case PK_Filename:
+    case PK_RootSep: {
+      // Add all non-dot and non-dot-dot elements to the stack of elements.
+      AddPart(Kind, Part);
+      MaybeNeedTrailingSep = false;
+      break;
+    }
+    case PK_DotDot: {
+      // Only push a ".." element if there are no elements preceding the "..",
+      // or if the preceding element is itself "..".
+      auto LastKind = LastPartKind();
+      if (LastKind == PK_Filename) {
+        NewPathSize -= Parts.back().first.size();
+        Parts.pop_back();
+      } else if (LastKind != PK_RootSep)
+        AddPart(PK_DotDot, PATHSTR(".."));
+      MaybeNeedTrailingSep = LastKind == PK_Filename;
+      break;
+    }
+    case PK_Dot:
+    case PK_TrailingSep: {
+      MaybeNeedTrailingSep = true;
+      break;
+    }
+    case PK_None:
+      __libcpp_unreachable();
+    }
+  }
+  // [fs.path.generic]p6.8: If the path is empty, add a dot.
+  if (Parts.empty())
+    return PATHSTR(".");
+
+  // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
+  // trailing directory-separator.
+  bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
+
+  path Result;
+  Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
+  for (auto& PK : Parts)
+    Result /= PK.first;
+
+  if (NeedTrailingSep)
+    Result /= PATHSTR("");
+
+  Result.make_preferred();
+  return Result;
+}
+
+static int DetermineLexicalElementCount(PathParser PP) {
+  int Count = 0;
+  for (; PP; ++PP) {
+    auto Elem = *PP;
+    if (Elem == PATHSTR(".."))
+      --Count;
+    else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
+      ++Count;
+  }
+  return Count;
+}
+
+path path::lexically_relative(const path& base) const {
+  { // perform root-name/root-directory mismatch checks
+    auto PP = PathParser::CreateBegin(__pn_);
+    auto PPBase = PathParser::CreateBegin(base.__pn_);
+    auto CheckIterMismatchAtBase = [&]() {
+      return PP.State != PPBase.State &&
+             (PP.inRootPath() || PPBase.inRootPath());
+    };
+    if (PP.inRootName() && PPBase.inRootName()) {
+      if (*PP != *PPBase)
+        return {};
+    } else if (CheckIterMismatchAtBase())
+      return {};
+
+    if (PP.inRootPath())
+      ++PP;
+    if (PPBase.inRootPath())
+      ++PPBase;
+    if (CheckIterMismatchAtBase())
+      return {};
+  }
+
+  // Find the first mismatching element
+  auto PP = PathParser::CreateBegin(__pn_);
+  auto PPBase = PathParser::CreateBegin(base.__pn_);
+  while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
+    ++PP;
+    ++PPBase;
+  }
+
+  // If there is no mismatch, return ".".
+  if (!PP && !PPBase)
+    return ".";
+
+  // Otherwise, determine the number of elements, 'n', which are not dot or
+  // dot-dot minus the number of dot-dot elements.
+  int ElemCount = DetermineLexicalElementCount(PPBase);
+  if (ElemCount < 0)
+    return {};
+
+  // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
+  if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
+    return PATHSTR(".");
+
+  // return a path constructed with 'n' dot-dot elements, followed by the
+  // elements of '*this' after the mismatch.
+  path Result;
+  // FIXME: Reserve enough room in Result that it won't have to re-allocate.
+  while (ElemCount--)
+    Result /= PATHSTR("..");
+  for (; PP; ++PP)
+    Result /= *PP;
+  return Result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.comparisons
+static int CompareRootName(PathParser *LHS, PathParser *RHS) {
+  if (!LHS->inRootName() && !RHS->inRootName())
+    return 0;
+
+  auto GetRootName = [](PathParser *Parser) -> string_view_t {
+    return Parser->inRootName() ? **Parser : PATHSTR("");
+  };
+  int res = GetRootName(LHS).compare(GetRootName(RHS));
+  ConsumeRootName(LHS);
+  ConsumeRootName(RHS);
+  return res;
+}
+
+static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
+  if (!LHS->inRootDir() && RHS->inRootDir())
+    return -1;
+  else if (LHS->inRootDir() && !RHS->inRootDir())
+    return 1;
+  else {
+    ConsumeRootDir(LHS);
+    ConsumeRootDir(RHS);
+    return 0;
+  }
+}
+
+static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
+  auto &LHS = *LHSPtr;
+  auto &RHS = *RHSPtr;
+
+  int res;
+  while (LHS && RHS) {
+    if ((res = (*LHS).compare(*RHS)) != 0)
+      return res;
+    ++LHS;
+    ++RHS;
+  }
+  return 0;
+}
+
+static int CompareEndState(PathParser *LHS, PathParser *RHS) {
+  if (LHS->atEnd() && !RHS->atEnd())
+    return -1;
+  else if (!LHS->atEnd() && RHS->atEnd())
+    return 1;
+  return 0;
+}
+
+int path::__compare(string_view_t __s) const {
+  auto LHS = PathParser::CreateBegin(__pn_);
+  auto RHS = PathParser::CreateBegin(__s);
+  int res;
+
+  if ((res = CompareRootName(&LHS, &RHS)) != 0)
+    return res;
+
+  if ((res = CompareRootDir(&LHS, &RHS)) != 0)
+    return res;
+
+  if ((res = CompareRelative(&LHS, &RHS)) != 0)
+    return res;
+
+  return CompareEndState(&LHS, &RHS);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.nonmembers
+size_t hash_value(const path& __p) noexcept {
+  auto PP = PathParser::CreateBegin(__p.native());
+  size_t hash_value = 0;
+  hash<string_view_t> hasher;
+  while (PP) {
+    hash_value = __hash_combine(hash_value, hasher(*PP));
+    ++PP;
+  }
+  return hash_value;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.itr
+path::iterator path::begin() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  iterator it;
+  it.__path_ptr_ = this;
+  it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
+  it.__entry_ = PP.RawEntry;
+  it.__stashed_elem_.__assign_view(*PP);
+  return it;
+}
+
+path::iterator path::end() const {
+  iterator it{};
+  it.__state_ = path::iterator::_AtEnd;
+  it.__path_ptr_ = this;
+  return it;
+}
+
+path::iterator& path::iterator::__increment() {
+  PathParser PP(__path_ptr_->native(), __entry_, __state_);
+  ++PP;
+  __state_ = static_cast<_ParserState>(PP.State);
+  __entry_ = PP.RawEntry;
+  __stashed_elem_.__assign_view(*PP);
+  return *this;
+}
+
+path::iterator& path::iterator::__decrement() {
+  PathParser PP(__path_ptr_->native(), __entry_, __state_);
+  --PP;
+  __state_ = static_cast<_ParserState>(PP.State);
+  __entry_ = PP.RawEntry;
+  __stashed_elem_.__assign_view(*PP);
+  return *this;
+}
+
+#if defined(_LIBCPP_WIN32API)
+////////////////////////////////////////////////////////////////////////////
+// Windows path conversions
+size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
+  if (str.empty())
+    return 0;
+  ErrorHandler<size_t> err("__wide_to_char", nullptr);
+  UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+  BOOL used_default = FALSE;
+  int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
+                                outlen, nullptr, &used_default);
+  if (ret <= 0 || used_default)
+    return err.report(errc::illegal_byte_sequence);
+  return ret;
+}
+
+size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
+  if (str.empty())
+    return 0;
+  ErrorHandler<size_t> err("__char_to_wide", nullptr);
+  UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+  int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
+                                str.size(), out, outlen);
+  if (ret <= 0)
+    return err.report(errc::illegal_byte_sequence);
+  return ret;
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/path_parser.h
@@ -0,0 +1,368 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 PATH_PARSER_H
+#define PATH_PARSER_H
+
+#include <__config>
+#include <__utility/unreachable.h>
+#include <cstddef>
+#include <filesystem>
+#include <utility>
+
+#include "format_string.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+inline bool isSeparator(path::value_type C) {
+  if (C == '/')
+    return true;
+#if defined(_LIBCPP_WIN32API)
+  if (C == '\\')
+    return true;
+#endif
+  return false;
+}
+
+inline bool isDriveLetter(path::value_type C) {
+  return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
+}
+
+namespace parser {
+
+using string_view_t = path::__string_view;
+using string_view_pair = pair<string_view_t, string_view_t>;
+using PosPtr = path::value_type const*;
+
+struct PathParser {
+  enum ParserState : unsigned char {
+    // Zero is a special sentinel value used by default constructed iterators.
+    PS_BeforeBegin = path::iterator::_BeforeBegin,
+    PS_InRootName = path::iterator::_InRootName,
+    PS_InRootDir = path::iterator::_InRootDir,
+    PS_InFilenames = path::iterator::_InFilenames,
+    PS_InTrailingSep = path::iterator::_InTrailingSep,
+    PS_AtEnd = path::iterator::_AtEnd
+  };
+
+  const string_view_t Path;
+  string_view_t RawEntry;
+  ParserState State;
+
+private:
+  PathParser(string_view_t P, ParserState State) noexcept : Path(P),
+                                                            State(State) {}
+
+public:
+  PathParser(string_view_t P, string_view_t E, unsigned char S)
+      : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
+    // S cannot be '0' or PS_BeforeBegin.
+  }
+
+  static PathParser CreateBegin(string_view_t P) noexcept {
+    PathParser PP(P, PS_BeforeBegin);
+    PP.increment();
+    return PP;
+  }
+
+  static PathParser CreateEnd(string_view_t P) noexcept {
+    PathParser PP(P, PS_AtEnd);
+    return PP;
+  }
+
+  PosPtr peek() const noexcept {
+    auto TkEnd = getNextTokenStartPos();
+    auto End = getAfterBack();
+    return TkEnd == End ? nullptr : TkEnd;
+  }
+
+  void increment() noexcept {
+    const PosPtr End = getAfterBack();
+    const PosPtr Start = getNextTokenStartPos();
+    if (Start == End)
+      return makeState(PS_AtEnd);
+
+    switch (State) {
+    case PS_BeforeBegin: {
+      PosPtr TkEnd = consumeRootName(Start, End);
+      if (TkEnd)
+        return makeState(PS_InRootName, Start, TkEnd);
+    }
+      _LIBCPP_FALLTHROUGH();
+    case PS_InRootName: {
+      PosPtr TkEnd = consumeAllSeparators(Start, End);
+      if (TkEnd)
+        return makeState(PS_InRootDir, Start, TkEnd);
+      else
+        return makeState(PS_InFilenames, Start, consumeName(Start, End));
+    }
+    case PS_InRootDir:
+      return makeState(PS_InFilenames, Start, consumeName(Start, End));
+
+    case PS_InFilenames: {
+      PosPtr SepEnd = consumeAllSeparators(Start, End);
+      if (SepEnd != End) {
+        PosPtr TkEnd = consumeName(SepEnd, End);
+        if (TkEnd)
+          return makeState(PS_InFilenames, SepEnd, TkEnd);
+      }
+      return makeState(PS_InTrailingSep, Start, SepEnd);
+    }
+
+    case PS_InTrailingSep:
+      return makeState(PS_AtEnd);
+
+    case PS_AtEnd:
+      __libcpp_unreachable();
+    }
+  }
+
+  void decrement() noexcept {
+    const PosPtr REnd = getBeforeFront();
+    const PosPtr RStart = getCurrentTokenStartPos() - 1;
+    if (RStart == REnd) // we're decrementing the begin
+      return makeState(PS_BeforeBegin);
+
+    switch (State) {
+    case PS_AtEnd: {
+      // Try to consume a trailing separator or root directory first.
+      if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
+        if (SepEnd == REnd)
+          return makeState(PS_InRootDir, Path.data(), RStart + 1);
+        PosPtr TkStart = consumeRootName(SepEnd, REnd);
+        if (TkStart == REnd)
+          return makeState(PS_InRootDir, RStart, RStart + 1);
+        return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
+      } else {
+        PosPtr TkStart = consumeRootName(RStart, REnd);
+        if (TkStart == REnd)
+          return makeState(PS_InRootName, TkStart + 1, RStart + 1);
+        TkStart = consumeName(RStart, REnd);
+        return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
+      }
+    }
+    case PS_InTrailingSep:
+      return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
+                       RStart + 1);
+    case PS_InFilenames: {
+      PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
+      if (SepEnd == REnd)
+        return makeState(PS_InRootDir, Path.data(), RStart + 1);
+      PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
+      if (TkStart == REnd) {
+        if (SepEnd)
+          return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
+        return makeState(PS_InRootName, TkStart + 1, RStart + 1);
+      }
+      TkStart = consumeName(SepEnd, REnd);
+      return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
+    }
+    case PS_InRootDir:
+      return makeState(PS_InRootName, Path.data(), RStart + 1);
+    case PS_InRootName:
+    case PS_BeforeBegin:
+      __libcpp_unreachable();
+    }
+  }
+
+  /// \brief Return a view with the "preferred representation" of the current
+  ///   element. For example trailing separators are represented as a '.'
+  string_view_t operator*() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+    case PS_AtEnd:
+      return PATHSTR("");
+    case PS_InRootDir:
+      if (RawEntry[0] == '\\')
+        return PATHSTR("\\");
+      else
+        return PATHSTR("/");
+    case PS_InTrailingSep:
+      return PATHSTR("");
+    case PS_InRootName:
+    case PS_InFilenames:
+      return RawEntry;
+    }
+    __libcpp_unreachable();
+  }
+
+  explicit operator bool() const noexcept {
+    return State != PS_BeforeBegin && State != PS_AtEnd;
+  }
+
+  PathParser& operator++() noexcept {
+    increment();
+    return *this;
+  }
+
+  PathParser& operator--() noexcept {
+    decrement();
+    return *this;
+  }
+
+  bool atEnd() const noexcept {
+    return State == PS_AtEnd;
+  }
+
+  bool inRootDir() const noexcept {
+    return State == PS_InRootDir;
+  }
+
+  bool inRootName() const noexcept {
+    return State == PS_InRootName;
+  }
+
+  bool inRootPath() const noexcept {
+    return inRootName() || inRootDir();
+  }
+
+private:
+  void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
+    State = NewState;
+    RawEntry = string_view_t(Start, End - Start);
+  }
+  void makeState(ParserState NewState) noexcept {
+    State = NewState;
+    RawEntry = {};
+  }
+
+  PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
+
+  PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
+
+  /// \brief Return a pointer to the first character after the currently
+  ///   lexed element.
+  PosPtr getNextTokenStartPos() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+      return Path.data();
+    case PS_InRootName:
+    case PS_InRootDir:
+    case PS_InFilenames:
+      return &RawEntry.back() + 1;
+    case PS_InTrailingSep:
+    case PS_AtEnd:
+      return getAfterBack();
+    }
+    __libcpp_unreachable();
+  }
+
+  /// \brief Return a pointer to the first character in the currently lexed
+  ///   element.
+  PosPtr getCurrentTokenStartPos() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+    case PS_InRootName:
+      return &Path.front();
+    case PS_InRootDir:
+    case PS_InFilenames:
+    case PS_InTrailingSep:
+      return &RawEntry.front();
+    case PS_AtEnd:
+      return &Path.back() + 1;
+    }
+    __libcpp_unreachable();
+  }
+
+  // Consume all consecutive separators.
+  PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
+    if (P == nullptr || P == End || !isSeparator(*P))
+      return nullptr;
+    const int Inc = P < End ? 1 : -1;
+    P += Inc;
+    while (P != End && isSeparator(*P))
+      P += Inc;
+    return P;
+  }
+
+  // Consume exactly N separators, or return nullptr.
+  PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
+    PosPtr Ret = consumeAllSeparators(P, End);
+    if (Ret == nullptr)
+      return nullptr;
+    if (P < End) {
+      if (Ret == P + N)
+        return Ret;
+    } else {
+      if (Ret == P - N)
+        return Ret;
+    }
+    return nullptr;
+  }
+
+  PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
+    PosPtr Start = P;
+    if (P == nullptr || P == End || isSeparator(*P))
+      return nullptr;
+    const int Inc = P < End ? 1 : -1;
+    P += Inc;
+    while (P != End && !isSeparator(*P))
+      P += Inc;
+    if (P == End && Inc < 0) {
+      // Iterating backwards and consumed all the rest of the input.
+      // Check if the start of the string would have been considered
+      // a root name.
+      PosPtr RootEnd = consumeRootName(End + 1, Start);
+      if (RootEnd)
+        return RootEnd - 1;
+    }
+    return P;
+  }
+
+  PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
+    if (P == End)
+      return nullptr;
+    if (P < End) {
+      if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
+        return nullptr;
+      return P + 2;
+    } else {
+      if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
+        return nullptr;
+      return P - 2;
+    }
+  }
+
+  PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
+    if (P == End)
+      return nullptr;
+    if (P < End)
+      return consumeName(consumeNSeparators(P, End, 2), End);
+    else
+      return consumeNSeparators(consumeName(P, End), End, 2);
+  }
+
+  PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
+#if defined(_LIBCPP_WIN32API)
+    if (PosPtr Ret = consumeDriveLetter(P, End))
+      return Ret;
+    if (PosPtr Ret = consumeNetworkRoot(P, End))
+      return Ret;
+#endif
+    return nullptr;
+  }
+};
+
+inline string_view_pair separate_filename(string_view_t const& s) {
+  if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
+    return string_view_pair{s, PATHSTR("")};
+  auto pos = s.find_last_of('.');
+  if (pos == string_view_t::npos || pos == 0)
+    return string_view_pair{s, string_view_t{}};
+  return string_view_pair{s.substr(0, pos), s.substr(pos)};
+}
+
+inline string_view_t createView(PosPtr S, PosPtr E) noexcept {
+  return {S, static_cast<size_t>(E - S) + 1};
+}
+
+} // namespace parser
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // PATH_PARSER_H
lib/libcxx/src/filesystem/posix_compat.h
@@ -24,9 +24,11 @@
 #define POSIX_COMPAT_H
 
 #include <__assert>
+#include <__config>
 #include <filesystem>
 
-#include "filesystem_common.h"
+#include "error.h"
+#include "time_utils.h"
 
 #if defined(_LIBCPP_WIN32API)
 # define WIN32_LEAN_AND_MEAN
@@ -35,10 +37,13 @@
 # include <io.h>
 # include <winioctl.h>
 #else
+# include <fcntl.h>
 # include <unistd.h>
 # include <sys/stat.h>
 # include <sys/statvfs.h>
+# include <sys/time.h>
 #endif
+#include <stdlib.h>
 #include <time.h>
 
 #if defined(_LIBCPP_WIN32API)
@@ -74,7 +79,6 @@ struct LIBCPP_REPARSE_DATA_BUFFER {
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
 namespace detail {
-namespace {
 
 #if defined(_LIBCPP_WIN32API)
 
@@ -118,36 +122,7 @@ namespace {
 
 #define O_NONBLOCK 0
 
-
-// There were 369 years and 89 leap days from the Windows epoch
-// (1601) to the Unix epoch (1970).
-#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
-
-TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
-  TimeSpec ret;
-  ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
-  ret.tv_nsec = (li.QuadPart % 10000000) * 100;
-  return ret;
-}
-
-TimeSpec filetime_to_timespec(FILETIME ft) {
-  LARGE_INTEGER li;
-  li.LowPart = ft.dwLowDateTime;
-  li.HighPart = ft.dwHighDateTime;
-  return filetime_to_timespec(li);
-}
-
-FILETIME timespec_to_filetime(TimeSpec ts) {
-  LARGE_INTEGER li;
-  li.QuadPart =
-      ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
-  FILETIME ft;
-  ft.dwLowDateTime = li.LowPart;
-  ft.dwHighDateTime = li.HighPart;
-  return ft;
-}
-
-int set_errno(int e = GetLastError()) {
+inline int set_errno(int e = GetLastError()) {
   errno = static_cast<int>(__win_err_to_errc(e));
   return -1;
 }
@@ -170,7 +145,7 @@ private:
   HANDLE h;
 };
 
-int stat_handle(HANDLE h, StatT *buf) {
+inline int stat_handle(HANDLE h, StatT *buf) {
   FILE_BASIC_INFO basic;
   if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
     return set_errno();
@@ -208,7 +183,7 @@ int stat_handle(HANDLE h, StatT *buf) {
   return 0;
 }
 
-int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
+inline int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
   WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
   if (!h)
     return set_errno();
@@ -216,24 +191,26 @@ int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
   return ret;
 }
 
-int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
+inline int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
 
-int lstat(const wchar_t *path, StatT *buf) {
+inline int lstat(const wchar_t *path, StatT *buf) {
   return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
 }
 
-int fstat(int fd, StatT *buf) {
+inline int fstat(int fd, StatT *buf) {
   HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
   return stat_handle(h, buf);
 }
 
-int mkdir(const wchar_t *path, int permissions) {
+inline int mkdir(const wchar_t *path, int permissions) {
   (void)permissions;
-  return _wmkdir(path);
+  if (!CreateDirectoryW(path, nullptr))
+    return set_errno();
+  return 0;
 }
 
-int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
-                     bool is_dir) {
+inline int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
+                            bool is_dir) {
   path dest(oldname);
   dest.make_preferred();
   oldname = dest.c_str();
@@ -249,21 +226,21 @@ int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
   return set_errno();
 }
 
-int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
   return symlink_file_dir(oldname, newname, false);
 }
 
-int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
   return symlink_file_dir(oldname, newname, true);
 }
 
-int link(const wchar_t *oldname, const wchar_t *newname) {
+inline int link(const wchar_t *oldname, const wchar_t *newname) {
   if (CreateHardLinkW(newname, oldname, nullptr))
     return 0;
   return set_errno();
 }
 
-int remove(const wchar_t *path) {
+inline int remove(const wchar_t *path) {
   detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
   if (!h)
     return set_errno();
@@ -274,7 +251,7 @@ int remove(const wchar_t *path) {
   return 0;
 }
 
-int truncate_handle(HANDLE h, off_t length) {
+inline int truncate_handle(HANDLE h, off_t length) {
   LARGE_INTEGER size_param;
   size_param.QuadPart = length;
   if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
@@ -284,19 +261,19 @@ int truncate_handle(HANDLE h, off_t length) {
   return 0;
 }
 
-int ftruncate(int fd, off_t length) {
+inline int ftruncate(int fd, off_t length) {
   HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
   return truncate_handle(h, length);
 }
 
-int truncate(const wchar_t *path, off_t length) {
+inline int truncate(const wchar_t *path, off_t length) {
   detail::WinHandle h(path, GENERIC_WRITE, 0);
   if (!h)
     return set_errno();
   return truncate_handle(h, length);
 }
 
-int rename(const wchar_t *from, const wchar_t *to) {
+inline int rename(const wchar_t *from, const wchar_t *to) {
   if (!(MoveFileExW(from, to,
                     MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
                         MOVEFILE_WRITE_THROUGH)))
@@ -304,11 +281,11 @@ int rename(const wchar_t *from, const wchar_t *to) {
   return 0;
 }
 
-template <class... Args> int open(const wchar_t *filename, Args... args) {
-  return _wopen(filename, args...);
+inline int chdir(const wchar_t* path) {
+  if (!SetCurrentDirectoryW(path))
+    return set_errno();
+  return 0;
 }
-int close(int fd) { return _close(fd); }
-int chdir(const wchar_t *path) { return _wchdir(path); }
 
 struct StatVFS {
   uint64_t f_frsize;
@@ -317,7 +294,7 @@ struct StatVFS {
   uint64_t f_bavail;
 };
 
-int statvfs(const wchar_t *p, StatVFS *buf) {
+inline int statvfs(const wchar_t *p, StatVFS *buf) {
   path dir = p;
   while (true) {
     error_code local_ec;
@@ -343,11 +320,29 @@ int statvfs(const wchar_t *p, StatVFS *buf) {
   return 0;
 }
 
-wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
+inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t in_size) {
+  // Only expected to be used with us allocating the buffer.
+  _LIBCPP_ASSERT(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr");
+  _LIBCPP_ASSERT(in_size == 0, "Windows getcwd() assumes in_size==0");
+
+  size_t buff_size = MAX_PATH + 10;
+  std::unique_ptr<wchar_t, decltype(&::free)> buff(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))), &::free);
+  DWORD retval = GetCurrentDirectoryW(buff_size, buff.get());
+  if (retval > buff_size) {
+    buff_size = retval;
+    buff.reset(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))));
+    retval = GetCurrentDirectoryW(buff_size, buff.get());
+  }
+  if (!retval) {
+    set_errno();
+    return nullptr;
+  }
+  return buff.release();
+}
 
-wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
+inline wchar_t *realpath(const wchar_t *path, [[maybe_unused]] wchar_t *resolved_name) {
   // Only expected to be used with us allocating the buffer.
-  _LIBCPP_ASSERT(resolved_name == nullptr,
+  _LIBCPP_ASSERT_UNCATEGORIZED(resolved_name == nullptr,
                  "Windows realpath() assumes a null resolved_name");
 
   WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
@@ -386,7 +381,7 @@ wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
 #define AT_SYMLINK_NOFOLLOW 1
 using ModeT = int;
 
-int fchmod_handle(HANDLE h, int perms) {
+inline int fchmod_handle(HANDLE h, int perms) {
   FILE_BASIC_INFO basic;
   if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
     return set_errno();
@@ -400,7 +395,7 @@ int fchmod_handle(HANDLE h, int perms) {
   return 0;
 }
 
-int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
+inline int fchmodat(int /*fd*/, const wchar_t *path, int perms, int flag) {
   DWORD attributes = GetFileAttributesW(path);
   if (attributes == INVALID_FILE_ATTRIBUTES)
     return set_errno();
@@ -427,7 +422,7 @@ int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
   return 0;
 }
 
-int fchmod(int fd, int perms) {
+inline int fchmod(int fd, int perms) {
   HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
   return fchmod_handle(h, perms);
 }
@@ -435,7 +430,7 @@ int fchmod(int fd, int perms) {
 #define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
 using SSizeT = ::int64_t;
 
-SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
+inline SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
   uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
   detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
   if (!h)
@@ -479,14 +474,13 @@ SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
 }
 
 #else
-int symlink_file(const char *oldname, const char *newname) {
+inline int symlink_file(const char *oldname, const char *newname) {
   return ::symlink(oldname, newname);
 }
-int symlink_dir(const char *oldname, const char *newname) {
+inline int symlink_dir(const char *oldname, const char *newname) {
   return ::symlink(oldname, newname);
 }
 using ::chdir;
-using ::close;
 using ::fchmod;
 #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
 using ::fchmodat;
@@ -497,7 +491,6 @@ using ::getcwd;
 using ::link;
 using ::lstat;
 using ::mkdir;
-using ::open;
 using ::readlink;
 using ::realpath;
 using ::remove;
@@ -514,7 +507,6 @@ using SSizeT = ::ssize_t;
 
 #endif
 
-} // namespace
 } // end namespace detail
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/filesystem_common.h → lib/libcxx/src/filesystem/time_utils.h
@@ -6,253 +6,47 @@
 //
 //===----------------------------------------------------------------------===////
 
-#ifndef FILESYSTEM_COMMON_H
-#define FILESYSTEM_COMMON_H
+#ifndef FILESYSTEM_TIME_UTILS_H
+#define FILESYSTEM_TIME_UTILS_H
 
-#include <__assert>
 #include <__config>
 #include <array>
 #include <chrono>
-#include <climits>
-#include <cstdarg>
-#include <ctime>
 #include <filesystem>
+#include <limits>
 #include <ratio>
 #include <system_error>
+#include <type_traits>
 #include <utility>
 
+#include "error.h"
+#include "format_string.h"
+
 #if defined(_LIBCPP_WIN32API)
 # define WIN32_LEAN_AND_MEAN
 # define NOMINMAX
 # include <windows.h>
 #else
-# include <dirent.h>   // for DIR & friends
-# include <fcntl.h>    /* values for fchmodat */
+# include <fcntl.h>
 # include <sys/stat.h>
-# include <sys/statvfs.h>
 # include <sys/time.h> // for ::utimes as used in __last_write_time
-# include <unistd.h>
-#endif // defined(_LIBCPP_WIN32API)
-
-#include "../include/apple_availability.h"
-
-#if !defined(__APPLE__)
-// We can use the presence of UTIME_OMIT to detect platforms that provide
-// utimensat.
-#if defined(UTIME_OMIT)
-#define _LIBCPP_USE_UTIMENSAT
 #endif
-#endif
-
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
 
-#if defined(_LIBCPP_WIN32API)
-#  define PATHSTR(x) (L##x)
-#  define PATH_CSTR_FMT "\"%ls\""
-#else
-#  define PATHSTR(x) (x)
-#  define PATH_CSTR_FMT "\"%s\""
+// We can use the presence of UTIME_OMIT to detect platforms that provide utimensat.
+#if defined(UTIME_OMIT)
+# define _LIBCPP_USE_UTIMENSAT
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
 namespace detail {
 
-#if defined(_LIBCPP_WIN32API)
-// Non anonymous, to allow access from two translation units.
-errc __win_err_to_errc(int err);
-#endif
-
-namespace {
-
-static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string
-format_string_impl(const char* msg, va_list ap) {
-  array<char, 256> buf;
-
-  va_list apcopy;
-  va_copy(apcopy, ap);
-  int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
-  va_end(apcopy);
-
-  string result;
-  if (static_cast<size_t>(ret) < buf.size()) {
-    result.assign(buf.data(), static_cast<size_t>(ret));
-  } else {
-    // we did not provide a long enough buffer on our first attempt. The
-    // return value is the number of bytes (excluding the null byte) that are
-    // needed for formatting.
-    size_t size_with_null = static_cast<size_t>(ret) + 1;
-    result.__resize_default_init(size_with_null - 1);
-    ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
-    _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
-  }
-  return result;
-}
-
-static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string
-format_string(const char* msg, ...) {
-  string ret;
-  va_list ap;
-  va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-  try {
-#endif // _LIBCPP_NO_EXCEPTIONS
-    ret = format_string_impl(msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-  } catch (...) {
-    va_end(ap);
-    throw;
-  }
-#endif // _LIBCPP_NO_EXCEPTIONS
-  va_end(ap);
-  return ret;
-}
-
-error_code capture_errno() {
-  _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero");
-  return error_code(errno, generic_category());
-}
-
-#if defined(_LIBCPP_WIN32API)
-error_code make_windows_error(int err) {
-  return make_error_code(__win_err_to_errc(err));
-}
-#endif
-
-template <class T>
-T error_value();
-template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
-template <>
-bool error_value<bool>() {
-  return false;
-}
-#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
-template <>
-size_t error_value<size_t>() {
-  return size_t(-1);
-}
-#endif
-template <>
-uintmax_t error_value<uintmax_t>() {
-  return uintmax_t(-1);
-}
-template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
-  return file_time_type::min();
-}
-template <>
-path error_value<path>() {
-  return {};
-}
-
-template <class T>
-struct ErrorHandler {
-  const char* func_name_;
-  error_code* ec_ = nullptr;
-  const path* p1_ = nullptr;
-  const path* p2_ = nullptr;
-
-  ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
-               const path* p2 = nullptr)
-      : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
-    if (ec_)
-      ec_->clear();
-  }
-
-  T report(const error_code& ec) const {
-    if (ec_) {
-      *ec_ = ec;
-      return error_value<T>();
-    }
-    string what = string("in ") + func_name_;
-    switch (bool(p1_) + bool(p2_)) {
-    case 0:
-      __throw_filesystem_error(what, ec);
-    case 1:
-      __throw_filesystem_error(what, *p1_, ec);
-    case 2:
-      __throw_filesystem_error(what, *p1_, *p2_, ec);
-    }
-    __libcpp_unreachable();
-  }
-
-  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
-  void report_impl(const error_code& ec, const char* msg, va_list ap) const {
-    if (ec_) {
-      *ec_ = ec;
-      return;
-    }
-    string what =
-        string("in ") + func_name_ + ": " + format_string_impl(msg, ap);
-    switch (bool(p1_) + bool(p2_)) {
-    case 0:
-      __throw_filesystem_error(what, ec);
-    case 1:
-      __throw_filesystem_error(what, *p1_, ec);
-    case 2:
-      __throw_filesystem_error(what, *p1_, *p2_, ec);
-    }
-    __libcpp_unreachable();
-  }
-
-  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
-  T report(const error_code& ec, const char* msg, ...) const {
-    va_list ap;
-    va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try {
-#endif // _LIBCPP_NO_EXCEPTIONS
-      report_impl(ec, msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    } catch (...) {
-      va_end(ap);
-      throw;
-    }
-#endif // _LIBCPP_NO_EXCEPTIONS
-    va_end(ap);
-    return error_value<T>();
-  }
-
-  T report(errc const& err) const {
-    return report(make_error_code(err));
-  }
-
-  _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
-  T report(errc const& err, const char* msg, ...) const {
-    va_list ap;
-    va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try {
-#endif // _LIBCPP_NO_EXCEPTIONS
-      report_impl(make_error_code(err), msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    } catch (...) {
-      va_end(ap);
-      throw;
-    }
-#endif // _LIBCPP_NO_EXCEPTIONS
-    va_end(ap);
-    return error_value<T>();
-  }
-
-private:
-  ErrorHandler(ErrorHandler const&) = delete;
-  ErrorHandler& operator=(ErrorHandler const&) = delete;
-};
-
-using chrono::duration;
-using chrono::duration_cast;
-
 #if defined(_LIBCPP_WIN32API)
 // Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
 // some mingw toolchains) provide different stat function implementations,
 // with a number of limitations with respect to what we want from the
-// stat function. Instead provide our own (in the anonymous detail namespace
-// in posix_compat.h) which does exactly what we want, along with our own
-// stat structure and flag macros.
+// stat function. Instead provide our own which does exactly what we want,
+// along with our own stat structure and flag macros.
 
 struct TimeSpec {
   int64_t tv_sec;
@@ -276,12 +70,56 @@ struct StatT {
   uintmax_t st_size;
 };
 
+// There were 369 years and 89 leap days from the Windows epoch
+// (1601) to the Unix epoch (1970).
+#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
+
+inline TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
+  TimeSpec ret;
+  ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
+  ret.tv_nsec = (li.QuadPart % 10000000) * 100;
+  return ret;
+}
+
+inline TimeSpec filetime_to_timespec(FILETIME ft) {
+  LARGE_INTEGER li;
+  li.LowPart = ft.dwLowDateTime;
+  li.HighPart = ft.dwHighDateTime;
+  return filetime_to_timespec(li);
+}
+
+inline FILETIME timespec_to_filetime(TimeSpec ts) {
+  LARGE_INTEGER li;
+  li.QuadPart =
+      ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
+  FILETIME ft;
+  ft.dwLowDateTime = li.LowPart;
+  ft.dwHighDateTime = li.HighPart;
+  return ft;
+}
+
 #else
 using TimeSpec = struct timespec;
 using TimeVal = struct timeval;
 using StatT = struct stat;
+
+inline TimeVal make_timeval(TimeSpec const& ts) {
+  using namespace chrono;
+  auto Convert = [](long nsec) {
+    using int_type = decltype(std::declval<TimeVal>().tv_usec);
+    auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
+    return static_cast<int_type>(dur);
+  };
+  TimeVal TV = {};
+  TV.tv_sec = ts.tv_sec;
+  TV.tv_usec = Convert(ts.tv_nsec);
+  return TV;
+}
 #endif
 
+using chrono::duration;
+using chrono::duration_cast;
+
 template <class FileTimeT, class TimeT,
           bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
 struct time_util_base {
@@ -309,7 +147,7 @@ struct time_util_base {
           .count();
 
 private:
-  static _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() {
+  static _LIBCPP_CONSTEXPR fs_duration get_min_nsecs() {
     return duration_cast<fs_duration>(
         fs_nanoseconds(min_nsec_timespec) -
         duration_cast<fs_nanoseconds>(fs_seconds(1)));
@@ -329,7 +167,9 @@ private:
     return max_seconds >= numeric_limits<TimeT>::max() &&
            min_seconds <= numeric_limits<TimeT>::min();
   }
+#if _LIBCPP_STD_VER >= 14
   static_assert(check_range(), "the representable range is unacceptable small");
+#endif
 };
 
 template <class FileTimeT, class TimeT>
@@ -489,20 +329,9 @@ inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
 inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
 #endif
 
-#if !defined(_LIBCPP_WIN32API)
-inline TimeVal make_timeval(TimeSpec const& ts) {
-  using namespace chrono;
-  auto Convert = [](long nsec) {
-    using int_type = decltype(std::declval<TimeVal>().tv_usec);
-    auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
-    return static_cast<int_type>(dur);
-  };
-  TimeVal TV = {};
-  TV.tv_sec = ts.tv_sec;
-  TV.tv_usec = Convert(ts.tv_nsec);
-  return TV;
-}
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM
 
+#if !defined(_LIBCPP_WIN32API)
 inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
                   error_code& ec) {
   TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
@@ -514,8 +343,8 @@ inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
 }
 
 #if defined(_LIBCPP_USE_UTIMENSAT)
-bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
-                     error_code& ec) {
+inline bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
+                            error_code& ec) {
   if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
     ec = capture_errno();
     return true;
@@ -524,8 +353,8 @@ bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
 }
 #endif
 
-bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
-                    error_code& ec) {
+inline bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+                           error_code& ec) {
 #if !defined(_LIBCPP_USE_UTIMENSAT)
   return posix_utimes(p, TS, ec);
 #else
@@ -533,81 +362,24 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
 #endif
 }
 
-#if defined(DT_BLK)
-template <class DirEntT, class = decltype(DirEntT::d_type)>
-static file_type get_file_type(DirEntT* ent, int) {
-  switch (ent->d_type) {
-  case DT_BLK:
-    return file_type::block;
-  case DT_CHR:
-    return file_type::character;
-  case DT_DIR:
-    return file_type::directory;
-  case DT_FIFO:
-    return file_type::fifo;
-  case DT_LNK:
-    return file_type::symlink;
-  case DT_REG:
-    return file_type::regular;
-  case DT_SOCK:
-    return file_type::socket;
-  // Unlike in lstat, hitting "unknown" here simply means that the underlying
-  // filesystem doesn't support d_type. Report is as 'none' so we correctly
-  // set the cache to empty.
-  case DT_UNKNOWN:
-    break;
-  }
-  return file_type::none;
-}
-#endif // defined(DT_BLK)
+#endif // !_LIBCPP_WIN32API
 
-template <class DirEntT>
-static file_type get_file_type(DirEntT*, long) {
-  return file_type::none;
-}
+inline file_time_type __extract_last_write_time(const path& p, const StatT& st,
+                                                error_code* ec) {
+  using detail::fs_time;
+  ErrorHandler<file_time_type> err("last_write_time", ec, &p);
 
-static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
-                                                  error_code& ec) {
-  struct dirent* dir_entry_ptr = nullptr;
-  errno = 0; // zero errno in order to detect errors
-  ec.clear();
-  if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
-    if (errno)
-      ec = capture_errno();
-    return {};
-  } else {
-    return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
-  }
-}
-
-#else // _LIBCPP_WIN32API
+  auto ts = detail::extract_mtime(st);
+  if (!fs_time::is_representable(ts))
+    return err.report(errc::value_too_large);
 
-static file_type get_file_type(const WIN32_FIND_DATAW& data) {
-  if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
-      data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
-    return file_type::symlink;
-  if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-    return file_type::directory;
-  return file_type::regular;
-}
-static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
-  return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
-}
-static file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
-  ULARGE_INTEGER tmp;
-  const FILETIME& time = data.ftLastWriteTime;
-  tmp.u.LowPart = time.dwLowDateTime;
-  tmp.u.HighPart = time.dwHighDateTime;
-  return file_time_type(file_time_type::duration(tmp.QuadPart));
+  return fs_time::convert_from_timespec(ts);
 }
 
-#endif // !_LIBCPP_WIN32API
+#endif // !_LIBCPP_HAS_NO_FILESYSTEM
 
-} // namespace
 } // end namespace detail
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
-_LIBCPP_DIAGNOSTIC_POP
-
-#endif // FILESYSTEM_COMMON_H
+#endif // FILESYSTEM_TIME_UTILS_H
lib/libcxx/src/include/ryu/common.h
@@ -43,7 +43,8 @@
 // clang-format off
 
 #include <__assert>
-#include "__config"
+#include <__config>
+#include <cstring>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -51,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   // Function precondition: __v is not a 10-digit number.
   // (f2s: 9 digits are sufficient for round-tripping.)
   // (d2fixed: We print 9-digit blocks.)
-  _LIBCPP_ASSERT(__v < 1000000000, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__v < 1000000000, "");
   if (__v >= 100000000) { return 9; }
   if (__v >= 10000000) { return 8; }
   if (__v >= 1000000) { return 7; }
@@ -68,36 +69,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   // This approximation works up to the point that the multiplication overflows at __e = 3529.
   // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
   // than 2^9297.
-  _LIBCPP_ASSERT(__e >= 0, "");
-  _LIBCPP_ASSERT(__e <= 3528, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 3528, "");
   return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1);
 }
 
 // Returns floor(log_10(2^__e)).
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI  inline uint32_t __log10Pow2(const int32_t __e) {
   // The first value this approximation fails for is 2^1651 which is just greater than 10^297.
-  _LIBCPP_ASSERT(__e >= 0, "");
-  _LIBCPP_ASSERT(__e <= 1650, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 1650, "");
   return (static_cast<uint32_t>(__e) * 78913) >> 18;
 }
 
 // Returns floor(log_10(5^__e)).
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) {
   // The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
-  _LIBCPP_ASSERT(__e >= 0, "");
-  _LIBCPP_ASSERT(__e <= 2620, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 2620, "");
   return (static_cast<uint32_t>(__e) * 732923) >> 20;
 }
 
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) {
   uint32_t __bits = 0;
-  _VSTD::memcpy(&__bits, &__f, sizeof(float));
+  std::memcpy(&__bits, &__f, sizeof(float));
   return __bits;
 }
 
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) {
   uint64_t __bits = 0;
-  _VSTD::memcpy(&__bits, &__d, sizeof(double));
+  std::memcpy(&__bits, &__d, sizeof(double));
   return __bits;
 }
 
lib/libcxx/src/include/ryu/d2s_intrinsics.h
@@ -63,7 +63,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   // (The shift value is in the range [49, 58].)
   // Check this here in case a future change requires larger shift
   // values. In this case this function needs to be adjusted.
-  _LIBCPP_ASSERT(__dist < 64, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
   return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist));
 }
 
@@ -85,7 +85,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   // (The shift value is in the range [49, 58].)
   // Check this here in case a future change requires larger shift
   // values. In this case this function needs to be adjusted.
-  _LIBCPP_ASSERT(__dist < 64, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
   auto __temp = __lo | ((unsigned __int128)__hi << 64);
   // For x64 128-bit shfits using the `shrd` instruction and two 64-bit
   // registers, the shift value is modulo 64.  Thus the `& 63` is free.
@@ -126,13 +126,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
   // We don't need to handle the case __dist >= 64 here (see above).
-  _LIBCPP_ASSERT(__dist < 64, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
 #ifdef _LIBCPP_64_BIT
-  _LIBCPP_ASSERT(__dist > 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__dist > 0, "");
   return (__hi << (64 - __dist)) | (__lo >> __dist);
 #else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
   // Avoid a 64-bit shift by taking advantage of the range of shift values.
-  _LIBCPP_ASSERT(__dist >= 32, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 32, "");
   return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32));
 #endif // ^^^ 32-bit ^^^
 }
@@ -227,7 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) {
   uint32_t __count = 0;
   for (;;) {
-    _LIBCPP_ASSERT(__value != 0, "");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
     const uint64_t __q = __div5(__value);
     const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q);
     if (__r != 0) {
@@ -247,8 +247,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Returns true if __value is divisible by 2^__p.
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) {
-  _LIBCPP_ASSERT(__value != 0, "");
-  _LIBCPP_ASSERT(__p < 64, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__p < 64, "");
   // __builtin_ctzll doesn't appear to be faster here.
   return (__value & ((1ull << __p) - 1)) == 0;
 }
lib/libcxx/src/include/ryu/ryu.h
@@ -47,8 +47,7 @@
 #include <__charconv/chars_format.h>
 #include <__charconv/to_chars_result.h>
 #include <__config>
-#include <__debug>
-#include <__errc>
+#include <__system_error/errc.h>
 #include <cstdint>
 #include <cstring>
 #include <type_traits>
lib/libcxx/src/include/apple_availability.h
@@ -11,24 +11,6 @@
 
 #if defined(__APPLE__)
 
-#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101300
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 110000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 110000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 40000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
-
 #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500
 #define _LIBCPP_USE_ULOCK
lib/libcxx/src/include/config_elast.h
@@ -35,8 +35,6 @@
 #define _LIBCPP_ELAST 4095
 #elif defined(__APPLE__)
 // No _LIBCPP_ELAST needed on Apple
-#elif defined(__sun__)
-#define _LIBCPP_ELAST ESTALE
 #elif defined(__MVS__)
 #define _LIBCPP_ELAST 1160
 #elif defined(_LIBCPP_MSVCRT_LIKE)
lib/libcxx/src/include/to_chars_floating_point.h
@@ -269,7 +269,7 @@ to_chars_result _Floating_to_chars_hex_precision(
     // * Print the leading hexit, then mask it away.
     {
         const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Adjusted_explicit_bits);
-        _LIBCPP_ASSERT(_Nibble < 3, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 3, "");
         const char _Leading_hexit = static_cast<char>('0' + _Nibble);
 
         *_First++ = _Leading_hexit;
@@ -288,12 +288,12 @@ to_chars_result _Floating_to_chars_hex_precision(
         int32_t _Number_of_bits_remaining = _Adjusted_explicit_bits; // 24 for float, 52 for double
 
         for (;;) {
-            _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, "");
-            _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
             _Number_of_bits_remaining -= 4;
 
             const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
-            _LIBCPP_ASSERT(_Nibble < 16, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
             const char _Hexit = __itoa::_Charconv_digits[_Nibble];
 
             *_First++ = _Hexit;
@@ -415,12 +415,12 @@ to_chars_result _Floating_to_chars_hex_shortest(
         // '0' hexits, the same condition works (as we print the final hexit and mask it away); we don't need to test
         // _Number_of_bits_remaining.
         do {
-            _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, "");
-            _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
             _Number_of_bits_remaining -= 4;
 
             const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
-            _LIBCPP_ASSERT(_Nibble < 16, "");
+            _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
             const char _Hexit = __itoa::_Charconv_digits[_Nibble];
 
             if (_First == _Last) {
@@ -940,13 +940,13 @@ to_chars_result _Floating_to_chars_general_precision(
         _Effective_precision = _VSTD::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision);
         const to_chars_result _Buf_result =
             _Floating_to_chars_fixed_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
-        _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
         _Significand_last = _Buf_result.ptr;
     } else {
         _Effective_precision = _VSTD::min(_Precision - 1, _Max_scientific_precision);
         const to_chars_result _Buf_result =
             _Floating_to_chars_scientific_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
-        _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
+        _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
         _Significand_last = _VSTD::find(_Buffer, _Buf_result.ptr, 'e');
         _Exponent_first   = _Significand_last;
         _Exponent_last    = _Buf_result.ptr;
@@ -992,10 +992,10 @@ to_chars_result _Floating_to_chars(
     char* _First, char* const _Last, _Floating _Value, const chars_format _Fmt, const int _Precision) noexcept {
 
     if constexpr (_Overload == _Floating_to_chars_overload::_Plain) {
-        _LIBCPP_ASSERT(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
+        _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
     } else {
-        _LIBCPP_ASSERT(_Fmt == chars_format::general || _Fmt == chars_format::scientific || _Fmt == chars_format::fixed
-                         || _Fmt == chars_format::hex,
+        _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format::general || _Fmt == chars_format::scientific
+                         || _Fmt == chars_format::fixed || _Fmt == chars_format::hex,
             "invalid format in to_chars()");
     }
 
lib/libcxx/src/pstl/libdispatch.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__algorithm/min.h>
+#include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
+#include <__config>
+#include <dispatch/dispatch.h>
+#include <thread>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __par_backend::inline __libdispatch {
+
+
+void __dispatch_apply(size_t chunk_count, void* context, void (*func)(void* context, size_t chunk)) noexcept {
+  ::dispatch_apply_f(chunk_count, DISPATCH_APPLY_AUTO, context, func);
+}
+
+__chunk_partitions __partition_chunks(ptrdiff_t element_count) {
+  if (element_count == 0) {
+    return __chunk_partitions{1, 0, 0};
+  } else if (element_count == 1) {
+    return __chunk_partitions{1, 0, 1};
+  }
+
+  __chunk_partitions partitions;
+  partitions.__chunk_count_ = [&] {
+    ptrdiff_t cores = std::max(1u, thread::hardware_concurrency());
+
+    auto medium = [&](ptrdiff_t n) { return cores + ((n - cores) / cores); };
+
+    // This is an approximation of `log(1.01, sqrt(n))` which seemes to be reasonable for `n` larger than 500 and tops
+    // at 800 tasks for n ~ 8 million
+    auto large = [](ptrdiff_t n) { return static_cast<ptrdiff_t>(100.499 * std::log(std::sqrt(n))); };
+
+    if (element_count < cores)
+      return element_count;
+    else if (element_count < 500)
+      return medium(element_count);
+    else
+      return std::min(medium(element_count), large(element_count)); // provide a "smooth" transition
+  }();
+  partitions.__chunk_size_       = element_count / partitions.__chunk_count_;
+  partitions.__first_chunk_size_ = partitions.__chunk_size_;
+
+  const ptrdiff_t leftover_item_count = element_count - (partitions.__chunk_count_ * partitions.__chunk_size_);
+
+  if (leftover_item_count == 0)
+    return partitions;
+
+  if (leftover_item_count == partitions.__chunk_size_) {
+    partitions.__chunk_count_ += 1;
+    return partitions;
+  }
+
+  const ptrdiff_t n_extra_items_per_chunk = leftover_item_count / partitions.__chunk_count_;
+  const ptrdiff_t n_final_leftover_items  = leftover_item_count - (n_extra_items_per_chunk * partitions.__chunk_count_);
+
+  partitions.__chunk_size_ += n_extra_items_per_chunk;
+  partitions.__first_chunk_size_ = partitions.__chunk_size_ + n_final_leftover_items;
+  return partitions;
+}
+
+// NOLINTNEXTLINE(llvm-namespace-comment) // This is https://llvm.org/PR56804
+} // namespace __par_backend::inline __libdispatch
+
+_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/ryu/d2fixed.cpp
@@ -43,7 +43,6 @@
 #include <__config>
 #include <charconv>
 #include <cstring>
-#include <system_error>
 
 #include "include/ryu/common.h"
 #include "include/ryu/d2fixed.h"
@@ -103,8 +102,8 @@ inline constexpr int __POW10_ADDITIONAL_BITS = 120;
   const uint64_t __s1low = __low2 + __high1 + __c1; // 128
   const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
   const uint64_t __s1high = __high2 + __c2;         // 192
-  _LIBCPP_ASSERT(__j >= 128, "");
-  _LIBCPP_ASSERT(__j <= 180, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, "");
 #ifdef _LIBCPP_INTRINSIC128
   const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
   const uint64_t __shiftedhigh = __s1high >> __dist;
@@ -135,19 +134,19 @@ void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const
     __digits /= 10000;
     const uint32_t __c0 = (__c % 100) << 1;
     const uint32_t __c1 = (__c / 100) << 1;
-    _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
     __i += 4;
   }
   if (__digits >= 100) {
     const uint32_t __c = (__digits % 100) << 1;
     __digits /= 100;
-    _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
     __i += 2;
   }
   if (__digits >= 10) {
     const uint32_t __c = __digits << 1;
-    _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
   } else {
     __result[0] = static_cast<char>('0' + __digits);
   }
@@ -164,14 +163,14 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, ui
     __digits /= 10000;
     const uint32_t __c0 = (__c % 100) << 1;
     const uint32_t __c1 = (__c / 100) << 1;
-    _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
     __i += 4;
   }
   if (__digits >= 100) {
     const uint32_t __c = (__digits % 100) << 1;
     __digits /= 100;
-    _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
     __i += 2;
   }
   if (__digits >= 10) {
@@ -190,7 +189,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
   for (; __i < __count - 1; __i += 2) {
     const uint32_t __c = (__digits % 100) << 1;
     __digits /= 100;
-    _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
   }
   if (__i < __count) {
     const char __c = static_cast<char>('0' + (__digits % 10));
@@ -200,7 +199,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
 
 void __append_nine_digits(uint32_t __digits, char* const __result) {
   if (__digits == 0) {
-    _VSTD::memset(__result, '0', 9);
+    std::memset(__result, '0', 9);
     return;
   }
 
@@ -213,8 +212,8 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
     __digits /= 10000;
     const uint32_t __c0 = (__c % 100) << 1;
     const uint32_t __c1 = (__c / 100) << 1;
-    _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
   }
   __result[0] = static_cast<char>('0' + __digits);
 }
@@ -251,7 +250,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
     *_First++ = '0';
     if (__precision > 0) {
       *_First++ = '.';
-      _VSTD::memset(_First, '0', __precision);
+      std::memset(_First, '0', __precision);
       _First += __precision;
     }
     return { _First, errc{} };
@@ -322,14 +321,14 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
       if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
         return { _Last, errc::value_too_large };
       }
-      _VSTD::memset(_First, '0', __precision);
+      std::memset(_First, '0', __precision);
       _First += __precision;
     } else if (__i < __MIN_BLOCK_2[__idx]) {
       __i = __MIN_BLOCK_2[__idx];
       if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
         return { _Last, errc::value_too_large };
       }
-      _VSTD::memset(_First, '0', 9 * __i);
+      std::memset(_First, '0', 9 * __i);
       _First += 9 * __i;
     }
     for (; __i < __blocks; ++__i) {
@@ -342,7 +341,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
         if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
           return { _Last, errc::value_too_large };
         }
-        _VSTD::memset(_First, '0', __fill);
+        std::memset(_First, '0', __fill);
         _First += __fill;
         break;
       }
@@ -416,7 +415,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
     if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
       return { _Last, errc::value_too_large };
     }
-    _VSTD::memset(_First, '0', __precision);
+    std::memset(_First, '0', __precision);
     _First += __precision;
   }
   return { _First, errc{} };
@@ -440,10 +439,10 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
     *_First++ = '0';
     if (__precision > 0) {
       *_First++ = '.';
-      _VSTD::memset(_First, '0', __precision);
+      std::memset(_First, '0', __precision);
       _First += __precision;
     }
-    _VSTD::memcpy(_First, "e+00", 4);
+    std::memcpy(_First, "e+00", 4);
     _First += 4;
     return { _First, errc{} };
   }
@@ -589,7 +588,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
       return { _Last, errc::value_too_large };
     }
     if (__digits == 0) {
-      _VSTD::memset(_First, '0', __maximum);
+      std::memset(_First, '0', __maximum);
     } else {
       __append_c_digits(__maximum, __digits, _First);
     }
@@ -654,11 +653,11 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
 
   if (__exp >= 100) {
     const int32_t __c = __exp % 10;
-    _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
+    std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
     _First[2] = static_cast<char>('0' + __c);
     _First += 3;
   } else {
-    _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
+    std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
     _First += 2;
   }
 
lib/libcxx/src/ryu/d2s.cpp
@@ -154,7 +154,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   // The average output length is 16.38 digits, so we check high-to-low.
   // Function precondition: __v is not an 18, 19, or 20-digit number.
   // (17 digits are sufficient for round-tripping.)
-  _LIBCPP_ASSERT(__v < 100000000000000000u, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__v < 100000000000000000u, "");
   if (__v >= 10000000000000000u) { return 17; }
   if (__v >= 1000000000000000u) { return 16; }
   if (__v >= 100000000000000u) { return 15; }
@@ -527,10 +527,10 @@ struct __floating_decimal_64 {
       const uint32_t __d0 = (__d % 100) << 1;
       const uint32_t __d1 = (__d / 100) << 1;
 
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
     }
     uint32_t __output2 = static_cast<uint32_t>(_Output);
     while (__output2 >= 10000) {
@@ -542,35 +542,35 @@ struct __floating_decimal_64 {
       __output2 /= 10000;
       const uint32_t __c0 = (__c % 100) << 1;
       const uint32_t __c1 = (__c / 100) << 1;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
     }
     if (__output2 >= 100) {
       const uint32_t __c = (__output2 % 100) << 1;
       __output2 /= 100;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
     }
     if (__output2 >= 10) {
       const uint32_t __c = __output2 << 1;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
     } else {
       *--_Mid = static_cast<char>('0' + __output2);
     }
 
     if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
       // Performance note: it might be more efficient to do this immediately after setting _Mid.
-      _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
+      std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
     } else if (_Ryu_exponent == 0) { // case "1729"
       // Done!
     } else if (_Whole_digits > 0) { // case "17.29"
       // Performance note: moving digits might not be optimal.
-      _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
+      std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
       _First[_Whole_digits] = '.';
     } else { // case "0.001729"
       // Performance note: a larger memset() followed by overwriting '.' might be more efficient.
       _First[0] = '0';
       _First[1] = '.';
-      _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
+      std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
     }
 
     return { _First + _Total_fixed_length, errc{} };
@@ -602,10 +602,10 @@ struct __floating_decimal_64 {
     const uint32_t __c1 = (__c / 100) << 1;
     const uint32_t __d0 = (__d % 100) << 1;
     const uint32_t __d1 = (__d / 100) << 1;
-    _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
-    _VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
-    _VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
+    std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
+    std::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
     __i += 8;
   }
   uint32_t __output2 = static_cast<uint32_t>(_Output);
@@ -618,14 +618,14 @@ struct __floating_decimal_64 {
     __output2 /= 10000;
     const uint32_t __c0 = (__c % 100) << 1;
     const uint32_t __c1 = (__c / 100) << 1;
-    _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
     __i += 4;
   }
   if (__output2 >= 100) {
     const uint32_t __c = (__output2 % 100) << 1;
     __output2 /= 100;
-    _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
     __i += 2;
   }
   if (__output2 >= 10) {
@@ -657,11 +657,11 @@ struct __floating_decimal_64 {
 
   if (_Scientific_exponent >= 100) {
     const int32_t __c = _Scientific_exponent % 10;
-    _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
+    std::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
     __result[__index + 2] = static_cast<char>('0' + __c);
     __index += 3;
   } else {
-    _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
+    std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
     __index += 2;
   }
 
@@ -713,7 +713,7 @@ struct __floating_decimal_64 {
         return { _Last, errc::value_too_large };
       }
 
-      _VSTD::memcpy(_First, "0e+00", 5);
+      std::memcpy(_First, "0e+00", 5);
 
       return { _First + 5, errc{} };
     }
lib/libcxx/src/ryu/f2s.cpp
@@ -86,7 +86,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) {
   uint32_t __count = 0;
   for (;;) {
-    _LIBCPP_ASSERT(__value != 0, "");
+    _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
     const uint32_t __q = __value / 5;
     const uint32_t __r = __value % 5;
     if (__r != 0) {
@@ -105,14 +105,14 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
 
 // Returns true if __value is divisible by 2^__p.
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) {
-  _LIBCPP_ASSERT(__value != 0, "");
-  _LIBCPP_ASSERT(__p < 32, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__p < 32, "");
   // __builtin_ctz doesn't appear to be faster here.
   return (__value & ((1u << __p) - 1)) == 0;
 }
 
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) {
-  _LIBCPP_ASSERT(__shift > 32, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__shift > 32, "");
 
   // The casts here help MSVC to avoid calls to the __allmul library
   // function.
@@ -134,7 +134,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
 #else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
   const uint64_t __sum = (__bits0 >> 32) + __bits1;
   const uint64_t __shiftedSum = __sum >> (__shift - 32);
-  _LIBCPP_ASSERT(__shiftedSum <= UINT32_MAX, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__shiftedSum <= UINT32_MAX, "");
   return static_cast<uint32_t>(__shiftedSum);
 #endif // ^^^ 64-bit ^^^
 }
@@ -309,8 +309,8 @@ struct __floating_decimal_32 {
   // Performance note: Long division appears to be faster than losslessly widening float to double and calling
   // __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division.
 
-  _LIBCPP_ASSERT(_Exponent2 > 0, "");
-  _LIBCPP_ASSERT(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
+  _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 > 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
 
   // Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits
   // (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits.
@@ -328,7 +328,7 @@ struct __floating_decimal_32 {
 
   // _Maxidx is the index of the most significant nonzero element.
   uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1;
-  _LIBCPP_ASSERT(_Maxidx < _Data_size, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(_Maxidx < _Data_size, "");
 
   const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32;
   if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary
@@ -388,9 +388,9 @@ struct __floating_decimal_32 {
     }
   }
 
-  _LIBCPP_ASSERT(_Data[0] != 0, "");
+  _LIBCPP_ASSERT_UNCATEGORIZED(_Data[0] != 0, "");
   for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) {
-    _LIBCPP_ASSERT(_Data[_Idx] == 0, "");
+    _LIBCPP_ASSERT_UNCATEGORIZED(_Data[_Idx] == 0, "");
   }
 
   const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]);
@@ -565,35 +565,35 @@ struct __floating_decimal_32 {
       _Output /= 10000;
       const uint32_t __c0 = (__c % 100) << 1;
       const uint32_t __c1 = (__c / 100) << 1;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
     }
     if (_Output >= 100) {
       const uint32_t __c = (_Output % 100) << 1;
       _Output /= 100;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
     }
     if (_Output >= 10) {
       const uint32_t __c = _Output << 1;
-      _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+      std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
     } else {
       *--_Mid = static_cast<char>('0' + _Output);
     }
 
     if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
       // Performance note: it might be more efficient to do this immediately after setting _Mid.
-      _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
+      std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
     } else if (_Ryu_exponent == 0) { // case "1729"
       // Done!
     } else if (_Whole_digits > 0) { // case "17.29"
       // Performance note: moving digits might not be optimal.
-      _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
+      std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
       _First[_Whole_digits] = '.';
     } else { // case "0.001729"
       // Performance note: a larger memset() followed by overwriting '.' might be more efficient.
       _First[0] = '0';
       _First[1] = '.';
-      _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
+      std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
     }
 
     return { _First + _Total_fixed_length, errc{} };
@@ -617,14 +617,14 @@ struct __floating_decimal_32 {
     _Output /= 10000;
     const uint32_t __c0 = (__c % 100) << 1;
     const uint32_t __c1 = (__c / 100) << 1;
-    _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
-    _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+    std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+    std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
     __i += 4;
   }
   if (_Output >= 100) {
     const uint32_t __c = (_Output % 100) << 1;
     _Output /= 100;
-    _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
+    std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
     __i += 2;
   }
   if (_Output >= 10) {
@@ -654,7 +654,7 @@ struct __floating_decimal_32 {
     __result[__index++] = '+';
   }
 
-  _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
+  std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
   __index += 2;
 
   return { _First + _Total_scientific_length, errc{} };
@@ -673,7 +673,7 @@ struct __floating_decimal_32 {
         return { _Last, errc::value_too_large };
       }
 
-      _VSTD::memcpy(_First, "0e+00", 5);
+      std::memcpy(_First, "0e+00", 5);
 
       return { _First + 5, errc{} };
     }
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp
@@ -18,7 +18,7 @@
 // Returns (size_t) -1 when an invalid sequence is encountered.
 // Leaves *`src` pointing to the next character to convert or NULL
 // if a null character was converted from *`src`.
-_LIBCPP_FUNC_VIS
+_LIBCPP_EXPORTED_FROM_ABI
 size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
                    size_t src_size_bytes, size_t max_dest_chars,
                    mbstate_t *__restrict ps) {
lib/libcxx/src/support/ibm/wcsnrtombs.cpp
@@ -17,7 +17,7 @@
 // converted from *src, excluding the null terminator.
 // Returns (size_t) -1 if an error occurs and sets errno.
 // If `dst` is NULL, `dst_size_bytes` is ignored and no bytes are copied to `dst`.
-_LIBCPP_FUNC_VIS
+_LIBCPP_EXPORTED_FROM_ABI
 size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
                    size_t max_source_chars, size_t dst_size_bytes,
                    mbstate_t *__restrict ps) {
lib/libcxx/src/support/ibm/xlocale_zos.cpp
@@ -111,7 +111,7 @@ locale_t uselocale(locale_t newloc) {
         tokenized.push_back(s);
     }
 
-    _LIBCPP_ASSERT(tokenized.size() >= _NCAT, "locale-name list is too short");
+    _LIBCPP_ASSERT_UNCATEGORIZED(tokenized.size() >= _NCAT, "locale-name list is too short");
 
     previous_loc->lc_collate = tokenized[LC_COLLATE];
     previous_loc->lc_ctype = tokenized[LC_CTYPE];
lib/libcxx/src/support/runtime/exception_fallback.ipp
@@ -51,15 +51,15 @@ _LIBCPP_NORETURN
 void
 terminate() noexcept
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         (*get_terminate())();
         // handler should not return
         fprintf(stderr, "terminate_handler unexpectedly returned\n");
         ::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -67,7 +67,7 @@ terminate() noexcept
         fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
         ::abort();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
lib/libcxx/src/support/runtime/exception_msvc.ipp
@@ -57,15 +57,15 @@ terminate_handler get_terminate() noexcept {
 _LIBCPP_NORETURN
 void terminate() noexcept
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         (*get_terminate())();
         // handler should not return
         fprintf(stderr, "terminate_handler unexpectedly returned\n");
         ::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -73,7 +73,7 @@ void terminate() noexcept
         fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
         ::abort();
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
lib/libcxx/src/support/solaris/mbsnrtowcs.inc
@@ -1,76 +0,0 @@
-
-
-/*-
- * As noted in the source, some portions of this implementation are copied from
- * FreeBSD libc.  These are covered by the following copyright:
- *
- * Copyright (c) 2002-2004 Tim J. Robbins.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-size_t
-mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,
-    size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc)
-{
-  const char *s;
-  size_t nchr;
-  wchar_t wc;
-  size_t nb;
-  FIX_LOCALE(loc);
-
-  s = *src;
-  nchr = 0;
-
-  if (dst == NULL) {
-    for (;;) {
-      if ((nb = mbrtowc_l(&wc, s, nms, ps, loc)) == (size_t)-1)
-        /* Invalid sequence - mbrtowc() sets errno. */
-        return ((size_t)-1);
-      else if (nb == 0 || nb == (size_t)-2)
-        return (nchr);
-      s += nb;
-      nms -= nb;
-      nchr++;
-    }
-    /*NOTREACHED*/
-  }
-
-  while (len-- > 0) {
-    if ((nb = mbrtowc_l(dst, s, nms, ps, loc)) == (size_t)-1) {
-      *src = s;
-      return ((size_t)-1);
-    } else if (nb == (size_t)-2) {
-      *src = s + nms;
-      return (nchr);
-    } else if (nb == 0) {
-      *src = NULL;
-      return (nchr);
-    }
-    s += nb;
-    nms -= nb;
-    nchr++;
-    dst++;
-  }
-  *src = s;
-  return (nchr);
-}
lib/libcxx/src/support/solaris/wcsnrtombs.inc
@@ -1,92 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-size_t
-wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
-    size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc)
-{
-  FIX_LOCALE(loc);
-  mbstate_t mbsbak;
-  char buf[MB_CUR_MAX_L(loc)];
-  const wchar_t *s;
-  size_t nbytes;
-  size_t nb;
-
-  s = *src;
-  nbytes = 0;
-
-  if (dst == NULL) {
-    while (nwc-- > 0) {
-      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1)
-        /* Invalid character - wcrtomb() sets errno. */
-        return ((size_t)-1);
-      else if (*s == L'\0')
-        return (nbytes + nb - 1);
-      s++;
-      nbytes += nb;
-    }
-    return (nbytes);
-  }
-
-  while (len > 0 && nwc-- > 0) {
-    if (len > (size_t)MB_CUR_MAX_L(loc)) {
-      /* Enough space to translate in-place. */
-      if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) {
-        *src = s;
-        return ((size_t)-1);
-      }
-    } else {
-      /*
-       * May not be enough space; use temp. buffer.
-       *
-       * We need to save a copy of the conversion state
-       * here so we can restore it if the multibyte
-       * character is too long for the buffer.
-       */
-      mbsbak = *ps;
-      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) {
-        *src = s;
-        return ((size_t)-1);
-      }
-      if (nb > (int)len) {
-        /* MB sequence for character won't fit. */
-        *ps = mbsbak;
-        break;
-      }
-      memcpy(dst, buf, nb);
-    }
-    if (*s == L'\0') {
-      *src = NULL;
-      return (nbytes + nb - 1);
-    }
-    s++;
-    dst += nb;
-    len -= nb;
-    nbytes += nb;
-  }
-  *src = s;
-  return (nbytes);
-}
lib/libcxx/src/support/solaris/xlocale.cpp
@@ -1,68 +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
-//
-//===----------------------------------------------------------------------===//
-
-#ifdef __sun__
-
-#include "__support/solaris/xlocale.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/localedef.h>
-
-extern "C" {
-
-int isxdigit_l(int __c, locale_t __l) {
-    return isxdigit(__c);
-}
-
-int iswxdigit_l(wint_t __c, locale_t __l) {
-    return isxdigit(__c);
-}
-
-// FIXME: This disregards the locale, which is Very Wrong
-#define vsnprintf_l(__s, __n, __l, __format, __va)  \
-    vsnprintf(__s, __n, __format, __va)
-
-int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...)
-{
-  va_list __va;
-  va_start(__va, __format);
-  int __res = vsnprintf_l(__s, __n , __l, __format, __va);
-  va_end(__va);
-  return __res;
-}
-
-int asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
-  va_list __va;
-  va_start(__va, __format);
-  // FIXME:
-  int __res = vasprintf(__s, __format, __va);
-  va_end(__va);
-  return __res;
-}
-
-int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
-  va_list __va;
-  va_start(__va, __format);
-  // FIXME:
-  int __res = vsscanf(__s, __format, __va);
-  va_end(__va);
-  return __res;
-}
-
-size_t mbrtowc_l(wchar_t *__pwc, const char *__pmb,
-                 size_t __max, mbstate_t *__ps, locale_t __loc) {
-  return mbrtowc(__pwc, __pmb, __max, __ps);
-}
-
-struct lconv *localeconv_l(locale_t __l) {
-  return localeconv();
-}
-
-};
-
-#endif // __sun__
lib/libcxx/src/support/win32/locale_win32.cpp
@@ -11,6 +11,8 @@
 #include <memory>
 #include <type_traits>
 
+#include <__locale_dir/locale_base_api/locale_guard.h>
+
 int __libcpp_vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
 
 using std::__libcpp_locale_guard;
lib/libcxx/src/algorithm.cpp
@@ -7,11 +7,25 @@
 //===----------------------------------------------------------------------===//
 
 #include <algorithm>
+#include <bit>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// TODO(varconst): this currently doesn't benefit `ranges::sort` because it uses `ranges::less` instead of `__less`.
+template <class Comp, class RandomAccessIterator>
+void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
+  auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));
 
+  // Only use bitset partitioning for arithmetic types.  We should also check
+  // that the default comparator is in use so that we are sure that there are no
+  // branches in the comparator.
+  std::__introsort<_ClassicAlgPolicy,
+                   ranges::less,
+                   RandomAccessIterator,
+                   __use_branchless_sort<ranges::less, RandomAccessIterator>::value>(
+      first, last, ranges::less{}, depth_limit);
+}
+
+// clang-format off
 template void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
@@ -29,25 +43,6 @@ template void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned
 template void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
 template void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
 template void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-template bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
-#endif
-template bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
-template bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
-template bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
-template bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
-template bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
-template bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
-template bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
-template bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
-template bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
-template bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
-template bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
-template bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
-template bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
+// clang-format on
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/any.cpp
@@ -21,7 +21,7 @@ const char* bad_any_cast::what() const noexcept {
 //  Even though it no longer exists in a header file
 _LIBCPP_BEGIN_NAMESPACE_LFTS
 
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
 {
 public:
     virtual const char* what() const noexcept;
lib/libcxx/src/atomic.cpp
@@ -9,11 +9,14 @@
 #include <__config>
 #ifndef _LIBCPP_HAS_NO_THREADS
 
+#include <__thread/timed_backoff_policy.h>
 #include <atomic>
 #include <climits>
 #include <functional>
 #include <thread>
 
+#include "include/apple_availability.h"
+
 #ifdef __linux__
 
 #include <unistd.h>
@@ -77,20 +80,25 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
                  const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
 }
 
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
+/*
+ * Since __cxx_contention_t is int64_t even on 32bit FreeBSD
+ * platforms, we have to use umtx ops that work on the long type, and
+ * limit its use to architectures where long and int64_t are synonyms.
+ */
 
 static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
                                               __cxx_contention_t __val)
 {
     _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
-             UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL);
+             UMTX_OP_WAIT, __val, NULL, NULL);
 }
 
 static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
                                               bool __notify_one)
 {
     _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
-             UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL);
+             UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, NULL, NULL);
 }
 
 #else // <- Add other operating systems here
lib/libcxx/src/charconv.cpp
@@ -18,13 +18,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __itoa
 {
 
-_LIBCPP_FUNC_VIS char*
+_LIBCPP_EXPORTED_FROM_ABI char*
 __u32toa(uint32_t value, char* buffer) noexcept
 {
   return __base_10_u32(buffer, value);
 }
 
-_LIBCPP_FUNC_VIS char*
+_LIBCPP_EXPORTED_FROM_ABI char*
 __u64toa(uint64_t value, char* buffer) noexcept
 {
   return __base_10_u64(buffer, value);
lib/libcxx/src/chrono.cpp
@@ -12,9 +12,9 @@
 #define _LARGE_TIME_API
 #endif
 
-#include <cerrno>        // errno
+#include <__system_error/system_error.h>
+#include <cerrno> // errno
 #include <chrono>
-#include <system_error>  // __throw_system_error
 
 #if defined(__MVS__)
 #include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic
@@ -24,15 +24,15 @@
 #include "include/apple_availability.h"
 
 #if __has_include(<unistd.h>)
-# include <unistd.h>
+# include <unistd.h> // _POSIX_TIMERS
 #endif
 
 #if __has_include(<sys/time.h>)
 # include <sys/time.h> // for gettimeofday and timeval
 #endif
 
-#if !defined(__APPLE__) && defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
-# define _LIBCPP_USE_CLOCK_GETTIME
+#if defined(__APPLE__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
+# define _LIBCPP_HAS_CLOCK_GETTIME
 #endif
 
 #if defined(_LIBCPP_WIN32API)
@@ -116,7 +116,7 @@ static system_clock::time_point __libcpp_system_clock_now() {
   return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
 }
 
-#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
+#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
 
 static system_clock::time_point __libcpp_system_clock_now() {
   struct timespec tp;
@@ -167,59 +167,6 @@ system_clock::from_time_t(time_t t) noexcept
 
 #if defined(__APPLE__)
 
-// TODO(ldionne):
-// This old implementation of steady_clock is retained until Chrome drops supports
-// for macOS < 10.12. The issue is that they link libc++ statically into their
-// application, which means that libc++ must support being built for such deployment
-// targets. See https://llvm.org/D74489 for details.
-#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
-    (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
-    (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
-    (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
-# define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME
-#endif
-
-#if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME)
-
-//   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
-//   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
-//   are run time constants supplied by the OS.  This clock has no relationship
-//   to the Gregorian calendar.  It's main use is as a high resolution timer.
-
-// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize
-//   for that case as an optimization.
-
-static steady_clock::rep steady_simplified() {
-    return static_cast<steady_clock::rep>(mach_absolute_time());
-}
-static double compute_steady_factor() {
-    mach_timebase_info_data_t MachInfo;
-    mach_timebase_info(&MachInfo);
-    return static_cast<double>(MachInfo.numer) / MachInfo.denom;
-}
-
-static steady_clock::rep steady_full() {
-    static const double factor = compute_steady_factor();
-    return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
-}
-
-typedef steady_clock::rep (*FP)();
-
-static FP init_steady_clock() {
-    mach_timebase_info_data_t MachInfo;
-    mach_timebase_info(&MachInfo);
-    if (MachInfo.numer == MachInfo.denom)
-        return &steady_simplified;
-    return &steady_full;
-}
-
-static steady_clock::time_point __libcpp_steady_clock_now() {
-    static FP fp = init_steady_clock();
-    return steady_clock::time_point(steady_clock::duration(fp()));
-}
-
-#else // vvvvv default behavior for Apple platforms  vvvvv
-
 // On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
 // mach_absolute_time are able to time functions in the nanosecond range.
 // Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
@@ -232,8 +179,6 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
     return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
 }
 
-#endif
-
 #elif defined(_LIBCPP_WIN32API)
 
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
@@ -281,7 +226,7 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept {
   return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic()));
 }
 
-#  elif defined(CLOCK_MONOTONIC)
+#  elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
 
 static steady_clock::time_point __libcpp_steady_clock_now() {
     struct timespec tp;
lib/libcxx/src/condition_variable.cpp
@@ -12,7 +12,6 @@
 
 #include <condition_variable>
 #include <thread>
-#include <system_error>
 
 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
 #  pragma comment(lib, "pthread")
lib/libcxx/src/condition_variable_destructor.cpp
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifdef NEEDS_CONDVAR_DESTRUCTOR
 
-class _LIBCPP_TYPE_VIS condition_variable
+class _LIBCPP_EXPORTED_FROM_ABI condition_variable
 {
     __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
 public:
lib/libcxx/src/debug.cpp
@@ -1,559 +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
-//
-//===----------------------------------------------------------------------===//
-
-#include <__assert>
-#include <__config>
-#include <__debug>
-#include <__hash_table>
-#include <algorithm>
-#include <cstdio>
-#include <functional>
-#include <string>
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-#  include <mutex>
-#  if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-#    pragma comment(lib, "pthread")
-#  endif
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-_LIBCPP_FUNC_VIS
-__libcpp_db*
-__get_db()
-{
-    static _LIBCPP_NO_DESTROY __libcpp_db db;
-    return &db;
-}
-
-_LIBCPP_FUNC_VIS
-const __libcpp_db*
-__get_const_db()
-{
-    return __get_db();
-}
-
-namespace
-{
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-typedef mutex mutex_type;
-typedef lock_guard<mutex_type> WLock;
-typedef lock_guard<mutex_type> RLock;
-
-mutex_type&
-mut()
-{
-    static _LIBCPP_NO_DESTROY mutex_type m;
-    return m;
-}
-#endif // !_LIBCPP_HAS_NO_THREADS
-
-}  // unnamed namespace
-
-__i_node::~__i_node()
-{
-    if (__next_)
-    {
-        __next_->~__i_node();
-        free(__next_);
-    }
-}
-
-__c_node::~__c_node()
-{
-    free(beg_);
-    if (__next_)
-    {
-        __next_->~__c_node();
-        free(__next_);
-    }
-}
-
-__libcpp_db::__libcpp_db()
-    : __cbeg_(nullptr),
-      __cend_(nullptr),
-      __csz_(0),
-      __ibeg_(nullptr),
-      __iend_(nullptr),
-      __isz_(0)
-{
-}
-
-__libcpp_db::~__libcpp_db()
-{
-    if (__cbeg_)
-    {
-        for (__c_node** p = __cbeg_; p != __cend_; ++p)
-        {
-            if (*p != nullptr)
-            {
-                (*p)->~__c_node();
-                free(*p);
-            }
-        }
-        free(__cbeg_);
-    }
-    if (__ibeg_)
-    {
-        for (__i_node** p = __ibeg_; p != __iend_; ++p)
-        {
-            if (*p != nullptr)
-            {
-                (*p)->~__i_node();
-                free(*p);
-            }
-        }
-        free(__ibeg_);
-    }
-}
-
-void*
-__libcpp_db::__find_c_from_i(void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
-    return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
-}
-
-void
-__libcpp_db::__insert_ic(void* __i, const void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    if (__cbeg_ == __cend_)
-        return;
-    size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* c = __cbeg_[hc];
-    if (c == nullptr)
-        return;
-    while (c->__c_ != __c)
-    {
-        c = c->__next_;
-        if (c == nullptr)
-            return;
-    }
-    __i_node* i = __insert_iterator(__i);
-    c->__add(i);
-    i->__c_ = c;
-}
-
-void
-__libcpp_db::__insert_c(void* __c, __libcpp_db::_InsertConstruct *__fn)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
-    {
-        size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
-        __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(__c_node*)));
-        if (cbeg == nullptr)
-            __throw_bad_alloc();
-
-        for (__c_node** p = __cbeg_; p != __cend_; ++p)
-        {
-            __c_node* q = *p;
-            while (q != nullptr)
-            {
-                size_t h = hash<void*>()(q->__c_) % nc;
-                __c_node* r = q->__next_;
-                q->__next_ = cbeg[h];
-                cbeg[h] = q;
-                q = r;
-            }
-        }
-        free(__cbeg_);
-        __cbeg_ = cbeg;
-        __cend_ = __cbeg_ + nc;
-    }
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    void *buf = malloc(sizeof(__c_node));
-    if (buf == nullptr)
-      __throw_bad_alloc();
-    __cbeg_[hc] = __fn(buf, __c, p);
-
-    ++__csz_;
-}
-
-void
-__libcpp_db::__erase_i(void* __i)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    if (__ibeg_ != __iend_)
-    {
-        size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
-        __i_node* p = __ibeg_[hi];
-        if (p != nullptr)
-        {
-            __i_node* q = nullptr;
-            while (p->__i_ != __i)
-            {
-                q = p;
-                p = p->__next_;
-                if (p == nullptr)
-                    return;
-            }
-            if (q == nullptr)
-                __ibeg_[hi] = p->__next_;
-            else
-                q->__next_ = p->__next_;
-            __c_node* c = p->__c_;
-            --__isz_;
-            if (c != nullptr)
-                c->__remove(p);
-            free(p);
-        }
-    }
-}
-
-void
-__libcpp_db::__invalidate_all(void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    if (__cend_ != __cbeg_)
-    {
-        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-        __c_node* p = __cbeg_[hc];
-        if (p == nullptr)
-            return;
-        while (p->__c_ != __c)
-        {
-            p = p->__next_;
-            if (p == nullptr)
-                return;
-        }
-        while (p->end_ != p->beg_)
-        {
-            --p->end_;
-            (*p->end_)->__c_ = nullptr;
-        }
-    }
-}
-
-__c_node*
-__libcpp_db::__find_c_and_lock(void* __c) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    mut().lock();
-#endif
-    if (__cend_ == __cbeg_)
-    {
-#ifndef _LIBCPP_HAS_NO_THREADS
-        mut().unlock();
-#endif
-        return nullptr;
-    }
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    if (p == nullptr)
-    {
-#ifndef _LIBCPP_HAS_NO_THREADS
-        mut().unlock();
-#endif
-        return nullptr;
-    }
-    while (p->__c_ != __c)
-    {
-        p = p->__next_;
-        if (p == nullptr)
-        {
-#ifndef _LIBCPP_HAS_NO_THREADS
-            mut().unlock();
-#endif
-            return nullptr;
-        }
-    }
-    return p;
-}
-
-__c_node*
-__libcpp_db::__find_c(void* __c) const
-{
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
-    while (p->__c_ != __c)
-    {
-        p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
-    }
-    return p;
-}
-
-void
-__libcpp_db::unlock() const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    mut().unlock();
-#endif
-}
-
-void
-__libcpp_db::__erase_c(void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    if (__cend_ != __cbeg_)
-    {
-        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-        __c_node* p = __cbeg_[hc];
-        if (p == nullptr)
-            return;
-        __c_node* q = nullptr;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
-        while (p->__c_ != __c)
-        {
-            q = p;
-            p = p->__next_;
-            if (p == nullptr)
-                return;
-            _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
-        }
-        if (q == nullptr)
-            __cbeg_[hc] = p->__next_;
-        else
-            q->__next_ = p->__next_;
-        while (p->end_ != p->beg_)
-        {
-            --p->end_;
-            (*p->end_)->__c_ = nullptr;
-        }
-        free(p->beg_);
-        free(p);
-        --__csz_;
-    }
-}
-
-void
-__libcpp_db::__iterator_copy(void* __i, const void* __i0)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    __i_node* i0 = __find_iterator(__i0);
-    __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
-    if (i == nullptr && i0 != nullptr)
-        i = __insert_iterator(__i);
-    __c_node* c = i != nullptr ? i->__c_ : nullptr;
-    if (c != c0)
-    {
-        if (c != nullptr)
-            c->__remove(i);
-        if (i != nullptr)
-        {
-            i->__c_ = nullptr;
-            if (c0 != nullptr)
-            {
-                i->__c_ = c0;
-                i->__c_->__add(i);
-            }
-        }
-    }
-}
-
-bool
-__libcpp_db::__dereferenceable(const void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
-}
-
-bool
-__libcpp_db::__decrementable(const void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
-}
-
-bool
-__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
-}
-
-bool
-__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
-}
-
-bool
-__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    RLock _(mut());
-#endif
-    __i_node* i = __find_iterator(__i);
-    __i_node* j = __find_iterator(__j);
-    __c_node* ci = i != nullptr ? i->__c_ : nullptr;
-    __c_node* cj = j != nullptr ? j->__c_ : nullptr;
-    return ci == cj;
-}
-
-void
-__libcpp_db::swap(void* c1, void* c2)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p1 = __cbeg_[hc];
-    _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
-    while (p1->__c_ != c1)
-    {
-        p1 = p1->__next_;
-        _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
-    }
-    hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p2 = __cbeg_[hc];
-    _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
-    while (p2->__c_ != c2)
-    {
-        p2 = p2->__next_;
-        _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
-    }
-    std::swap(p1->beg_, p2->beg_);
-    std::swap(p1->end_, p2->end_);
-    std::swap(p1->cap_, p2->cap_);
-    for (__i_node** p = p1->beg_; p != p1->end_; ++p)
-        (*p)->__c_ = p1;
-    for (__i_node** p = p2->beg_; p != p2->end_; ++p)
-        (*p)->__c_ = p2;
-}
-
-void
-__libcpp_db::__insert_i(void* __i)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
-    WLock _(mut());
-#endif
-    __insert_iterator(__i);
-}
-
-void
-__c_node::__add(__i_node* i)
-{
-    if (end_ == cap_)
-    {
-        size_t nc = 2*static_cast<size_t>(cap_ - beg_);
-        if (nc == 0)
-            nc = 1;
-        __i_node** beg =
-           static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
-        if (beg == nullptr)
-            __throw_bad_alloc();
-
-        if (nc > 1)
-            memcpy(beg, beg_, nc/2*sizeof(__i_node*));
-        free(beg_);
-        beg_ = beg;
-        end_ = beg_ + nc/2;
-        cap_ = beg_ + nc;
-    }
-    *end_++ = i;
-}
-
-// private api
-
-_LIBCPP_HIDDEN
-__i_node*
-__libcpp_db::__insert_iterator(void* __i)
-{
-    if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
-    {
-        size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
-        __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(__i_node*)));
-        if (ibeg == nullptr)
-            __throw_bad_alloc();
-
-        for (__i_node** p = __ibeg_; p != __iend_; ++p)
-        {
-            __i_node* q = *p;
-            while (q != nullptr)
-            {
-                size_t h = hash<void*>()(q->__i_) % nc;
-                __i_node* r = q->__next_;
-                q->__next_ = ibeg[h];
-                ibeg[h] = q;
-                q = r;
-            }
-        }
-        free(__ibeg_);
-        __ibeg_ = ibeg;
-        __iend_ = __ibeg_ + nc;
-    }
-    size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
-    __i_node* p = __ibeg_[hi];
-    __i_node* r = __ibeg_[hi] =
-      static_cast<__i_node*>(malloc(sizeof(__i_node)));
-    if (r == nullptr)
-        __throw_bad_alloc();
-
-    ::new(r) __i_node(__i, p, nullptr);
-    ++__isz_;
-    return r;
-}
-
-_LIBCPP_HIDDEN
-__i_node*
-__libcpp_db::__find_iterator(const void* __i) const
-{
-    __i_node* r = nullptr;
-    if (__ibeg_ != __iend_)
-    {
-        size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
-        for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
-        {
-            if (nd->__i_ == __i)
-            {
-                r = nd;
-                break;
-            }
-        }
-    }
-    return r;
-}
-
-_LIBCPP_HIDDEN
-void
-__c_node::__remove(__i_node* p)
-{
-    __i_node** r = find(beg_, end_, p);
-    _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
-    if (--end_ != r)
-        memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
-}
-
-_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/future.cpp
@@ -197,12 +197,12 @@ promise<void>::~promise()
 {
     if (__state_)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         if (!__state_->__has_value() && __state_->use_count() > 1)
             __state_->set_exception(make_exception_ptr(
                       future_error(make_error_code(future_errc::broken_promise))
                                                       ));
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         __state_->__release_shared();
     }
 }
lib/libcxx/src/ios.cpp
@@ -413,20 +413,20 @@ void
 ios_base::__set_badbit_and_consider_rethrow()
 {
     __rdstate_ |= badbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     if (__exceptions_ & badbit)
         throw;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 void
 ios_base::__set_failbit_and_consider_rethrow()
 {
     __rdstate_ |= failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     if (__exceptions_ & failbit)
         throw;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 bool
lib/libcxx/src/ios.instantiations.cpp
@@ -37,7 +37,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>
 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
 
-#ifndef _LIBCPP_HAS_NO_FSTREAM
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM
 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
lib/libcxx/src/iostream.cpp
@@ -7,17 +7,21 @@
 //===----------------------------------------------------------------------===//
 
 #include <__locale>
-#include <__std_stream>
+#include "std_stream.h"
 #include <new>
 #include <string>
 
+#ifdef _LIBCPP_MSVCRT_LIKE
+#  include <__locale_dir/locale_base_api/locale_guard.h>
+#endif
+
 #define _str(s) #s
 #define str(s) _str(s)
 #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)]
+_ALIGNAS_TYPE (istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -26,7 +30,7 @@ _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)];
 static mbstate_t mb_cin;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)]
+_ALIGNAS_TYPE (wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -35,7 +39,7 @@ _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar
 static mbstate_t mb_wcin;
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]
+_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -44,7 +48,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
 static mbstate_t mb_cout;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]
+_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -53,7 +57,7 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wcha
 static mbstate_t mb_wcout;
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]
+_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -62,7 +66,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
 static mbstate_t mb_cerr;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]
+_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
@@ -71,14 +75,14 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wcha
 static mbstate_t mb_wcerr;
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]
+_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
 ;
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)]
+_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
 __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
 #endif
lib/libcxx/src/legacy_pointer_safety.cpp
@@ -15,9 +15,9 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-_LIBCPP_FUNC_VIS void declare_reachable(void*) {}
-_LIBCPP_FUNC_VIS void declare_no_pointers(char*, size_t) {}
-_LIBCPP_FUNC_VIS void undeclare_no_pointers(char*, size_t) {}
-_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* p) { return p; }
+_LIBCPP_EXPORTED_FROM_ABI void declare_reachable(void*) {}
+_LIBCPP_EXPORTED_FROM_ABI void declare_no_pointers(char*, size_t) {}
+_LIBCPP_EXPORTED_FROM_ABI void undeclare_no_pointers(char*, size_t) {}
+_LIBCPP_EXPORTED_FROM_ABI void* __undeclare_reachable(void* p) { return p; }
 
 _LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/locale.cpp
@@ -6,13 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-// On Solaris, we need to define something to make the C99 parts of localeconv
-// visible.
-#ifdef __sun__
-#define _LCONV_C99
-#endif
-
 #include <__utility/unreachable.h>
+#include <__verbose_abort>
 #include <algorithm>
 #include <clocale>
 #include <codecvt>
@@ -118,16 +113,27 @@ countof(const T * const begin, const T * const end)
 
 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw runtime_error(msg);
 #else
-    (void)msg;
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg.c_str());
 #endif
 }
 
 }
 
+string
+build_name(const string& other, const string& one, locale::category c) {
+    if (other == "*" || one == "*")
+        return "*";
+    if (c == locale::none || other == one)
+        return other;
+
+    // FIXME: Handle the more complicated cases, such as when the locale has
+    // different names for different categories.
+    return "*";
+}
+
 const locale::category locale::none;
 const locale::category locale::collate;
 const locale::category locale::ctype;
@@ -236,10 +242,10 @@ locale::__imp::__imp(const string& name, size_t refs)
       facets_(N),
       name_(name)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         facets_ = locale::classic().__locale_->facets_;
         for (unsigned i = 0; i < facets_.size(); ++i)
             if (facets_[i])
@@ -286,7 +292,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
         install(new messages_byname<wchar_t>(name_));
 #endif
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -295,7 +301,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
                 facets_[i]->__release_shared();
         throw;
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 locale::__imp::__imp(const __imp& other)
@@ -309,17 +315,16 @@ locale::__imp::__imp(const __imp& other)
 }
 
 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
-    : facets_(N),
-      name_("*")
+    : facets_(N), name_(build_name(other.name_, name, c))
 {
     facets_ = other.facets_;
     for (unsigned i = 0; i < facets_.size(); ++i)
         if (facets_[i])
             facets_[i]->__add_shared();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         if (c & locale::collate)
         {
             install(new collate_byname<char>(name));
@@ -380,7 +385,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
             install(new messages_byname<wchar_t>(name));
 #endif
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -389,7 +394,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
                 facets_[i]->__release_shared();
         throw;
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 template<class F>
@@ -402,17 +407,16 @@ locale::__imp::install_from(const locale::__imp& one)
 }
 
 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
-    : facets_(N),
-      name_("*")
+    : facets_(N), name_(build_name(other.name_, one.name_, c))
 {
     facets_ = other.facets_;
     for (unsigned i = 0; i < facets_.size(); ++i)
         if (facets_[i])
             facets_[i]->__add_shared();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         if (c & locale::collate)
         {
             install_from<_VSTD::collate<char> >(one);
@@ -489,7 +493,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
             install_from<_VSTD::messages<wchar_t> >(one);
 #endif
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
@@ -498,7 +502,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
                 facets_[i]->__release_shared();
         throw;
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
 }
 
 locale::__imp::__imp(const __imp& other, facet* f, long id)
@@ -1189,8 +1193,6 @@ ctype<char>::classic_table() noexcept
     return _C_ctype_tab_ + 1;
 #elif defined(__GLIBC__)
     return _LIBCPP_GET_C_LOCALE->__ctype_b;
-#elif defined(__sun__)
-    return __ctype_mask;
 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     return __pctype_func();
 #elif defined(__EMSCRIPTEN__)
@@ -1411,10 +1413,8 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*
             if (iswxdigit_l(ch, __l_))
                 *vec |= xdigit;
 #endif
-#if !defined(__sun__)
             if (iswblank_l(ch, __l_))
                 *vec |= blank;
-#endif
         }
     }
     return low;
@@ -6529,11 +6529,10 @@ void __do_nothing(void*) {}
 
 void __throw_runtime_error(const char* msg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw runtime_error(msg);
 #else
-    (void)msg;
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg);
 #endif
 }
 
lib/libcxx/src/memory.cpp
@@ -25,8 +25,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-const allocator_arg_t allocator_arg = allocator_arg_t();
-
 bad_weak_ptr::~bad_weak_ptr() noexcept {}
 
 const char*
lib/libcxx/src/memory_resource.cpp
@@ -37,7 +37,7 @@ static bool is_aligned_to(void* ptr, size_t align) {
 }
 #endif
 
-class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource {
+class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp : public memory_resource {
   void* do_allocate(size_t bytes, size_t align) override {
 #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
     return std::__libcpp_allocate(bytes, align);
@@ -60,7 +60,7 @@ class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource
 
 // null_memory_resource()
 
-class _LIBCPP_TYPE_VIS __null_memory_resource_imp : public memory_resource {
+class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp : public memory_resource {
   void* do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
   void do_deallocate(void*, size_t, size_t) override {}
   bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; }
@@ -107,7 +107,7 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou
     new_res = new_res ? new_res : new_delete_resource();
     lock_guard<mutex> guard(res_lock);
     memory_resource* old_res = res;
-    res = new_res;
+    res                      = new_res;
     return old_res;
   } else {
     lock_guard<mutex> guard(res_lock);
@@ -175,7 +175,7 @@ void* unsynchronized_pool_resource::__adhoc_pool::__do_allocate(memory_resource*
 
 void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
     memory_resource* upstream, void* p, size_t bytes, size_t align) {
-  _LIBCPP_ASSERT(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
+  _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
   if (__first_->__start_ == p) {
     __chunk_footer* next = __first_->__next_;
     upstream->deallocate(p, __first_->__allocation_size(), __first_->__align_);
@@ -189,7 +189,7 @@ void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
         return;
       }
     }
-    _LIBCPP_ASSERT(false, "deallocating a block that was not allocated with this allocator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(false, "deallocating a block that was not allocated with this allocator");
   }
 }
 
@@ -230,7 +230,7 @@ public:
   }
 
   void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) {
-    _LIBCPP_ASSERT(chunk_size % block_size == 0, "");
+    _LIBCPP_ASSERT_UNCATEGORIZED(chunk_size % block_size == 0, "");
     static_assert(__default_alignment >= alignof(std::max_align_t), "");
     static_assert(__default_alignment >= alignof(__chunk_footer), "");
     static_assert(__default_alignment >= alignof(__vacancy_header), "");
@@ -401,7 +401,8 @@ void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t a
   if (i == __num_fixed_pools_)
     return __adhoc_pool_.__do_deallocate(__res_, p, bytes, align);
   else {
-    _LIBCPP_ASSERT(__fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
+    _LIBCPP_ASSERT_UNCATEGORIZED(
+        __fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
     __fixed_pools_[i].__evacuate(p);
   }
 }
lib/libcxx/src/mutex.cpp
@@ -7,9 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include <__assert>
+#include <__thread/id.h>
 #include <limits>
 #include <mutex>
-#include <system_error>
 
 #include "include/atomic_support.h"
 
@@ -26,10 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-const defer_lock_t  defer_lock{};
-const try_to_lock_t try_to_lock{};
-const adopt_lock_t  adopt_lock{};
-
 // ~mutex is defined elsewhere
 
 void
@@ -51,7 +47,7 @@ mutex::unlock() noexcept
 {
     int ec = __libcpp_mutex_unlock(&__m_);
     (void)ec;
-    _LIBCPP_ASSERT(ec == 0, "call to mutex::unlock failed");
+    _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed");
 }
 
 // recursive_mutex
@@ -67,7 +63,7 @@ recursive_mutex::~recursive_mutex()
 {
     int e = __libcpp_recursive_mutex_destroy(&__m_);
     (void)e;
-    _LIBCPP_ASSERT(e == 0, "call to ~recursive_mutex() failed");
+    _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed");
 }
 
 void
@@ -83,7 +79,7 @@ recursive_mutex::unlock() noexcept
 {
     int e = __libcpp_recursive_mutex_unlock(&__m_);
     (void)e;
-    _LIBCPP_ASSERT(e == 0, "call to recursive_mutex::unlock() failed");
+    _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed");
 }
 
 bool
@@ -211,21 +207,21 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
 #if defined(_LIBCPP_HAS_NO_THREADS)
     if (flag == 0)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             flag = 1;
             func(arg);
             flag = ~once_flag::_State_type(0);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
             flag = 0;
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
 #else // !_LIBCPP_HAS_NO_THREADS
     __libcpp_mutex_lock(&mut);
@@ -233,10 +229,10 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
         __libcpp_condvar_wait(&cv, &mut);
     if (flag == 0)
     {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         try
         {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
             __libcpp_relaxed_store(&flag, once_flag::_State_type(1));
             __libcpp_mutex_unlock(&mut);
             func(arg);
@@ -245,7 +241,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
                                   _AO_Release);
             __libcpp_mutex_unlock(&mut);
             __libcpp_condvar_broadcast(&cv);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
         }
         catch (...)
         {
@@ -255,7 +251,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
             __libcpp_condvar_broadcast(&cv);
             throw;
         }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     }
     else
         __libcpp_mutex_unlock(&mut);
lib/libcxx/src/mutex_destructor.cpp
@@ -28,7 +28,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifdef NEEDS_MUTEX_DESTRUCTOR
-class _LIBCPP_TYPE_VIS mutex
+class _LIBCPP_EXPORTED_FROM_ABI mutex
 {
     __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
 
lib/libcxx/src/new.cpp
@@ -6,53 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <__memory/aligned_alloc.h>
+#include <cstdlib>
 #include <new>
-#include <stdlib.h>
 
-#include "include/atomic_support.h"
+#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
 
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#   if !defined(_LIBCPP_ABI_VCRUNTIME)
-#       include "support/runtime/new_handler_fallback.ipp"
-#   endif
-#elif defined(LIBCXX_BUILDING_LIBCXXABI)
-#   include <cxxabi.h>
-#elif defined(LIBCXXRT)
-#   include <cxxabi.h>
-#   include "support/runtime/new_handler_fallback.ipp"
-#elif defined(__GLIBCXX__)
-    // nothing to do
-#else
-#   include "support/runtime/new_handler_fallback.ipp"
-#endif
-
-namespace std
-{
-
-#ifndef __GLIBCXX__
-const nothrow_t nothrow{};
-#endif
-
-#ifndef LIBSTDCXX
-
-void
-__throw_bad_alloc()
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    throw bad_alloc();
-#else
-    _VSTD::abort();
-#endif
-}
-
-#endif // !LIBSTDCXX
-
-}  // std
-
-#if !defined(__GLIBCXX__) &&                                                   \
-    !defined(_LIBCPP_ABI_VCRUNTIME) &&      \
-    !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
+// The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
+// file. The version in this file is the canonical one.
 
+// ------------------ BEGIN COPY ------------------
 // Implement all new and delete operators as weak definitions
 // in this shared library, so that they can be overridden by programs
 // that define non-weak copies of the functions.
@@ -64,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
     if (size == 0)
         size = 1;
     void* p;
-    while ((p = ::malloc(size)) == nullptr)
+    while ((p = std::malloc(size)) == nullptr)
     {
         // If malloc fails and there is a new_handler,
         // call it to try free up memory.
@@ -72,7 +35,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
         if (nh)
             nh();
         else
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             throw std::bad_alloc();
 #else
             break;
@@ -86,17 +49,17 @@ void*
 operator new(size_t size, const std::nothrow_t&) noexcept
 {
     void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         p = ::operator new(size);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return p;
 }
 
@@ -112,17 +75,17 @@ void*
 operator new[](size_t size, const std::nothrow_t&) noexcept
 {
     void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         p = ::operator new[](size);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return p;
 }
 
@@ -130,7 +93,7 @@ _LIBCPP_WEAK
 void
 operator delete(void* ptr) noexcept
 {
-    ::free(ptr);
+    std::free(ptr);
 }
 
 _LIBCPP_WEAK
@@ -192,7 +155,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
         if (nh)
             nh();
         else {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
             throw std::bad_alloc();
 #else
             break;
@@ -207,17 +170,17 @@ void*
 operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
 {
     void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         p = ::operator new(size, alignment);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return p;
 }
 
@@ -233,17 +196,17 @@ void*
 operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
 {
     void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try
     {
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
         p = ::operator new[](size, alignment);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     }
     catch (...)
     {
     }
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
     return p;
 }
 
@@ -290,4 +253,6 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
 }
 
 #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
+// ------------------ END COPY ------------------
+
+#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
lib/libcxx/src/new_handler.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <new>
+
+#include "include/atomic_support.h"
+
+#if defined(_LIBCPP_ABI_MICROSOFT)
+#  if !defined(_LIBCPP_ABI_VCRUNTIME)
+#    define _LIBPCPP_DEFINE_NEW_HANDLER
+#  endif
+#elif defined(LIBCXX_BUILDING_LIBCXXABI)
+// nothing to do, we use the one from libc++abi
+#elif defined(LIBCXXRT)
+#  define _LIBPCPP_DEFINE_NEW_HANDLER
+#elif defined(__GLIBCXX__)
+// nothing to do, we use the one from libstdc++/libsupc++
+#else
+#  define _LIBPCPP_DEFINE_NEW_HANDLER
+#endif
+
+#if defined(_LIBPCPP_DEFINE_NEW_HANDLER)
+
+namespace std { // purposefully not versioned
+
+static constinit std::new_handler __new_handler = nullptr;
+
+new_handler set_new_handler(new_handler handler) noexcept { return __libcpp_atomic_exchange(&__new_handler, handler); }
+
+new_handler get_new_handler() noexcept { return __libcpp_atomic_load(&__new_handler); }
+
+} // namespace std
+
+#endif // _LIBPCPP_DEFINE_NEW_HANDLER
lib/libcxx/src/support/runtime/new_handler_fallback.ipp → lib/libcxx/src/new_helpers.cpp
@@ -1,4 +1,3 @@
-// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,20 +6,25 @@
 //
 //===----------------------------------------------------------------------===//
 
-namespace std {
+#include <cstdlib>
+#include <new>
 
-static constinit std::new_handler __new_handler = nullptr;
+namespace std { // purposefully not versioned
 
-new_handler
-set_new_handler(new_handler handler) noexcept
-{
-    return __libcpp_atomic_exchange(&__new_handler, handler);
-}
+#ifndef __GLIBCXX__
+const nothrow_t nothrow{};
+#endif
+
+#ifndef LIBSTDCXX
 
-new_handler
-get_new_handler() noexcept
-{
-    return __libcpp_atomic_load(&__new_handler);
+void __throw_bad_alloc() {
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  throw bad_alloc();
+#  else
+  std::abort();
+#  endif
 }
 
+#endif // !LIBSTDCXX
+
 } // namespace std
lib/libcxx/src/optional.cpp
@@ -27,7 +27,7 @@ const char* bad_optional_access::what() const noexcept {
 //  Even though it no longer exists in a header file
 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
 
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
   : public std::logic_error
 {
 public:
lib/libcxx/src/print.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <cstdlib>
+#include <print>
+
+#if defined(_LIBCPP_WIN32API)
+#  define WIN32_LEAN_AND_MEAN
+#  define NOMINMAX
+#  include <io.h>
+#  include <windows.h>
+
+#  include <__system_error/system_error.h>
+
+#  include "filesystem/error.h"
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef _WIN32
+_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
+  // Note the Standard does this in one call, but it's unclear whether
+  // an invalid handle is allowed when calling GetConsoleMode.
+  //
+  // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
+  // https://learn.microsoft.com/en-us/windows/console/getconsolemode
+  intptr_t __handle = _get_osfhandle(fileno(__stream));
+  if (__handle == -1)
+    return false;
+
+  unsigned long __mode;
+  return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode);
+}
+
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+_LIBCPP_EXPORTED_FROM_ABI void
+__write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wstring_view __view) {
+  // https://learn.microsoft.com/en-us/windows/console/writeconsole
+  if (WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fileno(__stream))), // clang-format aid
+                    __view.data(),
+                    __view.size(),
+                    nullptr,
+                    nullptr) == 0) {
+#    ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+    // There is no __throw_system_error overload that takes an error code.
+    throw system_error{filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"};
+#    else  // _LIBCPP_HAS_NO_EXCEPTIONS
+    std::abort();
+#    endif // _LIBCPP_HAS_NO_EXCEPTIONS
+  }
+}
+#  endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+#endif // _WIN32
+
+_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/random.cpp
@@ -13,13 +13,9 @@
 #   define _CRT_RAND_S
 #endif // defined(_LIBCPP_USING_WIN32_RANDOM)
 
+#include <__system_error/system_error.h>
 #include <limits>
 #include <random>
-#include <system_error>
-
-#if defined(__sun__)
-#   define rename solaris_headers_are_broken
-#endif // defined(__sun__)
 
 #include <errno.h>
 #include <stdio.h>
lib/libcxx/src/shared_mutex.cpp
@@ -10,106 +10,86 @@
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
-#include <shared_mutex>
-#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-#  pragma comment(lib, "pthread")
-#endif
+#  include <mutex>
+#  include <shared_mutex>
+#  if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
+#    pragma comment(lib, "pthread")
+#  endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // Shared Mutex Base
-__shared_mutex_base::__shared_mutex_base()
-    : __state_(0)
-{
-}
+__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
 
 // Exclusive ownership
 
-void
-__shared_mutex_base::lock()
-{
-    unique_lock<mutex> lk(__mut_);
-    while (__state_ & __write_entered_)
-        __gate1_.wait(lk);
-    __state_ |= __write_entered_;
-    while (__state_ & __n_readers_)
-        __gate2_.wait(lk);
+void __shared_mutex_base::lock() {
+  unique_lock<mutex> lk(__mut_);
+  while (__state_ & __write_entered_)
+    __gate1_.wait(lk);
+  __state_ |= __write_entered_;
+  while (__state_ & __n_readers_)
+    __gate2_.wait(lk);
 }
 
-bool
-__shared_mutex_base::try_lock()
-{
-    unique_lock<mutex> lk(__mut_);
-    if (__state_ == 0)
-    {
-        __state_ = __write_entered_;
-        return true;
-    }
-    return false;
+bool __shared_mutex_base::try_lock() {
+  unique_lock<mutex> lk(__mut_);
+  if (__state_ == 0) {
+    __state_ = __write_entered_;
+    return true;
+  }
+  return false;
 }
 
-void
-__shared_mutex_base::unlock()
-{
-    lock_guard<mutex> _(__mut_);
-    __state_ = 0;
-    __gate1_.notify_all();
+void __shared_mutex_base::unlock() {
+  lock_guard<mutex> _(__mut_);
+  __state_ = 0;
+  __gate1_.notify_all();
 }
 
 // Shared ownership
 
-void
-__shared_mutex_base::lock_shared()
-{
-    unique_lock<mutex> lk(__mut_);
-    while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
-        __gate1_.wait(lk);
-    unsigned num_readers = (__state_ & __n_readers_) + 1;
-    __state_ &= ~__n_readers_;
-    __state_ |= num_readers;
-}
-
-bool
-__shared_mutex_base::try_lock_shared()
-{
-    unique_lock<mutex> lk(__mut_);
-    unsigned num_readers = __state_ & __n_readers_;
-    if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
-    {
-        ++num_readers;
-        __state_ &= ~__n_readers_;
-        __state_ |= num_readers;
-        return true;
-    }
-    return false;
+void __shared_mutex_base::lock_shared() {
+  unique_lock<mutex> lk(__mut_);
+  while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+    __gate1_.wait(lk);
+  unsigned num_readers = (__state_ & __n_readers_) + 1;
+  __state_ &= ~__n_readers_;
+  __state_ |= num_readers;
 }
 
-void
-__shared_mutex_base::unlock_shared()
-{
-    lock_guard<mutex> _(__mut_);
-    unsigned num_readers = (__state_ & __n_readers_) - 1;
+bool __shared_mutex_base::try_lock_shared() {
+  unique_lock<mutex> lk(__mut_);
+  unsigned num_readers = __state_ & __n_readers_;
+  if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
+    ++num_readers;
     __state_ &= ~__n_readers_;
     __state_ |= num_readers;
-    if (__state_ & __write_entered_)
-    {
-        if (num_readers == 0)
-            __gate2_.notify_one();
-    }
-    else
-    {
-        if (num_readers == __n_readers_ - 1)
-            __gate1_.notify_one();
-    }
+    return true;
+  }
+  return false;
 }
 
+void __shared_mutex_base::unlock_shared() {
+  lock_guard<mutex> _(__mut_);
+  unsigned num_readers = (__state_ & __n_readers_) - 1;
+  __state_ &= ~__n_readers_;
+  __state_ |= num_readers;
+  if (__state_ & __write_entered_) {
+    if (num_readers == 0)
+      __gate2_.notify_one();
+  } else {
+    if (num_readers == __n_readers_ - 1)
+      __gate1_.notify_one();
+  }
+}
 
 // Shared Timed Mutex
 // These routines are here for ABI stability
 shared_timed_mutex::shared_timed_mutex() : __base_() {}
-void shared_timed_mutex::lock()     { return __base_.lock(); }
+void shared_timed_mutex::lock() { return __base_.lock(); }
 bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
-void shared_timed_mutex::unlock()   { return __base_.unlock(); }
+void shared_timed_mutex::unlock() { return __base_.unlock(); }
 void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
 bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
 void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
lib/libcxx/include/__std_stream → lib/libcxx/src/std_stream.h
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___STD_STREAM
-#define _LIBCPP___STD_STREAM
+#ifndef _LIBCPP_STD_STREAM_H
+#define _LIBCPP_STD_STREAM_H
 
 #include <__config>
 #include <__locale>
@@ -60,6 +60,12 @@ private:
     bool __last_consumed_is_next_;
     bool __always_noconv_;
 
+#if defined(_LIBCPP_WIN32API)
+    static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
+#else
+    static constexpr bool __is_win32api_wide_char = false;
+#endif
+
     __stdinbuf(const __stdinbuf&);
     __stdinbuf& operator=(const __stdinbuf&);
 
@@ -74,6 +80,12 @@ __stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
       __last_consumed_is_next_(false)
 {
     imbue(this->getloc());
+    // On Windows, in wchar_t mode, ignore the codecvt from the locale by
+    // default and assume noconv; this passes wchar_t through unmodified from
+    // getwc. If the user sets a custom locale with imbue(), that gets honored,
+    // the IO is done with getc() and converted with the provided codecvt.
+    if constexpr (__is_win32api_wide_char)
+        __always_noconv_ = true;
 }
 
 template <class _CharT>
@@ -101,6 +113,36 @@ __stdinbuf<_CharT>::uflow()
     return __getchar(true);
 }
 
+static bool __do_getc(FILE *__fp, char *__pbuf) {
+    int __c = getc(__fp);
+    if (__c == EOF)
+        return false;
+    *__pbuf = static_cast<char>(__c);
+    return true;
+}
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_getc(FILE *__fp, wchar_t *__pbuf) {
+    wint_t __c = getwc(__fp);
+    if (__c == WEOF)
+        return false;
+    *__pbuf = static_cast<wchar_t>(__c);
+    return true;
+}
+#endif
+
+static bool __do_ungetc(int __c, FILE *__fp, char __dummy) {
+    if (ungetc(__c, __fp) == EOF)
+        return false;
+    return true;
+}
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_ungetc(std::wint_t __c, FILE *__fp, wchar_t __dummy) {
+    if (ungetwc(__c, __fp) == WEOF)
+        return false;
+    return true;
+}
+#endif
+
 template <class _CharT>
 typename __stdinbuf<_CharT>::int_type
 __stdinbuf<_CharT>::__getchar(bool __consume)
@@ -115,6 +157,20 @@ __stdinbuf<_CharT>::__getchar(bool __consume)
         }
         return __result;
     }
+    if (__always_noconv_) {
+        char_type __1buf;
+        if (!__do_getc(__file_, &__1buf))
+            return traits_type::eof();
+        if (!__consume)
+        {
+            if (!__do_ungetc(traits_type::to_int_type(__1buf), __file_, __1buf))
+                return traits_type::eof();
+        }
+        else
+            __last_consumed_ = traits_type::to_int_type(__1buf);
+        return traits_type::to_int_type(__1buf);
+    }
+
     char __extbuf[__limit];
     int __nread = _VSTD::max(1, __encoding_);
     for (int __i = 0; __i < __nread; ++__i)
@@ -125,42 +181,37 @@ __stdinbuf<_CharT>::__getchar(bool __consume)
         __extbuf[__i] = static_cast<char>(__c);
     }
     char_type __1buf;
-    if (__always_noconv_)
-        __1buf = static_cast<char_type>(__extbuf[0]);
-    else
+    const char* __enxt;
+    char_type* __inxt;
+    codecvt_base::result __r;
+    do
     {
-        const char* __enxt;
-        char_type* __inxt;
-        codecvt_base::result __r;
-        do
+        state_type __sv_st = *__st_;
+        __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
+                               &__1buf, &__1buf + 1, __inxt);
+        switch (__r)
         {
-            state_type __sv_st = *__st_;
-            __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
-                                   &__1buf, &__1buf + 1, __inxt);
-            switch (__r)
+        case _VSTD::codecvt_base::ok:
+            break;
+        case codecvt_base::partial:
+            *__st_ = __sv_st;
+            if (__nread == sizeof(__extbuf))
+                return traits_type::eof();
             {
-            case _VSTD::codecvt_base::ok:
-                break;
-            case codecvt_base::partial:
-                *__st_ = __sv_st;
-                if (__nread == sizeof(__extbuf))
+                int __c = getc(__file_);
+                if (__c == EOF)
                     return traits_type::eof();
-                {
-                    int __c = getc(__file_);
-                    if (__c == EOF)
-                        return traits_type::eof();
-                    __extbuf[__nread] = static_cast<char>(__c);
-                }
-                ++__nread;
-                break;
-            case codecvt_base::error:
-                return traits_type::eof();
-            case _VSTD::codecvt_base::noconv:
-                __1buf = static_cast<char_type>(__extbuf[0]);
-                break;
+                __extbuf[__nread] = static_cast<char>(__c);
             }
-        } while (__r == _VSTD::codecvt_base::partial);
-    }
+            ++__nread;
+            break;
+        case codecvt_base::error:
+            return traits_type::eof();
+        case _VSTD::codecvt_base::noconv:
+            __1buf = static_cast<char_type>(__extbuf[0]);
+            break;
+        }
+    } while (__r == _VSTD::codecvt_base::partial);
     if (!__consume)
     {
         for (int __i = __nread; __i > 0;)
@@ -188,8 +239,11 @@ __stdinbuf<_CharT>::pbackfail(int_type __c)
         }
         return __c;
     }
-    if (__last_consumed_is_next_)
-    {
+    if (__always_noconv_ && __last_consumed_is_next_) {
+        if (!__do_ungetc(__last_consumed_, __file_,
+                         traits_type::to_char_type(__last_consumed_)))
+            return traits_type::eof();
+    } else if (__last_consumed_is_next_) {
         char __extbuf[__limit];
         char* __enxt;
         const char_type __ci = traits_type::to_char_type(__last_consumed_);
@@ -244,6 +298,12 @@ private:
     state_type* __st_;
     bool __always_noconv_;
 
+#if defined(_LIBCPP_WIN32API)
+    static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
+#else
+    static constexpr bool __is_win32api_wide_char = false;
+#endif
+
     __stdoutbuf(const __stdoutbuf&);
     __stdoutbuf& operator=(const __stdoutbuf&);
 };
@@ -255,7 +315,30 @@ __stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)
       __st_(__st),
       __always_noconv_(__cv_->always_noconv())
 {
+    // On Windows, in wchar_t mode, ignore the codecvt from the locale by
+    // default and assume noconv; this passes wchar_t through unmodified to
+    // fputwc, which handles it correctly depending on the actual mode of the
+    // output stream. If the user sets a custom locale with imbue(), that
+    // gets honored.
+    if constexpr (__is_win32api_wide_char)
+        __always_noconv_ = true;
+}
+
+static bool __do_fputc(char __c, FILE* __fp) {
+    if (fwrite(&__c, sizeof(__c), 1, __fp) != 1)
+        return false;
+    return true;
 }
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_fputc(wchar_t __c, FILE* __fp) {
+    // fputwc works regardless of wide/narrow mode of stdout, while
+    // fwrite of wchar_t only works if the stream actually has been set
+    // into wide mode.
+    if (fputwc(__c, __fp) == WEOF)
+        return false;
+    return true;
+}
+#endif
 
 template <class _CharT>
 typename __stdoutbuf<_CharT>::int_type
@@ -268,7 +351,7 @@ __stdoutbuf<_CharT>::overflow(int_type __c)
         __1buf = traits_type::to_char_type(__c);
         if (__always_noconv_)
         {
-            if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)
+            if (!__do_fputc(__1buf, __file_))
                 return traits_type::eof();
         }
         else
@@ -313,7 +396,10 @@ template <class _CharT>
 streamsize
 __stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
 {
-    if (__always_noconv_)
+    // For wchar_t on Windows, don't call fwrite(), but write characters one
+    // at a time with fputwc(); that works both when stdout is in the default
+    // mode and when it is set to Unicode mode.
+    if (__always_noconv_ && !__is_win32api_wide_char)
         return fwrite(__s, sizeof(char_type), __n, __file_);
     streamsize __i = 0;
     for (; __i < __n; ++__i, ++__s)
@@ -358,4 +444,4 @@ _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
 
-#endif // _LIBCPP___STD_STREAM
+#endif // _LIBCPP_STD_STREAM_H
lib/libcxx/src/stdexcept.cpp
@@ -9,7 +9,6 @@
 #include <new>
 #include <stdexcept>
 #include <string>
-#include <system_error>
 
 #ifdef _LIBCPP_ABI_VCRUNTIME
 #include "support/runtime/stdexcept_vcruntime.ipp"
lib/libcxx/src/string.cpp
@@ -12,7 +12,6 @@
 #include <cstdlib>
 #include <limits>
 #include <stdexcept>
-#include <stdio.h>
 #include <string>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -61,22 +60,12 @@ template string operator+<char, char_traits<char>, allocator<char>>(char const*,
 namespace
 {
 
-template<typename T>
-inline void throw_helper(const string& msg) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    throw T(msg);
-#else
-    fprintf(stderr, "%s\n", msg.c_str());
-    _VSTD::abort();
-#endif
-}
-
 inline void throw_from_string_out_of_range(const string& func) {
-    throw_helper<out_of_range>(func + ": out of range");
+    std::__throw_out_of_range((func + ": out of range").c_str());
 }
 
 inline void throw_from_string_invalid_arg(const string& func) {
-    throw_helper<invalid_argument>(func + ": no conversion");
+    std::__throw_invalid_argument((func + ": no conversion").c_str());
 }
 
 // as_integer
@@ -357,7 +346,7 @@ S i_to_string(V v) {
     constexpr size_t bufsize = numeric_limits<V>::digits10 + 2;  // +1 for minus, +1 for digits10
     char buf[bufsize];
     const auto res = to_chars(buf, buf + bufsize, v);
-    _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
+    _LIBCPP_ASSERT_INTERNAL(res.ec == errc(), "bufsize must be large enough to accomodate the value");
     return S(buf, res.ptr);
 }
 
lib/libcxx/src/strstream.cpp
@@ -173,7 +173,7 @@ strstreambuf::overflow(int_type __c)
         if (buf == nullptr)
             return int_type(EOF);
         if (old_size != 0) {
-            _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
+            _LIBCPP_ASSERT_UNCATEGORIZED(eback(), "overflow copying from NULL");
             memcpy(buf, eback(), static_cast<size_t>(old_size));
         }
         ptrdiff_t ninp = gptr()  - eback();
lib/libcxx/src/system_error.cpp
@@ -12,6 +12,7 @@
 #endif
 
 #include <__assert>
+#include <__verbose_abort>
 #include <cerrno>
 #include <cstdio>
 #include <cstdlib>
@@ -103,7 +104,7 @@ handle_strerror_r_return(int strerror_return, char *buffer) {
   if (new_errno == EINVAL)
     return "";
 
-  _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r");
+  _LIBCPP_ASSERT_UNCATEGORIZED(new_errno == ERANGE, "unexpected error from ::strerror_r");
   // FIXME maybe? 'strerror_buff_size' is likely to exceed the
   // maximum error size so ERANGE shouldn't be returned.
   std::abort();
@@ -286,12 +287,10 @@ system_error::~system_error() noexcept
 void
 __throw_system_error(int ev, const char* what_arg)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     throw system_error(error_code(ev, system_category()), what_arg);
 #else
-    (void)ev;
-    (void)what_arg;
-    _VSTD::abort();
+    _LIBCPP_VERBOSE_ABORT("system_error was thrown in -fno-exceptions mode with error %i and message \"%s\"", ev, what_arg);
 #endif
 }
 
lib/libcxx/src/thread.cpp
@@ -10,6 +10,8 @@
 
 #ifndef _LIBCPP_HAS_NO_THREADS
 
+#include <__thread/poll_with_backoff.h>
+#include <__thread/timed_backoff_policy.h>
 #include <exception>
 #include <future>
 #include <limits>
lib/libcxx/src/valarray.cpp
@@ -12,8 +12,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // These two symbols are part of the v1 ABI but not part of the >=v2 ABI.
 #if _LIBCPP_ABI_VERSION == 1
-template _LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t);
-template _LIBCPP_FUNC_VIS valarray<size_t>::~valarray();
+template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t);
+template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
 #endif
 
 template void valarray<size_t>::resize(size_t, size_t);
src/Compilation.zig
@@ -4318,6 +4318,9 @@ pub fn addCCArgs(
             try argv.append("-D_LIBCPP_HAS_NO_THREADS");
         }
 
+        // See the comment in libcxx.zig for more details about this.
+        try argv.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
+
         try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
             @intFromEnum(comp.libcxx_abi_version),
         }));
src/libcxx.zig
@@ -46,15 +46,17 @@ const libcxx_files = [_][]const u8{
     "src/chrono.cpp",
     "src/condition_variable.cpp",
     "src/condition_variable_destructor.cpp",
-    "src/debug.cpp",
     "src/exception.cpp",
     "src/experimental/memory_resource.cpp",
+    "src/filesystem/directory_entry.cpp",
     "src/filesystem/directory_iterator.cpp",
+    "src/filesystem/filesystem_clock.cpp",
+    "src/filesystem/filesystem_error.cpp",
     // omit int128_builtins.cpp because it provides __muloti4 which is already provided
     // by compiler_rt and crashes on Windows x86_64: https://github.com/ziglang/zig/issues/10719
     //"src/filesystem/int128_builtins.cpp",
     "src/filesystem/operations.cpp",
-    "src/format.cpp",
+    "src/filesystem/path.cpp",
     "src/functional.cpp",
     "src/future.cpp",
     "src/hash.cpp",
@@ -65,10 +67,14 @@ const libcxx_files = [_][]const u8{
     "src/legacy_pointer_safety.cpp",
     "src/locale.cpp",
     "src/memory.cpp",
+    "src/memory_resource.cpp",
     "src/mutex.cpp",
     "src/mutex_destructor.cpp",
     "src/new.cpp",
+    "src/new_handler.cpp",
+    "src/new_helpers.cpp",
     "src/optional.cpp",
+    "src/print.cpp",
     "src/random.cpp",
     "src/random_shuffle.cpp",
     "src/regex.cpp",
@@ -82,14 +88,12 @@ const libcxx_files = [_][]const u8{
     "src/support/ibm/mbsnrtowcs.cpp",
     "src/support/ibm/wcsnrtombs.cpp",
     "src/support/ibm/xlocale_zos.cpp",
-    "src/support/solaris/xlocale.cpp",
     "src/support/win32/locale_win32.cpp",
     "src/support/win32/support.cpp",
     "src/support/win32/thread_win32.cpp",
     "src/system_error.cpp",
     "src/thread.cpp",
     "src/typeinfo.cpp",
-    "src/utility.cpp",
     "src/valarray.cpp",
     "src/variant.cpp",
     "src/vector.cpp",
@@ -166,6 +170,13 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
         try cflags.append("-D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS");
         try cflags.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
 
+        // See libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
+        // for potentially enabling some fancy features here, which would
+        // require corresponding changes in libcxx.zig, as well as
+        // Compilation.addCCArgs. This option makes it use serial backend which
+        // is simple and works everywhere.
+        try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
+
         try cflags.append(abi_version_arg);
         try cflags.append(abi_namespace_arg);
 
@@ -336,6 +347,8 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
         try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY");
         try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
         try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
+        // This must be coordinated with the same flag in libcxx
+        try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
 
         try cflags.append(abi_version_arg);
         try cflags.append(abi_namespace_arg);