]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 23_containers / unordered_map / 96088.cc
1 // { dg-do run { target c++17 } }
2 // { dg-require-effective-target std_allocator_new }
3
4 // Copyright (C) 2021-2023 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
20
21 // libstdc++/96088
22
23 #include <string_view>
24 #include <string>
25 #include <unordered_map>
26 #include <vector>
27
28 #include <testsuite_hooks.h>
29 #include <replacement_memory_operators.h>
30
31 static constexpr std::initializer_list<std::pair<const char*, int>> lst = {
32 {"long_str_for_dynamic_allocating", 1}
33 };
34
35 void
36 test01()
37 {
38 __gnu_test::counter::reset();
39 std::unordered_map<std::string, int> um;
40 um.insert(lst.begin(), lst.end());
41 VERIFY( um.size() == 1 );
42
43 VERIFY( __gnu_test::counter::count() == 3 );
44 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
45
46 um.insert(lst.begin(), lst.end());
47 VERIFY( um.size() == 1 );
48
49 VERIFY( __gnu_test::counter::count() == 3 );
50 VERIFY( __gnu_test::counter::get()._M_increments == 4 );
51 }
52
53 void
54 test02()
55 {
56 __gnu_test::counter::reset();
57 std::unordered_map<std::string, int,
58 std::hash<std::string_view>,
59 std::equal_to<std::string_view>> um;
60 um.insert(lst.begin(), lst.end());
61 VERIFY( um.size() == 1 );
62
63 VERIFY( __gnu_test::counter::count() == 3 );
64 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
65
66 um.insert(lst.begin(), lst.end());
67 VERIFY( um.size() == 1 );
68
69 VERIFY( __gnu_test::counter::count() == 3 );
70 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
71 }
72
73 std::size_t
74 hash_string_f(const std::string& str) noexcept
75 {
76 std::hash<std::string> h;
77 return h(str);
78 }
79
80 void
81 test11()
82 {
83 typedef std::size_t (*hash_string_t)(const std::string&) noexcept;
84 __gnu_test::counter::reset();
85 hash_string_t hasher = &hash_string_f;
86 std::unordered_map<std::string, int,
87 hash_string_t,
88 std::equal_to<std::string>> um(0, hasher);
89 um.insert(lst.begin(), lst.end());
90 VERIFY( um.size() == 1 );
91
92 VERIFY( __gnu_test::counter::count() == 3 );
93 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
94
95 um.insert(lst.begin(), lst.end());
96 VERIFY( um.size() == 1 );
97
98 VERIFY( __gnu_test::counter::count() == 3 );
99 VERIFY( __gnu_test::counter::get()._M_increments == 4 );
100 }
101
102 std::size_t
103 hash_string_view_f(const std::string_view& str) noexcept
104 {
105 std::hash<std::string_view> h;
106 return h(str);
107 }
108
109 void
110 test12()
111 {
112 typedef std::size_t (*hash_stringview_t) (const std::string_view&) noexcept;
113 __gnu_test::counter::reset();
114 hash_stringview_t hasher = &hash_string_view_f;
115 std::unordered_map<std::string, int, hash_stringview_t,
116 std::equal_to<std::string_view>> um(0, hasher);
117 um.insert(lst.begin(), lst.end());
118 VERIFY( um.size() == 1 );
119
120 VERIFY( __gnu_test::counter::count() == 3 );
121 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
122
123 um.insert(lst.begin(), lst.end());
124 VERIFY( um.size() == 1 );
125
126 VERIFY( __gnu_test::counter::count() == 3 );
127 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
128 }
129
130 struct hash_string_functor
131 {
132 std::size_t
133 operator()(const std::string& str) const noexcept
134 {
135 std::hash<std::string> h;
136 return h(str);
137 }
138 };
139
140 void
141 test21()
142 {
143 __gnu_test::counter::reset();
144 std::unordered_map<std::string, int,
145 hash_string_functor,
146 std::equal_to<std::string>> um;
147 um.insert(lst.begin(), lst.end());
148 VERIFY( um.size() == 1 );
149
150 VERIFY( __gnu_test::counter::count() == 3 );
151 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
152
153 um.insert(lst.begin(), lst.end());
154 VERIFY( um.size() == 1 );
155
156 VERIFY( __gnu_test::counter::count() == 3 );
157 VERIFY( __gnu_test::counter::get()._M_increments == 4 );
158 }
159
160 struct hash_string_view_noexcept_functor
161 {
162 std::size_t
163 operator()(const std::string_view& str) const noexcept
164 {
165 std::hash<std::string_view> h;
166 return h(str);
167 }
168 };
169
170 void
171 test22()
172 {
173 __gnu_test::counter::reset();
174 std::unordered_map<std::string, int,
175 hash_string_view_noexcept_functor,
176 std::equal_to<std::string_view>> um;
177 um.insert(lst.begin(), lst.end());
178 VERIFY( um.size() == 1 );
179
180 VERIFY( __gnu_test::counter::count() == 3 );
181 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
182
183 um.insert(lst.begin(), lst.end());
184 VERIFY( um.size() == 1 );
185
186 VERIFY( __gnu_test::counter::count() == 3 );
187 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
188 }
189
190 struct hash_string_view_functor
191 {
192 std::size_t
193 operator()(const std::string_view& str) const
194 {
195 std::hash<std::string_view> h;
196 return h(str);
197 }
198 };
199
200 void
201 test23()
202 {
203 __gnu_test::counter::reset();
204 std::unordered_map<std::string, int,
205 hash_string_view_functor,
206 std::equal_to<std::string_view>> um;
207 um.insert(lst.begin(), lst.end());
208 VERIFY( um.size() == 1 );
209
210 VERIFY( __gnu_test::counter::count() == 3 );
211 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
212
213 um.insert(lst.begin(), lst.end());
214 VERIFY( um.size() == 1 );
215
216 VERIFY( __gnu_test::counter::count() == 3 );
217 VERIFY( __gnu_test::counter::get()._M_increments == 3 );
218 }
219
220 void
221 test03()
222 {
223 std::vector<std::pair<std::string, int>> v;
224 v.insert(v.end(), lst.begin(), lst.end());
225
226 const auto origin = __gnu_test::counter::count();
227
228 {
229 __gnu_test::counter::reset();
230 std::unordered_map<std::string, int,
231 std::hash<std::string_view>,
232 std::equal_to<std::string_view>> um;
233 um.insert(v.begin(), v.end());
234 VERIFY( um.size() == 1 );
235
236 // Allocate array of buckets, a node, and the std::string (unless COW).
237 constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 3 : 2;
238
239 VERIFY( __gnu_test::counter::count() == origin + increments );
240 VERIFY( __gnu_test::counter::get()._M_increments == increments );
241
242 um.insert(v.begin(), v.end());
243 VERIFY( um.size() == 1 );
244
245 VERIFY( __gnu_test::counter::count() == origin + increments );
246 VERIFY( __gnu_test::counter::get()._M_increments == increments );
247 }
248 VERIFY( __gnu_test::counter::count() == origin );
249
250 {
251 __gnu_test::counter::reset();
252 std::unordered_map<std::string, int,
253 std::hash<std::string_view>,
254 std::equal_to<std::string_view>> um;
255 um.insert(std::make_move_iterator(v.begin()),
256 std::make_move_iterator(v.end()));
257 VERIFY( um.size() == 1 );
258
259 // Allocate array of buckets and a node. String is moved.
260 constexpr std::size_t increments = 2;
261
262 VERIFY( __gnu_test::counter::count() == origin + increments );
263 VERIFY( __gnu_test::counter::get()._M_increments == increments );
264 }
265 }
266
267 int
268 main()
269 {
270 test01();
271 test02();
272 test11();
273 test12();
274 test21();
275 test22();
276 test03();
277 return 0;
278 }