1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <vector> 10 11 // template <class InputIt> 12 // constexpr void assign(InputIt first, InputIt last); 13 14 #include <vector> 15 #include <algorithm> 16 #include <cassert> 17 #include "test_macros.h" 18 #include "min_allocator.h" 19 #include "asan_testing.h" 20 #include "test_iterators.h" 21 #if TEST_STD_VER >= 11 22 # include "emplace_constructible.h" 23 # include "container_test_types.h" 24 #endif 25 26 TEST_CONSTEXPR_CXX20 bool test() { 27 #if TEST_STD_VER >= 11 28 int arr1[] = {42}; 29 int arr2[] = {1, 101, 42}; 30 { // Test with new_size > capacity() == 0 for forward_iterator, resulting in reallocation during assign 31 using T = EmplaceConstructibleMoveableAndAssignable<int>; 32 using It = forward_iterator<int*>; 33 { 34 std::vector<T> v; 35 v.assign(It(arr1), It(std::end(arr1))); 36 assert(v[0].value == 42); 37 } 38 { 39 std::vector<T> v; 40 v.assign(It(arr2), It(std::end(arr2))); 41 assert(v[0].value == 1); 42 assert(v[1].value == 101); 43 assert(v[2].value == 42); 44 } 45 } 46 { // Test with new_size > capacity() == 0 for input_iterator, resulting in reallocation during assign 47 using T = EmplaceConstructibleMoveableAndAssignable<int>; 48 using It = cpp17_input_iterator<int*>; 49 { 50 std::vector<T> v; 51 v.assign(It(arr1), It(std::end(arr1))); 52 assert(v[0].copied == 0); 53 assert(v[0].value == 42); 54 } 55 { 56 std::vector<T> v; 57 v.assign(It(arr2), It(std::end(arr2))); 58 //assert(v[0].copied == 0); 59 assert(v[0].value == 1); 60 //assert(v[1].copied == 0); 61 assert(v[1].value == 101); 62 assert(v[2].copied == 0); 63 assert(v[2].value == 42); 64 } 65 } 66 67 { // Test with new_size < size() for forward_iterator, resulting in destruction at end during assign 68 using T = EmplaceConstructibleMoveableAndAssignable<int>; 69 using It = forward_iterator<int*>; 70 { 71 std::vector<T> v; 72 v.reserve(5); 73 for (std::size_t i = 0; i < v.capacity(); ++i) 74 v.emplace_back(99); 75 v.assign(It(arr1), It(std::end(arr1))); 76 assert(v.size() == 1); 77 assert(v[0].value == 42); 78 } 79 { 80 std::vector<T> v; 81 v.reserve(5); 82 for (std::size_t i = 0; i < v.capacity(); ++i) 83 v.emplace_back(99); 84 v.assign(It(arr2), It(std::end(arr2))); 85 assert(v.size() == 3); 86 assert(v[0].value == 1); 87 assert(v[1].value == 101); 88 assert(v[2].value == 42); 89 } 90 } 91 { // Test with new_size < size() for input_iterator, resulting in destruction at end during assign 92 using T = EmplaceConstructibleMoveableAndAssignable<int>; 93 using It = cpp17_input_iterator<int*>; 94 { 95 std::vector<T> v; 96 v.reserve(5); 97 for (std::size_t i = 0; i < v.capacity(); ++i) 98 v.emplace_back(99); 99 v.assign(It(arr1), It(std::end(arr1))); 100 assert(v.size() == 1); 101 assert(v[0].value == 42); 102 } 103 { 104 std::vector<T> v; 105 v.reserve(5); 106 for (std::size_t i = 0; i < v.capacity(); ++i) 107 v.emplace_back(99); 108 v.assign(It(arr2), It(std::end(arr2))); 109 assert(v.size() == 3); 110 assert(v[0].value == 1); 111 assert(v[1].value == 101); 112 assert(v[2].value == 42); 113 } 114 } 115 116 { // Test with size() < new_size < capacity() for forward_iterator, resulting in construction at end during assign 117 using T = EmplaceConstructibleMoveableAndAssignable<int>; 118 using It = forward_iterator<int*>; 119 { 120 std::vector<T> v; 121 v.reserve(5); 122 v.assign(It(arr1), It(std::end(arr1))); 123 assert(v.size() == 1); 124 assert(v[0].value == 42); 125 } 126 { 127 std::vector<T> v; 128 v.reserve(5); 129 for (std::size_t i = 0; i < 2; ++i) 130 v.emplace_back(99); 131 v.assign(It(arr2), It(std::end(arr2))); 132 assert(v.size() == 3); 133 assert(v[0].value == 1); 134 assert(v[1].value == 101); 135 assert(v[2].value == 42); 136 } 137 } 138 { // Test with size() < new_size < capacity() for input_iterator, resulting in construction at end during assign 139 using T = EmplaceConstructibleMoveableAndAssignable<int>; 140 using It = cpp17_input_iterator<int*>; 141 { 142 std::vector<T> v; 143 v.reserve(5); 144 v.assign(It(arr1), It(std::end(arr1))); 145 assert(v.size() == 1); 146 assert(v[0].value == 42); 147 } 148 { 149 std::vector<T> v; 150 v.reserve(5); 151 for (std::size_t i = 0; i < 2; ++i) 152 v.emplace_back(99); 153 v.assign(It(arr2), It(std::end(arr2))); 154 assert(v.size() == 3); 155 assert(v[0].value == 1); 156 assert(v[1].value == 101); 157 assert(v[2].value == 42); 158 } 159 } 160 #endif 161 162 // Test with a number of elements in the source range that is greater than capacity 163 { 164 typedef forward_iterator<int*> It; 165 166 std::vector<int> dst(10); 167 168 std::size_t n = dst.capacity() * 2; 169 std::vector<int> src(n); 170 171 dst.assign(It(src.data()), It(src.data() + src.size())); 172 assert(dst == src); 173 } 174 175 return true; 176 } 177 178 int main(int, char**) { 179 test(); 180 #if TEST_STD_VER > 17 181 static_assert(test()); 182 #endif 183 return 0; 184 } 185