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 // <unordered_map>
10 // UNSUPPORTED: c++03, c++11, c++14
11 // UNSUPPORTED: libcpp-no-deduction-guides
12 
13 // template<class InputIterator,
14 //          class Hash = hash<iter-key-type<InputIterator>>,
15 //          class Pred = equal_to<iter-key-type<InputIterator>>,
16 //          class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
17 // unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below,
18 //                    Hash = Hash(), Pred = Pred(), Allocator = Allocator())
19 //   -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred,
20 //                         Allocator>;
21 //
22 // template<class Key, class T, class Hash = hash<Key>,
23 //          class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
24 // unordered_multimap(initializer_list<pair<Key, T>>,
25 //                    typename see below::size_type = see below, Hash = Hash(),
26 //                    Pred = Pred(), Allocator = Allocator())
27 //   -> unordered_multimap<Key, T, Hash, Pred, Allocator>;
28 //
29 // template<class InputIterator, class Allocator>
30 // unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator)
31 //   -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
32 //                         hash<iter-key-type<InputIterator>>,
33 //                         equal_to<iter-key-type<InputIterator>>, Allocator>;
34 //
35 // template<class InputIterator, class Allocator>
36 // unordered_multimap(InputIterator, InputIterator, Allocator)
37 //   -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
38 //                         hash<iter-key-type<InputIterator>>,
39 //                         equal_to<iter-key-type<InputIterator>>, Allocator>;
40 //
41 // template<class InputIterator, class Hash, class Allocator>
42 // unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator)
43 //   -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash,
44 //                         equal_to<iter-key-type<InputIterator>>, Allocator>;
45 //
46 // template<class Key, class T, class Allocator>
47 // unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator)
48 //   -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
49 //
50 // template<class Key, class T, class Allocator>
51 // unordered_multimap(initializer_list<pair<Key, T>>, Allocator)
52 //   -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
53 //
54 // template<class Key, class T, class Hash, class Allocator>
55 // unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Hash,
56 //                    Allocator)
57 //   -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;
58 
59 #include <algorithm> // is_permutation
60 #include <cassert>
61 #include <climits> // INT_MAX
62 #include <type_traits>
63 #include <unordered_map>
64 
65 #include "test_allocator.h"
66 
67 using P = std::pair<int, long>;
68 using PC = std::pair<const int, long>;
69 
main(int,char **)70 int main(int, char**)
71 {
72     const PC expected_m[] = { {1,1}, {1,1}, {2,2}, {3,1}, {INT_MAX,1} };
73 
74     {
75     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
76     std::unordered_multimap m(std::begin(arr), std::end(arr));
77     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>);
78     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
79     }
80 
81     {
82     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
83     std::unordered_multimap m(std::begin(arr), std::end(arr), 42);
84     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>);
85     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
86     }
87 
88     {
89     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
90     std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>());
91     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>>);
92     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
93     }
94 
95     {
96     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
97     std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>());
98     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>);
99     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
100     }
101 
102     {
103     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
104     std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 41));
105     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>);
106     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
107     assert(m.get_allocator().get_id() == 41);
108     }
109 
110     {
111     std::unordered_multimap<int, long> source;
112     std::unordered_multimap m(source);
113     ASSERT_SAME_TYPE(decltype(m), decltype(source));
114     assert(m.size() == 0);
115     }
116 
117     {
118     std::unordered_multimap<int, long> source;
119     std::unordered_multimap m{source};  // braces instead of parens
120     ASSERT_SAME_TYPE(decltype(m), decltype(source));
121     assert(m.size() == 0);
122     }
123 
124     {
125     std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source;
126     test_allocator<PC> a(0, 42);
127     std::unordered_multimap m(source, a);
128     ASSERT_SAME_TYPE(decltype(m), decltype(source));
129     assert(m.get_allocator().get_id() == 42);
130     assert(m.size() == 0);
131     }
132 
133     {
134     std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source;
135     test_allocator<PC> a(0, 43);
136     std::unordered_multimap m{source, a};  // braces instead of parens
137     ASSERT_SAME_TYPE(decltype(m), decltype(source));
138     assert(m.get_allocator().get_id() == 43);
139     assert(m.size() == 0);
140     }
141 
142     {
143     std::unordered_multimap m { P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} };
144     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>);
145     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
146     }
147 
148     {
149     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42);
150     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>);
151     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
152     }
153 
154     {
155     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>());
156     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>>);
157     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
158     }
159 
160     {
161     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>());
162     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>);
163     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
164     }
165 
166     {
167     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 44));
168     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>);
169     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
170     assert(m.get_allocator().get_id() == 44);
171     }
172 
173     {
174     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
175     std::unordered_multimap m(std::begin(arr), std::end(arr), 42, test_allocator<PC>(0, 45));
176     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>);
177     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
178     assert(m.get_allocator().get_id() == 45);
179     }
180 
181     {
182     const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} };
183     std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<PC>(0, 46));
184     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>);
185     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
186     assert(m.get_allocator().get_id() == 46);
187     }
188 
189     {
190     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, test_allocator<PC>(0, 47));
191     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>);
192     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
193     assert(m.get_allocator().get_id() == 47);
194     }
195 
196     {
197     std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), test_allocator<PC>(0, 48));
198     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>);
199     assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
200     assert(m.get_allocator().get_id() == 48);
201     }
202 
203     {
204     // Examples from LWG3025
205     std::unordered_multimap m{std::pair{1, 1}, {2, 2}, {3, 3}};
206     ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, int>);
207 
208     std::unordered_multimap m2{m.begin(), m.end()};
209     ASSERT_SAME_TYPE(decltype(m2), std::unordered_multimap<int, int>);
210     }
211 
212     {
213     // Examples from LWG3531
214     std::unordered_multimap m1{{std::pair{1, 2}, {3, 4}}, 0};
215     ASSERT_SAME_TYPE(decltype(m1), std::unordered_multimap<int, int>);
216 
217     using value_type = std::pair<const int, int>;
218     std::unordered_multimap m2{{value_type{1, 2}, {3, 4}}, 0};
219     ASSERT_SAME_TYPE(decltype(m2), std::unordered_multimap<int, int>);
220     }
221 
222     return 0;
223 }
224