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 | // <list> |
10 | |
11 | // template <class InputIterator> |
12 | // list(InputIterator first, InputIterator last, const Allocator& = Allocator()); |
13 | |
14 | #include <list> |
15 | #include <cassert> |
16 | #include "test_macros.h" |
17 | #include "test_iterators.h" |
18 | #include "test_allocator.h" |
19 | #include "min_allocator.h" |
20 | #if TEST_STD_VER >= 11 |
21 | #include "emplace_constructible.h" |
22 | #include "container_test_types.h" |
23 | #endif |
24 | |
25 | void basic_test() |
26 | { |
27 | { |
28 | int a[] = {0, 1, 2, 3}; |
29 | std::list<int> l(cpp17_input_iterator<const int*>(a), |
30 | cpp17_input_iterator<const int*>(a + sizeof(a)/sizeof(a[0]))); |
31 | assert(l.size() == sizeof(a)/sizeof(a[0])); |
32 | assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); |
33 | int j = 0; |
34 | for (std::list<int>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) |
35 | assert(*i == j); |
36 | } |
37 | { |
38 | int a[] = {0, 1, 2, 3}; |
39 | std::list<int> l(cpp17_input_iterator<const int*>(a), |
40 | cpp17_input_iterator<const int*>(a + sizeof(a)/sizeof(a[0])), |
41 | std::allocator<int>()); |
42 | assert(l.size() == sizeof(a)/sizeof(a[0])); |
43 | assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); |
44 | int j = 0; |
45 | for (std::list<int>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) |
46 | assert(*i == j); |
47 | } |
48 | { |
49 | int a[] = {0, 1, 2, 3}; |
50 | // Add 2 for implementations that dynamically allocate a sentinel node and container proxy. |
51 | std::list<int, limited_allocator<int, sizeof(a)/sizeof(a[0]) + 2> > l(cpp17_input_iterator<const int*>(a), |
52 | cpp17_input_iterator<const int*>(a + sizeof(a)/sizeof(a[0]))); |
53 | assert(l.size() == sizeof(a)/sizeof(a[0])); |
54 | assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); |
55 | int j = 0; |
56 | for (std::list<int>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) |
57 | assert(*i == j); |
58 | } |
59 | #if TEST_STD_VER >= 11 |
60 | { |
61 | int a[] = {0, 1, 2, 3}; |
62 | std::list<int, min_allocator<int>> l(cpp17_input_iterator<const int*>(a), |
63 | cpp17_input_iterator<const int*>(a + sizeof(a)/sizeof(a[0]))); |
64 | assert(l.size() == sizeof(a)/sizeof(a[0])); |
65 | assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); |
66 | int j = 0; |
67 | for (std::list<int, min_allocator<int>>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) |
68 | assert(*i == j); |
69 | } |
70 | { |
71 | int a[] = {0, 1, 2, 3}; |
72 | std::list<int, min_allocator<int>> l(cpp17_input_iterator<const int*>(a), |
73 | cpp17_input_iterator<const int*>(a + sizeof(a)/sizeof(a[0])), |
74 | min_allocator<int>()); |
75 | assert(l.size() == sizeof(a)/sizeof(a[0])); |
76 | assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); |
77 | int j = 0; |
78 | for (std::list<int, min_allocator<int>>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) |
79 | assert(*i == j); |
80 | } |
81 | #endif |
82 | } |
83 | |
84 | |
85 | |
86 | void test_emplacable_concept() { |
87 | #if TEST_STD_VER >= 11 |
88 | int arr1[] = {42}; |
89 | int arr2[] = {1, 101, 42}; |
90 | { |
91 | using T = EmplaceConstructible<int>; |
92 | using It = random_access_iterator<int*>; |
93 | { |
94 | std::list<T> v(It(arr1), It(std::end(arr1))); |
95 | auto I = v.begin(); |
96 | assert(I->value == 42); |
97 | } |
98 | { |
99 | std::list<T> v(It(arr2), It(std::end(arr2))); |
100 | auto I = v.begin(); |
101 | assert(I->value == 1); |
102 | ++I; |
103 | assert(I->value == 101); |
104 | ++I; |
105 | assert(I->value == 42); |
106 | } |
107 | } |
108 | { |
109 | using T = EmplaceConstructible<int>; |
110 | using It = cpp17_input_iterator<int*>; |
111 | { |
112 | std::list<T> v(It(arr1), It(std::end(arr1))); |
113 | auto I = v.begin(); |
114 | assert(I->value == 42); |
115 | } |
116 | { |
117 | std::list<T> v(It(arr2), It(std::end(arr2))); |
118 | auto I = v.begin(); |
119 | //assert(v[0].copied == 0); |
120 | assert(I->value == 1); |
121 | //assert(v[1].copied == 0); |
122 | ++I; |
123 | assert(I->value == 101); |
124 | ++I; |
125 | assert(I->value == 42); |
126 | } |
127 | } |
128 | #endif |
129 | } |
130 | |
131 | |
132 | |
133 | void test_emplacable_concept_with_alloc() { |
134 | #if TEST_STD_VER >= 11 |
135 | int arr1[] = {42}; |
136 | int arr2[] = {1, 101, 42}; |
137 | { |
138 | using T = EmplaceConstructible<int>; |
139 | using It = random_access_iterator<int*>; |
140 | std::allocator<T> a; |
141 | { |
142 | std::list<T> v(It(arr1), It(std::end(arr1)), a); |
143 | auto I = v.begin(); |
144 | assert(I->value == 42); |
145 | } |
146 | { |
147 | std::list<T> v(It(arr2), It(std::end(arr2)), a); |
148 | auto I = v.begin(); |
149 | assert(I->value == 1); |
150 | ++I; |
151 | assert(I->value == 101); |
152 | ++I; |
153 | assert(I->value == 42); |
154 | } |
155 | } |
156 | { |
157 | using T = EmplaceConstructible<int>; |
158 | using It = cpp17_input_iterator<int*>; |
159 | std::allocator<T> a; |
160 | { |
161 | std::list<T> v(It(arr1), It(std::end(arr1)), a); |
162 | auto I = v.begin(); |
163 | assert(I->value == 42); |
164 | } |
165 | { |
166 | std::list<T> v(It(arr2), It(std::end(arr2)), a); |
167 | auto I = v.begin(); |
168 | //assert(v[0].copied == 0); |
169 | assert(I->value == 1); |
170 | //assert(v[1].copied == 0); |
171 | ++I; |
172 | assert(I->value == 101); |
173 | ++I; |
174 | assert(I->value == 42); |
175 | } |
176 | } |
177 | #endif |
178 | } |
179 | |
180 | void test_ctor_under_alloc() { |
181 | #if TEST_STD_VER >= 11 |
182 | int arr1[] = {42}; |
183 | int arr2[] = {1, 101, 42}; |
184 | { |
185 | using C = TCT::list<>; |
186 | using It = forward_iterator<int*>; |
187 | { |
188 | ExpectConstructGuard<int&> G(1); |
189 | C v(It(arr1), It(std::end(arr1))); |
190 | } |
191 | { |
192 | ExpectConstructGuard<int&> G(3); |
193 | C v(It(arr2), It(std::end(arr2))); |
194 | } |
195 | } |
196 | { |
197 | using C = TCT::list<>; |
198 | using It = cpp17_input_iterator<int*>; |
199 | { |
200 | ExpectConstructGuard<int&> G(1); |
201 | C v(It(arr1), It(std::end(arr1))); |
202 | } |
203 | { |
204 | ExpectConstructGuard<int&> G(3); |
205 | C v(It(arr2), It(std::end(arr2))); |
206 | } |
207 | } |
208 | #endif |
209 | } |
210 | |
211 | void test_ctor_under_alloc_with_alloc() { |
212 | #if TEST_STD_VER >= 11 |
213 | int arr1[] = {42}; |
214 | int arr2[] = {1, 101, 42}; |
215 | { |
216 | using C = TCT::list<>; |
217 | using It = forward_iterator<int*>; |
218 | using Alloc = typename C::allocator_type; |
219 | Alloc a; |
220 | { |
221 | ExpectConstructGuard<int&> G(1); |
222 | C v(It(arr1), It(std::end(arr1)), a); |
223 | } |
224 | { |
225 | ExpectConstructGuard<int&> G(3); |
226 | C v(It(arr2), It(std::end(arr2)), a); |
227 | } |
228 | } |
229 | { |
230 | using C = TCT::list<>; |
231 | using It = cpp17_input_iterator<int*>; |
232 | using Alloc = typename C::allocator_type; |
233 | Alloc a; |
234 | { |
235 | ExpectConstructGuard<int&> G(1); |
236 | C v(It(arr1), It(std::end(arr1)), a); |
237 | } |
238 | { |
239 | ExpectConstructGuard<int&> G(3); |
240 | C v(It(arr2), It(std::end(arr2)), a); |
241 | } |
242 | } |
243 | #endif |
244 | } |
245 | |
246 | |
247 | |
248 | int main(int, char**) { |
249 | basic_test(); |
250 | test_emplacable_concept(); |
251 | test_emplacable_concept_with_alloc(); |
252 | test_ctor_under_alloc(); |
253 | test_ctor_under_alloc_with_alloc(); |
254 | |
255 | return 0; |
256 | } |
257 | |