]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / tuple / cons / allocators.cc
1 // { dg-do run { target c++11 } }
2 // FIXME [!HOSTED]: avoidable std::allocator usage
3 // { dg-require-effective-target hosted }
4
5 // Copyright (C) 2011-2024 Free Software Foundation, Inc.
6 //
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)
11 // any later version.
12
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.
17
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/>.
21
22 // 20.4.2.1 [tuple.cnstr] Allocator-extended constructors
23
24 #include <memory>
25 #include <tuple>
26 #include <testsuite_hooks.h>
27
28 struct MyAlloc { };
29
30 // type that can't be constructed with an allocator
31 struct CannotUse
32 {
33 CannotUse(int = 0, int = 0) : ok(true) { }
34
35 bool ok;
36 };
37
38 // type that can be constructed with an allocator
39 // but which has uses_allocator == false
40 struct DoesNotUse
41 {
42 typedef MyAlloc allocator_type;
43
44 DoesNotUse(int = 0) : ok(true) { }
45 DoesNotUse(std::allocator_arg_t, MyAlloc, int = 0) : ok(false) { }
46 DoesNotUse(MyAlloc) : ok(false) { }
47 DoesNotUse(int, MyAlloc) : ok(false) { }
48
49 DoesNotUse(const DoesNotUse&) : ok(true) { }
50 DoesNotUse(std::allocator_arg_t, MyAlloc, const DoesNotUse&) : ok(false) { }
51 DoesNotUse(const DoesNotUse&, MyAlloc) : ok(false) { }
52
53 DoesNotUse(DoesNotUse&&) : ok(true) { }
54 DoesNotUse(std::allocator_arg_t, MyAlloc, DoesNotUse&&) : ok(false) { }
55 DoesNotUse(DoesNotUse&&, MyAlloc) : ok(false) { }
56
57 bool ok;
58 };
59
60 namespace std
61 {
62 template<typename A>
63 struct uses_allocator<DoesNotUse, A> : false_type { };
64 }
65
66 // type that can be constructed with an allocator as second argument
67 struct UsesWithTag
68 {
69 typedef MyAlloc allocator_type;
70
71 UsesWithTag(int = 0) : ok(false) { }
72 UsesWithTag(std::allocator_arg_t, MyAlloc, int = 0) : ok(true) { }
73 UsesWithTag(MyAlloc) : ok(false) { }
74 UsesWithTag(int, MyAlloc) : ok(false) { }
75
76 UsesWithTag(const UsesWithTag&) : ok(false) { }
77 UsesWithTag(std::allocator_arg_t, MyAlloc, const UsesWithTag&) : ok(true) { }
78 UsesWithTag(const UsesWithTag&, MyAlloc) : ok(false) { }
79
80 UsesWithTag(UsesWithTag&&) : ok(false) { }
81 UsesWithTag(std::allocator_arg_t, MyAlloc, UsesWithTag&&) : ok(true) { }
82 UsesWithTag(UsesWithTag&&, MyAlloc) : ok(false) { }
83
84 bool ok;
85 };
86
87 // type that can be constructed with an allocator as last argument
88 struct UsesWithoutTag
89 {
90 typedef MyAlloc allocator_type;
91
92 UsesWithoutTag(int = 0) : ok(false) { }
93 UsesWithoutTag(MyAlloc) : ok(true) { }
94 UsesWithoutTag(int, MyAlloc) : ok(true) { }
95
96 UsesWithoutTag(const UsesWithoutTag&) : ok(false) { }
97 UsesWithoutTag(const UsesWithoutTag&, MyAlloc) : ok(true) { }
98
99 UsesWithoutTag(UsesWithoutTag&&) : ok(false) { }
100 UsesWithoutTag(UsesWithoutTag&&, MyAlloc) : ok(true) { }
101
102 bool ok;
103 };
104
105 void test01()
106 {
107 using std::allocator_arg;
108 using std::tuple;
109 using std::make_tuple;
110 using std::get;
111
112 typedef CannotUse T1;
113 typedef DoesNotUse T2;
114 typedef UsesWithTag T3;
115 typedef UsesWithoutTag T4;
116 typedef tuple<T1, T2, T3, T4> test_type;
117
118 MyAlloc a;
119
120 // default construction
121 test_type t1(allocator_arg, a);
122 VERIFY( get<0>(t1).ok );
123 VERIFY( get<1>(t1).ok );
124 VERIFY( get<2>(t1).ok );
125 VERIFY( get<3>(t1).ok );
126
127 // copy construction
128 test_type t2(allocator_arg, a, t1);
129 VERIFY( get<0>(t2).ok );
130 VERIFY( get<1>(t2).ok );
131 VERIFY( get<2>(t2).ok );
132 VERIFY( get<3>(t2).ok );
133
134 // move construction
135 test_type t3(allocator_arg, a, std::move(t1));
136 VERIFY( get<0>(t3).ok );
137 VERIFY( get<1>(t3).ok );
138 VERIFY( get<2>(t3).ok );
139 VERIFY( get<3>(t3).ok );
140
141 // construction from int
142 test_type t4(allocator_arg, a, 1, 2, 3, 4);
143 VERIFY( get<0>(t4).ok );
144 VERIFY( get<1>(t4).ok );
145 VERIFY( get<2>(t4).ok );
146 VERIFY( get<3>(t4).ok );
147
148 auto ints = make_tuple(1, 2, 3, 4);
149
150 // construction from lvalue tuple of ints
151 test_type t5(allocator_arg, a, ints);
152 VERIFY( get<0>(t5).ok );
153 VERIFY( get<1>(t5).ok );
154 VERIFY( get<2>(t5).ok );
155 VERIFY( get<3>(t2).ok );
156
157 // construction from rvalue tuple of ints
158 test_type t6(allocator_arg, a, std::move(ints));
159 VERIFY( get<0>(t6).ok );
160 VERIFY( get<1>(t6).ok );
161 VERIFY( get<2>(t6).ok );
162 VERIFY( get<3>(t6).ok );
163
164 }
165
166 void test02()
167 {
168 using std::allocator_arg;
169 using std::tuple;
170 using std::make_tuple;
171
172 typedef tuple<> test_type;
173
174 MyAlloc a;
175
176 // default construction
177 test_type t1(allocator_arg, a);
178 // copy construction
179 test_type t2(allocator_arg, a, t1);
180 // move construction
181 test_type t3(allocator_arg, a, std::move(t1));
182 // make_tuple
183 test_type empty = make_tuple();
184 }
185
186 void test03()
187 {
188 struct dr2586
189 {
190 using allocator_type = std::allocator<int>;
191 dr2586() { }
192 dr2586(std::allocator_arg_t, allocator_type&&) { }
193 dr2586(const allocator_type&) : expected(true) { }
194 bool expected = false;
195 };
196
197 const dr2586::allocator_type a;
198 std::tuple<dr2586> t{std::allocator_arg, a};
199 VERIFY( std::get<0>(t).expected );
200 }
201
202 void test04()
203 {
204 struct X {
205 X(std::allocator_arg_t) { }
206 };
207
208 // The element types are not default constructible, so the allocator-extended
209 // default constructor should not participate in overload resolution.
210 std::tuple<X, void(&)()> t(std::allocator_arg, *+[]{});
211 }
212
213 int main()
214 {
215 test01();
216 test02();
217 test03();
218 test04();
219 return 0;
220 }