xref: /llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp (revision 4039a79de71bd969ef5bf944fd9f46430338ff7e)
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