[libc++] Split std::get_temporary_buffer out of <memory>

Differential Revision: https://reviews.llvm.org/D100216

GitOrigin-RevId: 6a1ac88fc19a6d1b373ea12247f84e41a07d3a94
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index edbde1d..87c1b28 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -18,6 +18,7 @@
   __memory/auto_ptr.h
   __memory/base.h
   __memory/pointer_traits.h
+  __memory/temporary_buffer.h
   __memory/utilities.h
   __mutex_base
   __node_handle
diff --git a/include/__memory/temporary_buffer.h b/include/__memory/temporary_buffer.h
new file mode 100644
index 0000000..cf37947
--- /dev/null
+++ b/include/__memory/temporary_buffer.h
@@ -0,0 +1,83 @@
+// -*- 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_TEMPORARY_BUFFER_H
+#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
+
+#include <__config>
+#include <cstddef>
+#include <new>
+#include <utility> // pair
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT _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(alignment_of<_Tp>::value);
+            __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;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void return_temporary_buffer(_Tp* __p) _NOEXCEPT
+{
+  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif  // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
diff --git a/include/memory b/include/memory
index 1b48573..aabbfdc 100644
--- a/include/memory
+++ b/include/memory
@@ -684,6 +684,7 @@
 #include <__memory/auto_ptr.h>
 #include <__memory/base.h>
 #include <__memory/pointer_traits.h>
+#include <__memory/temporary_buffer.h>
 #include <__memory/utilities.h>
 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
@@ -838,58 +839,6 @@
 #endif
 };
 
-template <class _Tp>
-_LIBCPP_NODISCARD_EXT _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(alignment_of<_Tp>::value);
-            __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;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void return_temporary_buffer(_Tp* __p) _NOEXCEPT
-{
-  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
-}
-
 // Tag used to default initialize one or both of the pair's elements.
 struct __default_init_tag {};
 struct __value_init_tag {};