aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__memory/uninitialized_algorithms.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__memory/uninitialized_algorithms.h')
-rw-r--r--libcxx/include/__memory/uninitialized_algorithms.h71
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) {