1 // { dg-do run { target c++17 } }
2 // { dg-require-effective-target std_allocator_new }
3 // { dg-xfail-run-if "AIX operator new" { powerpc-ibm-aix* } }
5 // Copyright (C) 2021-2025 Free Software Foundation, Inc.
7 // This file is part of the GNU ISO C++ Library. This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License along
19 // with this library; see the file COPYING3. If not see
20 // <http://www.gnu.org/licenses/>.
24 #include <string_view>
26 #include <unordered_set>
29 #include <testsuite_hooks.h>
30 #include <replacement_memory_operators.h>
32 static constexpr std::initializer_list
<const char*> lst
=
33 { "long_str_for_dynamic_allocation" };
38 __gnu_test::counter::reset();
39 std::unordered_set
<std::string
> us
;
40 us
.insert(lst
.begin(), lst
.end());
41 VERIFY( us
.size() == 1 );
43 VERIFY( __gnu_test::counter::count() == 3 );
44 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
46 us
.insert(lst
.begin(), lst
.end());
47 VERIFY( us
.size() == 1 );
49 VERIFY( __gnu_test::counter::count() == 3 );
50 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
56 __gnu_test::counter::reset();
57 std::unordered_set
<std::string
,
58 std::hash
<std::string_view
>,
59 std::equal_to
<std::string_view
>> us
;
60 us
.insert(lst
.begin(), lst
.end());
61 VERIFY( us
.size() == 1 );
63 VERIFY( __gnu_test::counter::count() == 3 );
64 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
66 us
.insert(lst
.begin(), lst
.end());
67 VERIFY( us
.size() == 1 );
69 VERIFY( __gnu_test::counter::count() == 3 );
70 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
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_set
<std::string
,
88 std::equal_to
<std::string
>> us(0, hasher
);
89 us
.insert(lst
.begin(), lst
.end());
90 VERIFY( us
.size() == 1 );
92 VERIFY( __gnu_test::counter::count() == 3 );
93 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
95 us
.insert(lst
.begin(), lst
.end());
96 VERIFY( us
.size() == 1 );
98 VERIFY( __gnu_test::counter::count() == 3 );
99 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
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_set
<std::string
,
117 std::equal_to
<std::string_view
>> us(0, hasher
);
118 us
.insert(lst
.begin(), lst
.end());
119 VERIFY( us
.size() == 1 );
121 VERIFY( __gnu_test::counter::count() == 3 );
122 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
124 us
.insert(lst
.begin(), lst
.end());
125 VERIFY( us
.size() == 1 );
127 VERIFY( __gnu_test::counter::count() == 3 );
128 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
131 struct hash_string_functor
134 operator()(const std::string
& str
) const noexcept
136 std::hash
<std::string
> h
;
144 __gnu_test::counter::reset();
145 std::unordered_set
<std::string
,
147 std::equal_to
<std::string
>> us
;
148 us
.insert(lst
.begin(), lst
.end());
149 VERIFY( us
.size() == 1 );
151 VERIFY( __gnu_test::counter::count() == 3 );
152 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
154 us
.insert(lst
.begin(), lst
.end());
155 VERIFY( us
.size() == 1 );
157 VERIFY( __gnu_test::counter::count() == 3 );
158 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
161 struct hash_string_view_noexcept_functor
164 operator()(const std::string_view
& str
) const noexcept
166 std::hash
<std::string_view
> h
;
174 __gnu_test::counter::reset();
175 std::unordered_set
<std::string
,
176 hash_string_view_noexcept_functor
,
177 std::equal_to
<std::string_view
>> us
;
178 us
.insert(lst
.begin(), lst
.end());
179 VERIFY( us
.size() == 1 );
181 VERIFY( __gnu_test::counter::count() == 3 );
182 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
184 us
.insert(lst
.begin(), lst
.end());
185 VERIFY( us
.size() == 1 );
187 VERIFY( __gnu_test::counter::count() == 3 );
188 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
191 struct hash_string_view_functor
194 operator()(const std::string_view
& str
) const
196 std::hash
<std::string_view
> h
;
204 __gnu_test::counter::reset();
205 std::unordered_set
<std::string
,
206 hash_string_view_functor
,
207 std::equal_to
<std::string_view
>> us
;
208 us
.insert(lst
.begin(), lst
.end());
209 VERIFY( us
.size() == 1 );
211 VERIFY( __gnu_test::counter::count() == 3 );
212 VERIFY( __gnu_test::counter::get()._M_increments
== 3 );
214 us
.insert(lst
.begin(), lst
.end());
215 VERIFY( us
.size() == 1 );
217 VERIFY( __gnu_test::counter::count() == 3 );
218 VERIFY( __gnu_test::counter::get()._M_increments
== 5 );
224 std::vector
<std::string
> v
;
225 v
.insert(v
.end(), lst
.begin(), lst
.end());
227 const auto origin
= __gnu_test::counter::count();
230 __gnu_test::counter::reset();
231 std::unordered_set
<std::string
,
232 std::hash
<std::string_view
>,
233 std::equal_to
<std::string_view
>> us
;
234 us
.insert(v
.begin(), v
.end());
235 VERIFY( us
.size() == 1 );
237 // Allocate array of buckets, a node, and the std::string (unless COW).
238 constexpr std::size_t increments
= _GLIBCXX_USE_CXX11_ABI
? 3 : 2;
240 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
241 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);
243 us
.insert(v
.begin(), v
.end());
244 VERIFY( us
.size() == 1 );
246 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
247 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);
249 VERIFY( __gnu_test::counter::count() == origin
);
252 __gnu_test::counter::reset();
253 std::unordered_set
<std::string
,
254 std::hash
<std::string_view
>,
255 std::equal_to
<std::string_view
>> us
;
256 us
.insert(std::make_move_iterator(v
.begin()),
257 std::make_move_iterator(v
.end()));
258 VERIFY( us
.size() == 1 );
260 // Allocate array of buckets and a node. String is moved.
261 constexpr std::size_t increments
= 2;
263 VERIFY( __gnu_test::counter::count() == origin
+ increments
);
264 VERIFY( __gnu_test::counter::get()._M_increments
== increments
);
271 __gnu_test::counter::scope s
;