Index: libcxx/include/memory =================================================================== --- libcxx/include/memory +++ libcxx/include/memory @@ -1502,6 +1502,12 @@ typedef typename _Alloc::difference_type type; }; +template +struct __is_default_allocator : false_type {}; + +template +struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + template struct _LIBCPP_TEMPLATE_VIS allocator_traits { @@ -1615,7 +1621,7 @@ static typename enable_if < - (is_same >::value + (__is_default_allocator::value || !__has_construct::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1640,23 +1646,25 @@ construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1); } - template + template ::type, + class _RawDestTp = typename remove_const<_DestTp>::type> _LIBCPP_INLINE_VISIBILITY static typename enable_if < - (is_same >::value - || !__has_construct::value) && - is_trivially_move_constructible<_Tp>::value, + is_trivially_move_constructible<_DestTp>::value && + is_same<_RawSourceTp, _RawDestTp>::value && + (__is_default_allocator::value || + !__has_construct::value), void >::type - __construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2) { - typedef typename remove_const<_Tp>::type _Vp; ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { - _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp)); + _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp)); __begin2 += _Np; } } @@ -1679,7 +1687,7 @@ static typename enable_if < - (is_same >::value + (__is_default_allocator::value || !__has_construct::value) && is_trivially_move_constructible<_Tp>::value, void Index: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -146,9 +146,20 @@ #endif } +// Initialize a vector with a different value type. Make sure initialization +// is performed with each element value, not with a memory blob. +void test_ctor_with_different_value_type() { + float array[3] = {0.0f, 1.0f, 2.0f}; + std::vector v(array, array + 3); + assert(v[0] == 0); + assert(v[1] == 1); + assert(v[2] == 2); +} + int main() { basic_test_cases(); emplaceable_concept_tests(); // See PR34898 test_ctor_under_alloc(); + test_ctor_with_different_value_type(); }