diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -225,7 +225,7 @@ difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = _VSTD::min(__len1, __len2); - auto __buf = std::__make_uninitialized_buffer(nothrow, __buf_size); + auto __buf = std::__make_uninitialized_buffer(__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 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -139,9 +139,9 @@ // *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - __uninitialized_buffer_t __buf; + __uninitialized_buffer_t __buf; if (__len >= __alloc_limit) - __buf = std::__make_uninitialized_buffer(nothrow, __len); + __buf = std::__make_uninitialized_buffer(__len); return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), @@ -292,9 +292,9 @@ // *__last is known to be true // __len >= 2 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - __uninitialized_buffer_t __buf; + __uninitialized_buffer_t __buf; if (__len >= __alloc_limit) - __buf = std::__make_uninitialized_buffer(nothrow, __len); + __buf = std::__make_uninitialized_buffer( __len); return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( std::move(__first), diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -249,9 +249,10 @@ using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; - __uninitialized_buffer_t __buf; + + __uninitialized_buffer_t __buf; if (__len > static_cast(__stable_sort_switch::value)) - __buf = std::__make_uninitialized_buffer(nothrow, __len); + __buf = std::__make_uninitialized_buffer(__len); std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >( __first, __last, __comp, __len, __buf.get(), __buf ? __len : 0); diff --git a/libcxx/include/__memory/uninitialized_buffer.h b/libcxx/include/__memory/uninitialized_buffer.h --- a/libcxx/include/__memory/uninitialized_buffer.h +++ b/libcxx/include/__memory/uninitialized_buffer.h @@ -10,11 +10,7 @@ #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 #include @@ -29,51 +25,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template class __uninitialized_buffer_deleter { size_t __count_; - _Destructor __destructor_; public: - template ::value, _Dummy> = 0> - _LIBCPP_HIDE_FROM_ABI __uninitialized_buffer_deleter() : __count_(0) {} - - _LIBCPP_HIDE_FROM_ABI __uninitialized_buffer_deleter(size_t __count, _Destructor __destructor) - : __count_(__count), __destructor_(std::move(__destructor)) {} + _LIBCPP_HIDE_FROM_ABI + explicit constexpr __uninitialized_buffer_deleter(size_t __count = 0) noexcept + : __count_(__count) {} template - _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 + _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __ptr) const noexcept { + std::__libcpp_deallocate(__ptr, __count_ * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); } }; -struct __noop { - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void operator()(_Args&&...) const {} -}; - -template -using __uninitialized_buffer_t = unique_ptr<_Array, __uninitialized_buffer_deleter<_Destructor> >; - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __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>; +template +using __uninitialized_buffer_t = unique_ptr<_Tp, __uninitialized_buffer_deleter>; -#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 +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __uninitialized_buffer_t<_Tp> +__make_uninitialized_buffer(size_t __count) { + _Tp* __ptr = static_cast<_Tp*>(std::__libcpp_allocate(sizeof(_Tp) * __count, _LIBCPP_ALIGNOF(_Tp), nothrow)); - using _Deleter = __uninitialized_buffer_deleter<_Destructor>; - return unique_ptr<_Array, _Deleter>(__ptr, _Deleter(__count, std::move(__destructor))); + using _Deleter = __uninitialized_buffer_deleter; + return __uninitialized_buffer_t<_Tp>(__ptr, _Deleter(__ptr ? __count : 0)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/new b/libcxx/include/new --- a/libcxx/include/new +++ b/libcxx/include/new @@ -294,6 +294,19 @@ return __libcpp_operator_new(__size); } +inline _LIBCPP_INLINE_VISIBILITY +void *__libcpp_allocate(size_t __size, size_t __align, nothrow_t) { +#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION + if (__is_overaligned_for_new(__align)) { + const align_val_t __align_val = static_cast(__align); + return __libcpp_operator_new(__size, __align_val, nothrow); + } +#endif + + (void)__align; + return __libcpp_operator_new(__size, nothrow); +} + template _LIBCPP_INLINE_VISIBILITY void __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {