construct_iter_iter.pass.cpp (5740B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <vector> 11 12 // template <class InputIter> vector(InputIter first, InputIter last); 13 14 #include <vector> 15 #include <cassert> 16 #include <cstddef> 17 18 #include "test_macros.h" 19 #include "test_iterators.h" 20 #include "test_allocator.h" 21 #include "min_allocator.h" 22 #include "asan_testing.h" 23 #if TEST_STD_VER >= 11 24 #include "emplace_constructible.h" 25 #include "container_test_types.h" 26 #endif 27 28 template <class C, class Iterator> 29 void test(Iterator first, Iterator last) { 30 C c(first, last); 31 LIBCPP_ASSERT(c.__invariants()); 32 assert(c.size() == static_cast<std::size_t>(std::distance(first, last))); 33 LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); 34 for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; 35 ++i, ++first) 36 assert(*i == *first); 37 } 38 39 static void basic_test_cases() { 40 int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; 41 int* an = a + sizeof(a) / sizeof(a[0]); 42 test<std::vector<int> >(input_iterator<const int*>(a), 43 input_iterator<const int*>(an)); 44 test<std::vector<int> >(forward_iterator<const int*>(a), 45 forward_iterator<const int*>(an)); 46 test<std::vector<int> >(bidirectional_iterator<const int*>(a), 47 bidirectional_iterator<const int*>(an)); 48 test<std::vector<int> >(random_access_iterator<const int*>(a), 49 random_access_iterator<const int*>(an)); 50 test<std::vector<int> >(a, an); 51 52 test<std::vector<int, limited_allocator<int, 63> > >( 53 input_iterator<const int*>(a), input_iterator<const int*>(an)); 54 // Add 1 for implementations that dynamically allocate a container proxy. 55 test<std::vector<int, limited_allocator<int, 18 + 1> > >( 56 forward_iterator<const int*>(a), forward_iterator<const int*>(an)); 57 test<std::vector<int, limited_allocator<int, 18 + 1> > >( 58 bidirectional_iterator<const int*>(a), 59 bidirectional_iterator<const int*>(an)); 60 test<std::vector<int, limited_allocator<int, 18 + 1> > >( 61 random_access_iterator<const int*>(a), 62 random_access_iterator<const int*>(an)); 63 test<std::vector<int, limited_allocator<int, 18 + 1> > >(a, an); 64 #if TEST_STD_VER >= 11 65 test<std::vector<int, min_allocator<int> > >(input_iterator<const int*>(a), 66 input_iterator<const int*>(an)); 67 test<std::vector<int, min_allocator<int> > >( 68 forward_iterator<const int*>(a), forward_iterator<const int*>(an)); 69 test<std::vector<int, min_allocator<int> > >( 70 bidirectional_iterator<const int*>(a), 71 bidirectional_iterator<const int*>(an)); 72 test<std::vector<int, min_allocator<int> > >( 73 random_access_iterator<const int*>(a), 74 random_access_iterator<const int*>(an)); 75 test<std::vector<int> >(a, an); 76 #endif 77 } 78 79 void emplaceable_concept_tests() { 80 #if TEST_STD_VER >= 11 81 int arr1[] = {42}; 82 int arr2[] = {1, 101, 42}; 83 { 84 using T = EmplaceConstructible<int>; 85 using It = forward_iterator<int*>; 86 { 87 std::vector<T> v(It(arr1), It(std::end(arr1))); 88 assert(v[0].value == 42); 89 } 90 { 91 std::vector<T> v(It(arr2), It(std::end(arr2))); 92 assert(v[0].value == 1); 93 assert(v[1].value == 101); 94 assert(v[2].value == 42); 95 } 96 } 97 { 98 using T = EmplaceConstructibleAndMoveInsertable<int>; 99 using It = input_iterator<int*>; 100 { 101 std::vector<T> v(It(arr1), It(std::end(arr1))); 102 assert(v[0].copied == 0); 103 assert(v[0].value == 42); 104 } 105 { 106 std::vector<T> v(It(arr2), It(std::end(arr2))); 107 //assert(v[0].copied == 0); 108 assert(v[0].value == 1); 109 //assert(v[1].copied == 0); 110 assert(v[1].value == 101); 111 assert(v[2].copied == 0); 112 assert(v[2].value == 42); 113 } 114 } 115 #endif 116 } 117 118 void test_ctor_under_alloc() { 119 #if TEST_STD_VER >= 11 120 int arr1[] = {42}; 121 int arr2[] = {1, 101, 42}; 122 { 123 using C = TCT::vector<>; 124 using It = forward_iterator<int*>; 125 { 126 ExpectConstructGuard<int&> G(1); 127 C v(It(arr1), It(std::end(arr1))); 128 } 129 { 130 ExpectConstructGuard<int&> G(3); 131 C v(It(arr2), It(std::end(arr2))); 132 } 133 } 134 { 135 using C = TCT::vector<>; 136 using It = input_iterator<int*>; 137 { 138 ExpectConstructGuard<int&> G(1); 139 C v(It(arr1), It(std::end(arr1))); 140 } 141 { 142 //ExpectConstructGuard<int&> G(3); 143 //C v(It(arr2), It(std::end(arr2)), a); 144 } 145 } 146 #endif 147 } 148 149 // Initialize a vector with a different value type. 150 void test_ctor_with_different_value_type() { 151 { 152 // Make sure initialization is performed with each element value, not with 153 // a memory blob. 154 float array[3] = {0.0f, 1.0f, 2.0f}; 155 std::vector<int> v(array, array + 3); 156 assert(v[0] == 0); 157 assert(v[1] == 1); 158 assert(v[2] == 2); 159 } 160 struct X { int x; }; 161 struct Y { int y; }; 162 struct Z : X, Y { int z; }; 163 { 164 Z z; 165 Z *array[1] = { &z }; 166 // Though the types Z* and Y* are very similar, initialization still cannot 167 // be done with `memcpy`. 168 std::vector<Y*> v(array, array + 1); 169 assert(v[0] == &z); 170 } 171 { 172 // Though the types are different, initialization can be done with `memcpy`. 173 int32_t array[1] = { -1 }; 174 std::vector<uint32_t> v(array, array + 1); 175 assert(v[0] == 4294967295); 176 } 177 } 178 179 180 int main() { 181 basic_test_cases(); 182 emplaceable_concept_tests(); // See PR34898 183 test_ctor_under_alloc(); 184 test_ctor_with_different_value_type(); 185 }