[libcxx-commits] [libcxx] [llvm] [libc++] Remove `get_temporary_buffer`/`return_temporary_buffer` (PR #100914)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 13 23:54:14 PDT 2024


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/100914

>From f7ff07eca878d623777ab440e1f82dd93e273826 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 28 Jul 2024 14:02:52 +0800
Subject: [PATCH 01/20] [libc++] Remove functions deprecated in C++17 and
 removed in C++20

Works towards P0619R4.

- `std::uncaught_exception` was not previously deprecated. This patch deprecates it since C++17 as per N4259. `std::uncaught_exceptions` is used instead as libc++ unconditionally provides this function.
- `std::get_temporary_buffer` is replaced with the internal version `__get_temporary_buffer`.
- `std::return_temporary_buffer` is replaced with direct `__libcpp_deallocate_unsized` call.

Escape hatches:
- `_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION` restores `std::uncaught_exception`.
- `_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER` restores `std::get_temporary_buffer` and `std::return_temporary_buffer`.
---
 libcxx/docs/Status/Cxx17.rst                  |  1 +
 libcxx/docs/Status/Cxx17Papers.csv            |  2 +-
 libcxx/docs/Status/Cxx20.rst                  |  2 +-
 libcxx/docs/UsingLibcxx.rst                   |  6 ++++
 libcxx/include/__algorithm/inplace_merge.h    |  5 +---
 libcxx/include/__algorithm/stable_partition.h | 10 ++-----
 libcxx/include/__algorithm/stable_sort.h      |  5 +---
 libcxx/include/__exception/operations.h       |  4 ++-
 libcxx/include/__memory/temporary_buffer.h    | 28 ++++++++++++-------
 libcxx/include/__ostream/basic_ostream.h      |  2 +-
 libcxx/include/exception                      |  2 +-
 libcxx/include/memory                         |  4 +--
 libcxx/include/syncstream                     |  2 +-
 libcxx/modules/std/exception.inc              |  1 -
 libcxx/src/exception.cpp                      |  3 ++
 .../diagnostics/memory.nodiscard.verify.cpp   |  1 +
 .../alg.partitions/stable_partition.pass.cpp  |  6 ++--
 .../uncaught/uncaught_exception.pass.cpp      |  4 +++
 .../temporary.buffer/overaligned.pass.cpp     |  1 +
 .../temporary_buffer.pass.cpp                 |  1 +
 libcxx/utils/libcxx/test/modules.py           |  7 -----
 21 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/libcxx/docs/Status/Cxx17.rst b/libcxx/docs/Status/Cxx17.rst
index ad4f8576f03dbc..ac07d299d7e743 100644
--- a/libcxx/docs/Status/Cxx17.rst
+++ b/libcxx/docs/Status/Cxx17.rst
@@ -40,6 +40,7 @@ Paper Status
 
 .. note::
 
+   .. [#note-N4259] N4259: ``std::uncaught_exception`` is deprecated since version 20.0.
    .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``.
    .. [#note-P0226] P0226: Progress is tracked `here <https://https://libcxx.llvm.org/Status/SpecialMath.html>`_.
    .. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.
diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv
index 6c657d51f5c7e3..f9a87b2cbfd229 100644
--- a/libcxx/docs/Status/Cxx17Papers.csv
+++ b/libcxx/docs/Status/Cxx17Papers.csv
@@ -4,7 +4,7 @@
 "`N4169 <https://wg21.link/n4169>`__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7"
 "`N4190 <https://wg21.link/n4190>`__","LWG","Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.","Urbana","|Complete|","15.0"
 "`N4258 <https://wg21.link/n4258>`__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7"
-"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7"
+"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete| [#note-N4259]_","3.7"
 "`N4277 <https://wg21.link/n4277>`__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2"
 "`N4279 <https://wg21.link/n4279>`__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7"
 "`N4280 <https://wg21.link/n4280>`__","LWG","Non-member size() and more","Urbana","|Complete|","3.6"
diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst
index b76e30fbb3712e..a13496bd0a8fd8 100644
--- a/libcxx/docs/Status/Cxx20.rst
+++ b/libcxx/docs/Status/Cxx20.rst
@@ -44,7 +44,7 @@ Paper Status
    .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature
       (the feature-test macro is not set).
    .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 <https://llvm.org/PR45368>`__.
-   .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, and D.12 remain undone.
+   .. [#note-P0619] P0619: Section D.4 remains undone.
    .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
    .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
    .. [#note-P0660] P0660: The paper is implemented but the features are experimental and can be enabled via ``-fexperimental-library``.
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index df08875c13beae..8937639bd2bf2b 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -215,6 +215,9 @@ C++17 Specific Configuration Macros
 
 C++20 Specific Configuration Macros
 -----------------------------------
+**_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION**:
+  This macro is used to re-enable `uncaught_exception`.
+
 **_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**:
   This macro is used to re-enable the function
   ``std::shared_ptr<...>::unique()``.
@@ -231,6 +234,9 @@ C++20 Specific Configuration Macros
 **_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**:
   This macro is used to re-enable `raw_storage_iterator`.
 
+**_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER**:
+  This macro is used to re-enable `get_temporary_buffer` and `return_temporary_buffer`.
+
 **_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**:
   This macro is used to re-enable `is_literal_type`, `is_literal_type_v`,
   `result_of` and `result_of_t`.
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index a6bcc66a2fa47a..4c6ab527c8188c 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -211,10 +211,7 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
   difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
   difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
   difference_type __buf_size = std::min(__len1, __len2);
-  // TODO: Remove the use of std::get_temporary_buffer
-  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-  pair<value_type*, ptrdiff_t> __buf = std::get_temporary_buffer<value_type>(__buf_size);
-  _LIBCPP_SUPPRESS_DEPRECATED_POP
+  pair<value_type*, ptrdiff_t> __buf = std::__get_temporary_buffer<value_type>(__buf_size);
   unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
   return std::__inplace_merge<_AlgPolicy>(
       std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 8bb1eaf2d22495..4f09b87ae0f9a1 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -135,10 +135,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   pair<value_type*, ptrdiff_t> __p(0, 0);
   unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len >= __alloc_limit) {
-    // TODO: Remove the use of std::get_temporary_buffer
-    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-    __p = std::get_temporary_buffer<value_type>(__len);
-    _LIBCPP_SUPPRESS_DEPRECATED_POP
+    __p = std::__get_temporary_buffer<value_type>(__len);
     __h.reset(__p.first);
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
@@ -275,10 +272,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   pair<value_type*, ptrdiff_t> __p(0, 0);
   unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len >= __alloc_limit) {
-    // TODO: Remove the use of std::get_temporary_buffer
-    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-    __p = std::get_temporary_buffer<value_type>(__len);
-    _LIBCPP_SUPPRESS_DEPRECATED_POP
+    __p = std::__get_temporary_buffer<value_type>(__len);
     __h.reset(__p.first);
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 726e7e16b3564a..69fd85cc798bd2 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -244,10 +244,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
-    // TODO: Remove the use of std::get_temporary_buffer
-    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-    __buf = std::get_temporary_buffer<value_type>(__len);
-    _LIBCPP_SUPPRESS_DEPRECATED_POP
+    __buf = std::__get_temporary_buffer<value_type>(__len);
     __h.reset(__buf.first);
   }
 
diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h
index 0a9c7a7c7f0d88..4a0a697c00e6e5 100644
--- a/libcxx/include/__exception/operations.h
+++ b/libcxx/include/__exception/operations.h
@@ -29,7 +29,9 @@ 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;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
+_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
 _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
 
 class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index 88799ca95c1f35..c6cb3389051843 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -22,8 +22,8 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
-get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t>
+__get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
   pair<_Tp*, ptrdiff_t> __r(0, 0);
   const ptrdiff_t __m =
       (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);
@@ -56,20 +56,28 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
   return __r;
 }
 
-template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
-}
-
 struct __return_temporary_buffer {
-  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
   template <class _Tp>
   _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const {
-    std::return_temporary_buffer(__p);
+    std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
   }
-  _LIBCPP_SUPPRESS_DEPRECATED_POP
 };
 
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+
+template <class _Tp>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
+get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
+  return std::__get_temporary_buffer<_Tp>(__n);
+}
+
+template <class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
+  std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
+}
+
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h
index 178359d6815671..e0698ccb4842a5 100644
--- a/libcxx/include/__ostream/basic_ostream.h
+++ b/libcxx/include/__ostream/basic_ostream.h
@@ -152,7 +152,7 @@ basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& _
 
 template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>::sentry::~sentry() {
-  if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) {
+  if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) {
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
diff --git a/libcxx/include/exception b/libcxx/include/exception
index 5eff8e3f8a4bfa..64463e02cb16aa 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -47,7 +47,7 @@ terminate_handler set_terminate(terminate_handler  f ) noexcept;
 terminate_handler get_terminate() noexcept;
 [[noreturn]] void terminate() noexcept;
 
-bool uncaught_exception()  noexcept;
+bool uncaught_exception()  noexcept;  // deprecated in C++17, removed in C++20
 int  uncaught_exceptions() noexcept;  // C++17
 
 typedef unspecified exception_ptr;
diff --git a/libcxx/include/memory b/libcxx/include/memory
index b940a32c3ebe6c..db3386cca48009 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -182,8 +182,8 @@ public:
     raw_storage_iterator  operator++(int);
 };
 
-template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
-template <class T> void               return_temporary_buffer(T* p) noexcept;
+template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; // deprecated in C++17, removed in C++20
+template <class T> void               return_temporary_buffer(T* p) noexcept;     // deprecated in C++17, removed in C++20
 
 template <class T> T* addressof(T& r) noexcept;
 template <class T> T* addressof(const T&& r) noexcept = delete;
diff --git a/libcxx/include/syncstream b/libcxx/include/syncstream
index e6f35b6f428eda..9da2abb252bfdd 100644
--- a/libcxx/include/syncstream
+++ b/libcxx/include/syncstream
@@ -358,7 +358,7 @@ private:
   // TODO Use a more generic buffer.
   // That buffer should be light with almost no additional headers. Then
   // it can be use here, the __retarget_buffer, and place that use
-  // the now deprecated get_temporary_buffer
+  // the now removed get_temporary_buffer
 
   basic_string<_CharT, _Traits, _Allocator> __str_;
   bool __emit_on_sync_{false};
diff --git a/libcxx/modules/std/exception.inc b/libcxx/modules/std/exception.inc
index 8e802c7065e0f5..0c110e6e743fb7 100644
--- a/libcxx/modules/std/exception.inc
+++ b/libcxx/modules/std/exception.inc
@@ -21,6 +21,5 @@ export namespace std {
   using std::terminate;
   using std::terminate_handler;
   using std::throw_with_nested;
-  using std::uncaught_exception;
   using std::uncaught_exceptions;
 } // namespace std
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index ddb186bf8048fe..ac6324cd9fe355 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -6,6 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
+#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 #include <exception>
 #include <new>
 #include <typeinfo>
diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index 646569e3d573ab..6410c84e926aad 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -10,6 +10,7 @@
 
 // check that <memory> functions are marked [[nodiscard]]
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
 
 // clang-format off
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
index 85d12d08c96750..44027543aaf16e 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
@@ -282,9 +282,9 @@ test()
     assert(array[9] == P(0, 2));
   }
 #if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
-  // TODO: Re-enable this test once we're no longer using get_temporary_buffer().
+  // TODO: Re-enable this test once we get recursive inlining fixed.
   // For now it trips up GCC due to the use of always_inline.
-#if 0
+#  if 0
   { // check that the algorithm still works when no memory is available
     std::vector<int> vec(150, 3);
     vec[5]                             = 6;
@@ -300,7 +300,7 @@ test()
     assert(std::is_partitioned(vec.begin(), vec.end(), [](int i) { return i < 5; }));
     getGlobalMemCounter()->reset();
   }
-#endif
+#  endif
 #endif // TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
 }
 
diff --git a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
index e368ce177b3177..6fa4cb22070c8e 100644
--- a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
+++ b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
@@ -7,6 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: no-exceptions
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 // test uncaught_exception
 
 #include <exception>
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
index 8499478d1fb384..4c66370fac9221 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
@@ -8,6 +8,7 @@
 
 // UNSUPPORTED: c++03
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
 
 // <memory>
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
index 6c0fbf2568fff6..5f7fc4571906cc 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
@@ -8,6 +8,7 @@
 
 // <memory>
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
 
 // template <class T>
diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py
index b7758dc9a41ee8..ed0e0d684327ba 100644
--- a/libcxx/utils/libcxx/test/modules.py
+++ b/libcxx/utils/libcxx/test/modules.py
@@ -52,13 +52,6 @@
     "std::operator==",
 ]
 
-# TODO MODULES remove zombie names
-# https://libcxx.llvm.org/Status/Cxx20.html#note-p0619
-SkipDeclarations["memory"] = [
-    "std::return_temporary_buffer",
-    "std::get_temporary_buffer",
-]
-
 # include/__type_traits/is_swappable.h
 SkipDeclarations["type_traits"] = [
     "std::swap",

>From 25a978279fdf90f99dae1f823b3b6ac3624ac6f0 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Thu, 1 Aug 2024 22:33:41 +0800
Subject: [PATCH 02/20] Document escape hatches to 20.rst

---
 libcxx/docs/ReleaseNotes/20.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index f959c8829277e6..db318525f4b5f0 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -44,6 +44,12 @@ Implemented Papers
 Improvements and New Features
 -----------------------------
 
+- The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception``
+  available.
+
+- The ``_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER`` macro has been added to make ``std::get_temporary_buffer`` and
+  ``std::return_temporary_buffer`` available.
+
 - TODO
 
 

>From 60212b2e95da50f21e20ffc402a0b259add89f39 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 23:19:17 +0800
Subject: [PATCH 03/20] Split changes for `uncaught_exception` to another PR

---
 libcxx/docs/ReleaseNotes/20.rst          | 3 ---
 libcxx/docs/Status/Cxx17.rst             | 1 -
 libcxx/docs/Status/Cxx20.rst             | 2 +-
 libcxx/docs/UsingLibcxx.rst              | 3 ---
 libcxx/include/__exception/operations.h  | 4 +---
 libcxx/include/__ostream/basic_ostream.h | 2 +-
 libcxx/modules/std/exception.inc         | 1 +
 libcxx/src/exception.cpp                 | 3 ---
 8 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index f6b5b3e9623d4a..b24b65270e3c7a 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -44,9 +44,6 @@ Implemented Papers
 Improvements and New Features
 -----------------------------
 
-- The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception``
-  available.
-
 - The ``_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER`` macro has been added to make ``std::get_temporary_buffer`` and
   ``std::return_temporary_buffer`` available.
 
diff --git a/libcxx/docs/Status/Cxx17.rst b/libcxx/docs/Status/Cxx17.rst
index 6bccd4cf854c40..3f1f2071300c80 100644
--- a/libcxx/docs/Status/Cxx17.rst
+++ b/libcxx/docs/Status/Cxx17.rst
@@ -40,7 +40,6 @@ Paper Status
 
 .. note::
 
-   .. [#note-N4259] N4259: ``std::uncaught_exception`` is deprecated since version 20.0.
    .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``.
    .. [#note-P0226] P0226: Progress is tracked `here <https://https://libcxx.llvm.org/Status/SpecialMath.html>`_.
    .. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.
diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst
index a13496bd0a8fd8..a962779cabe939 100644
--- a/libcxx/docs/Status/Cxx20.rst
+++ b/libcxx/docs/Status/Cxx20.rst
@@ -44,7 +44,7 @@ Paper Status
    .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature
       (the feature-test macro is not set).
    .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 <https://llvm.org/PR45368>`__.
-   .. [#note-P0619] P0619: Section D.4 remains undone.
+   .. [#note-P0619] P0619: Only sections D.8, D.9, D.10, D.12, and D.13 are implemented. Sections D.4, D.7, and D.11 remain undone.
    .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
    .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
    .. [#note-P0660] P0660: The paper is implemented but the features are experimental and can be enabled via ``-fexperimental-library``.
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 8937639bd2bf2b..846dfaaf0bef34 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -215,9 +215,6 @@ C++17 Specific Configuration Macros
 
 C++20 Specific Configuration Macros
 -----------------------------------
-**_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION**:
-  This macro is used to re-enable `uncaught_exception`.
-
 **_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**:
   This macro is used to re-enable the function
   ``std::shared_ptr<...>::unique()``.
diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h
index 4a0a697c00e6e5..0a9c7a7c7f0d88 100644
--- a/libcxx/include/__exception/operations.h
+++ b/libcxx/include/__exception/operations.h
@@ -29,9 +29,7 @@ using terminate_handler = void (*)();
 _LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
 _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
 
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
-_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
+_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT;
 _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
 
 class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h
index e0698ccb4842a5..178359d6815671 100644
--- a/libcxx/include/__ostream/basic_ostream.h
+++ b/libcxx/include/__ostream/basic_ostream.h
@@ -152,7 +152,7 @@ basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& _
 
 template <class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>::sentry::~sentry() {
-  if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) {
+  if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) {
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     try {
 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
diff --git a/libcxx/modules/std/exception.inc b/libcxx/modules/std/exception.inc
index 0c110e6e743fb7..8e802c7065e0f5 100644
--- a/libcxx/modules/std/exception.inc
+++ b/libcxx/modules/std/exception.inc
@@ -21,5 +21,6 @@ export namespace std {
   using std::terminate;
   using std::terminate_handler;
   using std::throw_with_nested;
+  using std::uncaught_exception;
   using std::uncaught_exceptions;
 } // namespace std
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index ac6324cd9fe355..ddb186bf8048fe 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -6,9 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
-#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
 #include <exception>
 #include <new>
 #include <typeinfo>

>From 2841f7201870e8472986f70d59123ac8268e5882 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 23:55:57 +0800
Subject: [PATCH 04/20] Split changes for `uncaught_exception` to another PR
 (completing)

---
 libcxx/include/exception                                      | 2 +-
 .../support.exception/uncaught/uncaught_exception.pass.cpp    | 4 ----
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/libcxx/include/exception b/libcxx/include/exception
index 64463e02cb16aa..5eff8e3f8a4bfa 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -47,7 +47,7 @@ terminate_handler set_terminate(terminate_handler  f ) noexcept;
 terminate_handler get_terminate() noexcept;
 [[noreturn]] void terminate() noexcept;
 
-bool uncaught_exception()  noexcept;  // deprecated in C++17, removed in C++20
+bool uncaught_exception()  noexcept;
 int  uncaught_exceptions() noexcept;  // C++17
 
 typedef unspecified exception_ptr;
diff --git a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
index 6fa4cb22070c8e..e368ce177b3177 100644
--- a/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
+++ b/libcxx/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
@@ -7,10 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: no-exceptions
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
 // test uncaught_exception
 
 #include <exception>

>From 5268aa909b81e3adc765df3748f17fab91823f0a Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 5 Aug 2024 01:20:47 +0800
Subject: [PATCH 05/20] Attempt to create `__scoped_temporary_buffer`

---
 libcxx/include/CMakeLists.txt                 |   1 +
 libcxx/include/__algorithm/inplace_merge.h    |  15 ++-
 libcxx/include/__algorithm/stable_partition.h |  18 ++-
 libcxx/include/__algorithm/stable_sort.h      |  10 +-
 .../__memory/scoped_temporary_buffer.h        | 121 ++++++++++++++++++
 libcxx/include/__memory/temporary_buffer.h    |  58 ++-------
 libcxx/include/module.modulemap               |   1 +
 .../gn/secondary/libcxx/include/BUILD.gn      |   1 +
 8 files changed, 162 insertions(+), 63 deletions(-)
 create mode 100644 libcxx/include/__memory/scoped_temporary_buffer.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 32579272858a8e..51f404f23c0284 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -541,6 +541,7 @@ set(files
   __memory/ranges_construct_at.h
   __memory/ranges_uninitialized_algorithms.h
   __memory/raw_storage_iterator.h
+  __memory/scoped_temporary_buffer.h
   __memory/shared_ptr.h
   __memory/swap_allocator.h
   __memory/temp_value.h
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 4c6ab527c8188c..6daa236df7c2f1 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -24,7 +24,7 @@
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/destruct_n.h>
-#include <__memory/temporary_buffer.h>
+#include <__memory/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
 #include <__utility/pair.h>
 #include <new>
@@ -211,10 +211,17 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
   difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
   difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
   difference_type __buf_size = std::min(__len1, __len2);
-  pair<value_type*, ptrdiff_t> __buf = std::__get_temporary_buffer<value_type>(__buf_size);
-  unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
+  __scoped_temporary_buffer<value_type> __scoped_buf(__buf_size);
+  __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
   return std::__inplace_merge<_AlgPolicy>(
-      std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
+      std::move(__first),
+      std::move(__middle),
+      std::move(__last),
+      __comp,
+      __len1,
+      __len2,
+      __buf_state.__ptr,
+      __buf_state.__count);
 }
 
 template <class _BidirectionalIterator, class _Compare>
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 4f09b87ae0f9a1..2209b0d10bdf41 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -16,7 +16,7 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/destruct_n.h>
-#include <__memory/temporary_buffer.h>
+#include <__memory/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
@@ -132,11 +132,13 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   // We now have a reduced range [__first, __last)
   // *__first is known to be false
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
+  __scoped_temporary_buffer<value_type> __scoped_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
-  unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len >= __alloc_limit) {
-    __p = std::__get_temporary_buffer<value_type>(__len);
-    __h.reset(__p.first);
+    __scoped_buf.__try_allocate(__len);
+    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
+    __p.first                                             = __buf_state.__ptr;
+    __p.second                                            = __buf_state.__count;
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
       std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag());
@@ -269,11 +271,13 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   // *__last is known to be true
   // __len >= 2
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
+  __scoped_temporary_buffer<value_type> __scoped_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
-  unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len >= __alloc_limit) {
-    __p = std::__get_temporary_buffer<value_type>(__len);
-    __h.reset(__p.first);
+    __scoped_buf.__try_allocate(__len);
+    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
+    __p.first                                             = __buf_state.__ptr;
+    __p.second                                            = __buf_state.__count;
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
       std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag());
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 69fd85cc798bd2..1ecace30ef6550 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -18,7 +18,7 @@
 #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/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
 #include <__type_traits/is_trivially_assignable.h>
 #include <__utility/move.h>
@@ -241,11 +241,13 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
 
   difference_type __len = __last - __first;
+  __scoped_temporary_buffer<value_type> __scoped_buf;
   pair<value_type*, ptrdiff_t> __buf(0, 0);
-  unique_ptr<value_type, __return_temporary_buffer> __h;
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
-    __buf = std::__get_temporary_buffer<value_type>(__len);
-    __h.reset(__buf.first);
+    __scoped_buf.__try_allocate(__len);
+    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
+    __buf.first                                           = __buf_state.__ptr;
+    __buf.second                                          = __buf_state.__count;
   }
 
   std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
new file mode 100644
index 00000000000000..c9a9d0b730b143
--- /dev/null
+++ b/libcxx/include/__memory/scoped_temporary_buffer.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___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+
+#include <__config>
+#include <__memory/allocator.h>
+#include <cstddef>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __temporary_allocation_result {
+  _Tp* __ptr;
+  ptrdiff_t __count;
+};
+
+template <class _Tp>
+class __scoped_temporary_buffer {
+public:
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT
+      : __ptr_(NULL),
+        __count_(0) {}
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT
+      : __ptr_(NULL),
+        __count_(0) {
+    __try_allocate(__count);
+  }
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+  // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null
+  // notes: __count_ is ignored in non-constant evaluation
+  _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {}
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT {
+    if (__libcpp_is_constant_evaluated()) {
+      allocator<_Tp>().deallocate(__ptr_, __count_);
+    }
+
+    std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp));
+  }
+
+  __scoped_temporary_buffer(const __scoped_temporary_buffer&)            = delete;
+  __scoped_temporary_buffer& operator=(const __scoped_temporary_buffer&) = delete;
+
+  // pre: __ptr_ == nullptr && __count_ == 0
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT {
+    if (__libcpp_is_constant_evaluated()) {
+      __ptr_   = allocator<_Tp>().allocate(__count);
+      __count_ = __count;
+      return;
+    }
+
+    const ptrdiff_t __max_count =
+        (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);
+    if (__count > __max_count)
+      __count = __max_count;
+    while (__count > 0) {
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+      if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
+        align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp));
+        __ptr_           = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow));
+      } else {
+        __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
+      }
+#else
+      if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
+        // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment.
+        return;
+      }
+
+      __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
+#endif
+
+      if (__ptr_) {
+        __count_ = __count;
+        break;
+      }
+      __count_ /= 2;
+    }
+  }
+
+  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __temporary_allocation_result<_Tp>
+  __get() const _NOEXCEPT {
+    __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
+    return __result;
+  }
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release() _NOEXCEPT {
+    __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
+
+    __ptr_   = NULL;
+    __count_ = 0;
+
+    return __result;
+  }
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+
+private:
+  _Tp* __ptr_;
+  ptrdiff_t __count_;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index c6cb3389051843..ecd6e86099f452 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
 
 #include <__config>
+#include <__memory/scoped_temporary_buffer.h>
 #include <__utility/pair.h>
 #include <cstddef>
 #include <new>
@@ -19,65 +20,26 @@
 #  pragma GCC system_header
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t>
-__get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  pair<_Tp*, ptrdiff_t> __r(0, 0);
-  const ptrdiff_t __m =
-      (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);
-  if (__n > __m)
-    __n = __m;
-  while (__n > 0) {
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
-    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
-      align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp));
-      __r.first        = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al, nothrow));
-    } else {
-      __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
-    }
-#else
-    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
-      // Since aligned operator new is unavailable, return an empty
-      // buffer rather than one with invalid alignment.
-      return __r;
-    }
-
-    __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
-#endif
-
-    if (__r.first) {
-      __r.second = __n;
-      break;
-    }
-    __n /= 2;
-  }
-  return __r;
-}
-
-struct __return_temporary_buffer {
-  template <class _Tp>
-  _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const {
-    std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
-  }
-};
-
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
 
+_LIBCPP_BEGIN_NAMESPACE_STD
+
 template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  return std::__get_temporary_buffer<_Tp>(__n);
+  __scoped_temporary_buffer<_Tp> __scoped_buf(__n);
+  __temporary_allocation_result<_Tp> __result = __scoped_buf.__release();
+  return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count);
 }
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
+  __scoped_temporary_buffer __scoped_buf(__p);
+  (void)__scoped_buf;
 }
 
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
-
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+
 #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 13d0dce34d97e3..70faf49f4feecd 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1532,6 +1532,7 @@ module std_private_memory_ranges_uninitialized_algorithms [system] {
   export std_private_algorithm_in_out_result
 }
 module std_private_memory_raw_storage_iterator            [system] { header "__memory/raw_storage_iterator.h" }
+module std_private_memory_scoped_temporary_buffer         [system] { header "__memory/scoped_temporary_buffer.h" }
 module std_private_memory_shared_ptr                      [system] {
   header "__memory/shared_ptr.h"
   export std_private_memory_uninitialized_algorithms
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index cc759d2337516d..9ecd5caf40481d 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -612,6 +612,7 @@ if (current_toolchain == default_toolchain) {
       "__memory/ranges_construct_at.h",
       "__memory/ranges_uninitialized_algorithms.h",
       "__memory/raw_storage_iterator.h",
+      "__memory/scoped_temporary_buffer.h",
       "__memory/shared_ptr.h",
       "__memory/swap_allocator.h",
       "__memory/temp_value.h",

>From 352900791d6fa36799a86a41e82c871330f74cbc Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 5 Aug 2024 07:39:48 +0800
Subject: [PATCH 06/20] Try to fix errors: module map, no CTAD

---
 libcxx/include/__memory/temporary_buffer.h | 2 +-
 libcxx/include/module.modulemap            | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index ecd6e86099f452..f298a6840d54e7 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -34,7 +34,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  __scoped_temporary_buffer __scoped_buf(__p);
+  __scoped_temporary_buffer<_Tp> __scoped_buf(__p);
   (void)__scoped_buf;
 }
 
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 70faf49f4feecd..ad39c0f37ab349 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1532,7 +1532,10 @@ module std_private_memory_ranges_uninitialized_algorithms [system] {
   export std_private_algorithm_in_out_result
 }
 module std_private_memory_raw_storage_iterator            [system] { header "__memory/raw_storage_iterator.h" }
-module std_private_memory_scoped_temporary_buffer         [system] { header "__memory/scoped_temporary_buffer.h" }
+module std_private_memory_scoped_temporary_buffer         [system] {
+  header "__memory/scoped_temporary_buffer.h"
+  export std_private_type_traits_is_constant_evaluated
+}
 module std_private_memory_shared_ptr                      [system] {
   header "__memory/shared_ptr.h"
   export std_private_memory_uninitialized_algorithms

>From 2a71c0e14a4c490e7384459a538449a61d0f898c Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 5 Aug 2024 09:22:40 +0800
Subject: [PATCH 07/20] Try to fix inclusion error for
 `__libcpp_is_constant_evaluated`

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index c9a9d0b730b143..c92b8a33f7db13 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -12,6 +12,7 @@
 
 #include <__config>
 #include <__memory/allocator.h>
+#include <__type_traits/is_constant_evaluated.h>
 #include <cstddef>
 #include <new>
 

>From 6d42fd6f2ee255beb8311dcfe951e9f3f028b85d Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 5 Aug 2024 09:43:13 +0800
Subject: [PATCH 08/20] Release `__release` to `__release_to_raw`

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 2 +-
 libcxx/include/__memory/temporary_buffer.h        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index c92b8a33f7db13..ca6e3d4e9c401c 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -102,7 +102,7 @@ class __scoped_temporary_buffer {
   }
 
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
-  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release() _NOEXCEPT {
+  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT {
     __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
 
     __ptr_   = NULL;
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index f298a6840d54e7..bdacf65dac9258 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -28,7 +28,7 @@ template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
   __scoped_temporary_buffer<_Tp> __scoped_buf(__n);
-  __temporary_allocation_result<_Tp> __result = __scoped_buf.__release();
+  __temporary_allocation_result<_Tp> __result = __scoped_buf.__release_to_raw();
   return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count);
 }
 

>From b83103b97fa1e602b6cbb8fc4ace7cf5c4a77bfc Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 28 Aug 2024 14:49:48 +0800
Subject: [PATCH 09/20] Avoid UB in deallocating null pointer value

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index ca6e3d4e9c401c..8807089aba045d 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -49,7 +49,9 @@ class __scoped_temporary_buffer {
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT {
     if (__libcpp_is_constant_evaluated()) {
-      allocator<_Tp>().deallocate(__ptr_, __count_);
+      if (__ptr_)
+        allocator<_Tp>().deallocate(__ptr_, __count_);
+      return;
     }
 
     std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp));

>From c812180b0474d02f8f892dc0f55798b2de5c12e5 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 28 Aug 2024 14:50:25 +0800
Subject: [PATCH 10/20] Make legacy member functions unconditionally available

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index 8807089aba045d..59fbcf09c7a875 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -41,11 +41,10 @@ class __scoped_temporary_buffer {
     __try_allocate(__count);
   }
 
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
+  // This constructor is only needed to implement get_temporary_buffer().
   // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null
   // notes: __count_ is ignored in non-constant evaluation
   _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {}
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT {
     if (__libcpp_is_constant_evaluated()) {
@@ -103,7 +102,6 @@ class __scoped_temporary_buffer {
     return __result;
   }
 
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
   _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT {
     __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
 
@@ -112,7 +110,6 @@ class __scoped_temporary_buffer {
 
     return __result;
   }
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER)
 
 private:
   _Tp* __ptr_;

>From f6e94f7640a0a4c045389bce3ce02282ef55e7a2 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 28 Aug 2024 14:53:26 +0800
Subject: [PATCH 11/20] Also add comment for `__release_to_raw`

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index 59fbcf09c7a875..727dbf9efce287 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -102,6 +102,7 @@ class __scoped_temporary_buffer {
     return __result;
   }
 
+  // This member function is only needed to implement get_temporary_buffer().
   _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT {
     __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
 

>From 5c50d6a0dd73b40c446ca3bd7da938644920c83f Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 14:31:27 +0800
Subject: [PATCH 12/20] Use `nullptr` and internal assertion from review
 comments

---
 libcxx/include/__memory/scoped_temporary_buffer.h | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
index 727dbf9efce287..92c745408a260f 100644
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ b/libcxx/include/__memory/scoped_temporary_buffer.h
@@ -10,7 +10,9 @@
 #ifndef _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
 #define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
 
+#include <__assert>
 #include <__config>
+
 #include <__memory/allocator.h>
 #include <__type_traits/is_constant_evaluated.h>
 #include <cstddef>
@@ -32,11 +34,11 @@ template <class _Tp>
 class __scoped_temporary_buffer {
 public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT
-      : __ptr_(NULL),
+      : __ptr_(nullptr),
         __count_(0) {}
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT
-      : __ptr_(NULL),
+      : __ptr_(nullptr),
         __count_(0) {
     __try_allocate(__count);
   }
@@ -61,6 +63,9 @@ class __scoped_temporary_buffer {
 
   // pre: __ptr_ == nullptr && __count_ == 0
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT {
+    _LIBCPP_ASSERT_INTERNAL(__ptr_ == nullptr && __count_ == 0,
+                            "There must be no dynamically allocator buffer before calling __try_allocate().");
+
     if (__libcpp_is_constant_evaluated()) {
       __ptr_   = allocator<_Tp>().allocate(__count);
       __count_ = __count;
@@ -106,7 +111,7 @@ class __scoped_temporary_buffer {
   _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT {
     __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
 
-    __ptr_   = NULL;
+    __ptr_   = nullptr;
     __count_ = 0;
 
     return __result;

>From b8de11de85938b0fc147c518eaf47976aa815686 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 14:35:24 +0800
Subject: [PATCH 13/20] Restore the note changes in Cxx20Papers.csv

---
 libcxx/docs/Status/Cxx20Papers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
index ad788d7416fdad..7c08557ef7666d 100644
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -34,7 +34,7 @@
 "`P0528R3 <https://wg21.link/P0528R3>`__","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","2018-06 (Rapperswil)","","",""
 "`P0542R5 <https://wg21.link/P0542R5>`__","Support for contract based programming in C++","2018-06 (Rapperswil)","|Nothing To Do|","n/a","Pulled at the 2019-07 meeting in Cologne"
 "`P0556R3 <https://wg21.link/P0556R3>`__","Integral power-of-2 operations","2018-06 (Rapperswil)","|Complete|","9.0",""
-"`P0619R4 <https://wg21.link/P0619R4>`__","Reviewing Deprecated Facilities of C++17 for C++20","2018-06 (Rapperswil)","|Partial|","","Only sections D.7, D.8, D.9, D.10, D.11 and D.13 are implemented. Sections D.4 and D.12 remain undone."
+"`P0619R4 <https://wg21.link/P0619R4>`__","Reviewing Deprecated Facilities of C++17 for C++20","2018-06 (Rapperswil)","|Partial|","","Only sections D.7, D.8, D.9, D.10, D.11, D.12, and D.13 are implemented. Section D.4 remains undone."
 "`P0646R1 <https://wg21.link/P0646R1>`__","Improving the Return Value of Erase-Like Algorithms","2018-06 (Rapperswil)","|Complete|","10.0",""
 "`P0722R3 <https://wg21.link/P0722R3>`__","Efficient sized delete for variable sized classes","2018-06 (Rapperswil)","|Complete|","9.0",""
 "`P0758R1 <https://wg21.link/P0758R1>`__","Implicit conversion traits and utility functions","2018-06 (Rapperswil)","|Complete|","",""

>From 1f3fde76398c0125887991157efc75c0ba93eb18 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 16:37:29 +0800
Subject: [PATCH 14/20] Switch to use `unique_ptr`-based approach

---
 libcxx/include/CMakeLists.txt                 |   2 +-
 libcxx/include/__algorithm/inplace_merge.h    |  10 +-
 libcxx/include/__algorithm/stable_partition.h |  20 ++-
 libcxx/include/__algorithm/stable_sort.h      |  11 +-
 .../__memory/scoped_temporary_buffer.h        | 127 ------------------
 libcxx/include/__memory/temporary_buffer.h    |  14 +-
 .../__memory/unique_temporary_buffer.h        |  89 ++++++++++++
 libcxx/include/module.modulemap               |   8 +-
 .../gn/secondary/libcxx/include/BUILD.gn      |   2 +-
 9 files changed, 122 insertions(+), 161 deletions(-)
 delete mode 100644 libcxx/include/__memory/scoped_temporary_buffer.h
 create mode 100644 libcxx/include/__memory/unique_temporary_buffer.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 51f404f23c0284..782f2b79993afa 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -541,13 +541,13 @@ set(files
   __memory/ranges_construct_at.h
   __memory/ranges_uninitialized_algorithms.h
   __memory/raw_storage_iterator.h
-  __memory/scoped_temporary_buffer.h
   __memory/shared_ptr.h
   __memory/swap_allocator.h
   __memory/temp_value.h
   __memory/temporary_buffer.h
   __memory/uninitialized_algorithms.h
   __memory/unique_ptr.h
+  __memory/unique_temporary_buffer.h
   __memory/uses_allocator.h
   __memory/uses_allocator_construction.h
   __memory/voidify.h
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 6daa236df7c2f1..4e04241b3266aa 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -24,8 +24,8 @@
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/destruct_n.h>
-#include <__memory/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
+#include <__memory/unique_temporary_buffer.h>
 #include <__utility/pair.h>
 #include <new>
 
@@ -211,8 +211,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
   difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
   difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
   difference_type __buf_size = std::min(__len1, __len2);
-  __scoped_temporary_buffer<value_type> __scoped_buf(__buf_size);
-  __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf =
+      std::__make_unique_sized_temporary_buffer<value_type>(__buf_size);
   return std::__inplace_merge<_AlgPolicy>(
       std::move(__first),
       std::move(__middle),
@@ -220,8 +220,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
       __comp,
       __len1,
       __len2,
-      __buf_state.__ptr,
-      __buf_state.__count);
+      __unique_buf.get(),
+      __unique_buf.get_deleter().__count_);
 }
 
 template <class _BidirectionalIterator, class _Compare>
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 2209b0d10bdf41..5bf74957de4e1d 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -16,8 +16,8 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/destruct_n.h>
-#include <__memory/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
+#include <__memory/unique_temporary_buffer.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
 #include <new>
@@ -132,13 +132,12 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   // We now have a reduced range [__first, __last)
   // *__first is known to be false
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
-  __scoped_temporary_buffer<value_type> __scoped_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
-    __scoped_buf.__try_allocate(__len);
-    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
-    __p.first                                             = __buf_state.__ptr;
-    __p.second                                            = __buf_state.__count;
+    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __p.first    = __unique_buf.get();
+    __p.second   = __unique_buf.get_deleter().__count_;
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
       std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag());
@@ -271,13 +270,12 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   // *__last is known to be true
   // __len >= 2
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
-  __scoped_temporary_buffer<value_type> __scoped_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
-    __scoped_buf.__try_allocate(__len);
-    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
-    __p.first                                             = __buf_state.__ptr;
-    __p.second                                            = __buf_state.__count;
+    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __p.first    = __unique_buf.get();
+    __p.second   = __unique_buf.get_deleter().__count_;
   }
   return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
       std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag());
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 1ecace30ef6550..4599e9748e0b1c 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -18,8 +18,8 @@
 #include <__debug_utils/strict_weak_ordering_check.h>
 #include <__iterator/iterator_traits.h>
 #include <__memory/destruct_n.h>
-#include <__memory/scoped_temporary_buffer.h>
 #include <__memory/unique_ptr.h>
+#include <__memory/unique_temporary_buffer.h>
 #include <__type_traits/is_trivially_assignable.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
@@ -241,13 +241,12 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
 
   difference_type __len = __last - __first;
-  __scoped_temporary_buffer<value_type> __scoped_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
-    __scoped_buf.__try_allocate(__len);
-    __temporary_allocation_result<value_type> __buf_state = __scoped_buf.__get();
-    __buf.first                                           = __buf_state.__ptr;
-    __buf.second                                          = __buf_state.__count;
+    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __p.first    = __unique_buf.get();
+    __p.second   = __unique_buf.get_deleter().__count_;
   }
 
   std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
diff --git a/libcxx/include/__memory/scoped_temporary_buffer.h b/libcxx/include/__memory/scoped_temporary_buffer.h
deleted file mode 100644
index 92c745408a260f..00000000000000
--- a/libcxx/include/__memory/scoped_temporary_buffer.h
+++ /dev/null
@@ -1,127 +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___MEMORY_SCOPED_TEMPORARY_BUFFER_H
-#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
-
-#include <__assert>
-#include <__config>
-
-#include <__memory/allocator.h>
-#include <__type_traits/is_constant_evaluated.h>
-#include <cstddef>
-#include <new>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-struct __temporary_allocation_result {
-  _Tp* __ptr;
-  ptrdiff_t __count;
-};
-
-template <class _Tp>
-class __scoped_temporary_buffer {
-public:
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __scoped_temporary_buffer() _NOEXCEPT
-      : __ptr_(nullptr),
-        __count_(0) {}
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __scoped_temporary_buffer(ptrdiff_t __count) _NOEXCEPT
-      : __ptr_(nullptr),
-        __count_(0) {
-    __try_allocate(__count);
-  }
-
-  // This constructor is only needed to implement get_temporary_buffer().
-  // pre: __buf_ptr points to the beginning of a previously allocated scoped temporary buffer or is null
-  // notes: __count_ is ignored in non-constant evaluation
-  _LIBCPP_HIDE_FROM_ABI explicit __scoped_temporary_buffer(_Tp* __buf_ptr) _NOEXCEPT : __ptr_(__buf_ptr), __count_(0) {}
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__scoped_temporary_buffer() _NOEXCEPT {
-    if (__libcpp_is_constant_evaluated()) {
-      if (__ptr_)
-        allocator<_Tp>().deallocate(__ptr_, __count_);
-      return;
-    }
-
-    std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp));
-  }
-
-  __scoped_temporary_buffer(const __scoped_temporary_buffer&)            = delete;
-  __scoped_temporary_buffer& operator=(const __scoped_temporary_buffer&) = delete;
-
-  // pre: __ptr_ == nullptr && __count_ == 0
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __try_allocate(ptrdiff_t __count) _NOEXCEPT {
-    _LIBCPP_ASSERT_INTERNAL(__ptr_ == nullptr && __count_ == 0,
-                            "There must be no dynamically allocator buffer before calling __try_allocate().");
-
-    if (__libcpp_is_constant_evaluated()) {
-      __ptr_   = allocator<_Tp>().allocate(__count);
-      __count_ = __count;
-      return;
-    }
-
-    const ptrdiff_t __max_count =
-        (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);
-    if (__count > __max_count)
-      __count = __max_count;
-    while (__count > 0) {
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
-      if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
-        align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp));
-        __ptr_           = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow));
-      } else {
-        __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
-      }
-#else
-      if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
-        // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment.
-        return;
-      }
-
-      __ptr_ = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
-#endif
-
-      if (__ptr_) {
-        __count_ = __count;
-        break;
-      }
-      __count_ /= 2;
-    }
-  }
-
-  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __temporary_allocation_result<_Tp>
-  __get() const _NOEXCEPT {
-    __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
-    return __result;
-  }
-
-  // This member function is only needed to implement get_temporary_buffer().
-  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __temporary_allocation_result<_Tp> __release_to_raw() _NOEXCEPT {
-    __temporary_allocation_result<_Tp> __result = {__ptr_, __count_};
-
-    __ptr_   = nullptr;
-    __count_ = 0;
-
-    return __result;
-  }
-
-private:
-  _Tp* __ptr_;
-  ptrdiff_t __count_;
-};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index bdacf65dac9258..51ac9e63a0fa34 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -11,7 +11,7 @@
 #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
 
 #include <__config>
-#include <__memory/scoped_temporary_buffer.h>
+#include <__memory/unique_temporary_buffer.h>
 #include <__utility/pair.h>
 #include <cstddef>
 #include <new>
@@ -27,15 +27,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  __scoped_temporary_buffer<_Tp> __scoped_buf(__n);
-  __temporary_allocation_result<_Tp> __result = __scoped_buf.__release_to_raw();
-  return pair<_Tp*, ptrdiff_t>(__result.__ptr, __result.__count);
+  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf =
+      std::__make_unique_sized_temporary_buffer<_Tp>(__n);
+  pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_);
+  __unique_buf.release();
+  return __result;
 }
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  __scoped_temporary_buffer<_Tp> __scoped_buf(__p);
-  (void)__scoped_buf;
+  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf(__p, 0);
+  (void)__unique_buf;
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
new file mode 100644
index 00000000000000..df0d4537a625ab
--- /dev/null
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -0,0 +1,89 @@
+// -*- 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___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+
+#include <__assert>
+#include <__config>
+
+#include <__memory/allocator.h>
+#include <__memory/unique_ptr.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <cstddef>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __sized_temporary_buffer_deleter {
+  ptrdiff_t __count_; // ignored in non-constant evaluation
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __sized_temporary_buffer_deleter() _NOEXCEPT : __count_(0) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __sized_temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT
+      : __count_(__count) {}
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT {
+    if (__libcpp_is_constant_evaluated()) {
+      allocator<_Tp>().deallocate(__ptr_, __count_);
+      return;
+    }
+
+    std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp));
+  }
+};
+
+template <class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>>
+__make_unique_sized_temporary_buffer(ptrdiff_t __count) {
+  typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type;
+  typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type;
+
+  if (__libcpp_is_constant_evaluated()) {
+    return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count));
+  }
+
+  _Tp* __ptr = nullptr;
+  const ptrdiff_t __max_count =
+      (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);
+  if (__count > __max_count)
+    __count = __max_count;
+  while (__count > 0) {
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
+      align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp));
+      __ptr            = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), __al, nothrow));
+    } else {
+      __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
+    }
+#else
+    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
+      // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment.
+      return;
+    }
+
+    __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));
+#endif
+
+    if (__ptr) {
+      break;
+    }
+    __count /= 2;
+  }
+
+  return __unique_buffer_type(__ptr, __deleter_type(__count));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index de16df9c5f6ab0..b1d566c12fbae9 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1539,10 +1539,6 @@ module std_private_memory_ranges_uninitialized_algorithms [system] {
   export std_private_algorithm_in_out_result
 }
 module std_private_memory_raw_storage_iterator            [system] { header "__memory/raw_storage_iterator.h" }
-module std_private_memory_scoped_temporary_buffer         [system] {
-  header "__memory/scoped_temporary_buffer.h"
-  export std_private_type_traits_is_constant_evaluated
-}
 module std_private_memory_shared_ptr                      [system] {
   header "__memory/shared_ptr.h"
   export std_private_memory_uninitialized_algorithms
@@ -1563,6 +1559,10 @@ module std_private_memory_unique_ptr                      [system] {
   export std_private_type_traits_is_pointer
   export std_private_type_traits_type_identity
 }
+module std_private_memory_unique_temporary_buffer         [system] {
+  header "__memory/unique_temporary_buffer.h"
+  export std_private_type_traits_is_constant_evaluated
+}
 module std_private_memory_uses_allocator                  [system] { header "__memory/uses_allocator.h" }
 module std_private_memory_uses_allocator_construction     [system] { header "__memory/uses_allocator_construction.h" }
 module std_private_memory_voidify                         [system] { header "__memory/voidify.h" }
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 8a2d3214dd98e5..af97d76b497a45 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -613,13 +613,13 @@ if (current_toolchain == default_toolchain) {
       "__memory/ranges_construct_at.h",
       "__memory/ranges_uninitialized_algorithms.h",
       "__memory/raw_storage_iterator.h",
-      "__memory/scoped_temporary_buffer.h",
       "__memory/shared_ptr.h",
       "__memory/swap_allocator.h",
       "__memory/temp_value.h",
       "__memory/temporary_buffer.h",
       "__memory/uninitialized_algorithms.h",
       "__memory/unique_ptr.h",
+      "__memory/unique_temporary_buffer.h",
       "__memory/uses_allocator.h",
       "__memory/uses_allocator_construction.h",
       "__memory/voidify.h",

>From 5e4b15732367ceb25e21a241c8c7e922ef335a44 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 16:48:50 +0800
Subject: [PATCH 15/20] Fix copy-pasta

---
 libcxx/include/__algorithm/stable_sort.h          |  4 ++--
 libcxx/include/__memory/unique_temporary_buffer.h | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 4599e9748e0b1c..2e7b84c7a93bec 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -245,8 +245,8 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
     __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
-    __p.first    = __unique_buf.get();
-    __p.second   = __unique_buf.get_deleter().__count_;
+    __buf.first  = __unique_buf.get();
+    __buf.second = __unique_buf.get_deleter().__count_;
   }
 
   std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index df0d4537a625ab..dc680ba034a963 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
-#define _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+#ifndef _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H
+#define _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H
 
 #include <__assert>
 #include <__config>
@@ -35,11 +35,11 @@ struct __sized_temporary_buffer_deleter {
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT {
     if (__libcpp_is_constant_evaluated()) {
-      allocator<_Tp>().deallocate(__ptr_, __count_);
+      allocator<_Tp>().deallocate(__ptr, __count_);
       return;
     }
 
-    std::__libcpp_deallocate_unsized((void*)__ptr_, _LIBCPP_ALIGNOF(_Tp));
+    std::__libcpp_deallocate_unsized((void*)__ptr, _LIBCPP_ALIGNOF(_Tp));
   }
 };
 
@@ -86,4 +86,4 @@ __make_unique_sized_temporary_buffer(ptrdiff_t __count) {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___MEMORY_SCOPED_TEMPORARY_BUFFER_H
+#endif // _LIBCPP___MEMORY_UNIQUE_TEMPORARY_BUFFER_H

>From 2bd52cb6f7c0206c112f0fc1461c9970d60181a3 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 17:09:36 +0800
Subject: [PATCH 16/20] Fix CI failures

- C++03 `> >`
- Module exporting
- `unique_ptr` construction
---
 libcxx/include/__algorithm/inplace_merge.h        | 2 +-
 libcxx/include/__algorithm/stable_partition.h     | 4 ++--
 libcxx/include/__algorithm/stable_sort.h          | 2 +-
 libcxx/include/__memory/temporary_buffer.h        | 4 ++--
 libcxx/include/__memory/unique_temporary_buffer.h | 2 +-
 libcxx/include/module.modulemap                   | 1 +
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 4e04241b3266aa..f510307503ef17 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -211,7 +211,7 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
   difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
   difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
   difference_type __buf_size = std::min(__len1, __len2);
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf =
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf =
       std::__make_unique_sized_temporary_buffer<value_type>(__buf_size);
   return std::__inplace_merge<_AlgPolicy>(
       std::move(__first),
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 5bf74957de4e1d..9dd6792de368a2 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -132,7 +132,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   // We now have a reduced range [__first, __last)
   // *__first is known to be false
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
     __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
@@ -270,7 +270,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   // *__last is known to be true
   // __len >= 2
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
     __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 2e7b84c7a93bec..af98b77535c4a2 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -241,7 +241,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
 
   difference_type __len = __last - __first;
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type>> __unique_buf;
+  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
     __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index 51ac9e63a0fa34..9de9074e01b2cb 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf =
+  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf =
       std::__make_unique_sized_temporary_buffer<_Tp>(__n);
   pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_);
   __unique_buf.release();
@@ -36,7 +36,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>> __unique_buf(__p, 0);
+  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf(__p);
   (void)__unique_buf;
 }
 
diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index dc680ba034a963..63dee2208faf88 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -44,7 +44,7 @@ struct __sized_temporary_buffer_deleter {
 };
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp>>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> >
 __make_unique_sized_temporary_buffer(ptrdiff_t __count) {
   typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type;
   typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type;
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index b1d566c12fbae9..bae1eb491bfbb2 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1561,6 +1561,7 @@ module std_private_memory_unique_ptr                      [system] {
 }
 module std_private_memory_unique_temporary_buffer         [system] {
   header "__memory/unique_temporary_buffer.h"
+  export std_private_memory_unique_ptr
   export std_private_type_traits_is_constant_evaluated
 }
 module std_private_memory_uses_allocator                  [system] { header "__memory/uses_allocator.h" }

>From 51b18a2c5da3a85a1c9119b40adea23e57c19d4d Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 18:44:22 +0800
Subject: [PATCH 17/20] Fix bad `return;`

---
 libcxx/include/__memory/unique_temporary_buffer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index 63dee2208faf88..b743191753beeb 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -69,7 +69,7 @@ __make_unique_sized_temporary_buffer(ptrdiff_t __count) {
 #else
     if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {
       // Since aligned operator new is unavailable, constructs an empty buffer rather than one with invalid alignment.
-      return;
+      return __unique_buffer_type();
     }
 
     __ptr = static_cast<_Tp*>(::operator new(__count * sizeof(_Tp), nothrow));

>From 0961a501ae94c5030578d11c714d22ac83fdbb21 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 21:36:27 +0800
Subject: [PATCH 18/20] Address review comments for `unique_ptr`-based buffer

---
 libcxx/include/__algorithm/inplace_merge.h        |  4 ++--
 libcxx/include/__algorithm/stable_partition.h     |  8 ++++----
 libcxx/include/__algorithm/stable_sort.h          |  4 ++--
 libcxx/include/__memory/temporary_buffer.h        |  5 ++---
 libcxx/include/__memory/unique_temporary_buffer.h | 14 +++++++-------
 5 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index f510307503ef17..79e68d0d57bc7f 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -211,8 +211,8 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
   difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
   difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
   difference_type __buf_size = std::min(__len1, __len2);
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf =
-      std::__make_unique_sized_temporary_buffer<value_type>(__buf_size);
+  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf =
+      std::__allocate_unique_temporary_buffer<value_type>(__buf_size);
   return std::__inplace_merge<_AlgPolicy>(
       std::move(__first),
       std::move(__middle),
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 9dd6792de368a2..81452bf5a230d9 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -132,10 +132,10 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   // We now have a reduced range [__first, __last)
   // *__first is known to be false
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
+  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
-    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
     __p.first    = __unique_buf.get();
     __p.second   = __unique_buf.get_deleter().__count_;
   }
@@ -270,10 +270,10 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   // *__last is known to be true
   // __len >= 2
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
+  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
-    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
     __p.first    = __unique_buf.get();
     __p.second   = __unique_buf.get_deleter().__count_;
   }
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index af98b77535c4a2..e47d1e03342988 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -241,10 +241,10 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
 
   difference_type __len = __last - __first;
-  unique_ptr<value_type, __sized_temporary_buffer_deleter<value_type> > __unique_buf;
+  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
-    __unique_buf = std::__make_unique_sized_temporary_buffer<value_type>(__len);
+    __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
     __buf.first  = __unique_buf.get();
     __buf.second = __unique_buf.get_deleter().__count_;
   }
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index 9de9074e01b2cb..acb8910336bf1f 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -27,8 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf =
-      std::__make_unique_sized_temporary_buffer<_Tp>(__n);
+  unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n);
   pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_);
   __unique_buf.release();
   return __result;
@@ -36,7 +35,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> > __unique_buf(__p);
+  unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf(__p);
   (void)__unique_buf;
 }
 
diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index b743191753beeb..cfb770cc0dee4a 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -26,11 +26,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __sized_temporary_buffer_deleter {
+struct __temporary_buffer_deleter {
   ptrdiff_t __count_; // ignored in non-constant evaluation
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __sized_temporary_buffer_deleter() _NOEXCEPT : __count_(0) {}
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __sized_temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __temporary_buffer_deleter() _NOEXCEPT : __count_(0) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT
       : __count_(__count) {}
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT {
@@ -44,10 +44,10 @@ struct __sized_temporary_buffer_deleter {
 };
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __sized_temporary_buffer_deleter<_Tp> >
-__make_unique_sized_temporary_buffer(ptrdiff_t __count) {
-  typedef __sized_temporary_buffer_deleter<_Tp> __deleter_type;
-  typedef unique_ptr<_Tp, __deleter_type> __unique_buffer_type;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >
+__allocate_unique_temporary_buffer(ptrdiff_t __count) {
+  using __deleter_type       = __temporary_buffer_deleter<_Tp>;
+  using __unique_buffer_type = unique_ptr<_Tp, __deleter_type>;
 
   if (__libcpp_is_constant_evaluated()) {
     return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count));

>From dc503fa4b844639c6f2cf4938628cd974972a0f8 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 21:40:28 +0800
Subject: [PATCH 19/20] Use alias template

---
 libcxx/include/__algorithm/inplace_merge.h        | 9 ++++-----
 libcxx/include/__algorithm/stable_partition.h     | 4 ++--
 libcxx/include/__algorithm/stable_sort.h          | 2 +-
 libcxx/include/__memory/temporary_buffer.h        | 4 ++--
 libcxx/include/__memory/unique_temporary_buffer.h | 7 +++++--
 5 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 79e68d0d57bc7f..2133f440d2fea6 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -208,11 +208,10 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
     _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) {
   typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
   typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-  difference_type __len1     = _IterOps<_AlgPolicy>::distance(__first, __middle);
-  difference_type __len2     = _IterOps<_AlgPolicy>::distance(__middle, __last);
-  difference_type __buf_size = std::min(__len1, __len2);
-  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf =
-      std::__allocate_unique_temporary_buffer<value_type>(__buf_size);
+  difference_type __len1                             = _IterOps<_AlgPolicy>::distance(__first, __middle);
+  difference_type __len2                             = _IterOps<_AlgPolicy>::distance(__middle, __last);
+  difference_type __buf_size                         = std::min(__len1, __len2);
+  __unique_temporary_buffer<value_type> __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__buf_size);
   return std::__inplace_merge<_AlgPolicy>(
       std::move(__first),
       std::move(__middle),
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 81452bf5a230d9..bf86201dbb6a61 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -132,7 +132,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
   // We now have a reduced range [__first, __last)
   // *__first is known to be false
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
-  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
+  __unique_temporary_buffer<value_type> __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
     __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
@@ -270,7 +270,7 @@ _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
   // *__last is known to be true
   // __len >= 2
   difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
-  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
+  __unique_temporary_buffer<value_type> __unique_buf;
   pair<value_type*, ptrdiff_t> __p(0, 0);
   if (__len >= __alloc_limit) {
     __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index e47d1e03342988..ec556aad82e8d8 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -241,7 +241,7 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
   using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
 
   difference_type __len = __last - __first;
-  unique_ptr<value_type, __temporary_buffer_deleter<value_type> > __unique_buf;
+  __unique_temporary_buffer<value_type> __unique_buf;
   pair<value_type*, ptrdiff_t> __buf(0, 0);
   if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
     __unique_buf = std::__allocate_unique_temporary_buffer<value_type>(__len);
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index acb8910336bf1f..1a4498572c9055 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp>
 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
-  unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n);
+  __unique_temporary_buffer<_Tp> __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n);
   pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_);
   __unique_buf.release();
   return __result;
@@ -35,7 +35,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT {
-  unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> > __unique_buf(__p);
+  __unique_temporary_buffer<_Tp> __unique_buf(__p);
   (void)__unique_buf;
 }
 
diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index cfb770cc0dee4a..a505610957e158 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -44,10 +44,13 @@ struct __temporary_buffer_deleter {
 };
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >
+using __unique_temporary_buffer = unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >;
+
+template <class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __unique_temporary_buffer<_Tp>
 __allocate_unique_temporary_buffer(ptrdiff_t __count) {
   using __deleter_type       = __temporary_buffer_deleter<_Tp>;
-  using __unique_buffer_type = unique_ptr<_Tp, __deleter_type>;
+  using __unique_buffer_type = __unique_temporary_buffer<_Tp>;
 
   if (__libcpp_is_constant_evaluated()) {
     return __unique_buffer_type(allocator<_Tp>().allocate(__count), __deleter_type(__count));

>From 1406cd51896dd66f3f0d3b1d9cbf364a88f51bc4 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sun, 1 Sep 2024 21:53:06 +0800
Subject: [PATCH 20/20] Clang-format for CI purpose

---
 libcxx/include/__memory/unique_temporary_buffer.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h
index a505610957e158..b9e2a47332682f 100644
--- a/libcxx/include/__memory/unique_temporary_buffer.h
+++ b/libcxx/include/__memory/unique_temporary_buffer.h
@@ -30,8 +30,8 @@ struct __temporary_buffer_deleter {
   ptrdiff_t __count_; // ignored in non-constant evaluation
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __temporary_buffer_deleter() _NOEXCEPT : __count_(0) {}
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT
-      : __count_(__count) {}
+  _LIBCPP_HIDE_FROM_ABI
+  _LIBCPP_CONSTEXPR explicit __temporary_buffer_deleter(ptrdiff_t __count) _NOEXCEPT : __count_(__count) {}
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) _NOEXCEPT {
     if (__libcpp_is_constant_evaluated()) {



More information about the libcxx-commits mailing list