1212
1313#include  < __algorithm/copy.h> 
1414#include  < __algorithm/move.h> 
15+ #include  < __algorithm/unwrap_iter.h> 
16+ #include  < __algorithm/unwrap_range.h> 
1517#include  < __config> 
1618#include  < __iterator/iterator_traits.h> 
1719#include  < __iterator/reverse_iterator.h> 
@@ -545,7 +547,7 @@ class _AllocatorDestroyRangeReverse {
545547//  already copied elements are destroyed in reverse order of their construction.
546548template  <class  _Alloc , class  _Iter1 , class  _Sent1 , class  _Iter2 >
547549_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
548- __uninitialized_allocator_copy (_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
550+ __uninitialized_allocator_copy_impl (_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
549551  auto  __destruct_first = __first2;
550552  auto  __guard =
551553      std::__make_exception_guard (_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
@@ -565,14 +567,16 @@ template <class _Type>
565567struct  __allocator_has_trivial_copy_construct <allocator<_Type>, _Type> : true_type {};
566568
567569template  <class  _Alloc ,
568-           class  _Type ,
569-           class  _RawType  = __remove_const_t <_Type>,
570+           class  _In ,
571+           class  _RawTypeIn  = __remove_const_t <_In>,
572+           class  _Out ,
570573          __enable_if_t <
571-               //  using _RawType because of the allocator<T const> extension
572-               is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
573-               __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr >
574- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
575- __uninitialized_allocator_copy (_Alloc&, const  _Type* __first1, const  _Type* __last1, _Type* __first2) {
574+               //  using _RawTypeIn because of the allocator<T const> extension
575+               is_trivially_copy_constructible<_RawTypeIn>::value && is_trivially_copy_assignable<_RawTypeIn>::value &&
576+               is_same<__remove_cv_t <_In>, __remove_cv_t <_Out> >::value &&
577+               __allocator_has_trivial_copy_construct<_Alloc, _RawTypeIn>::value>* = nullptr >
578+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Out*
579+ __uninitialized_allocator_copy_impl (_Alloc&, _In* __first1, _In* __last1, _Out* __first2) {
576580  //  TODO: Remove the const_cast once we drop support for std::allocator<T const>
577581  if  (__libcpp_is_constant_evaluated ()) {
578582    while  (__first1 != __last1) {
@@ -582,10 +586,17 @@ __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __la
582586    }
583587    return  __first2;
584588  } else  {
585-     return  std::copy (__first1, __last1, const_cast <_RawType *>(__first2));
589+     return  std::copy (__first1, __last1, const_cast <_RawTypeIn *>(__first2));
586590  }
587591}
588592
593+ template  <class  _Alloc , class  _Iter1 , class  _Sent1 , class  _Iter2 >
594+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_copy (_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
595+     auto  __unwrapped_range = std::__unwrap_range (__first1, __last1);
596+     auto  __result = std::__uninitialized_allocator_copy_impl (__alloc, __unwrapped_range.first , __unwrapped_range.second , std::__unwrap_iter (__first2));
597+     return  std::__rewrap_iter (__first2, __result);
598+ }
599+ 
589600//  Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
590601//  if the move constructor is noexcept, where N is distance(__first1, __last1).
591602// 
0 commit comments