[libcxx-commits] [libcxx] [libc++] Optimize vector growing of trivially relocatable types (PR #76657)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 18 09:25:41 PST 2024
================
@@ -591,60 +592,48 @@ __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1,
return std::__rewrap_iter(__first2, __result);
}
-// Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
-// if the move constructor is noexcept, where N is distance(__first1, __last1).
-//
-// 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_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");
- auto __destruct_first = __first2;
- auto __guard =
- std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
- while (__first1 != __last1) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1));
-#else
- allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move(*__first1));
-#endif
- ++__first1;
- ++__first2;
- }
- __guard.__complete();
- return __first2;
-}
-
template <class _Alloc, class _Type>
struct __allocator_has_trivial_move_construct : _Not<__has_construct<_Alloc, _Type*, _Type&&> > {};
template <class _Type>
struct __allocator_has_trivial_move_construct<allocator<_Type>, _Type> : true_type {};
-#ifndef _LIBCPP_COMPILER_GCC
-template <
- class _Alloc,
- class _Iter1,
- class _Iter2,
- 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_SINCE_CXX20 _Iter2
-__uninitialized_allocator_move_if_noexcept(_Alloc&, _Iter1 __first1, _Iter1 __last1, _Iter2 __first2) {
- if (__libcpp_is_constant_evaluated()) {
- while (__first1 != __last1) {
- std::__construct_at(std::__to_address(__first2), std::move(*__first1));
- ++__first1;
- ++__first2;
+template <class _Alloc, class _Tp>
+struct __allocator_has_trivial_destroy : _Not<__has_destroy<_Alloc, _Tp*>> {};
+
+template <class _Tp, class _Up>
+struct __allocator_has_trivial_destroy<allocator<_Tp>, _Up> : true_type {};
+
+// __uninitialized_allocator_relocate relocates the objects in [__first, __last) into __result.
----------------
ldionne wrote:
Let's document that this function provides the strong exception safety guarantee in case the elements are not nothrow_move_constructible and one of the copy constructors decides to throw.
https://github.com/llvm/llvm-project/pull/76657
More information about the libcxx-commits
mailing list