@@ -612,20 +612,22 @@ struct __allocator_has_trivial_destroy<allocator<_Tp>, _Up> : true_type {};
612612// [__first, __last) doesn't contain any objects
613613//
614614// The strong exception guarantee is provided if any of the following are true:
615- // - is_nothrow_move_constructible<_Tp>
616- // - is_copy_constructible<_Tp>
617- // - __libcpp_is_trivially_relocatable<_Tp>
618- template <class _Alloc , class _Tp >
619- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
620- __uninitialized_allocator_relocate (_Alloc& __alloc, _Tp* __first, _Tp* __last, _Tp* __result) {
615+ // - is_nothrow_move_constructible<_ValueType>
616+ // - is_copy_constructible<_ValueType>
617+ // - __libcpp_is_trivially_relocatable<_ValueType>
618+ template <class _Alloc , class _ContiguousIterator >
619+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __uninitialized_allocator_relocate (
620+ _Alloc& __alloc, _ContiguousIterator __first, _ContiguousIterator __last, _ContiguousIterator __result) {
621+ static_assert (__libcpp_is_contiguous_iterator<_ContiguousIterator>::value, " " );
622+ using _ValueType = typename iterator_traits<_ContiguousIterator>::value_type;
621623 static_assert (__is_cpp17_move_insertable<_Alloc>::value,
622624 " The specified type does not meet the requirements of Cpp17MoveInsertable" );
623- if (__libcpp_is_constant_evaluated () || !__libcpp_is_trivially_relocatable<_Tp >::value ||
624- !__allocator_has_trivial_move_construct<_Alloc, _Tp >::value ||
625- !__allocator_has_trivial_destroy<_Alloc, _Tp >::value) {
625+ if (__libcpp_is_constant_evaluated () || !__libcpp_is_trivially_relocatable<_ValueType >::value ||
626+ !__allocator_has_trivial_move_construct<_Alloc, _ValueType >::value ||
627+ !__allocator_has_trivial_destroy<_Alloc, _ValueType >::value) {
626628 auto __destruct_first = __result;
627- auto __guard =
628- std::__make_exception_guard ( _AllocatorDestroyRangeReverse<_Alloc, _Tp* >(__alloc, __destruct_first, __result));
629+ auto __guard = std::__make_exception_guard (
630+ _AllocatorDestroyRangeReverse<_Alloc, _ContiguousIterator >(__alloc, __destruct_first, __result));
629631 auto __iter = __first;
630632 while (__iter != __last) {
631633#if _LIBCPP_HAS_EXCEPTIONS
@@ -640,7 +642,9 @@ __uninitialized_allocator_relocate(_Alloc& __alloc, _Tp* __first, _Tp* __last, _
640642 std::__allocator_destroy (__alloc, __first, __last);
641643 } else {
642644 // Casting to void* to suppress clang complaining that this is technically UB.
643- __builtin_memcpy (static_cast <void *>(__result), __first, sizeof (_Tp) * (__last - __first));
645+ __builtin_memcpy (static_cast <void *>(std::__to_address (__result)),
646+ std::__to_address (__first),
647+ sizeof (_ValueType) * (__last - __first));
644648 }
645649}
646650
0 commit comments