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// flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare());
14// template<class Alloc>
15// flat_multiset(initializer_list<value_type> il, const Alloc& a);
16// template<class Alloc>
17// flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
18
19#include <algorithm>
20#include <cassert>
21#include <deque>
22#include <flat_set>
23#include <functional>
24#include <type_traits>
25#include <vector>
26#include <ranges>
27
28#include "test_macros.h"
29#include "min_allocator.h"
30#include "test_allocator.h"
31
32#include "../../../test_compare.h"
33
34struct DefaultCtableComp {
35 explicit DefaultCtableComp() { default_constructed_ = true; }
36 bool operator()(int, int) const { return false; }
37 bool default_constructed_ = false;
38};
39
40void test() {
41 {
42 // The constructors in this subclause shall not participate in overload
43 // resolution unless uses_allocator_v<container_type, Alloc> is true.
44
45 using C = test_less<int>;
46 using A1 = test_allocator<int>;
47 using A2 = other_allocator<int>;
48 using V1 = std::vector<int, A1>;
49 using V2 = std::vector<int, A2>;
50 using M1 = std::flat_multiset<int, C, V1>;
51 using M2 = std::flat_multiset<int, C, V2>;
52 using IL = std::initializer_list<int>;
53 static_assert(std::is_constructible_v<M1, IL, const A1&>);
54 static_assert(std::is_constructible_v<M2, IL, const A2&>);
55 static_assert(!std::is_constructible_v<M1, IL, const A2&>);
56 static_assert(!std::is_constructible_v<M2, IL, const A1&>);
57
58 static_assert(std::is_constructible_v<M1, IL, const C&, const A1&>);
59 static_assert(std::is_constructible_v<M2, IL, const C&, const A2&>);
60 static_assert(!std::is_constructible_v<M1, IL, const C&, const A2&>);
61 static_assert(!std::is_constructible_v<M2, IL, const C&, const A1&>);
62 }
63
64 {
65 // initializer_list<value_type> needs to match exactly
66 using M = std::flat_multiset<int>;
67 using C = typename M::key_compare;
68 static_assert(std::is_constructible_v<M, std::initializer_list<int>>);
69 static_assert(std::is_constructible_v<M, std::initializer_list<int>, C>);
70 static_assert(std::is_constructible_v<M, std::initializer_list<int>, C, std::allocator<int>>);
71 static_assert(std::is_constructible_v<M, std::initializer_list<int>, std::allocator<int>>);
72 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>>);
73 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, C>);
74 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, C, std::allocator<int>>);
75 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, std::allocator<int>>);
76 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>>);
77 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, C>);
78 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, C, std::allocator<int>>);
79 static_assert(!std::is_constructible_v<M, std::initializer_list<const int>, std::allocator<int>>);
80 }
81
82 int expected[] = {1, 2, 2, 3, 3, 5};
83 {
84 // flat_multiset(initializer_list<value_type>);
85 using M = std::flat_multiset<int>;
86 std::initializer_list<int> il = {5, 2, 2, 3, 1, 3};
87 M m(il);
88 assert(std::ranges::equal(m, expected));
89 }
90 {
91 // flat_multiset(initializer_list<value_type>);
92 // explicit(false)
93 using M = std::flat_multiset<int>;
94 M m = {5, 2, 2, 3, 1, 3};
95 assert(std::ranges::equal(m, expected));
96 }
97 {
98 // flat_multiset(initializer_list<value_type>);
99 using M = std::flat_multiset<int, std::greater<int>, std::deque<int, min_allocator<int>>>;
100 M m = {5, 2, 2, 3, 1, 3};
101 assert(std::ranges::equal(m, expected | std::views::reverse));
102 }
103 {
104 using A = explicit_allocator<int>;
105 {
106 // flat_multiset(initializer_list<value_type>);
107 // different comparator
108 using M = std::flat_multiset<int, DefaultCtableComp, std::vector<int, A>>;
109 M m = {1, 2, 3};
110 assert(m.size() == 3);
111 LIBCPP_ASSERT(*m.begin() == 1);
112 assert(m.key_comp().default_constructed_);
113 }
114 {
115 // flat_multiset(initializer_list<value_type>, const Allocator&);
116 using M = std::flat_multiset<int, std::greater<int>, std::deque<int, A>>;
117 A a;
118 M m({5, 2, 2, 3, 1, 3}, a);
119 assert(std::ranges::equal(m, expected | std::views::reverse));
120 }
121 }
122 {
123 // flat_multiset(initializer_list<value_type>, const key_compare&);
124 using C = test_less<int>;
125 using M = std::flat_multiset<int, C>;
126 auto m = M({5, 2, 2, 3, 1, 3}, C(10));
127 assert(std::ranges::equal(m, expected));
128 assert(m.key_comp() == C(10));
129
130 // explicit(false)
131 M m2 = {{5, 2, 2, 1, 3, 3}, C(10)};
132 assert(m2 == m);
133 assert(m2.key_comp() == C(10));
134 }
135 {
136 // flat_multiset(initializer_list<value_type>, const key_compare&);
137 // Sorting uses the comparator that was passed in
138 using M = std::flat_multiset<int, std::function<bool(int, int)>, std::deque<int, min_allocator<int>>>;
139 auto m = M({5, 2, 2, 1, 3, 3}, std::greater<int>());
140 assert(std::ranges::equal(m, expected | std::views::reverse));
141 assert(m.key_comp()(2, 1) == true);
142 }
143 {
144 // flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
145 using A = explicit_allocator<int>;
146 using M = std::flat_multiset<int, std::greater<int>, std::deque<int, A>>;
147 A a;
148 M m({5, 2, 2, 3, 1, 3}, {}, a);
149 assert(std::ranges::equal(m, expected | std::views::reverse));
150 }
151}
152
153int main(int, char**) {
154 test();
155
156 return 0;
157}
158

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