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 
basic_test()25 void basic_test()
26 {
27     {
28         int a[] = {0, 1, 2, 3};
29         std::list<int> l(input_iterator<const int*>(a),
30                          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(input_iterator<const int*>(a),
40                          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(input_iterator<const int*>(a),
52                          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(input_iterator<const int*>(a),
63                          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(input_iterator<const int*>(a),
73                          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 
test_emplacable_concept()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 = 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 
test_emplacable_concept_with_alloc()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 = 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 
test_ctor_under_alloc()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 = 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 
test_ctor_under_alloc_with_alloc()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 = 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 
main(int,char **)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