]>
Commit | Line | Data |
---|---|---|
f11cc050 VV |
1 | // { dg-do run { target c++14 } } |
2 | ||
83ffe9cd | 3 | // Copyright (C) 2016-2023 Free Software Foundation, Inc. |
f11cc050 VV |
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 | ||
c7cbb4da | 16 | // You should have received a copy of the GNU General Public License along |
f11cc050 VV |
17 | // with this library; see the file COPYING3. If not see |
18 | // <http://www.gnu.org/licenses/>. | |
19 | ||
20 | #include <experimental/optional> | |
21 | #include <experimental/any> | |
22 | ||
23 | using std::experimental::optional; | |
24 | ||
25 | #include <testsuite_hooks.h> | |
26 | ||
27 | void test01() | |
28 | { | |
29 | optional<optional<int>> nested_element; | |
30 | optional<int> element = {}; | |
31 | nested_element = element; | |
32 | VERIFY(nested_element); | |
33 | } | |
34 | ||
35 | template <class T> | |
36 | struct service_result | |
37 | { | |
38 | static optional<T> get_result() | |
39 | { | |
40 | T sr; | |
41 | return sr; | |
42 | } | |
43 | ||
44 | static optional<T> get_result_with_cond(bool cond) | |
45 | { | |
46 | if (cond) | |
47 | return T{}; | |
48 | return {}; | |
49 | } | |
50 | }; | |
51 | ||
52 | void test02() | |
53 | { | |
54 | VERIFY(service_result<int>::get_result()); | |
55 | VERIFY(service_result<optional<int>>::get_result()); | |
56 | VERIFY(service_result<int>::get_result_with_cond(true)); | |
57 | VERIFY(service_result<optional<int>>::get_result_with_cond(true)); | |
58 | VERIFY(!service_result<int>::get_result_with_cond(false)); | |
59 | VERIFY(!service_result<optional<int>>::get_result_with_cond(false)); | |
60 | } | |
61 | ||
62 | struct Widget | |
63 | { | |
64 | Widget(int) {} | |
65 | Widget(optional<int>) {} | |
66 | }; | |
67 | ||
68 | ||
69 | void test03() | |
70 | { | |
71 | optional<Widget> w; | |
72 | w = optional<int>(); | |
73 | VERIFY(w); | |
74 | static_assert(!std::is_assignable<optional<Widget>&, | |
75 | optional<short>>::value); | |
76 | w = optional<optional<int>>(); | |
77 | VERIFY(!w); | |
78 | static_assert(!std::is_assignable<optional<Widget>&, | |
79 | optional<optional<short>>>::value); | |
80 | ||
81 | optional<Widget> w2{optional<int>()}; | |
82 | VERIFY(w2); | |
83 | optional<Widget> w3 = optional<int>(); | |
84 | VERIFY(w3); | |
85 | optional<Widget> w4{optional<short>()}; | |
86 | VERIFY(w4); | |
87 | static_assert(!std::is_convertible<optional<short>&&, | |
88 | optional<Widget>>::value); | |
89 | ||
90 | optional<Widget> w6{optional<optional<int>>()}; | |
91 | VERIFY(!w6); | |
92 | optional<Widget> w7 = optional<optional<int>>(); | |
93 | VERIFY(!w7); | |
94 | optional<Widget> w8{optional<optional<short>>()}; | |
95 | VERIFY(!w8); | |
96 | static_assert(!std::is_convertible<optional<optional<short>>&&, | |
97 | optional<Widget>>::value); | |
98 | optional<Widget> w10{optional<optional<short>>(10)}; | |
99 | VERIFY(w10); | |
100 | optional<Widget> w11 = std::experimental::nullopt; | |
101 | VERIFY(!w11); | |
102 | optional<Widget> w12 = {}; | |
103 | VERIFY(!w12); | |
104 | optional<Widget> w13{std::experimental::nullopt}; | |
105 | VERIFY(!w13); | |
106 | optional<Widget> w14; | |
107 | w14 = {}; | |
108 | VERIFY(!w14); | |
109 | } | |
110 | ||
111 | struct Widget2 | |
112 | { | |
113 | Widget2(int) {} | |
114 | Widget2(optional<int>) {} | |
115 | Widget2& operator=(int) {return *this;} | |
116 | Widget2& operator=(optional<int>) {return *this;} | |
117 | }; | |
118 | ||
119 | void test04() | |
120 | { | |
121 | optional<Widget2> w; | |
122 | w = optional<int>(); | |
123 | VERIFY(w); | |
124 | w = optional<short>(); | |
125 | VERIFY(w); | |
126 | w = optional<optional<int>>(); | |
127 | VERIFY(!w); | |
128 | w = optional<optional<short>>(); | |
129 | VERIFY(!w); | |
130 | w = optional<optional<short>>(10); | |
131 | optional<Widget2> w2 = std::experimental::nullopt; | |
132 | VERIFY(!w2); | |
133 | optional<Widget2> w3 = {}; | |
134 | VERIFY(!w3); | |
135 | optional<Widget2> w4{std::experimental::nullopt}; | |
136 | VERIFY(!w4); | |
137 | optional<Widget2> w5; | |
138 | w5 = {}; | |
139 | VERIFY(!w5); | |
140 | } | |
141 | ||
142 | struct Thingy | |
143 | { | |
144 | Thingy(int) {} | |
145 | Thingy(Widget) {} | |
146 | }; | |
147 | ||
148 | void test05() | |
149 | { | |
150 | optional<Thingy> ot; | |
151 | ||
152 | static_assert(!std::is_assignable<optional<Thingy>&, | |
153 | optional<int>>::value); | |
154 | static_assert(std::is_assignable<optional<Thingy>&, | |
155 | optional<short>>::value); | |
156 | static_assert(!std::is_assignable<optional<Thingy>&, | |
157 | optional<optional<int>>>::value); | |
158 | ot = optional<Widget>(); | |
159 | VERIFY(!ot); | |
160 | optional<Thingy> ot2{optional<int>()}; | |
161 | VERIFY(ot2); | |
162 | static_assert(!std::is_convertible<optional<int>&&, | |
163 | optional<Thingy>>::value); | |
164 | optional<Thingy> ot3{optional<short>()}; | |
165 | VERIFY(!ot3); | |
166 | optional<Thingy> ot4 = optional<short>(); | |
167 | VERIFY(!ot4); | |
168 | ||
169 | optional<Thingy> ot5{optional<optional<int>>()}; | |
170 | VERIFY(!ot5); | |
171 | static_assert(!std::is_convertible<optional<optional<int>>&&, | |
172 | optional<Thingy>>::value); | |
173 | ||
174 | optional<Thingy> ot7{optional<Widget>()}; | |
175 | VERIFY(!ot7); | |
176 | optional<Thingy> ot8 = optional<Widget>(); | |
177 | VERIFY(!ot8); | |
178 | static_assert(!std::is_constructible<optional<Thingy>, | |
179 | optional<optional<short>>>::value); | |
180 | static_assert(!std::is_convertible<optional<optional<short>>, | |
181 | optional<Thingy>>::value); | |
182 | static_assert(!std::is_assignable<optional<Thingy>&, | |
183 | optional<optional<short>>>::value); | |
184 | optional<Thingy> ot9 = std::experimental::nullopt; | |
185 | VERIFY(!ot9); | |
186 | optional<Thingy> ot10 = {}; | |
187 | VERIFY(!ot10); | |
188 | optional<Thingy> ot11{std::experimental::nullopt}; | |
189 | VERIFY(!ot11); | |
190 | optional<Thingy> ot12; | |
191 | ot12 = {}; | |
192 | VERIFY(!ot12); | |
193 | } | |
194 | ||
195 | struct RvalueConstructible | |
196 | { | |
197 | RvalueConstructible(int) {} | |
198 | RvalueConstructible(optional<int>&&) {} | |
199 | }; | |
200 | ||
201 | void test06() | |
202 | { | |
203 | optional<int> oi; | |
204 | optional<RvalueConstructible> ori; | |
205 | static_assert(!std::is_assignable<optional<RvalueConstructible>&, | |
206 | optional<int>&>::value); | |
207 | ori = std::move(oi); | |
208 | VERIFY(ori); | |
209 | ||
210 | optional<optional<int>> ooi; | |
211 | static_assert(!std::is_assignable<optional<RvalueConstructible>&, | |
212 | optional<optional<int>>&>::value); | |
213 | ori = std::move(ooi); | |
214 | VERIFY(!ori); | |
215 | ||
216 | static_assert(!std::is_constructible<optional<RvalueConstructible>, | |
217 | optional<int>&>::value); | |
218 | static_assert(!std::is_convertible<optional<int>&, | |
219 | optional<RvalueConstructible>>::value); | |
220 | ||
221 | optional<RvalueConstructible> ori2(std::move(oi)); | |
222 | VERIFY(ori2); | |
223 | optional<RvalueConstructible> ori3 = std::move(oi); | |
224 | VERIFY(ori3); | |
225 | ||
226 | static_assert(!std::is_constructible<optional<RvalueConstructible>, | |
227 | optional<optional<int>>&>::value); | |
228 | static_assert(!std::is_convertible<optional<optional<int>>&, | |
229 | optional<RvalueConstructible>>::value); | |
230 | optional<RvalueConstructible> ori6(std::move(ooi)); | |
231 | VERIFY(!ori6); | |
232 | optional<RvalueConstructible> ori7 = std::move(ooi); | |
233 | VERIFY(!ori7); | |
234 | optional<RvalueConstructible> ori8 = std::experimental::nullopt; | |
235 | VERIFY(!ori8); | |
236 | optional<RvalueConstructible> ori9 = {}; | |
237 | VERIFY(!ori9); | |
238 | optional<RvalueConstructible> ori10{std::experimental::nullopt}; | |
239 | VERIFY(!ori10); | |
240 | optional<RvalueConstructible> ori11; | |
241 | ori11 = {}; | |
242 | VERIFY(!ori11); | |
243 | } | |
244 | ||
245 | struct Thingy2 | |
246 | { | |
247 | Thingy2(int) {} | |
248 | explicit Thingy2(optional<int>) {} | |
249 | Thingy2(Widget) {} | |
250 | }; | |
251 | ||
252 | void test07() | |
253 | { | |
254 | optional<Thingy2> ot{optional<int>{}}; | |
255 | VERIFY(ot); | |
256 | static_assert(!std::is_convertible<optional<int>, | |
257 | optional<Thingy2>>::value); | |
258 | optional<Thingy2> ot2{optional<short>{}}; | |
259 | VERIFY(ot2); | |
260 | static_assert(!std::is_convertible<optional<short>, | |
261 | optional<Thingy2>>::value); | |
262 | optional<Thingy2> ot3{optional<optional<int>>{}}; | |
263 | VERIFY(!ot3); | |
264 | static_assert(!std::is_convertible<optional<optional<int>>, | |
265 | optional<Thingy2>>::value); | |
266 | optional<Thingy2> ot4{optional<optional<short>>{}}; | |
267 | VERIFY(!ot4); | |
268 | static_assert(!std::is_convertible<optional<optional<short>>, | |
269 | optional<Thingy2>>::value); | |
270 | ||
271 | optional<Thingy2> ot5{optional<Widget>{}}; | |
272 | VERIFY(!ot5); | |
273 | optional<Thingy2> ot6 = optional<Widget>(); | |
274 | VERIFY(!ot6); | |
275 | ||
276 | static_assert(!std::is_assignable<optional<Thingy2>&, | |
277 | optional<int>>::value); | |
278 | static_assert(!std::is_assignable<optional<Thingy2>&, | |
279 | optional<short>>::value); | |
280 | static_assert(!std::is_assignable<optional<Thingy2>&, | |
281 | optional<optional<int>>>::value); | |
282 | static_assert(!std::is_assignable<optional<Thingy2>&, | |
283 | optional<optional<short>>>::value); | |
284 | optional<Thingy2> ot7; | |
285 | ot = optional<Widget>(); | |
286 | VERIFY(!ot7); | |
287 | optional<Thingy2> ot8 = std::experimental::nullopt; | |
288 | VERIFY(!ot8); | |
289 | optional<Thingy2> ot9 = {}; | |
290 | VERIFY(!ot9); | |
291 | optional<Thingy2> ot10{std::experimental::nullopt}; | |
292 | VERIFY(!ot10); | |
293 | optional<Thingy2> ot11; | |
294 | ot11 = {}; | |
295 | VERIFY(!ot11); | |
296 | } | |
297 | ||
298 | struct Thingy3 | |
299 | { | |
300 | Thingy3(int) {} | |
301 | template<class... Args, | |
302 | std::enable_if_t<std::is_constructible<Widget, Args&&...>::value, | |
303 | bool> = true> | |
304 | explicit Thingy3(Args&&... args) {} | |
305 | Thingy3(Widget) {} | |
306 | }; | |
307 | ||
308 | void test08() | |
309 | { | |
310 | optional<Thingy3> ot{optional<int>{}}; | |
311 | VERIFY(ot); | |
312 | static_assert(!std::is_convertible<optional<int>, | |
313 | optional<Thingy3>>::value); | |
314 | optional<Thingy3> ot2{optional<short>{}}; | |
315 | VERIFY(ot2); | |
316 | static_assert(!std::is_convertible<optional<short>, | |
317 | optional<Thingy3>>::value); | |
318 | optional<Thingy3> ot3{optional<optional<int>>{}}; | |
319 | VERIFY(!ot3); | |
320 | static_assert(!std::is_convertible<optional<optional<int>>, | |
321 | optional<Thingy3>>::value); | |
322 | optional<Thingy3> ot4{optional<optional<short>>{}}; | |
323 | VERIFY(!ot4); | |
324 | static_assert(!std::is_convertible<optional<optional<short>>, | |
325 | optional<Thingy3>>::value); | |
326 | ||
327 | optional<Thingy3> ot5{optional<Widget>{}}; | |
328 | VERIFY(!ot5); | |
329 | optional<Thingy3> ot6 = optional<Widget>(); | |
330 | VERIFY(!ot6); | |
331 | ||
332 | static_assert(!std::is_assignable<optional<Thingy3>&, | |
333 | optional<int>>::value); | |
334 | static_assert(!std::is_assignable<optional<Thingy3>&, | |
335 | optional<short>>::value); | |
336 | static_assert(!std::is_assignable<optional<Thingy3>&, | |
337 | optional<optional<int>>>::value); | |
338 | static_assert(!std::is_assignable<optional<Thingy3>&, | |
339 | optional<optional<short>>>::value); | |
340 | optional<Thingy3> ot7; | |
341 | ot = optional<Widget>(); | |
342 | VERIFY(!ot7); | |
343 | optional<Thingy3> ot8 = std::experimental::nullopt; | |
344 | VERIFY(!ot8); | |
345 | optional<Thingy3> ot9 = {}; | |
346 | VERIFY(!ot9); | |
347 | optional<Thingy3> ot10{std::experimental::nullopt}; | |
348 | VERIFY(!ot10); | |
349 | optional<Thingy3> ot11; | |
350 | ot11 = {}; | |
351 | VERIFY(!ot11); | |
352 | } | |
353 | ||
354 | void test09() | |
355 | { | |
356 | std::experimental::any a = 42; | |
357 | optional<std::experimental::any> oa2 = a; | |
358 | VERIFY(oa2); | |
359 | VERIFY(std::experimental::any_cast<int>(*oa2) == 42); | |
360 | optional<std::experimental::any> oa3 = oa2; | |
361 | VERIFY(oa3); | |
362 | VERIFY(std::experimental::any_cast<int>(*oa3) == 42); | |
363 | optional<std::experimental::any> oa4{oa2}; | |
364 | VERIFY(oa4); | |
365 | VERIFY(std::experimental::any_cast<int>(*oa4) == 42); | |
366 | optional<std::experimental::any> oa5(oa2); | |
367 | VERIFY(oa5); | |
368 | VERIFY(std::experimental::any_cast<int>(*oa5) == 42); | |
369 | optional<std::experimental::any> oa6; | |
370 | VERIFY(!oa6); | |
371 | optional<std::experimental::any> oa7 = oa6; | |
372 | VERIFY(!oa7); | |
373 | optional<std::experimental::any> oa8{oa6}; | |
374 | VERIFY(!oa8); | |
375 | optional<std::experimental::any> oa9(oa6); | |
376 | VERIFY(!oa9); | |
377 | } | |
378 | ||
379 | void test10() | |
380 | { | |
381 | struct X {}; | |
382 | optional<int> oi(std::experimental::in_place); | |
383 | oi = {}; | |
384 | VERIFY(bool(oi) == false); | |
385 | optional<X> ot(std::experimental::in_place); | |
386 | ot = {}; | |
387 | VERIFY(bool(ot) == false); | |
388 | optional<int> oi2(std::experimental::in_place); | |
389 | short int si = 6; | |
390 | oi2 = si; | |
391 | } | |
392 | ||
393 | int main() | |
394 | { | |
395 | test01(); | |
396 | test02(); | |
397 | test03(); | |
398 | test04(); | |
399 | test05(); | |
400 | test06(); | |
401 | test07(); | |
402 | test08(); | |
403 | test09(); | |
404 | test10(); | |
405 | } |