1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++03, c++11, c++14
11 
12 // Throwing bad_variant_access is supported starting in macosx10.13
13 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12}} && !no-exceptions
14 
15 // <variant>
16 
17 // template <class ...Types> class variant;
18 
19 // constexpr variant() noexcept(see below);
20 
21 #include <cassert>
22 #include <type_traits>
23 #include <variant>
24 
25 #include "test_macros.h"
26 #include "variant_test_helpers.h"
27 
28 struct NonDefaultConstructible {
29   constexpr NonDefaultConstructible(int) {}
30 };
31 
32 struct NotNoexcept {
33   NotNoexcept() noexcept(false) {}
34 };
35 
36 #ifndef TEST_HAS_NO_EXCEPTIONS
37 struct DefaultCtorThrows {
38   DefaultCtorThrows() { throw 42; }
39 };
40 #endif
41 
42 void test_default_ctor_sfinae() {
43   {
44     using V = std::variant<std::monostate, int>;
45     static_assert(std::is_default_constructible<V>::value, "");
46   }
47   {
48     using V = std::variant<NonDefaultConstructible, int>;
49     static_assert(!std::is_default_constructible<V>::value, "");
50   }
51 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
52   {
53     using V = std::variant<int &, int>;
54     static_assert(!std::is_default_constructible<V>::value, "");
55   }
56 #endif
57 }
58 
59 void test_default_ctor_noexcept() {
60   {
61     using V = std::variant<int>;
62     static_assert(std::is_nothrow_default_constructible<V>::value, "");
63   }
64   {
65     using V = std::variant<NotNoexcept>;
66     static_assert(!std::is_nothrow_default_constructible<V>::value, "");
67   }
68 }
69 
70 void test_default_ctor_throws() {
71 #ifndef TEST_HAS_NO_EXCEPTIONS
72   using V = std::variant<DefaultCtorThrows, int>;
73   try {
74     V v;
75     assert(false);
76   } catch (const int &ex) {
77     assert(ex == 42);
78   } catch (...) {
79     assert(false);
80   }
81 #endif
82 }
83 
84 void test_default_ctor_basic() {
85   {
86     std::variant<int> v;
87     assert(v.index() == 0);
88     assert(std::get<0>(v) == 0);
89   }
90   {
91     std::variant<int, long> v;
92     assert(v.index() == 0);
93     assert(std::get<0>(v) == 0);
94   }
95   {
96     std::variant<int, NonDefaultConstructible> v;
97     assert(v.index() == 0);
98     assert(std::get<0>(v) == 0);
99   }
100   {
101     using V = std::variant<int, long>;
102     constexpr V v;
103     static_assert(v.index() == 0, "");
104     static_assert(std::get<0>(v) == 0, "");
105   }
106   {
107     using V = std::variant<int, long>;
108     constexpr V v;
109     static_assert(v.index() == 0, "");
110     static_assert(std::get<0>(v) == 0, "");
111   }
112   {
113     using V = std::variant<int, NonDefaultConstructible>;
114     constexpr V v;
115     static_assert(v.index() == 0, "");
116     static_assert(std::get<0>(v) == 0, "");
117   }
118 }
119 
120 int main(int, char**) {
121   test_default_ctor_basic();
122   test_default_ctor_sfinae();
123   test_default_ctor_noexcept();
124   test_default_ctor_throws();
125 
126   return 0;
127 }
128