1 // Copyright (C) 2016-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 <memory_resource>
23 #include <testsuite_hooks.h>
24 #include <testsuite_allocator.h>
27 do_not_copy() = default;
28 do_not_copy(const do_not_copy
&) { throw 1; }
38 using pair
= std::pair
<X
, int>;
39 std::pmr::polymorphic_allocator
<pair
> a
;
40 auto ptr
= a
.allocate(1);
41 a
.construct(ptr
, std::piecewise_construct
,
42 std::tuple
<do_not_copy
>{}, std::make_tuple(1));
50 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
51 X(do_not_copy
&&, const allocator_type
&) { }
54 using pair
= std::pair
<X
, int>;
55 std::pmr::polymorphic_allocator
<pair
> a
;
56 auto ptr
= a
.allocate(1);
57 a
.construct(ptr
, std::piecewise_construct
,
58 std::tuple
<do_not_copy
>{}, std::make_tuple(1));
66 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
67 X(std::allocator_arg_t
, const allocator_type
&, do_not_copy
&&) { }
70 using pair
= std::pair
<X
, int>;
71 std::pmr::polymorphic_allocator
<pair
> a
;
72 auto ptr
= a
.allocate(1);
73 a
.construct(ptr
, std::piecewise_construct
,
74 std::tuple
<do_not_copy
>{}, std::make_tuple(1));
83 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
85 X(const X
&) { throw 1; }
86 X(const X
&, const allocator_type
&) { }
91 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
94 Y(std::allocator_arg_t
, const allocator_type
&, const Y
&) { }
97 using pair_type
= std::pair
<X
, Y
>;
98 std::pmr::polymorphic_allocator
<pair_type
> a
;
99 auto ptr
= a
.allocate(1);
100 /* not const */ pair_type p
;
101 a
.construct(ptr
, p
); // LWG 2975
102 a
.deallocate(ptr
, 1);
109 using allocator_type
= std::pmr::polymorphic_allocator
<char>;
111 X(int, const allocator_type
&) { }
113 std::pmr::polymorphic_allocator
<X
> a
;
114 auto ptr
= a
.allocate(1);
116 a
.deallocate(ptr
, 1);
119 // P0591R4 makes uses-allocator construction apply recursively for nested pairs
125 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
127 X(const X
&) { throw 1; }
128 X(const X
&, const allocator_type
& a
) : mr(a
.resource()) { }
130 std::pmr::memory_resource
* mr
= nullptr;
135 using allocator_type
= std::pmr::polymorphic_allocator
<int>;
137 Y(const Y
&) = delete;
138 Y(std::allocator_arg_t
, const allocator_type
& a
, const Y
&)
139 : mr(a
.resource()) { }
141 std::pmr::memory_resource
* mr
= nullptr;
144 using value_type
= std::pair
<std::pair
<X
, int>, std::pair
<int, Y
>>;
145 __gnu_test::memory_resource mr
;
146 std::pmr::polymorphic_allocator
<int> a(&mr
);
147 std::pmr::vector
<value_type
> v(a
);
148 VERIFY( v
.get_allocator().resource() == &mr
);
151 val
.first
.second
= 2;
152 val
.second
.first
= 3;
154 X
& x
= v
.back().first
.first
;
155 VERIFY( x
.mr
!= val
.first
.first
.mr
);
156 VERIFY( x
.mr
== &mr
);
158 Y
& y
= v
.back().second
.second
;
159 VERIFY( y
.mr
!= val
.second
.second
.mr
);
160 VERIFY( y
.mr
== &mr
);
162 // Check other members of the pairs are correctly initialized too:
163 VERIFY( v
.back().first
.second
== val
.first
.second
);
164 VERIFY( v
.back().second
.first
== val
.second
.first
);