]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/optional/77288.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / optional / 77288.cc
1 // { dg-options "-std=gnu++17" }
2 // { dg-do run { target c++17 } }
3
4 // Copyright (C) 2016-2019 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
20
21 #include <optional>
22 #include <any>
23
24 using std::optional;
25
26 #include <testsuite_hooks.h>
27
28 void test01()
29 {
30 optional<optional<int>> nested_element;
31 optional<int> element = {};
32 nested_element = element;
33 VERIFY(nested_element);
34 }
35
36 template <class T>
37 struct service_result
38 {
39 static optional<T> get_result()
40 {
41 T sr;
42 return sr;
43 }
44
45 static optional<T> get_result_with_cond(bool cond)
46 {
47 if (cond)
48 return T{};
49 return {};
50 }
51 };
52
53 void test02()
54 {
55 VERIFY(service_result<int>::get_result());
56 VERIFY(service_result<optional<int>>::get_result());
57 VERIFY(service_result<int>::get_result_with_cond(true));
58 VERIFY(service_result<optional<int>>::get_result_with_cond(true));
59 VERIFY(!service_result<int>::get_result_with_cond(false));
60 VERIFY(!service_result<optional<int>>::get_result_with_cond(false));
61 }
62
63 struct Widget
64 {
65 Widget(int) {}
66 Widget(optional<int>) {}
67 };
68
69
70 void test03()
71 {
72 optional<Widget> w;
73 w = optional<int>();
74 VERIFY(w);
75 static_assert(!std::is_assignable_v<optional<Widget>&,
76 optional<short>>);;
77 w = optional<optional<int>>();
78 VERIFY(!w);
79 static_assert(!std::is_assignable_v<optional<Widget>&,
80 optional<optional<short>>>);;
81
82 optional<Widget> w2{optional<int>()};
83 VERIFY(w2);
84 optional<Widget> w3 = optional<int>();
85 VERIFY(w3);
86 optional<Widget> w4{optional<short>()};
87 VERIFY(w4);
88 static_assert(!std::is_convertible_v<optional<short>&&, optional<Widget>>);
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_v<optional<optional<short>>&&,
97 optional<Widget>>);
98 optional<Widget> w10{optional<optional<short>>(10)};
99 VERIFY(w10);
100 optional<Widget> w11 = std::nullopt;
101 VERIFY(!w11);
102 optional<Widget> w12 = {};
103 VERIFY(!w12);
104 optional<Widget> w13{std::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::nullopt;
132 VERIFY(!w2);
133 optional<Widget2> w3 = {};
134 VERIFY(!w3);
135 optional<Widget2> w4{std::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_v<optional<Thingy>&,
153 optional<int>>);
154 static_assert(std::is_assignable_v<optional<Thingy>&,
155 optional<short>>);
156 static_assert(!std::is_assignable_v<optional<Thingy>&,
157 optional<optional<int>>>);
158 ot = optional<Widget>();
159 VERIFY(!ot);
160 optional<Thingy> ot2{optional<int>()};
161 VERIFY(ot2);
162 static_assert(!std::is_convertible_v<optional<int>&&,
163 optional<Thingy>>);
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_v<optional<optional<int>>&&,
172 optional<Thingy>>);
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_v<optional<Thingy>,
179 optional<optional<short>>>);
180 static_assert(!std::is_convertible_v<optional<optional<short>>,
181 optional<Thingy>>);
182 static_assert(!std::is_assignable_v<optional<Thingy>&,
183 optional<optional<short>>>);
184 optional<Thingy> ot9 = std::nullopt;
185 VERIFY(!ot9);
186 optional<Thingy> ot10 = {};
187 VERIFY(!ot10);
188 optional<Thingy> ot11{std::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_v<optional<RvalueConstructible>&,
206 optional<int>&>);
207 ori = std::move(oi);
208 VERIFY(ori);
209
210 optional<optional<int>> ooi;
211 static_assert(!std::is_assignable_v<optional<RvalueConstructible>&,
212 optional<optional<int>>&>);
213 ori = std::move(ooi);
214 VERIFY(!ori);
215
216 static_assert(!std::is_constructible_v<optional<RvalueConstructible>,
217 optional<int>&>);
218 static_assert(!std::is_convertible_v<optional<int>&,
219 optional<RvalueConstructible>>);
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_v<optional<RvalueConstructible>,
227 optional<optional<int>>&>);
228 static_assert(!std::is_convertible_v<optional<optional<int>>&,
229 optional<RvalueConstructible>>);
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::nullopt;
235 VERIFY(!ori8);
236 optional<RvalueConstructible> ori9 = {};
237 VERIFY(!ori9);
238 optional<RvalueConstructible> ori10{std::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_v<optional<int>,
257 optional<Thingy2>>);
258 optional<Thingy2> ot2{optional<short>{}};
259 VERIFY(ot2);
260 static_assert(!std::is_convertible_v<optional<short>,
261 optional<Thingy2>>);
262 optional<Thingy2> ot3{optional<optional<int>>{}};
263 VERIFY(!ot3);
264 static_assert(!std::is_convertible_v<optional<optional<int>>,
265 optional<Thingy2>>);
266 optional<Thingy2> ot4{optional<optional<short>>{}};
267 VERIFY(!ot4);
268 static_assert(!std::is_convertible_v<optional<optional<short>>,
269 optional<Thingy2>>);
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_v<optional<Thingy2>&,
277 optional<int>>);
278 static_assert(!std::is_assignable_v<optional<Thingy2>&,
279 optional<short>>);
280 static_assert(!std::is_assignable_v<optional<Thingy2>&,
281 optional<optional<int>>>);
282 static_assert(!std::is_assignable_v<optional<Thingy2>&,
283 optional<optional<short>>>);
284 optional<Thingy2> ot7;
285 ot = optional<Widget>();
286 VERIFY(!ot7);
287 optional<Thingy2> ot8 = std::nullopt;
288 VERIFY(!ot8);
289 optional<Thingy2> ot9 = {};
290 VERIFY(!ot9);
291 optional<Thingy2> ot10{std::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_v<Widget, Args&&...>,
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_v<optional<int>,
313 optional<Thingy3>>);
314 optional<Thingy3> ot2{optional<short>{}};
315 VERIFY(ot2);
316 static_assert(!std::is_convertible_v<optional<short>,
317 optional<Thingy3>>);
318 optional<Thingy3> ot3{optional<optional<int>>{}};
319 VERIFY(!ot3);
320 static_assert(!std::is_convertible_v<optional<optional<int>>,
321 optional<Thingy3>>);
322 optional<Thingy3> ot4{optional<optional<short>>{}};
323 VERIFY(!ot4);
324 static_assert(!std::is_convertible_v<optional<optional<short>>,
325 optional<Thingy3>>);
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_v<optional<Thingy3>&,
333 optional<int>>);
334 static_assert(!std::is_assignable_v<optional<Thingy3>&,
335 optional<short>>);
336 static_assert(!std::is_assignable_v<optional<Thingy3>&,
337 optional<optional<int>>>);
338 static_assert(!std::is_assignable_v<optional<Thingy3>&,
339 optional<optional<short>>>);
340 optional<Thingy3> ot7;
341 ot = optional<Widget>();
342 VERIFY(!ot7);
343 optional<Thingy3> ot8 = std::nullopt;
344 VERIFY(!ot8);
345 optional<Thingy3> ot9 = {};
346 VERIFY(!ot9);
347 optional<Thingy3> ot10{std::nullopt};
348 VERIFY(!ot10);
349 optional<Thingy3> ot11;
350 ot11 = {};
351 VERIFY(!ot11);
352 }
353
354 void test09()
355 {
356 std::any a = 42;
357 optional<std::any> oa2 = a;
358 VERIFY(oa2);
359 VERIFY(std::any_cast<int>(*oa2) == 42);
360 optional<std::any> oa3 = oa2;
361 VERIFY(oa3);
362 VERIFY(std::any_cast<int>(*oa3) == 42);
363 optional<std::any> oa4{oa2};
364 VERIFY(oa4);
365 VERIFY(std::any_cast<int>(*oa4) == 42);
366 optional<std::any> oa5(oa2);
367 VERIFY(oa5);
368 VERIFY(std::any_cast<int>(*oa5) == 42);
369 optional<std::any> oa6;
370 VERIFY(!oa6);
371 optional<std::any> oa7 = oa6;
372 VERIFY(!oa7);
373 optional<std::any> oa8{oa6};
374 VERIFY(!oa8);
375 optional<std::any> oa9(oa6);
376 VERIFY(!oa9);
377 }
378
379 void test10()
380 {
381 struct X {};
382 optional<int> oi(std::in_place);
383 oi = {};
384 VERIFY(oi.has_value() == false);
385 optional<X> ot(std::in_place);
386 ot = {};
387 VERIFY(ot.has_value() == false);
388 optional<int> oi2(std::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 }