]> 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
3 // Copyright (C) 2011-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
19
20 // 20.4.2.1 [tuple.cnstr] Allocator-extended constructors
21
22 #include <memory>
23 #include <tuple>
24 #include <testsuite_hooks.h>
25
26 struct MyAlloc { };
27
28 // type that can't be constructed with an allocator
29 struct CannotUse
30 {
31 CannotUse(int = 0, int = 0) : ok(true) { }
32
33 bool ok;
34 };
35
36 // type that can be constructed with an allocator
37 // but which has uses_allocator == false
38 struct DoesNotUse
39 {
40 typedef MyAlloc allocator_type;
41
42 DoesNotUse(int = 0) : ok(true) { }
43 DoesNotUse(std::allocator_arg_t, MyAlloc, int = 0) : ok(false) { }
44 DoesNotUse(MyAlloc) : ok(false) { }
45 DoesNotUse(int, MyAlloc) : ok(false) { }
46
47 DoesNotUse(const DoesNotUse&) : ok(true) { }
48 DoesNotUse(std::allocator_arg_t, MyAlloc, const DoesNotUse&) : ok(false) { }
49 DoesNotUse(const DoesNotUse&, MyAlloc) : ok(false) { }
50
51 DoesNotUse(DoesNotUse&&) : ok(true) { }
52 DoesNotUse(std::allocator_arg_t, MyAlloc, DoesNotUse&&) : ok(false) { }
53 DoesNotUse(DoesNotUse&&, MyAlloc) : ok(false) { }
54
55 bool ok;
56 };
57
58 namespace std
59 {
60 template<typename A>
61 struct uses_allocator<DoesNotUse, A> : false_type { };
62 }
63
64 // type that can be constructed with an allocator as second argument
65 struct UsesWithTag
66 {
67 typedef MyAlloc allocator_type;
68
69 UsesWithTag(int = 0) : ok(false) { }
70 UsesWithTag(std::allocator_arg_t, MyAlloc, int = 0) : ok(true) { }
71 UsesWithTag(MyAlloc) : ok(false) { }
72 UsesWithTag(int, MyAlloc) : ok(false) { }
73
74 UsesWithTag(const UsesWithTag&) : ok(false) { }
75 UsesWithTag(std::allocator_arg_t, MyAlloc, const UsesWithTag&) : ok(true) { }
76 UsesWithTag(const UsesWithTag&, MyAlloc) : ok(false) { }
77
78 UsesWithTag(UsesWithTag&&) : ok(false) { }
79 UsesWithTag(std::allocator_arg_t, MyAlloc, UsesWithTag&&) : ok(true) { }
80 UsesWithTag(UsesWithTag&&, MyAlloc) : ok(false) { }
81
82 bool ok;
83 };
84
85 // type that can be constructed with an allocator as last argument
86 struct UsesWithoutTag
87 {
88 typedef MyAlloc allocator_type;
89
90 UsesWithoutTag(int = 0) : ok(false) { }
91 UsesWithoutTag(MyAlloc) : ok(true) { }
92 UsesWithoutTag(int, MyAlloc) : ok(true) { }
93
94 UsesWithoutTag(const UsesWithoutTag&) : ok(false) { }
95 UsesWithoutTag(const UsesWithoutTag&, MyAlloc) : ok(true) { }
96
97 UsesWithoutTag(UsesWithoutTag&&) : ok(false) { }
98 UsesWithoutTag(UsesWithoutTag&&, MyAlloc) : ok(true) { }
99
100 bool ok;
101 };
102
103 void test01()
104 {
105 using std::allocator_arg;
106 using std::tuple;
107 using std::make_tuple;
108 using std::get;
109
110 typedef CannotUse T1;
111 typedef DoesNotUse T2;
112 typedef UsesWithTag T3;
113 typedef UsesWithoutTag T4;
114 typedef tuple<T1, T2, T3, T4> test_type;
115
116 MyAlloc a;
117
118 // default construction
119 test_type t1(allocator_arg, a);
120 VERIFY( get<0>(t1).ok );
121 VERIFY( get<1>(t1).ok );
122 VERIFY( get<2>(t1).ok );
123 VERIFY( get<3>(t1).ok );
124
125 // copy construction
126 test_type t2(allocator_arg, a, t1);
127 VERIFY( get<0>(t2).ok );
128 VERIFY( get<1>(t2).ok );
129 VERIFY( get<2>(t2).ok );
130 VERIFY( get<3>(t2).ok );
131
132 // move construction
133 test_type t3(allocator_arg, a, std::move(t1));
134 VERIFY( get<0>(t3).ok );
135 VERIFY( get<1>(t3).ok );
136 VERIFY( get<2>(t3).ok );
137 VERIFY( get<3>(t3).ok );
138
139 // construction from int
140 test_type t4(allocator_arg, a, 1, 2, 3, 4);
141 VERIFY( get<0>(t4).ok );
142 VERIFY( get<1>(t4).ok );
143 VERIFY( get<2>(t4).ok );
144 VERIFY( get<3>(t4).ok );
145
146 auto ints = make_tuple(1, 2, 3, 4);
147
148 // construction from lvalue tuple of ints
149 test_type t5(allocator_arg, a, ints);
150 VERIFY( get<0>(t5).ok );
151 VERIFY( get<1>(t5).ok );
152 VERIFY( get<2>(t5).ok );
153 VERIFY( get<3>(t2).ok );
154
155 // construction from rvalue tuple of ints
156 test_type t6(allocator_arg, a, std::move(ints));
157 VERIFY( get<0>(t6).ok );
158 VERIFY( get<1>(t6).ok );
159 VERIFY( get<2>(t6).ok );
160 VERIFY( get<3>(t6).ok );
161
162 }
163
164 void test02()
165 {
166 using std::allocator_arg;
167 using std::tuple;
168 using std::make_tuple;
169
170 typedef tuple<> test_type;
171
172 MyAlloc a;
173
174 // default construction
175 test_type t1(allocator_arg, a);
176 // copy construction
177 test_type t2(allocator_arg, a, t1);
178 // move construction
179 test_type t3(allocator_arg, a, std::move(t1));
180 // make_tuple
181 test_type empty = make_tuple();
182 }
183
184 void test03()
185 {
186 struct dr2586
187 {
188 using allocator_type = std::allocator<int>;
189 dr2586() { }
190 dr2586(std::allocator_arg_t, allocator_type&&) { }
191 dr2586(const allocator_type&) : expected(true) { }
192 bool expected = false;
193 };
194
195 const dr2586::allocator_type a;
196 std::tuple<dr2586> t{std::allocator_arg, a};
197 VERIFY( std::get<0>(t).expected );
198 }
199
200 void test04()
201 {
202 struct X {
203 X(std::allocator_arg_t) { }
204 };
205
206 // The element types are not default constructible, so the allocator-extended
207 // default constructor should not participate in overload resolution.
208 std::tuple<X, void(&)()> t(std::allocator_arg, *+[]{});
209 }
210
211 int main()
212 {
213 test01();
214 test02();
215 test03();
216 test04();
217 return 0;
218 }