PR libstdc++/86874 fix std::variant::swap regression
[official-gcc.git] / libstdc++-v3 / testsuite / 20_util / variant / run.cc
blob614def232dc6ec22ab7d190bb6211f34d55880af
1 // { dg-options "-std=gnu++17" }
2 // { dg-do run }
4 // Copyright (C) 2016-2018 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.
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.
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/>.
21 #include <variant>
22 #include <string>
23 #include <vector>
24 #include <unordered_set>
25 #include <testsuite_hooks.h>
27 using namespace std;
29 struct AlwaysThrow
31 AlwaysThrow() = default;
33 AlwaysThrow(const AlwaysThrow&)
34 { throw nullptr; }
36 AlwaysThrow(AlwaysThrow&&)
37 { throw nullptr; }
39 AlwaysThrow& operator=(const AlwaysThrow&)
41 throw nullptr;
42 return *this;
45 AlwaysThrow& operator=(AlwaysThrow&&)
47 throw nullptr;
48 return *this;
51 bool operator<(const AlwaysThrow&) const { VERIFY(false); }
52 bool operator<=(const AlwaysThrow&) const { VERIFY(false); }
53 bool operator==(const AlwaysThrow&) const { VERIFY(false); }
54 bool operator!=(const AlwaysThrow&) const { VERIFY(false); }
55 bool operator>=(const AlwaysThrow&) const { VERIFY(false); }
56 bool operator>(const AlwaysThrow&) const { VERIFY(false); }
59 void default_ctor()
61 variant<monostate, string> v;
62 VERIFY(holds_alternative<monostate>(v));
65 void copy_ctor()
67 variant<monostate, string> v("a");
68 VERIFY(holds_alternative<string>(v));
69 variant<monostate, string> u(v);
70 VERIFY(holds_alternative<string>(u));
71 VERIFY(get<string>(u) == "a");
74 void move_ctor()
76 variant<monostate, string> v("a");
77 VERIFY(holds_alternative<string>(v));
78 variant<monostate, string> u(std::move(v));
79 VERIFY(holds_alternative<string>(u));
80 VERIFY(get<string>(u) == "a");
81 VERIFY(holds_alternative<string>(v));
84 void arbitrary_ctor()
86 variant<int, string> v("a");
87 VERIFY(holds_alternative<string>(v));
88 VERIFY(get<1>(v) == "a");
91 void copy_assign()
93 variant<monostate, string> v("a");
94 VERIFY(holds_alternative<string>(v));
95 variant<monostate, string> u;
96 u = v;
97 VERIFY(holds_alternative<string>(u));
98 VERIFY(get<string>(u) == "a");
101 void move_assign()
103 variant<monostate, string> v("a");
104 VERIFY(holds_alternative<string>(v));
105 variant<monostate, string> u;
106 u = std::move(v);
107 VERIFY(holds_alternative<string>(u));
108 VERIFY(get<string>(u) == "a");
109 VERIFY(holds_alternative<string>(v));
112 void arbitrary_assign()
114 variant<int, string> v;
115 v = "a";
117 VERIFY(holds_alternative<string>(variant<int, string>("a")));
118 VERIFY(get<1>(v) == "a");
121 void dtor()
123 struct A {
124 A(int& called) : called(called) {}
125 ~A() {
126 called++;
128 int& called;
131 int called = 0;
132 { variant<string, A> a(in_place_index<1>, called); }
133 VERIFY(called == 1);
136 int called = 0;
137 { variant<string, A> a(in_place_index<0>); }
138 VERIFY(called == 0);
142 void in_place_index_ctor()
145 variant<int, string> v(in_place_index<1>, "a");
146 VERIFY(holds_alternative<string>(v));
147 VERIFY(get<1>(v) == "a");
150 variant<int, string> v(in_place_index<1>, {'a', 'b'});
151 VERIFY(holds_alternative<string>(v));
152 VERIFY(get<1>(v) == "ab");
156 void in_place_type_ctor()
159 variant<int, string> v(in_place_type<string>, "a");
160 VERIFY(holds_alternative<string>(v));
161 VERIFY(get<1>(v) == "a");
164 variant<int, string> v(in_place_type<string>, {'a', 'b'});
165 VERIFY(holds_alternative<string>(v));
166 VERIFY(get<1>(v) == "ab");
170 void emplace()
172 variant<int, string> v;
173 v.emplace<0>(1);
174 VERIFY(get<0>(v) == 1);
175 v.emplace<string>("a");
176 VERIFY(get<string>(v) == "a");
177 v.emplace<1>({'a', 'b'});
178 VERIFY(get<1>(v) == "ab");
179 v.emplace<string>({'a', 'c'});
180 VERIFY(get<string>(v) == "ac");
182 variant<int, AlwaysThrow> v;
183 AlwaysThrow a;
184 try { v.emplace<1>(a); } catch (nullptr_t) { }
185 VERIFY(v.valueless_by_exception());
188 variant<int, AlwaysThrow> v;
189 try { v.emplace<1>(AlwaysThrow{}); } catch (nullptr_t) { }
190 VERIFY(v.valueless_by_exception());
192 VERIFY(&v.emplace<0>(1) == &std::get<0>(v));
193 VERIFY(&v.emplace<int>(1) == &std::get<int>(v));
194 VERIFY(&v.emplace<1>("a") == &std::get<1>(v));
195 VERIFY(&v.emplace<string>("a") == &std::get<string>(v));
197 variant<vector<int>> v;
198 VERIFY(&v.emplace<0>({1,2,3}) == &std::get<0>(v));
199 VERIFY(&v.emplace<vector<int>>({1,2,3}) == &std::get<vector<int>>(v));
203 void test_get()
205 VERIFY(get<1>(variant<int, string>("a")) == "a");
206 VERIFY(get<string>(variant<int, string>("a")) == "a");
208 bool caught = false;
212 get<0>(variant<int, string>("a"));
214 catch (const bad_variant_access&)
216 caught = true;
218 VERIFY(caught);
221 bool caught = false;
225 get<int>(variant<int, string>("a"));
227 catch (const bad_variant_access&)
229 caught = true;
231 VERIFY(caught);
235 void test_relational()
237 VERIFY((variant<int, string>(2) < variant<int, string>(3)));
238 VERIFY((variant<int, string>(3) == variant<int, string>(3)));
239 VERIFY((variant<int, string>(3) > variant<int, string>(2)));
240 VERIFY((variant<int, string>(3) <= variant<int, string>(3)));
241 VERIFY((variant<int, string>(2) <= variant<int, string>(3)));
242 VERIFY((variant<int, string>(3) >= variant<int, string>(3)));
243 VERIFY((variant<int, string>(3) >= variant<int, string>(2)));
244 VERIFY((variant<int, string>(2) != variant<int, string>(3)));
246 VERIFY((variant<int, string>(2) < variant<int, string>("a")));
247 VERIFY((variant<string, int>(2) > variant<string, int>("a")));
250 variant<int, AlwaysThrow> v, w;
253 AlwaysThrow a;
254 v = a;
256 catch (nullptr_t) { }
257 VERIFY(v.valueless_by_exception());
258 VERIFY(v < w);
259 VERIFY(v <= w);
260 VERIFY(!(v == w));
261 VERIFY(v != w);
262 VERIFY(w > v);
263 VERIFY(w >= v);
267 void test_swap()
269 variant<int, string> a("a"), b("b");
270 a.swap(b);
271 VERIFY(get<1>(a) == "b");
272 VERIFY(get<1>(b) == "a");
273 swap(a, b);
274 VERIFY(get<1>(a) == "a");
275 VERIFY(get<1>(b) == "b");
278 void test_visit()
281 struct Visitor
283 int operator()(int, float) {
284 return 0;
286 int operator()(int, double) {
287 return 1;
289 int operator()(char, float) {
290 return 2;
292 int operator()(char, double) {
293 return 3;
295 int operator()(int, float) const {
296 return 5;
298 int operator()(int, double) const {
299 return 6;
301 int operator()(char, float) const {
302 return 7;
304 int operator()(char, double) const {
305 return 8;
307 } visitor1;
308 VERIFY(visit(visitor1, variant<int, char>(1), variant<float, double>(1.0f)) == 0);
309 VERIFY(visit(visitor1, variant<int, char>(1), variant<float, double>(1.0)) == 1);
310 VERIFY(visit(visitor1, variant<int, char>('a'), variant<float, double>(1.0f)) == 2);
311 VERIFY(visit(visitor1, variant<int, char>('a'), variant<float, double>(1.0)) == 3);
313 const auto& visitor2 = visitor1;
314 VERIFY(visit(visitor2, variant<int, char>(1), variant<float, double>(1.0f)) == 5);
315 VERIFY(visit(visitor2, variant<int, char>(1), variant<float, double>(1.0)) == 6);
316 VERIFY(visit(visitor2, variant<int, char>('a'), variant<float, double>(1.0f)) == 7);
317 VERIFY(visit(visitor2, variant<int, char>('a'), variant<float, double>(1.0)) == 8);
321 struct Visitor
323 int operator()(int, float) && {
324 return 0;
326 int operator()(int, double) && {
327 return 1;
329 int operator()(char, float) && {
330 return 2;
332 int operator()(char, double) && {
333 return 3;
336 VERIFY(visit(Visitor{}, variant<int, char>(1), variant<float, double>(1.0f)) == 0);
337 VERIFY(visit(Visitor{}, variant<int, char>(1), variant<float, double>(1.0)) == 1);
338 VERIFY(visit(Visitor{}, variant<int, char>('a'), variant<float, double>(1.0f)) == 2);
339 VERIFY(visit(Visitor{}, variant<int, char>('a'), variant<float, double>(1.0)) == 3);
343 void test_hash()
345 unordered_set<variant<int, string>> s;
346 VERIFY(s.emplace(3).second);
347 VERIFY(s.emplace("asdf").second);
348 VERIFY(s.emplace().second);
349 VERIFY(s.size() == 3);
350 VERIFY(!s.emplace(3).second);
351 VERIFY(!s.emplace("asdf").second);
352 VERIFY(!s.emplace().second);
353 VERIFY(s.size() == 3);
355 struct A
357 operator int()
359 throw nullptr;
362 variant<int, string> v;
365 v.emplace<0>(A{});
367 catch (nullptr_t)
370 VERIFY(v.valueless_by_exception());
371 VERIFY(s.insert(v).second);
372 VERIFY(s.size() == 4);
373 VERIFY(!s.insert(v).second);
377 void test_valueless_by_exception()
380 AlwaysThrow a;
381 bool caught = false;
384 variant<int, AlwaysThrow> v(a);
386 catch (nullptr_t)
388 caught = true;
390 VERIFY(caught);
393 AlwaysThrow a;
394 bool caught = false;
397 variant<int, AlwaysThrow> v(a);
399 catch (nullptr_t)
401 caught = true;
403 VERIFY(caught);
406 variant<int, AlwaysThrow> v;
407 bool caught = false;
410 AlwaysThrow a;
411 v = a;
413 catch (nullptr_t)
415 caught = true;
417 VERIFY(caught);
418 VERIFY(v.valueless_by_exception());
421 variant<int, AlwaysThrow> v;
422 bool caught = false;
425 v = AlwaysThrow{};
427 catch (nullptr_t)
429 caught = true;
431 VERIFY(caught);
432 VERIFY(v.valueless_by_exception());
436 int main()
438 default_ctor();
439 copy_ctor();
440 move_ctor();
441 arbitrary_ctor();
442 in_place_index_ctor();
443 in_place_type_ctor();
444 copy_assign();
445 move_assign();
446 arbitrary_assign();
447 dtor();
448 emplace();
449 test_get();
450 test_relational();
451 test_swap();
452 test_visit();
453 test_hash();
454 test_valueless_by_exception();