vsapsai updated this revision to Diff 152990.
vsapsai added a comment.
- Don't use memcpy specialization with custom allocators.
Not entirely satisfied with comparing allocator to non-const and const, don't
know if there is a more elegant way to do the same.
https://reviews.llvm.org/D48342
Files:
libcxx/include/memory
libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_different_value_type.pass.cpp
Index: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_different_value_type.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_different_value_type.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class InputIter> vector(InputIter first, InputIter last);
+
+// Initialize a vector with a different value type. Make sure initialization
+// is performed with each element value, not with a memory blob.
+
+#include <vector>
+#include <cassert>
+#include <cfloat>
+#include <cmath>
+
+int main()
+{
+ int array[3] = {0, 1, 2};
+ std::vector<float> v(array, array + 3);
+ assert(std::fabs(v[0] - 0.0f) < FLT_EPSILON);
+ assert(std::fabs(v[1] - 1.0f) < FLT_EPSILON);
+ assert(std::fabs(v[2] - 2.0f) < FLT_EPSILON);
+}
Index: libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
===================================================================
--- libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
+++ libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -162,6 +162,17 @@
//C v(It(arr2), It(std::end(arr2)), a);
}
}
+ {
+ using C = std::vector<int, ContainerTestAllocator<int, int> >;
+ {
+ ExpectConstructGuard<int&> G(1);
+ C v(arr1, arr1 + 1);
+ }
+ {
+ ExpectConstructGuard<int&> G(3);
+ C v(arr2, arr2 + 3);
+ }
+ }
#endif
}
Index: libcxx/include/memory
===================================================================
--- libcxx/include/memory
+++ libcxx/include/memory
@@ -1399,6 +1399,13 @@
{
};
+template <class _Alloc, class _Pointer, class ..._Args>
+struct __has_construct_missing
+ : integral_constant<bool,
+ !__has_construct<_Alloc, _Pointer, _Args...>::value>
+{
+};
+
template <class _Alloc, class _Pointer>
auto
__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
@@ -1467,14 +1474,26 @@
{
};
+template <class _Alloc, class _Pointer, class ..._Args>
+struct __has_construct_missing
+ : false_type
+{
+};
+
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Alloc, class _Pointer, class _Args>
struct __has_construct
: false_type
{
};
+template <class _Alloc, class _Pointer, class _Args>
+struct __has_construct_missing
+ : false_type
+{
+};
+
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Alloc, class _Pointer>
@@ -1622,7 +1641,7 @@
typename enable_if
<
(is_same<allocator_type, allocator<_Tp> >::value
- || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+ || __has_construct_missing<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
>::type
@@ -1646,23 +1665,24 @@
construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
}
- template <class _Tp>
+ template <class _SourceTp, class _DestTp>
_LIBCPP_INLINE_VISIBILITY
static
typename enable_if
<
- (is_same<allocator_type, allocator<_Tp> >::value
- || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
- is_trivially_move_constructible<_Tp>::value,
+ (is_same<allocator_type, allocator<typename _VSTD::remove_const<_SourceTp>::type> >::value
+ || is_same<allocator_type, allocator<const _SourceTp> >::value
+ || __has_construct_missing<allocator_type, _DestTp*, _SourceTp>::value) &&
+ is_trivially_move_constructible<_DestTp>::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;
+ typedef typename remove_const<_DestTp>::type _Vp;
ptrdiff_t _Np = __end1 - __begin1;
if (_Np > 0)
{
- _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp));
+ _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_DestTp));
__begin2 += _Np;
}
}
@@ -1686,7 +1706,7 @@
typename enable_if
<
(is_same<allocator_type, allocator<_Tp> >::value
- || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+ || __has_construct_missing<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
>::type
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits