[PATCH] D48342: [libcxx] Optimize vectors construction of trivial types from an iterator range with const-ness mismatch.
Volodymyr Sapsai via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 5 15:06:06 PDT 2018
vsapsai updated this revision to Diff 154327.
vsapsai added a comment.
- Clean up tests according to review. We don't need a new test for custom allocators, parent patch covers that.
https://reviews.llvm.org/D48342
Files:
libcxx/include/memory
libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
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
@@ -13,6 +13,8 @@
#include <vector>
#include <cassert>
+#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
@@ -176,9 +178,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() {
+ 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);
+}
+
int main() {
basic_test_cases();
emplaceable_concept_tests(); // See PR34898
test_ctor_under_alloc();
+ test_ctor_with_different_value_type();
}
Index: libcxx/include/memory
===================================================================
--- libcxx/include/memory
+++ libcxx/include/memory
@@ -1642,23 +1642,29 @@
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
+ <
+ typename _VSTD::remove_const<_SourceTp>::type,
+ typename _VSTD::remove_const<_DestTp>::type
+ >::value &&
+ (is_same<allocator_type, allocator<typename _VSTD::remove_const<_SourceTp>::type> >::value
+ || is_same<allocator_type, allocator<const _SourceTp> >::value
+ || !__has_construct<allocator_type, _DestTp*, const _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;
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48342.154327.patch
Type: text/x-patch
Size: 2945 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180705/84ae63db/attachment.bin>
More information about the cfe-commits
mailing list