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// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11// <flat_set>
12
13#include <algorithm>
14#include <cassert>
15#include <climits>
16#include <deque>
17#include <initializer_list>
18#include <list>
19#include <flat_set>
20#include <functional>
21#include <ranges>
22#include <type_traits>
23#include <utility>
24#include <vector>
25
26#include "deduction_guides_sfinae_checks.h"
27#include "test_allocator.h"
28
29void test() {
30 {
31 // deduction guide generated from
32 // flat_set(const flat_set&)
33 std::flat_set<long> source = {1, 2};
34 std::flat_set s(source);
35 ASSERT_SAME_TYPE(decltype(s), decltype(source));
36 assert(s == source);
37 }
38 {
39 // deduction guide generated from
40 // flat_set(const flat_set&)
41 std::flat_set<short, std::greater<short>> source = {1, 2};
42 std::flat_set s{source}; // braces instead of parens
43 ASSERT_SAME_TYPE(decltype(s), decltype(source));
44 assert(s == source);
45 }
46 {
47 // deduction guide generated from
48 // flat_set(const flat_set&, const Allocator&)
49 std::flat_set<long, std::greater<long>> source = {1, 2};
50 std::flat_set s(source, std::allocator<int>());
51 ASSERT_SAME_TYPE(decltype(s), decltype(source));
52 assert(s == source);
53 }
54
55 {
56 // various overloads that takes a container
57 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
58 std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42));
59 int expected[] = {1, 2, 3, INT_MAX};
60 {
61 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
62 // flat_set(KeyContainer, Compare = Compare())
63 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
64 std::flat_set s(ks);
65
66 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);
67 assert(std::ranges::equal(s, expected));
68 assert(std::move(s).extract().get_allocator().get_id() == 42);
69 }
70 {
71 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
72 // flat_set(sorted_unique_t, KeyContainer, Compare = Compare())
73 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
74 std::flat_set s(std::sorted_unique, sorted_ks);
75
76 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);
77 assert(std::ranges::equal(s, expected));
78 assert(std::move(s).extract().get_allocator().get_id() == 42);
79 }
80 {
81 // template<class KeyContainer, class Allocator>
82 // flat_set(KeyContainer, Allocator)
83 // -> flat_set<typename KeyContainer::value_type,
84 // less<typename KeyContainer::value_type>, KeyContainer>;
85 std::flat_set s(ks, test_allocator<long>(0, 44));
86
87 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);
88 assert(std::ranges::equal(s, expected));
89 assert(std::move(s).extract().get_allocator().get_id() == 44);
90 }
91 {
92 // template<class KeyContainer, class Allocator>
93 // flat_set(sorted_unique_t, KeyContainer, Allocator)
94 // -> flat_set<typename KeyContainer::value_type,
95 // less<typename KeyContainer::value_type>, KeyContainer>;
96 std::flat_set s(std::sorted_unique, sorted_ks, test_allocator<long>(0, 44));
97
98 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);
99 assert(std::ranges::equal(s, expected));
100 assert(std::move(s).extract().get_allocator().get_id() == 44);
101 }
102 }
103 {
104 // various overloads that takes a container and a comparator
105 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
106 std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42));
107 int expected[] = {INT_MAX, 3, 2, 1};
108 {
109 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
110 // flat_set(KeyContainer, Compare = Compare())
111 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
112 std::flat_set s(ks, std::greater<int>());
113
114 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);
115 assert(std::ranges::equal(s, expected));
116 assert(std::move(s).extract().get_allocator().get_id() == 42);
117 }
118 {
119 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
120 // flat_set(sorted_unique_t, KeyContainer, Compare = Compare())
121 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
122 std::flat_set s(std::sorted_unique, sorted_ks, std::greater<int>());
123
124 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);
125 assert(std::ranges::equal(s, expected));
126 assert(std::move(s).extract().get_allocator().get_id() == 42);
127 }
128 {
129 // template<class KeyContainer, class Compare, class Allocator>
130 // flat_set(KeyContainer, Compare, Allocator)
131 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
132 std::flat_set s(ks, std::greater<int>(), test_allocator<long>(0, 44));
133
134 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);
135 assert(std::ranges::equal(s, expected));
136 assert(std::move(s).extract().get_allocator().get_id() == 44);
137 }
138 {
139 // template<class KeyContainer, class Compare, class Allocator>
140 // flat_set(sorted_unique_t, KeyContainer, Compare, Allocator)
141 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
142 std::flat_set s(std::sorted_unique, sorted_ks, std::greater<int>(), test_allocator<long>(0, 44));
143
144 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);
145 assert(std::ranges::equal(s, expected));
146 assert(std::move(s).extract().get_allocator().get_id() == 44);
147 }
148 }
149 {
150 // overloads that take pair of iterators
151 int arr[] = {1, 2, 1, INT_MAX, 3};
152 int sorted_arr[] = {1, 2, 3, INT_MAX};
153 const int arrc[] = {1, 2, 1, INT_MAX, 3};
154 const int sorted_arrc[] = {1, 2, 3, INT_MAX};
155 {
156 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
157 // flat_set(InputIterator, InputIterator, Compare = Compare())
158 // -> flat_set<iter-value-type<InputIterator>, Compare>;
159 std::flat_set m(std::begin(arr), std::end(arr));
160
161 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
162 assert(std::ranges::equal(m, sorted_arr));
163 }
164 {
165 // const
166 std::flat_set m(std::begin(arrc), std::end(arrc));
167
168 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
169 assert(std::ranges::equal(m, sorted_arr));
170 }
171 {
172 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
173 // flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
174 // -> flat_set<iter-value-type<InputIterator>, Compare>;
175 std::flat_set m(std::sorted_unique, std::begin(sorted_arr), std::end(sorted_arr));
176
177 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
178 assert(std::ranges::equal(m, sorted_arr));
179 }
180 {
181 // const
182 std::flat_set m(std::sorted_unique, std::begin(sorted_arrc), std::end(sorted_arrc));
183
184 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
185 assert(std::ranges::equal(m, sorted_arr));
186 }
187 {
188 // from flat_set::iterator
189 std::flat_set<int> mo;
190 std::flat_set m(mo.begin(), mo.end());
191 ASSERT_SAME_TYPE(decltype(m), decltype(mo));
192 }
193 {
194 // from flat_set::const_iterator
195 std::flat_set<int> mo;
196 std::flat_set m(mo.cbegin(), mo.cend());
197 ASSERT_SAME_TYPE(decltype(m), decltype(mo));
198 }
199 {
200 // This does not deduce to flat_set(InputIterator, InputIterator)
201 // But deduces to flat_set(initializer_list<int*>)
202 std::flat_set s = {arr, arr + 3};
203 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int*>);
204 assert(s.size() == 2);
205 }
206 {
207 // This deduces to flat_set(sorted_unique_t, InputIterator, InputIterator)
208 std::flat_set s{std::sorted_unique, sorted_arr, sorted_arr + 3};
209 static_assert(std::is_same_v<decltype(s), std::flat_set<int>>);
210 assert(s.size() == 3);
211 }
212 }
213 {
214 // overloads that take pair of iterators and comparator
215 int arr[] = {1, 2, 1, INT_MAX, 3};
216 int sorted_arr[] = {INT_MAX, 3, 2, 1};
217 const int arrc[] = {1, 2, 1, INT_MAX, 3};
218 const int sorted_arrc[] = {INT_MAX, 3, 2, 1};
219 using C = std::greater<long>;
220 {
221 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
222 // flat_set(InputIterator, InputIterator, Compare = Compare())
223 // -> flat_set<iter-value-type<InputIterator>, Compare>;
224 std::flat_set m(std::begin(arr), std::end(arr), C());
225
226 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
227 assert(std::ranges::equal(m, sorted_arr));
228 }
229 {
230 // const
231 std::flat_set m(std::begin(arrc), std::end(arrc), C());
232
233 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
234 assert(std::ranges::equal(m, sorted_arr));
235 }
236 {
237 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
238 // flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
239 // -> flat_set<iter-value-type<InputIterator>, Compare>;
240 std::flat_set m(std::sorted_unique, std::begin(sorted_arr), std::end(sorted_arr), C());
241
242 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
243 assert(std::ranges::equal(m, sorted_arr));
244 }
245 {
246 // const
247 std::flat_set m(std::sorted_unique, std::begin(sorted_arrc), std::end(sorted_arrc), C());
248
249 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
250 assert(std::ranges::equal(m, sorted_arr));
251 }
252 {
253 // from flat_set::iterator
254 std::flat_set<int> mo;
255 std::flat_set m(mo.begin(), mo.end(), C());
256 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
257 }
258 {
259 // from flat_set::const_iterator
260 std::flat_set<int> mo;
261 std::flat_set m(mo.cbegin(), mo.cend(), C());
262 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
263 }
264 }
265 {
266 // overloads that take an initializer_list
267 const int sorted_arr[] = {1, 2, 3, INT_MAX};
268 {
269 // template<class Key, class Compare = less<Key>>
270 // flat_set(initializer_list<Key>, Compare = Compare())
271 // -> flat_set<Key, Compare>;
272 std::flat_set m{1, 2, 1, INT_MAX, 3};
273
274 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
275 assert(std::ranges::equal(m, sorted_arr));
276 }
277 {
278 // template<class Key, class Compare = less<Key>>
279 // flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())
280 // -> flat_set<Key, Compare>;
281 std::flat_set m(std::sorted_unique, {1, 2, 3, INT_MAX});
282
283 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);
284 assert(std::ranges::equal(m, sorted_arr));
285 }
286 {
287 // one argument/element of an int -> should be treated as an initializer_list<int>
288 std::flat_set s = {1};
289 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int>);
290 assert(s.size() == 1);
291 }
292 {
293 // two of the flat_sets -> should be treated as an initializer_list<flat_set<int>>
294 using M = std::flat_set<int>;
295 M m;
296 std::flat_set s{m, m}; // flat_set(initializer_list<M>)
297 ASSERT_SAME_TYPE(decltype(s), std::flat_set<M>);
298 assert(s.size() == 1);
299 }
300 }
301 {
302 // overloads that take an initializer_list and a comparator
303 const int sorted_arr[] = {INT_MAX, 3, 2, 1};
304 using C = std::greater<long>;
305 {
306 // template<class Key, class Compare = less<Key>>
307 // flat_set(initializer_list<Key>, Compare = Compare())
308 // -> flat_set<Key, Compare>;
309 std::flat_set m({1, 2, 1, INT_MAX, 3}, C());
310
311 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
312 assert(std::ranges::equal(m, sorted_arr));
313 }
314 {
315 // template<class Key, class Compare = less<Key>>
316 // flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())
317 // -> flat_set<Key, Compare>;
318 std::flat_set m(std::sorted_unique, {INT_MAX, 3, 2, 1}, C());
319
320 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);
321 assert(std::ranges::equal(m, sorted_arr));
322 }
323 }
324 {
325 // from_range without comparator
326 std::list<int> r = {1, 2, 1, INT_MAX, 3};
327 const int expected[] = {1, 2, 3, INT_MAX};
328 {
329 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
330 // class Allocator = allocator<ranges::range_value_t<R>>>
331 // flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
332 // -> flat_set<ranges::range_value_t<R>, Compare,
333 // vector<ranges::range_value_t<R>,
334 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
335 std::flat_set s(std::from_range, r);
336 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>>);
337 assert(std::ranges::equal(s, expected));
338 }
339 {
340 // template<ranges::input_range R, class Allocator>
341 // flat_set(from_range_t, R&&, Allocator)
342 // -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
343 // vector<ranges::range_value_t<R>,
344 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
345 std::flat_set s(std::from_range, r, test_allocator<long>(0, 42));
346 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, std::vector<int, test_allocator<int>>>);
347 assert(std::ranges::equal(s, expected));
348 assert(std::move(s).extract().get_allocator().get_id() == 42);
349 }
350 }
351 {
352 // from_range with comparator
353 std::list<int> r = {1, 2, 1, INT_MAX, 3};
354 const int expected[] = {INT_MAX, 3, 2, 1};
355 {
356 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
357 // class Allocator = allocator<ranges::range_value_t<R>>>
358 // flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
359 // -> flat_set<ranges::range_value_t<R>, Compare,
360 // vector<ranges::range_value_t<R>,
361 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
362 std::flat_set s(std::from_range, r, std::greater<int>());
363 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>>);
364 assert(std::ranges::equal(s, expected));
365 }
366 {
367 // template<ranges::input_range R, class Allocator>
368 // flat_set(from_range_t, R&&, Allocator)
369 // -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
370 // vector<ranges::range_value_t<R>,
371 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
372 std::flat_set s(std::from_range, r, std::greater<int>(), test_allocator<long>(0, 42));
373 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, std::vector<int, test_allocator<int>>>);
374 assert(std::ranges::equal(s, expected));
375 assert(std::move(s).extract().get_allocator().get_id() == 42);
376 }
377 }
378
379 AssociativeContainerDeductionGuidesSfinaeAway<std::flat_set, std::flat_set<int>>();
380}
381
382int main(int, char**) {
383 test();
384
385 return 0;
386}
387

source code of libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/deduct.pass.cpp