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
10
11// <set>
12
13// template<class InputIterator,
14// class Compare = less<iter-value-type<InputIterator>>,
15// class Allocator = allocator<iter-value-type<InputIterator>>>
16// multiset(InputIterator, InputIterator,
17// Compare = Compare(), Allocator = Allocator())
18// -> multiset<iter-value-type<InputIterator>, Compare, Allocator>;
19// template<class Key, class Compare = less<Key>,
20// class Allocator = allocator<Key>>
21// multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
22// -> multiset<Key, Compare, Allocator>;
23// template<class InputIterator, class Allocator>
24// multiset(InputIterator, InputIterator, Allocator)
25// -> multiset<iter-value-type<InputIterator>,
26// less<iter-value-type<InputIterator>>, Allocator>;
27// template<class Key, class Allocator>
28// multiset(initializer_list<Key>, Allocator)
29// -> multiset<Key, less<Key>, Allocator>;
30//
31// template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
32// class Allocator = allocator<ranges::range_value_t<R>>>
33// multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
34// -> multiset<ranges::range_value_t<R>, Compare, Allocator>;
35//
36// template<ranges::input_range R, class Allocator>
37// multiset(from_range_t, R&&, Allocator)
38// -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
39
40#include <algorithm> // std::equal
41#include <array>
42#include <cassert>
43#include <climits> // INT_MAX
44#include <functional>
45#include <set>
46#include <type_traits>
47
48#include "deduction_guides_sfinae_checks.h"
49#include "test_allocator.h"
50
51struct NotAnAllocator {
52 friend bool operator<(NotAnAllocator, NotAnAllocator) { return false; }
53};
54
55int main(int, char**) {
56 {
57 const int arr[] = {1, 2, 1, INT_MAX, 3};
58 std::multiset s(std::begin(arr: arr), std::end(arr: arr));
59
60 ASSERT_SAME_TYPE(decltype(s), std::multiset<int>);
61 const int expected_s[] = {1, 1, 2, 3, INT_MAX};
62 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
63 }
64
65 {
66 const int arr[] = {1, 2, 1, INT_MAX, 3};
67 std::multiset s(std::begin(arr: arr), std::end(arr: arr), std::greater<int>());
68
69 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::greater<int> >);
70 const int expected_s[] = {INT_MAX, 3, 2, 1, 1};
71 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
72 }
73
74 {
75 const int arr[] = {1, 2, 1, INT_MAX, 3};
76 std::multiset s(std::begin(arr: arr), std::end(arr: arr), std::greater<int>(), test_allocator<int>(0, 42));
77
78 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::greater<int>, test_allocator<int> >);
79 const int expected_s[] = {INT_MAX, 3, 2, 1, 1};
80 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
81 assert(s.get_allocator().get_id() == 42);
82 }
83
84 {
85 std::multiset<long> source;
86 std::multiset s(source);
87 ASSERT_SAME_TYPE(decltype(s), std::multiset<long>);
88 assert(s.size() == 0);
89 }
90
91 {
92 std::multiset<long> source;
93 std::multiset s{source}; // braces instead of parens
94 ASSERT_SAME_TYPE(decltype(s), std::multiset<long>);
95 assert(s.size() == 0);
96 }
97
98 {
99 std::multiset<long> source;
100 std::multiset s(source, std::multiset<long>::allocator_type());
101 ASSERT_SAME_TYPE(decltype(s), std::multiset<long>);
102 assert(s.size() == 0);
103 }
104
105 {
106 std::multiset s{1, 2, 1, INT_MAX, 3};
107
108 ASSERT_SAME_TYPE(decltype(s), std::multiset<int>);
109 const int expected_s[] = {1, 1, 2, 3, INT_MAX};
110 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
111 }
112
113 {
114 std::multiset s({1, 2, 1, INT_MAX, 3}, std::greater<int>());
115
116 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::greater<int> >);
117 const int expected_s[] = {INT_MAX, 3, 2, 1, 1};
118 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
119 }
120
121 {
122 std::multiset s({1, 2, 1, INT_MAX, 3}, std::greater<int>(), test_allocator<int>(0, 43));
123
124 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::greater<int>, test_allocator<int> >);
125 const int expected_s[] = {INT_MAX, 3, 2, 1, 1};
126 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
127 assert(s.get_allocator().get_id() == 43);
128 }
129
130 {
131 const int arr[] = {1, 2, 1, INT_MAX, 3};
132 std::multiset s(std::begin(arr: arr), std::end(arr: arr), test_allocator<int>(0, 44));
133
134 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::less<int>, test_allocator<int> >);
135 const int expected_s[] = {1, 1, 2, 3, INT_MAX};
136 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
137 assert(s.get_allocator().get_id() == 44);
138 }
139
140 {
141 std::multiset s({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 45));
142
143 ASSERT_SAME_TYPE(decltype(s), std::multiset<int, std::less<int>, test_allocator<int> >);
144 const int expected_s[] = {1, 1, 2, 3, INT_MAX};
145 assert(std::equal(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
146 assert(s.get_allocator().get_id() == 45);
147 }
148
149 {
150 NotAnAllocator a;
151 std::multiset s{a}; // multiset(initializer_list<NotAnAllocator>)
152 ASSERT_SAME_TYPE(decltype(s), std::multiset<NotAnAllocator>);
153 assert(s.size() == 1);
154 }
155
156 {
157 std::multiset<long> source;
158 std::multiset s{source, source}; // multiset(initializer_list<multiset<long>>)
159 ASSERT_SAME_TYPE(decltype(s), std::multiset<std::multiset<long> >);
160 assert(s.size() == 2);
161 }
162
163 {
164 NotAnAllocator a;
165 std::multiset s{a, a}; // multiset(initializer_list<NotAnAllocator>)
166 ASSERT_SAME_TYPE(decltype(s), std::multiset<NotAnAllocator>);
167 assert(s.size() == 2);
168 }
169
170 {
171 int source[3] = {3, 4, 5};
172 std::multiset s(source, source + 3); // multiset(InputIterator, InputIterator)
173 ASSERT_SAME_TYPE(decltype(s), std::multiset<int>);
174 assert(s.size() == 3);
175 }
176
177 {
178 int source[3] = {3, 4, 5};
179 std::multiset s{source, source + 3}; // multiset(initializer_list<int*>)
180 ASSERT_SAME_TYPE(decltype(s), std::multiset<int*>);
181 assert(s.size() == 2);
182 }
183
184#if TEST_STD_VER >= 23
185 {
186 using Range = std::array<int, 0>;
187 using Comp = std::greater<int>;
188 using DefaultComp = std::less<int>;
189 using Alloc = test_allocator<int>;
190
191 { // (from_range, range)
192 std::multiset c(std::from_range, Range());
193 static_assert(std::is_same_v<decltype(c), std::multiset<int>>);
194 }
195
196 { // (from_range, range, comp)
197 std::multiset c(std::from_range, Range(), Comp());
198 static_assert(std::is_same_v<decltype(c), std::multiset<int, Comp>>);
199 }
200
201 { // (from_range, range, comp, alloc)
202 std::multiset c(std::from_range, Range(), Comp(), Alloc());
203 static_assert(std::is_same_v<decltype(c), std::multiset<int, Comp, Alloc>>);
204 }
205
206 { // (from_range, range, alloc)
207 std::multiset c(std::from_range, Range(), Alloc());
208 static_assert(std::is_same_v<decltype(c), std::multiset<int, DefaultComp, Alloc>>);
209 }
210 }
211#endif
212
213 AssociativeContainerDeductionGuidesSfinaeAway<std::multiset, std::multiset<int>>();
214
215 return 0;
216}
217

source code of libcxx/test/std/containers/associative/multiset/multiset.cons/deduct.pass.cpp