[libcxx-commits] [PATCH] D147741: [libc++] unwrap iterator parameters to __uninitialized_allocator_copy before calling std::copy

Aditya Kumar via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Apr 12 06:50:36 PDT 2023


hiraditya updated this revision to Diff 512815.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147741/new/

https://reviews.llvm.org/D147741

Files:
  libcxx/include/__memory/uninitialized_algorithms.h


Index: libcxx/include/__memory/uninitialized_algorithms.h
===================================================================
--- libcxx/include/__memory/uninitialized_algorithms.h
+++ libcxx/include/__memory/uninitialized_algorithms.h
@@ -12,6 +12,7 @@
 
 #include <__algorithm/copy.h>
 #include <__algorithm/move.h>
+#include <__algorithm/unwrap_iter.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
@@ -539,13 +540,25 @@
   _Iter& __last_;
 };
 
-// Copy-construct [__first1, __last1) in [__first2, __first2 + N), where N is distance(__first1, __last1).
-//
-// 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>
+template <class _Alloc, class _Type>
+struct __allocator_has_trivial_copy_construct : _Not<__has_construct<_Alloc, _Type*, const _Type&> > {};
+
+template <class _Type>
+struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_type {};
+
+template <class _Alloc,
+          class _Iter1,
+          class _Sent1,
+          class _Iter2
+          /* Adding this calls the other overload for vector<int>
+          class _RawType = __remove_const_t<_Iter2>,
+          __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>* */ >
+
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
-__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
+__uninitialized_allocator_copy_impl(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
   auto __destruct_first = __first2;
   auto __guard =
       std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
@@ -558,12 +571,6 @@
   return __first2;
 }
 
-template <class _Alloc, class _Type>
-struct __allocator_has_trivial_copy_construct : _Not<__has_construct<_Alloc, _Type*, const _Type&> > {};
-
-template <class _Type>
-struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_type {};
-
 template <class _Alloc,
           class _Type,
           class _RawType = __remove_const_t<_Type>,
@@ -572,7 +579,7 @@
               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_SINCE_CXX20 _Type*
-__uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) {
+__uninitialized_allocator_copy_impl(_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()) {
     while (__first1 != __last1) {
@@ -586,6 +593,16 @@
   }
 }
 
+// Copy-construct [__first1, __last1) in [__first2, __first2 + N), where N is distance(__first1, __last1).
+//
+// 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_SINCE_CXX20 _Iter2
+__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
+    return std::__uninitialized_allocator_copy_impl(__alloc, std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2));
+}
+
 // Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
 // if the move constructor is noexcept, where N is distance(__first1, __last1).
 //


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147741.512815.patch
Type: text/x-patch
Size: 4083 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230412/1e54d898/attachment-0001.bin>


More information about the libcxx-commits mailing list