1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <list>
11
12// template <class InputIterator>
13//   list(InputIterator first, InputIterator last, const Allocator& = Allocator());
14
15#include <list>
16#include <cassert>
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
25void 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
86void 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
133void 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
180void 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 T = typename C::value_type;
187    using It = forward_iterator<int*>;
188    {
189      ExpectConstructGuard<int&> G(1);
190      C v(It(arr1), It(std::end(arr1)));
191    }
192    {
193      ExpectConstructGuard<int&> G(3);
194      C v(It(arr2), It(std::end(arr2)));
195    }
196  }
197  {
198    using C = TCT::list<>;
199    using T = typename C::value_type;
200    using It = input_iterator<int*>;
201    {
202      ExpectConstructGuard<int&> G(1);
203      C v(It(arr1), It(std::end(arr1)));
204    }
205    {
206      ExpectConstructGuard<int&> G(3);
207      C v(It(arr2), It(std::end(arr2)));
208    }
209  }
210#endif
211}
212
213void test_ctor_under_alloc_with_alloc() {
214#if TEST_STD_VER >= 11
215  int arr1[] = {42};
216  int arr2[] = {1, 101, 42};
217  {
218    using C = TCT::list<>;
219    using T = typename C::value_type;
220    using It = forward_iterator<int*>;
221    using Alloc = typename C::allocator_type;
222    Alloc a;
223    {
224      ExpectConstructGuard<int&> G(1);
225      C v(It(arr1), It(std::end(arr1)), a);
226    }
227    {
228      ExpectConstructGuard<int&> G(3);
229      C v(It(arr2), It(std::end(arr2)), a);
230    }
231  }
232  {
233    using C = TCT::list<>;
234    using T = typename C::value_type;
235    using It = input_iterator<int*>;
236    using Alloc = typename C::allocator_type;
237    Alloc a;
238    {
239      ExpectConstructGuard<int&> G(1);
240      C v(It(arr1), It(std::end(arr1)), a);
241    }
242    {
243      ExpectConstructGuard<int&> G(3);
244      C v(It(arr2), It(std::end(arr2)), a);
245    }
246  }
247#endif
248}
249
250
251
252int main() {
253  basic_test();
254  test_emplacable_concept();
255  test_emplacable_concept_with_alloc();
256  test_ctor_under_alloc();
257  test_ctor_under_alloc_with_alloc();
258}
259