diff options
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) { | 
