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
26TEST_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(n: It(src.data()), val: It(src.data() + src.size()));
172 assert(dst == src);
173 }
174
175 return true;
176}
177
178int main(int, char**) {
179 test();
180#if TEST_STD_VER > 17
181 static_assert(test());
182#endif
183 return 0;
184}
185

source code of libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp