diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /libcxx/include/__memory/uninitialized_algorithms.h | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'libcxx/include/__memory/uninitialized_algorithms.h')
| -rw-r--r-- | libcxx/include/__memory/uninitialized_algorithms.h | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h index 72b6890c2225..63a45b2ac87b 100644 --- a/libcxx/include/__memory/uninitialized_algorithms.h +++ b/libcxx/include/__memory/uninitialized_algorithms.h @@ -20,11 +20,21 @@ #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__memory/voidify.h> +#include <__type_traits/extent.h> +#include <__type_traits/is_array.h> #include <__type_traits/is_constant_evaluated.h> +#include <__type_traits/is_trivially_copy_assignable.h> +#include <__type_traits/is_trivially_copy_constructible.h> +#include <__type_traits/is_trivially_move_assignable.h> +#include <__type_traits/is_trivially_move_constructible.h> +#include <__type_traits/is_unbounded_array.h> +#include <__type_traits/negation.h> +#include <__type_traits/remove_const.h> +#include <__type_traits/remove_extent.h> +#include <__utility/exception_guard.h> #include <__utility/move.h> #include <__utility/pair.h> -#include <__utility/transaction.h> -#include <type_traits> +#include <new> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -64,6 +74,7 @@ __uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast, } template <class _InputIterator, class _ForwardIterator> +_LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, _ForwardIterator __ofirst) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; @@ -282,7 +293,7 @@ template <class _ForwardIterator, class _Size> inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; - return __uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); + return std::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } // uninitialized_move @@ -410,7 +421,10 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) { _Tp& __array = *__loc; // If an exception is thrown, destroy what we have constructed so far in reverse order. - __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); }); + __exception_guard __guard([&]() { + std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); + }); + for (; __i != extent_v<_Tp>; ++__i) { std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i])); } @@ -447,7 +461,9 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& _Tp& __array = *__loc; // If an exception is thrown, destroy what we have constructed so far in reverse order. - __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); }); + __exception_guard __guard([&]() { + std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); + }); for (; __i != extent_v<_Tp>; ++__i) { std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]); } @@ -472,7 +488,7 @@ constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it _BidirIter __begin = __it; // If an exception is thrown, destroy what we have constructed so far in reverse order. - __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); + __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); for (; __n != 0; --__n, ++__it) { std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value); } @@ -489,7 +505,7 @@ constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _Bid _BidirIter __begin = __it; // If an exception is thrown, destroy what we have constructed so far in reverse order. - __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); + __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); for (; __n != 0; --__n, ++__it) { std::__allocator_construct_at(__value_alloc, std::addressof(*__it)); } @@ -500,7 +516,7 @@ constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _Bid // Destroy all elements in [__first, __last) from left to right using allocator destruction. template <class _Alloc, class _Iter, class _Sent> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) { for (; __first != __last; ++__first) allocator_traits<_Alloc>::destroy(__alloc, std::__to_address(__first)); @@ -509,10 +525,11 @@ __allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) { template <class _Alloc, class _Iter> class _AllocatorDestroyRangeReverse { public: - _LIBCPP_HIDE_FROM_ABI _AllocatorDestroyRangeReverse(_Alloc& __alloc, _Iter& __first, _Iter& __last) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + _AllocatorDestroyRangeReverse(_Alloc& __alloc, _Iter& __first, _Iter& __last) : __alloc_(__alloc), __first_(__first), __last_(__last) {} - _LIBCPP_CONSTEXPR_AFTER_CXX11 void operator()() const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void operator()() const { std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_)); } @@ -527,23 +544,17 @@ private: // The caller has to ensure that __first2 can hold at least N uninitialized elements. If an exception is thrown the // already copied elements are destroyed in reverse order of their construction. template <class _Alloc, class _Iter1, class _Sent1, class _Iter2> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter2 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) { -#ifndef _LIBCPP_NO_EXCEPTIONS auto __destruct_first = __first2; - try { -#endif + auto __guard = + std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); while (__first1 != __last1) { allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), *__first1); ++__first1; ++__first2; } -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)(); - throw; - } -#endif + __guard.__complete(); return __first2; } @@ -555,12 +566,12 @@ struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_ty template <class _Alloc, class _Type, - class _RawType = typename remove_const<_Type>::type, + class _RawType = __remove_const_t<_Type>, __enable_if_t< // using _RawType because of the allocator<T const> extension is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value && __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Type* +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type* __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) { // TODO: Remove the const_cast once we drop support for std::allocator<T const> if (__libcpp_is_constant_evaluated()) { @@ -581,14 +592,13 @@ __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __la // Otherwise try to copy all elements. If an exception is thrown the already copied // elements are destroyed in reverse order of their construction. template <class _Alloc, class _Iter1, class _Sent1, class _Iter2> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter2 __uninitialized_allocator_move_if_noexcept( +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_move_if_noexcept( _Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) { static_assert(__is_cpp17_move_insertable<_Alloc>::value, "The specified type does not meet the requirements of Cpp17MoveInsertable"); -#ifndef _LIBCPP_NO_EXCEPTIONS auto __destruct_first = __first2; - try { -#endif + auto __guard = + std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); while (__first1 != __last1) { #ifndef _LIBCPP_NO_EXCEPTIONS allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1)); @@ -598,12 +608,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter2 __uninitialized_alloc ++__first1; ++__first2; } -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)(); - throw; - } -#endif + __guard.__complete(); return __first2; } @@ -621,7 +626,7 @@ template < class _Type = typename iterator_traits<_Iter1>::value_type, class = __enable_if_t<is_trivially_move_constructible<_Type>::value && is_trivially_move_assignable<_Type>::value && __allocator_has_trivial_move_construct<_Alloc, _Type>::value> > -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter1 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_move_if_noexcept(_Alloc&, _Iter1 __first1, _Iter1 __last1, _Iter2 __first2) { if (__libcpp_is_constant_evaluated()) { while (__first1 != __last1) { |
