[libcxx-commits] [libcxx] 31eeba3 - [libc++] Introduce __make_uninitialized_buffer and use it instead of get_temporary_buffer
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jun 16 07:54:04 PDT 2023
Author: Nikolas Klauser
Date: 2023-06-16T07:53:56-07:00
New Revision: 31eeba3f7c0e2ef4a21c07da9326a4ae1a8de7e2
URL: https://github.com/llvm/llvm-project/commit/31eeba3f7c0e2ef4a21c07da9326a4ae1a8de7e2
DIFF: https://github.com/llvm/llvm-project/commit/31eeba3f7c0e2ef4a21c07da9326a4ae1a8de7e2.diff
LOG: [libc++] Introduce __make_uninitialized_buffer and use it instead of get_temporary_buffer
This will also be used in some PSTL backends.
Reviewed By: ldionne, #libc, Mordante
Spies: arichardson, mstorsjo, Mordante, sstefan1, jplehr, libcxx-commits
Differential Revision: https://reviews.llvm.org/D152208
Added:
libcxx/include/__memory/uninitialized_buffer.h
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/__algorithm/inplace_merge.h
libcxx/include/__algorithm/stable_partition.h
libcxx/include/__algorithm/stable_sort.h
libcxx/include/__memory/construct_at.h
libcxx/include/__memory/temporary_buffer.h
libcxx/include/module.modulemap.in
libcxx/test/support/count_new.h
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a2cc9e2cac3b3..38156627053ad 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -502,6 +502,7 @@ set(files
__memory/temp_value.h
__memory/temporary_buffer.h
__memory/uninitialized_algorithms.h
+ __memory/uninitialized_buffer.h
__memory/unique_ptr.h
__memory/uses_allocator.h
__memory/uses_allocator_construction.h
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 44a9425559ef1..8da7a344f6937 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/uninitialized_buffer.h>
#include <__memory/unique_ptr.h>
#include <__utility/pair.h>
#include <new>
@@ -225,13 +225,16 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
diff erence_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle);
diff erence_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last);
diff erence_type __buf_size = _VSTD::min(__len1, __len2);
-// TODO: Remove the use of std::get_temporary_buffer
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
- pair<value_type*, ptr
diff _t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
-_LIBCPP_SUPPRESS_DEPRECATED_POP
- unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
+ auto __buf = std::__make_uninitialized_buffer<value_type[]>(nothrow, __buf_size);
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.get(),
+ __buf ? __buf_size : 0);
}
template <class _BidirectionalIterator, class _Compare>
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 38fa9ce37d00d..33339817a8f5b 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/uninitialized_buffer.h>
#include <__memory/unique_ptr.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -29,7 +29,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
-_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+_LIBCPP_HIDDEN _ForwardIterator
__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
_Distance __len, _Pair __p, forward_iterator_tag __fit)
{
@@ -138,18 +138,18 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
// We now have a reduced range [__first, __last)
// *__first is known to be false
diff erence_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
- pair<value_type*, ptr
diff _t> __p(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
+
+ __uninitialized_buffer_t<value_type[]> __buf;
if (__len >= __alloc_limit)
- {
-// TODO: Remove the use of std::get_temporary_buffer
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
- __p = _VSTD::get_temporary_buffer<value_type>(__len);
-_LIBCPP_SUPPRESS_DEPRECATED_POP
- __h.reset(__p.first);
- }
+ __buf = std::__make_uninitialized_buffer<value_type[]>(nothrow, __len);
+
return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
- std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag());
+ std::move(__first),
+ std::move(__last),
+ __pred,
+ __len,
+ std::make_pair(__buf.get(), __buf ? __len : 0),
+ forward_iterator_tag());
}
template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
@@ -292,18 +292,17 @@ __stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator _
// *__last is known to be true
// __len >= 2
diff erence_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
- pair<value_type*, ptr
diff _t> __p(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
+ __uninitialized_buffer_t<value_type[]> __buf;
if (__len >= __alloc_limit)
- {
-// TODO: Remove the use of std::get_temporary_buffer
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
- __p = _VSTD::get_temporary_buffer<value_type>(__len);
-_LIBCPP_SUPPRESS_DEPRECATED_POP
- __h.reset(__p.first);
- }
+ __buf = std::__make_uninitialized_buffer<value_type[]>(nothrow, __len);
+
return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
- std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag());
+ std::move(__first),
+ std::move(__last),
+ __pred,
+ __len,
+ std::make_pair(__buf.get(), __buf ? __len : 0),
+ bidirectional_iterator_tag());
}
template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _IterCategory>
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index dc24218b74dd3..0a15b4dd99888 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/uninitialized_buffer.h>
#include <__memory/unique_ptr.h>
#include <__type_traits/is_trivially_copy_assignable.h>
#include <__utility/move.h>
@@ -249,17 +249,12 @@ void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __l
using
diff erence_type = typename iterator_traits<_RandomAccessIterator>::
diff erence_type;
diff erence_type __len = __last - __first;
- pair<value_type*, ptr
diff _t> __buf(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
- if (__len > static_cast<
diff erence_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
- __h.reset(__buf.first);
- }
+ __uninitialized_buffer_t<value_type[]> __buf;
+ if (__len > static_cast<
diff erence_type>(__stable_sort_switch<value_type>::value))
+ __buf = std::__make_uninitialized_buffer<value_type[]>(nothrow, __len);
- std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
+ std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(
+ __first, __last, __comp, __len, __buf.get(), __buf ? __len : 0);
std::__check_strict_weak_ordering_sorted(__first, __last, __comp);
}
diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h
index fb146b7c783d0..14923a1bbf7f5 100644
--- a/libcxx/include/__memory/construct_at.h
+++ b/libcxx/include/__memory/construct_at.h
@@ -93,6 +93,16 @@ _BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _Bidire
return __last;
}
+template <class _ForwardIterator, class _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+_ForwardIterator __destroy_n(_ForwardIterator __first, _Size __n) {
+ while (__n > 0) {
+ std::__destroy_at(std::addressof(*__first));
+ ++__first;
+ --__n;
+ }
+ return __first;
+}
#if _LIBCPP_STD_VER >= 17
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
@@ -118,9 +128,7 @@ void destroy(_ForwardIterator __first, _ForwardIterator __last) {
template <class _ForwardIterator, class _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
- for (; __n > 0; (void)++__first, --__n)
- std::__destroy_at(std::addressof(*__first));
- return __first;
+ return std::__destroy_n(__first, __n);
}
#endif // _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index c917f041a0147..a32dfa0eabe04 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -74,14 +74,6 @@ void return_temporary_buffer(_Tp* __p) _NOEXCEPT
_VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
}
-struct __return_temporary_buffer
-{
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-};
-
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
diff --git a/libcxx/include/__memory/uninitialized_buffer.h b/libcxx/include/__memory/uninitialized_buffer.h
new file mode 100644
index 0000000000000..8a2cc98904711
--- /dev/null
+++ b/libcxx/include/__memory/uninitialized_buffer.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_UNINITIALIZED_BUFFER_H
+#define _LIBCPP___MEMORY_UNINITIALIZED_BUFFER_H
+
+#include <__config>
+#include <__memory/construct_at.h>
+#include <__memory/unique_ptr.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/remove_extent.h>
+#include <__utility/move.h>
+#include <cstddef>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+// __make_uninitialized_buffer is a utility function to allocate some memory for scratch storage. The __destructor is
+// called before deleting the memory, making it possible to destroy any leftover elements. The __destructor is called
+// with the pointer to the first element and the total number of elements.
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Destructor>
+class __uninitialized_buffer_deleter {
+ size_t __count_;
+ _Destructor __destructor_;
+
+public:
+ template <class _Dummy = int, __enable_if_t<is_default_constructible<_Destructor>::value, _Dummy> = 0>
+ __uninitialized_buffer_deleter() : __count_(0) {}
+
+ __uninitialized_buffer_deleter(size_t __count, _Destructor __destructor)
+ : __count_(__count), __destructor_(std::move(__destructor)) {}
+
+ template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __ptr) {
+ __destructor_(__ptr, __count_);
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+ ::operator delete(__ptr);
+#else
+ ::operator delete(__ptr, __count_ * sizeof(_Tp), align_val_t(_LIBCPP_ALIGNOF(_Tp)));
+#endif
+ }
+};
+
+struct __noop {
+ template <class... _Args>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void operator()(_Args&&...) const {}
+};
+
+template <class _Array, class _Destructor = __noop>
+using __uninitialized_buffer_t = unique_ptr<_Array, __uninitialized_buffer_deleter<_Destructor> >;
+
+template <class _Array, class _Destructor = __noop>
+_LIBCPP_HIDE_FROM_ABI __uninitialized_buffer_t<_Array, _Destructor>
+__make_uninitialized_buffer(nothrow_t, size_t __count, _Destructor __destructor = __noop()) {
+ static_assert(is_array<_Array>::value, "");
+ using _Tp = __remove_extent_t<_Array>;
+
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+ _Tp* __ptr = static_cast<_Tp*>(::operator new(sizeof(_Tp) * __count, nothrow));
+#else
+ _Tp* __ptr = static_cast<_Tp*>(::operator new(sizeof(_Tp) * __count, align_val_t(_LIBCPP_ALIGNOF(_Tp)), nothrow));
+#endif
+
+ using _Deleter = __uninitialized_buffer_deleter<_Destructor>;
+ return unique_ptr<_Array, _Deleter>(__ptr, _Deleter(__count, std::move(__destructor)));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_UNINITIALIZED_BUFFER_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 92b45d3ae0d9b..3a524ec152109 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1211,6 +1211,7 @@ module std [system] {
module temp_value { private header "__memory/temp_value.h" }
module temporary_buffer { private header "__memory/temporary_buffer.h" }
module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" }
+ module uninitialized_buffer { private header "__memory/uninitialized_buffer.h" }
module unique_ptr { private header "__memory/unique_ptr.h" }
module uses_allocator { private header "__memory/uses_allocator.h" }
module uses_allocator_construction { private header "__memory/uses_allocator_construction.h" }
diff --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h
index 3e3856ca30e04..b642485010162 100644
--- a/libcxx/test/support/count_new.h
+++ b/libcxx/test/support/count_new.h
@@ -11,6 +11,7 @@
#include <algorithm>
#include <cassert>
+#include <cerrno>
#include <cstdlib>
#include <new>
#include <type_traits>
More information about the libcxx-commits
mailing list