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