1 // { dg-do run { target c++17 } }
2 // { dg-require-effective-target std_allocator_new }
4 // Copyright (C) 2021-2023 Free Software Foundation, Inc.
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)
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.
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/>.
23 #include <string_view>
25 #include <unordered_map>
28 #include <testsuite_hooks.h>
29 #include <replacement_memory_operators.h>
31 static constexpr std::initializer_list
<std::pair
<const char*, int>> lst
= {
32 {"long_str_for_dynamic_allocating", 1}
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 );
43 VERIFY( __gnu_test::counter::count() == 3 );
44 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
46 um
.insert(lst
.begin(), lst
.end());
47 VERIFY( um
.size() == 1 );
49 VERIFY( __gnu_test::counter::count() == 3 );
50 VERIFY( __gnu_test::counter::get()._M_increments
== 4 );
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 );
63 VERIFY( __gnu_test::counter::count() == 3 );
64 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
66 um
.insert(lst
.begin(), lst
.end());
67 VERIFY( um
.size() == 1 );
69 VERIFY( __gnu_test::counter::count() == 3 );
70 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
74 hash_string_f(const std::string
& str
) noexcept
76 std::hash
<std::string
> h
;
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,
88 std::equal_to
<std::string
>> um(0, hasher
);
89 um
.insert(lst
.begin(), lst
.end());
90 VERIFY( um
.size() == 1 );
92 VERIFY( __gnu_test::counter::count() == 3 );
93 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
95 um
.insert(lst
.begin(), lst
.end());
96 VERIFY( um
.size() == 1 );
98 VERIFY( __gnu_test::counter::count() == 3 );
99 VERIFY( __gnu_test::counter::get()._M_increments
== 4 );
103 hash_string_view_f(const std::string_view
& str
) noexcept
105 std::hash
<std::string_view
> h
;
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 );
120 VERIFY( __gnu_test::counter::count() == 3 );
121 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
123 um
.insert(lst
.begin(), lst
.end());
124 VERIFY( um
.size() == 1 );
126 VERIFY( __gnu_test::counter::count() == 3 );
127 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
130 struct hash_string_functor
133 operator()(const std::string
& str
) const noexcept
135 std::hash
<std::string
> h
;
143 __gnu_test::counter::reset();
144 std::unordered_map
<std::string
, int,
146 std::equal_to
<std::string
>> um
;
147 um
.insert(lst
.begin(), lst
.end());
148 VERIFY( um
.size() == 1 );
150 VERIFY( __gnu_test::counter::count() == 3 );
151 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
153 um
.insert(lst
.begin(), lst
.end());
154 VERIFY( um
.size() == 1 );
156 VERIFY( __gnu_test::counter::count() == 3 );
157 VERIFY( __gnu_test::counter::get()._M_increments
== 4 );
160 struct hash_string_view_noexcept_functor
163 operator()(const std::string_view
& str
) const noexcept
165 std::hash
<std::string_view
> h
;
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 );
180 VERIFY( __gnu_test::counter::count() == 3 );
181 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
183 um
.insert(lst
.begin(), lst
.end());
184 VERIFY( um
.size() == 1 );
186 VERIFY( __gnu_test::counter::count() == 3 );
187 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
190 struct hash_string_view_functor
193 operator()(const std::string_view
& str
) const
195 std::hash
<std::string_view
> h
;
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 );
210 VERIFY( __gnu_test::counter::count() == 3 );
211 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
213 um
.insert(lst
.begin(), lst
.end());
214 VERIFY( um
.size() == 1 );
216 VERIFY( __gnu_test::counter::count() == 3 );
217 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
223 std::vector
<std::pair
<std::string
, int>> v
;
224 v
.insert(v
.end(), lst
.begin(), lst
.end());
226 const auto origin
= __gnu_test::counter::count();
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 );
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;
239 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
240 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);
242 um
.insert(v
.begin(), v
.end());
243 VERIFY( um
.size() == 1 );
245 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
246 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);
248 VERIFY( __gnu_test::counter::count() == origin
);
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 );
259 // Allocate array of buckets and a node. String is moved.
260 constexpr std::size_t increments
= 2;
262 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
263 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);