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 InputIter> vector(InputIter first, InputIter last,
12// const allocator_type& a);
13
14#include <vector>
15#include <cassert>
16#include <cstddef>
17
18#include "test_macros.h"
19#include "test_iterators.h"
20#include "test_allocator.h"
21#include "min_allocator.h"
22#include "asan_testing.h"
23#if TEST_STD_VER >= 11
24# include "emplace_constructible.h"
25# include "container_test_types.h"
26#endif
27
28template <class C, class Iterator, class A>
29TEST_CONSTEXPR_CXX20 void test(Iterator first, Iterator last, const A& a) {
30 C c(first, last, a);
31 LIBCPP_ASSERT(c.__invariants());
32 assert(c.size() == static_cast<std::size_t>(std::distance(first, last)));
33 LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
34 for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first)
35 assert(*i == *first);
36}
37
38#if TEST_STD_VER >= 11
39
40template <class T>
41struct implicit_conv_allocator : min_allocator<T> {
42 TEST_CONSTEXPR implicit_conv_allocator(void*) {}
43 TEST_CONSTEXPR implicit_conv_allocator(const implicit_conv_allocator&) = default;
44
45 template <class U>
46 TEST_CONSTEXPR implicit_conv_allocator(implicit_conv_allocator<U>) {}
47};
48
49#endif
50
51TEST_CONSTEXPR_CXX20 void basic_tests() {
52 {
53 int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
54 int* an = a + sizeof(a) / sizeof(a[0]);
55 std::allocator<int> alloc;
56 test<std::vector<int> >(cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(an), alloc);
57 test<std::vector<int> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an), alloc);
58 test<std::vector<int> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an), alloc);
59 test<std::vector<int> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc);
60 test<std::vector<int> >(a, an, alloc);
61 }
62#if TEST_STD_VER >= 11
63 {
64 int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
65 int* an = a + sizeof(a) / sizeof(a[0]);
66 min_allocator<int> alloc;
67 test<std::vector<int, min_allocator<int> > >(
68 cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(an), alloc);
69 test<std::vector<int, min_allocator<int> > >(
70 forward_iterator<const int*>(a), forward_iterator<const int*>(an), alloc);
71 test<std::vector<int, min_allocator<int> > >(
72 bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an), alloc);
73 test<std::vector<int, min_allocator<int> > >(
74 random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc);
75 test<std::vector<int, min_allocator<int> > >(a, an, alloc);
76 test<std::vector<int, implicit_conv_allocator<int> > >(a, an, nullptr);
77 }
78 {
79 int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
80 int* an = a + sizeof(a) / sizeof(a[0]);
81 safe_allocator<int> alloc;
82 test<std::vector<int, safe_allocator<int> > >(
83 cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(an), alloc);
84 test<std::vector<int, safe_allocator<int> > >(
85 forward_iterator<const int*>(a), forward_iterator<const int*>(an), alloc);
86 test<std::vector<int, safe_allocator<int> > >(
87 bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an), alloc);
88 test<std::vector<int, safe_allocator<int> > >(
89 random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc);
90 test<std::vector<int, safe_allocator<int> > >(a, an, alloc);
91 }
92
93 // Regression test for https://github.com/llvm/llvm-project/issues/46841
94 {
95 min_allocator<int> alloc;
96 std::vector<int, min_allocator<int> > v1({}, forward_iterator<const int*>{}, alloc);
97 std::vector<int, min_allocator<int> > v2(forward_iterator<const int*>{}, {}, alloc);
98 }
99#endif
100}
101
102TEST_CONSTEXPR_CXX20 void emplaceable_concept_tests() {
103#if TEST_STD_VER >= 11
104 int arr1[] = {42};
105 int arr2[] = {1, 101, 42};
106 {
107 using T = EmplaceConstructible<int>;
108 using It = forward_iterator<int*>;
109 using Alloc = std::allocator<T>;
110 Alloc a;
111 {
112 std::vector<T> v(It(arr1), It(std::end(arr1)), a);
113 assert(v[0].value == 42);
114 }
115 {
116 std::vector<T> v(It(arr2), It(std::end(arr2)), a);
117 assert(v[0].value == 1);
118 assert(v[1].value == 101);
119 assert(v[2].value == 42);
120 }
121 }
122 {
123 using T = EmplaceConstructibleAndMoveInsertable<int>;
124 using It = cpp17_input_iterator<int*>;
125 using Alloc = std::allocator<T>;
126 Alloc a;
127 {
128 std::vector<T> v(It(arr1), It(std::end(arr1)), a);
129 assert(v[0].copied == 0);
130 assert(v[0].value == 42);
131 }
132 {
133 std::vector<T> v(It(arr2), It(std::end(arr2)), a);
134 assert(v[0].value == 1);
135 assert(v[1].value == 101);
136 assert(v[2].copied == 0);
137 assert(v[2].value == 42);
138 }
139 }
140#endif
141}
142
143void test_ctor_under_alloc() {
144#if TEST_STD_VER >= 11
145 int arr1[] = {42};
146 int arr2[] = {1, 101, 42};
147 {
148 using C = TCT::vector<>;
149 using It = forward_iterator<int*>;
150 using Alloc = typename C::allocator_type;
151 Alloc a;
152 {
153 ExpectConstructGuard<int&> G(1);
154 C v(It(arr1), It(std::end(arr1)), a);
155 }
156 {
157 ExpectConstructGuard<int&> G(3);
158 C v(It(arr2), It(std::end(arr2)), a);
159 }
160 }
161 {
162 using C = TCT::vector<>;
163 using It = cpp17_input_iterator<int*>;
164 using Alloc = typename C::allocator_type;
165 Alloc a;
166 {
167 ExpectConstructGuard<int&> G(1);
168 C v(It(arr1), It(std::end(arr1)), a);
169 }
170 {
171 //ExpectConstructGuard<int&> G(3);
172 //C v(It(arr2), It(std::end(arr2)), a);
173 }
174 }
175#endif
176}
177
178TEST_CONSTEXPR_CXX20 bool test() {
179 basic_tests();
180 emplaceable_concept_tests(); // See PR34898
181
182 return true;
183}
184
185int main(int, char**) {
186 test();
187#if TEST_STD_VER > 17
188 static_assert(test());
189#endif
190 test_ctor_under_alloc();
191
192 return 0;
193}
194

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