]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/polymorphic_allocator/construct_c++2a.cc
dd5b63fbcc1c6853fb64843793c5037bbd9436a9
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / polymorphic_allocator / construct_c++2a.cc
1 // Copyright (C) 2016-2021 Free Software Foundation, Inc.
2 //
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)
7 // any later version.
8
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.
13
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/>.
17
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
20
21 #include <memory_resource>
22 #include <utility>
23 #include <tuple>
24 #include <testsuite_hooks.h>
25 #include <testsuite_allocator.h>
26
27 struct do_not_copy {
28 do_not_copy() = default;
29 do_not_copy(const do_not_copy&) { throw 1; }
30 };
31
32 void
33 test01()
34 {
35 struct X {
36 X(do_not_copy&&) { }
37 };
38
39 using pair = std::pair<X, int>;
40 std::pmr::polymorphic_allocator<pair> a;
41 auto ptr = a.allocate(1);
42 a.construct(ptr, std::piecewise_construct,
43 std::tuple<do_not_copy>{}, std::make_tuple(1));
44 a.deallocate(ptr, 1);
45 }
46
47 void
48 test02()
49 {
50 struct X {
51 using allocator_type = std::pmr::polymorphic_allocator<int>;
52 X(do_not_copy&&, const allocator_type&) { }
53 };
54
55 using pair = std::pair<X, int>;
56 std::pmr::polymorphic_allocator<pair> a;
57 auto ptr = a.allocate(1);
58 a.construct(ptr, std::piecewise_construct,
59 std::tuple<do_not_copy>{}, std::make_tuple(1));
60 a.deallocate(ptr, 1);
61 }
62
63 void
64 test03()
65 {
66 struct X {
67 using allocator_type = std::pmr::polymorphic_allocator<int>;
68 X(std::allocator_arg_t, const allocator_type&, do_not_copy&&) { }
69 };
70
71 using pair = std::pair<X, int>;
72 std::pmr::polymorphic_allocator<pair> a;
73 auto ptr = a.allocate(1);
74 a.construct(ptr, std::piecewise_construct,
75 std::tuple<do_not_copy>{}, std::make_tuple(1));
76 a.deallocate(ptr, 1);
77 }
78
79 void
80 test04()
81 {
82 struct X
83 {
84 using allocator_type = std::pmr::polymorphic_allocator<int>;
85 X() = default;
86 X(const X&) { throw 1; }
87 X(const X&, const allocator_type&) { }
88 };
89
90 struct Y
91 {
92 using allocator_type = std::pmr::polymorphic_allocator<int>;
93 Y() = default;
94 Y(const Y&) = delete;
95 Y(std::allocator_arg_t, const allocator_type&, const Y&) { }
96 };
97
98 using pair_type = std::pair<X, Y>;
99 std::pmr::polymorphic_allocator<pair_type> a;
100 auto ptr = a.allocate(1);
101 /* not const */ pair_type p;
102 a.construct(ptr, p); // LWG 2975
103 a.deallocate(ptr, 1);
104 }
105
106 void
107 test05()
108 {
109 struct X {
110 using allocator_type = std::pmr::polymorphic_allocator<char>;
111 X(int);
112 X(int, const allocator_type&) { }
113 };
114 std::pmr::polymorphic_allocator<X> a;
115 auto ptr = a.allocate(1);
116 a.construct(ptr, 1);
117 a.deallocate(ptr, 1);
118 }
119
120 // P0591R4 makes uses-allocator construction apply recursively for nested pairs
121 void
122 test06()
123 {
124 struct X
125 {
126 using allocator_type = std::pmr::polymorphic_allocator<int>;
127 X() = default;
128 X(const X&) { throw 1; }
129 X(const X&, const allocator_type& a) : mr(a.resource()) { }
130
131 std::pmr::memory_resource* mr = nullptr;
132 };
133
134 struct Y
135 {
136 using allocator_type = std::pmr::polymorphic_allocator<int>;
137 Y() = default;
138 Y(const Y&) = delete;
139 Y(std::allocator_arg_t, const allocator_type& a, const Y&)
140 : mr(a.resource()) { }
141
142 std::pmr::memory_resource* mr = nullptr;
143 };
144
145 using value_type = std::pair<std::pair<X, int>, std::pair<int, Y>>;
146 __gnu_test::memory_resource mr;
147 std::pmr::polymorphic_allocator<int> a(&mr);
148 std::pmr::vector<value_type> v(a);
149 VERIFY( v.get_allocator().resource() == &mr );
150
151 value_type val;
152 val.first.second = 2;
153 val.second.first = 3;
154 v.push_back(val);
155 X& x = v.back().first.first;
156 VERIFY( x.mr != val.first.first.mr );
157 VERIFY( x.mr == &mr );
158
159 Y& y = v.back().second.second;
160 VERIFY( y.mr != val.second.second.mr );
161 VERIFY( y.mr == &mr );
162
163 // Check other members of the pairs are correctly initialized too:
164 VERIFY( v.back().first.second == val.first.second );
165 VERIFY( v.back().second.first == val.second.first );
166 }
167
168 int main()
169 {
170 test01();
171 test02();
172 test03();
173 test04();
174 test05();
175 test06();
176 }