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

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