]>
Commit | Line | Data |
---|---|---|
52066eae | 1 | // { dg-do run { target c++11 } } |
7cc9022f AA |
2 | // FIXME [!HOSTED]: avoidable std::allocator usage |
3 | // { dg-require-effective-target hosted } | |
b8214660 | 4 | |
a945c346 | 5 | // Copyright (C) 2011-2024 Free Software Foundation, Inc. |
b8214660 JW |
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 | { | |
b8214660 JW |
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 | ||
dbc6221f VV |
166 | void test02() |
167 | { | |
dbc6221f VV |
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 | ||
b7dbc672 JW |
186 | void test03() |
187 | { | |
188 | struct dr2586 | |
189 | { | |
190 | using allocator_type = std::allocator<int>; | |
d355635e | 191 | dr2586() { } |
b7dbc672 | 192 | dr2586(std::allocator_arg_t, allocator_type&&) { } |
d355635e JW |
193 | dr2586(const allocator_type&) : expected(true) { } |
194 | bool expected = false; | |
b7dbc672 JW |
195 | }; |
196 | ||
197 | const dr2586::allocator_type a; | |
198 | std::tuple<dr2586> t{std::allocator_arg, a}; | |
d355635e JW |
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, *+[]{}); | |
b7dbc672 JW |
211 | } |
212 | ||
b8214660 JW |
213 | int main() |
214 | { | |
215 | test01(); | |
dbc6221f | 216 | test02(); |
b7dbc672 | 217 | test03(); |
d355635e | 218 | test04(); |
b8214660 JW |
219 | return 0; |
220 | } |