diff options
author | Tom Stellard <tstellar@redhat.com> | 2017-11-22 15:06:35 +0000 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2017-11-22 15:06:35 +0000 |
commit | 598ae4fa2e4da8b0a4b839c8c26b6cd3f672a968 (patch) | |
tree | a42814e786626dd74bd3d1fee4221a2eab71c60e /test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp | |
parent | 1496b0e710aa010a384910b36d10a257cdeae2b7 (diff) |
Merging r315994:release_50
------------------------------------------------------------------------
r315994 | ericwf | 2017-10-17 06:03:17 -0700 (Tue, 17 Oct 2017) | 18 lines
[libc++] Fix PR34898 - vector iterator constructors and assign method perform push_back instead of emplace_back.
Summary:
The constructors `vector(Iter, Iter, Alloc = Alloc{})` and `assign(Iter, Iter)` don't correctly perform EmplaceConstruction from the result of dereferencing the iterator. This results in them performing an additional and unneeded copy.
This patch addresses the issue by correctly using `emplace_back` in C++11 and newer.
There are also some bugs in our `insert` implementation, but those will be handled separately.
@mclow.lists We should probably merge this into 5.1, agreed?
Reviewers: mclow.lists, dlj, EricWF
Reviewed By: mclow.lists, EricWF
Subscribers: cfe-commits, mclow.lists
Differential Revision: https://reviews.llvm.org/D38757
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/branches/release_50@318837 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp')
-rw-r--r-- | test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp | 157 |
1 files changed, 127 insertions, 30 deletions
diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index ec4944d1a..88613efe7 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -20,40 +20,137 @@ #include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" +#if TEST_STD_VER >= 11 +#include "emplace_constructible.h" +#include "container_test_types.h" +#endif template <class C, class Iterator> -void -test(Iterator first, Iterator last) -{ - C c(first, last); - LIBCPP_ASSERT(c.__invariants()); - assert(c.size() == static_cast<std::size_t>(std::distance(first, last))); - LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); - for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) - assert(*i == *first); +void test(Iterator first, Iterator last) { + C c(first, last); + LIBCPP_ASSERT(c.__invariants()); + assert(c.size() == static_cast<std::size_t>(std::distance(first, last))); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); + for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; + ++i, ++first) + assert(*i == *first); +} + +static void basic_test_cases() { + int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; + int* an = a + sizeof(a) / sizeof(a[0]); + test<std::vector<int> >(input_iterator<const int*>(a), + input_iterator<const int*>(an)); + test<std::vector<int> >(forward_iterator<const int*>(a), + forward_iterator<const int*>(an)); + test<std::vector<int> >(bidirectional_iterator<const int*>(a), + bidirectional_iterator<const int*>(an)); + test<std::vector<int> >(random_access_iterator<const int*>(a), + random_access_iterator<const int*>(an)); + test<std::vector<int> >(a, an); + + test<std::vector<int, limited_allocator<int, 63> > >( + input_iterator<const int*>(a), input_iterator<const int*>(an)); + // Add 1 for implementations that dynamically allocate a container proxy. + test<std::vector<int, limited_allocator<int, 18 + 1> > >( + forward_iterator<const int*>(a), forward_iterator<const int*>(an)); + test<std::vector<int, limited_allocator<int, 18 + 1> > >( + bidirectional_iterator<const int*>(a), + bidirectional_iterator<const int*>(an)); + test<std::vector<int, limited_allocator<int, 18 + 1> > >( + random_access_iterator<const int*>(a), + random_access_iterator<const int*>(an)); + test<std::vector<int, limited_allocator<int, 18 + 1> > >(a, an); +#if TEST_STD_VER >= 11 + test<std::vector<int, min_allocator<int> > >(input_iterator<const int*>(a), + input_iterator<const int*>(an)); + test<std::vector<int, min_allocator<int> > >( + forward_iterator<const int*>(a), forward_iterator<const int*>(an)); + test<std::vector<int, min_allocator<int> > >( + bidirectional_iterator<const int*>(a), + bidirectional_iterator<const int*>(an)); + test<std::vector<int, min_allocator<int> > >( + random_access_iterator<const int*>(a), + random_access_iterator<const int*>(an)); + test<std::vector<int> >(a, an); +#endif } -int main() -{ - int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; - int* an = a + sizeof(a)/sizeof(a[0]); - test<std::vector<int> >(input_iterator<const int*>(a), input_iterator<const int*>(an)); - test<std::vector<int> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an)); - test<std::vector<int> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an)); - test<std::vector<int> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an)); - test<std::vector<int> >(a, an); - - test<std::vector<int, limited_allocator<int, 63> > >(input_iterator<const int*>(a), input_iterator<const int*>(an)); - // Add 1 for implementations that dynamically allocate a container proxy. - test<std::vector<int, limited_allocator<int, 18 + 1> > >(forward_iterator<const int*>(a), forward_iterator<const int*>(an)); - test<std::vector<int, limited_allocator<int, 18 + 1> > >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an)); - test<std::vector<int, limited_allocator<int, 18 + 1> > >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an)); - test<std::vector<int, limited_allocator<int, 18 + 1> > >(a, an); +void emplaceable_concept_tests() { #if TEST_STD_VER >= 11 - test<std::vector<int, min_allocator<int>> >(input_iterator<const int*>(a), input_iterator<const int*>(an)); - test<std::vector<int, min_allocator<int>> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an)); - test<std::vector<int, min_allocator<int>> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an)); - test<std::vector<int, min_allocator<int>> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an)); - test<std::vector<int> >(a, an); + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + using T = EmplaceConstructible<int>; + using It = forward_iterator<int*>; + { + std::vector<T> v(It(arr1), It(std::end(arr1))); + assert(v[0].value == 42); + } + { + std::vector<T> v(It(arr2), It(std::end(arr2))); + assert(v[0].value == 1); + assert(v[1].value == 101); + assert(v[2].value == 42); + } + } + { + using T = EmplaceConstructibleAndMoveInsertable<int>; + using It = input_iterator<int*>; + { + std::vector<T> v(It(arr1), It(std::end(arr1))); + assert(v[0].copied == 0); + assert(v[0].value == 42); + } + { + std::vector<T> v(It(arr2), It(std::end(arr2))); + //assert(v[0].copied == 0); + assert(v[0].value == 1); + //assert(v[1].copied == 0); + assert(v[1].value == 101); + assert(v[2].copied == 0); + assert(v[2].value == 42); + } + } #endif } + +void test_ctor_under_alloc() { +#if TEST_STD_VER >= 11 + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + using C = TCT::vector<>; + using T = typename C::value_type; + using It = forward_iterator<int*>; + { + ExpectConstructGuard<int&> G(1); + C v(It(arr1), It(std::end(arr1))); + } + { + ExpectConstructGuard<int&> G(3); + C v(It(arr2), It(std::end(arr2))); + } + } + { + using C = TCT::vector<>; + using T = typename C::value_type; + using It = input_iterator<int*>; + { + ExpectConstructGuard<int&> G(1); + C v(It(arr1), It(std::end(arr1))); + } + { + //ExpectConstructGuard<int&> G(3); + //C v(It(arr2), It(std::end(arr2)), a); + } + } +#endif +} + + +int main() { + basic_test_cases(); + emplaceable_concept_tests(); // See PR34898 + test_ctor_under_alloc(); +} |