1 // Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // { dg-do run { target c++20 } }
20 #include <testsuite_hooks.h>
21 #include <testsuite_allocator.h>
23 using test_allocator
= __gnu_test::uneq_allocator
<int>;
30 A(float&) : nargs(1) { }
31 A(int, void*) : nargs(2) { }
33 // These should not be used:
34 A(const test_allocator
& a
);
35 A(float&, const test_allocator
& a
);
36 A(int, void*, const test_allocator
& a
);
39 const int alloc_id
= -1;
41 // std::uses_allocator<A, test_allocator> should be false:
42 using allocator_type
= void*();
47 // This means std::uses_allocator<B, test_allocator> is true:
48 using allocator_type
= test_allocator
;
51 B(float&) : nargs(1) { }
52 B(int, void*) : nargs(2) { }
54 B(std::allocator_arg_t
, const test_allocator
& a
)
55 : nargs(0), alloc_id(a
.get_personality()) { }
56 B(std::allocator_arg_t
, const test_allocator
& a
, float&)
57 : nargs(1), alloc_id(a
.get_personality()) { }
58 B(std::allocator_arg_t
, const test_allocator
& a
, int, void*)
59 : nargs(2), alloc_id(a
.get_personality()) { }
60 B(std::allocator_arg_t
, const test_allocator
& a
, B
&& b
)
61 : nargs(b
.nargs
), alloc_id(a
.get_personality()) { }
63 // These should not be used:
64 B(const test_allocator
&);
65 B(float&, const test_allocator
&, float&);
66 B(int, void*, const test_allocator
&);
67 B(const test_allocator
&, float&);
68 B(const test_allocator
&, int, void*);
70 B(B
&&, const test_allocator
&);
73 const int alloc_id
= -1;
79 C(float&) : nargs(1) { }
80 C(int, void*) : nargs(2) { }
82 C(const test_allocator
& a
)
83 : nargs(0), alloc_id(a
.get_personality()) { }
84 C(float&, const test_allocator
& a
)
85 : nargs(1), alloc_id(a
.get_personality()) { }
86 C(int, void*, const test_allocator
& a
)
87 : nargs(2), alloc_id(a
.get_personality()) { }
88 C(C
&& c
, const test_allocator
& a
)
89 : nargs(c
.nargs
), alloc_id(a
.get_personality()) { }
94 const int alloc_id
= -1;
98 // This means std::uses_allocator<C, test_allocator> is true:
99 template<> struct uses_allocator
<C
, test_allocator
> : std::true_type
{ };
102 test_allocator
alloc1(1);
103 test_allocator
alloc2(2);
108 auto i0
= std::make_obj_using_allocator
<int>(alloc1
, 2);
113 auto a0
= std::make_obj_using_allocator
<A
>(alloc1
);
114 VERIFY( a0
.nargs
== 0 );
115 VERIFY( a0
.alloc_id
== -1 );
116 auto a1
= std::make_obj_using_allocator
<A
>(alloc1
, f
);
117 VERIFY( a1
.nargs
== 1 );
118 VERIFY( a1
.alloc_id
== -1 );
119 auto a2
= std::make_obj_using_allocator
<A
>(alloc1
, 123, nullptr);
120 VERIFY( a2
.nargs
== 2 );
121 VERIFY( a2
.alloc_id
== -1 );
123 auto b0
= std::make_obj_using_allocator
<B
>(alloc1
);
124 VERIFY( b0
.nargs
== 0 );
125 VERIFY( b0
.alloc_id
== 1 );
126 auto b1
= std::make_obj_using_allocator
<B
>(alloc2
, f
);
127 VERIFY( b1
.nargs
== 1 );
128 VERIFY( b1
.alloc_id
== 2 );
129 auto b2
= std::make_obj_using_allocator
<B
>(alloc1
, 123, nullptr);
130 VERIFY( b2
.nargs
== 2 );
131 VERIFY( b2
.alloc_id
== 1 );
133 auto c0
= std::make_obj_using_allocator
<C
>(alloc1
);
134 VERIFY( c0
.nargs
== 0 );
135 VERIFY( c0
.alloc_id
== 1 );
136 auto c1
= std::make_obj_using_allocator
<C
>(alloc2
, f
);
137 VERIFY( c1
.nargs
== 1 );
138 VERIFY( c1
.alloc_id
== 2 );
139 auto c2
= std::make_obj_using_allocator
<C
>(alloc1
, 123, nullptr);
140 VERIFY( c2
.nargs
== 2 );
141 VERIFY( c2
.alloc_id
== 1 );
148 = std::make_obj_using_allocator
<const B
>(alloc1
, 123, nullptr);
149 static_assert( std::is_const_v
<decltype(b
)> );
150 VERIFY( b
.nargs
== 2 );
151 VERIFY( b
.alloc_id
== 1 );
153 decltype(auto) c
= std::make_obj_using_allocator
<const C
>(alloc1
);
154 static_assert( std::is_const_v
<decltype(c
)> );
155 VERIFY( c
.nargs
== 0 );
156 VERIFY( c
.alloc_id
== 1 );
163 decltype(auto) ref
= std::make_obj_using_allocator
<B
&>(alloc1
, b
);
164 static_assert( std::is_same_v
<decltype(ref
), B
&> );
165 VERIFY( &ref
== &b
);
166 VERIFY( ref
.nargs
== 0 );
167 VERIFY( ref
.alloc_id
== -1 );
168 const B
& cref
= std::make_obj_using_allocator
<const B
&>(alloc1
, b
);
169 static_assert( std::is_same_v
<decltype(cref
), const B
&> );
170 VERIFY( &cref
== &b
);
171 VERIFY( cref
.nargs
== 0 );
172 VERIFY( cref
.alloc_id
== -1 );
180 D(std::allocator_arg_t
) { }
181 D(std::allocator_arg_t
, int) { }
183 // These should not be used:
184 D(std::allocator_arg_t
, const test_allocator
&);
185 D(std::allocator_arg_t
, const test_allocator
&, int);
190 D d1
= std::make_obj_using_allocator
<D
>(alloc1
, std::allocator_arg
);
194 using allocator_type
= test_allocator
;
196 E(std::allocator_arg_t
, const test_allocator
&) { }
197 E(std::allocator_arg_t
, int, const test_allocator
&) { }
199 // These should not be used:
200 E(std::allocator_arg_t
);
201 E(std::allocator_arg_t
, int);
206 E e1
= std::make_obj_using_allocator
<E
>(alloc1
, std::allocator_arg
);
207 E e2
= std::make_obj_using_allocator
<E
>(alloc2
, std::allocator_arg
, 2);
214 std::piecewise_construct_t p
;
217 std::tuple
<float&> t1(f
);
218 std::tuple
<int, void*> t2
{};
220 auto aa00
= std::make_obj_using_allocator
<pair
<A
, A
>>(alloc1
, p
, t0
, t0
);
221 VERIFY( aa00
.first
.nargs
== 0 );
222 VERIFY( aa00
.first
.alloc_id
== -1 );
223 VERIFY( aa00
.second
.nargs
== 0 );
224 VERIFY( aa00
.second
.alloc_id
== -1 );
225 auto ab00
= std::make_obj_using_allocator
<pair
<A
, B
>>(alloc1
, p
, t0
, t0
);
226 VERIFY( ab00
.first
.nargs
== 0 );
227 VERIFY( ab00
.first
.alloc_id
== -1 );
228 VERIFY( ab00
.second
.nargs
== 0 );
229 VERIFY( ab00
.second
.alloc_id
== 1 );
230 auto bc00
= std::make_obj_using_allocator
<pair
<B
, C
>>(alloc2
, p
, t0
, t0
);
231 VERIFY( bc00
.first
.nargs
== 0 );
232 VERIFY( bc00
.first
.alloc_id
== 2 );
233 VERIFY( bc00
.second
.nargs
== 0 );
234 VERIFY( bc00
.second
.alloc_id
== 2 );
235 auto cb00
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
, p
, t0
, t0
);
236 VERIFY( cb00
.first
.nargs
== 0 );
237 VERIFY( cb00
.first
.alloc_id
== 2 );
238 VERIFY( cb00
.second
.nargs
== 0 );
239 VERIFY( cb00
.second
.alloc_id
== 2 );
241 = std::make_obj_using_allocator
<pair
<C
, const C
>>(alloc1
, p
, t0
, t0
);
242 VERIFY( cc00
.first
.nargs
== 0 );
243 VERIFY( cc00
.first
.alloc_id
== 1 );
244 VERIFY( cc00
.second
.nargs
== 0 );
245 VERIFY( cc00
.second
.alloc_id
== 1 );
247 auto aa21
= std::make_obj_using_allocator
<pair
<A
, A
>>(alloc1
, p
, t2
, t1
);
248 VERIFY( aa21
.first
.nargs
== 2 );
249 VERIFY( aa21
.first
.alloc_id
== -1 );
250 VERIFY( aa21
.second
.nargs
== 1 );
251 VERIFY( aa21
.second
.alloc_id
== -1 );
252 auto ab21
= std::make_obj_using_allocator
<pair
<A
, B
>>(alloc1
, p
, t2
, t1
);
253 VERIFY( ab21
.first
.nargs
== 2 );
254 VERIFY( ab21
.first
.alloc_id
== -1 );
255 VERIFY( ab21
.second
.nargs
== 1 );
256 VERIFY( ab21
.second
.alloc_id
== 1 );
257 auto bc11
= std::make_obj_using_allocator
<pair
<B
, C
>>(alloc2
, p
, t1
, t1
);
258 VERIFY( bc11
.first
.nargs
== 1 );
259 VERIFY( bc11
.first
.alloc_id
== 2 );
260 VERIFY( bc11
.second
.nargs
== 1 );
261 VERIFY( bc11
.second
.alloc_id
== 2 );
262 auto cb12
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
, p
, t1
, t2
);
263 VERIFY( cb12
.first
.nargs
== 1 );
264 VERIFY( cb12
.first
.alloc_id
== 2 );
265 VERIFY( cb12
.second
.nargs
== 2 );
266 VERIFY( cb12
.second
.alloc_id
== 2 );
268 = std::make_obj_using_allocator
<pair
<C
, const C
>>(alloc1
, p
, t2
, t1
);
269 VERIFY( cc22
.first
.nargs
== 2 );
270 VERIFY( cc22
.first
.alloc_id
== 1 );
271 VERIFY( cc22
.second
.nargs
== 1 );
272 VERIFY( cc22
.second
.alloc_id
== 1 );
281 auto aa00
= std::make_obj_using_allocator
<pair
<A
, A
>>(alloc1
);
282 VERIFY( aa00
.first
.nargs
== 0 );
283 VERIFY( aa00
.first
.alloc_id
== -1 );
284 VERIFY( aa00
.second
.nargs
== 0 );
285 VERIFY( aa00
.second
.alloc_id
== -1 );
286 auto ab00
= std::make_obj_using_allocator
<pair
<A
, B
>>(alloc1
);
287 VERIFY( ab00
.first
.nargs
== 0 );
288 VERIFY( ab00
.first
.alloc_id
== -1 );
289 VERIFY( ab00
.second
.nargs
== 0 );
290 VERIFY( ab00
.second
.alloc_id
== 1 );
291 auto bc00
= std::make_obj_using_allocator
<pair
<B
, C
>>(alloc2
);
292 VERIFY( bc00
.first
.nargs
== 0 );
293 VERIFY( bc00
.first
.alloc_id
== 2 );
294 VERIFY( bc00
.second
.nargs
== 0 );
295 VERIFY( bc00
.second
.alloc_id
== 2 );
296 auto cb00
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
);
297 VERIFY( cb00
.first
.nargs
== 0 );
298 VERIFY( cb00
.first
.alloc_id
== 2 );
299 VERIFY( cb00
.second
.nargs
== 0 );
300 VERIFY( cb00
.second
.alloc_id
== 2 );
301 auto cc00
= std::make_obj_using_allocator
<pair
<C
, const C
>>(alloc1
);
302 VERIFY( cc00
.first
.nargs
== 0 );
303 VERIFY( cc00
.first
.alloc_id
== 1 );
304 VERIFY( cc00
.second
.nargs
== 0 );
305 VERIFY( cc00
.second
.alloc_id
== 1 );
307 auto aa11
= std::make_obj_using_allocator
<pair
<A
, A
>>(alloc1
, f
, f
);
308 VERIFY( aa11
.first
.nargs
== 1 );
309 VERIFY( aa11
.first
.alloc_id
== -1 );
310 VERIFY( aa11
.second
.nargs
== 1 );
311 VERIFY( aa11
.second
.alloc_id
== -1 );
312 auto aba1
= std::make_obj_using_allocator
<pair
<A
, B
>>(alloc1
, A
{}, f
);
313 VERIFY( aba1
.first
.nargs
== 0 );
314 VERIFY( aba1
.first
.alloc_id
== -1 );
315 VERIFY( aba1
.second
.nargs
== 1 );
316 VERIFY( aba1
.second
.alloc_id
== 1 );
317 auto bc11
= std::make_obj_using_allocator
<pair
<B
, C
>>(alloc2
, f
, f
);
318 VERIFY( bc11
.first
.nargs
== 1 );
319 VERIFY( bc11
.first
.alloc_id
== 2 );
320 VERIFY( bc11
.second
.nargs
== 1 );
321 VERIFY( bc11
.second
.alloc_id
== 2 );
322 auto cb1b
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
, f
, B
{});
323 VERIFY( cb1b
.first
.nargs
== 1 );
324 VERIFY( cb1b
.first
.alloc_id
== 2 );
325 VERIFY( cb1b
.second
.nargs
== 0 );
326 VERIFY( cb1b
.second
.alloc_id
== 2 );
328 = std::make_obj_using_allocator
<pair
<C
, const C
>>(alloc1
, C
{}, C
{});
329 VERIFY( cccc
.first
.nargs
== 0 );
330 VERIFY( cccc
.first
.alloc_id
== 1 );
331 VERIFY( cccc
.second
.nargs
== 0 );
332 VERIFY( cccc
.second
.alloc_id
== 1 );
334 pair
<float&, A
> p1a(f
, A
{});
335 pair
<float&, float&> p11(f
, f
);
336 auto aa1a
= std::make_obj_using_allocator
<pair
<A
, A
>>(alloc1
, p1a
);
337 VERIFY( aa1a
.first
.nargs
== 1 );
338 VERIFY( aa1a
.first
.alloc_id
== -1 );
339 VERIFY( aa1a
.second
.nargs
== 0 );
340 VERIFY( aa1a
.second
.alloc_id
== -1 );
341 auto ab11
= std::make_obj_using_allocator
<pair
<A
, B
>>(alloc1
, p11
);
342 VERIFY( ab11
.first
.nargs
== 1 );
343 VERIFY( ab11
.first
.alloc_id
== -1 );
344 VERIFY( ab11
.second
.nargs
== 1 );
345 VERIFY( ab11
.second
.alloc_id
== 1 );
346 auto cb11
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
, p11
);
347 VERIFY( cb11
.first
.nargs
== 1 );
348 VERIFY( cb11
.first
.alloc_id
== 2 );
349 VERIFY( cb11
.second
.nargs
== 1 );
350 VERIFY( cb11
.second
.alloc_id
== 2 );
352 auto bcbc
= std::make_obj_using_allocator
<pair
<B
, C
>>(alloc2
, pair
<B
, C
>());
353 VERIFY( bcbc
.first
.nargs
== 0 );
354 VERIFY( bcbc
.first
.alloc_id
== 2 );
355 VERIFY( bcbc
.second
.nargs
== 0 );
356 VERIFY( bcbc
.second
.alloc_id
== 2 );
358 auto cc11
= std::make_obj_using_allocator
<pair
<C
, B
>>(alloc2
, std::move(p11
));
359 VERIFY( cc11
.first
.nargs
== 1 );
360 VERIFY( cc11
.first
.alloc_id
== 2 );
361 VERIFY( cc11
.second
.nargs
== 1 );
362 VERIFY( cc11
.second
.alloc_id
== 2 );
368 using nested_pair
= std::pair
<const std::pair
<B
, const B
>, C
>;
369 auto p
= std::make_obj_using_allocator
<const nested_pair
>(alloc1
);
370 VERIFY( p
.first
.first
.alloc_id
== 1 );
371 VERIFY( p
.first
.second
.alloc_id
== 1 );
372 VERIFY( p
.second
.alloc_id
== 1 );
379 // P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct()
382 using allocator_type
= std::allocator
<X
>;
383 X(std::allocator_arg_t
, allocator_type
&&) { }
384 X(const allocator_type
&) { }
388 std::make_obj_using_allocator
<X
>(a
);
394 // PR libstdc++/104542 - missing constexpr
395 std::allocator
<void> a
;
396 int i
= std::make_obj_using_allocator
<int>(a
, 1);
399 using allocator_type
= std::allocator
<long>;
400 constexpr X(std::allocator_arg_t
, std::allocator
<int>, int i
) : i(i
+1) { }
404 X x
= std::make_obj_using_allocator
<X
>(a
, i
);
407 using allocator_type
= std::allocator
<char>;
408 constexpr Y(X x
, std::allocator
<int>) : i(x
.i
+1) { }
412 Y y
= std::make_obj_using_allocator
<Y
>(a
, x
);
417 static_assert( test_pr104542() );