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: with_system_cxx_lib=macosx10.12 && !no-exceptions
14 // XFAIL: with_system_cxx_lib=macosx10.11 && !no-exceptions
15 // XFAIL: with_system_cxx_lib=macosx10.10 && !no-exceptions
16 // XFAIL: with_system_cxx_lib=macosx10.9 && !no-exceptions
17 
18 // <variant>
19 
20 // template <class ...Types> class variant;
21 
22 // constexpr variant() noexcept(see below);
23 
24 #include <cassert>
25 #include <type_traits>
26 #include <variant>
27 
28 #include "test_macros.h"
29 #include "variant_test_helpers.h"
30 
31 struct NonDefaultConstructible {
NonDefaultConstructibleNonDefaultConstructible32   constexpr NonDefaultConstructible(int) {}
33 };
34 
35 struct NotNoexcept {
NotNoexceptNotNoexcept36   NotNoexcept() noexcept(false) {}
37 };
38 
39 #ifndef TEST_HAS_NO_EXCEPTIONS
40 struct DefaultCtorThrows {
DefaultCtorThrowsDefaultCtorThrows41   DefaultCtorThrows() { throw 42; }
42 };
43 #endif
44 
test_default_ctor_sfinae()45 void test_default_ctor_sfinae() {
46   {
47     using V = std::variant<std::monostate, int>;
48     static_assert(std::is_default_constructible<V>::value, "");
49   }
50   {
51     using V = std::variant<NonDefaultConstructible, int>;
52     static_assert(!std::is_default_constructible<V>::value, "");
53   }
54 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
55   {
56     using V = std::variant<int &, int>;
57     static_assert(!std::is_default_constructible<V>::value, "");
58   }
59 #endif
60 }
61 
test_default_ctor_noexcept()62 void test_default_ctor_noexcept() {
63   {
64     using V = std::variant<int>;
65     static_assert(std::is_nothrow_default_constructible<V>::value, "");
66   }
67   {
68     using V = std::variant<NotNoexcept>;
69     static_assert(!std::is_nothrow_default_constructible<V>::value, "");
70   }
71 }
72 
test_default_ctor_throws()73 void test_default_ctor_throws() {
74 #ifndef TEST_HAS_NO_EXCEPTIONS
75   using V = std::variant<DefaultCtorThrows, int>;
76   try {
77     V v;
78     assert(false);
79   } catch (const int &ex) {
80     assert(ex == 42);
81   } catch (...) {
82     assert(false);
83   }
84 #endif
85 }
86 
test_default_ctor_basic()87 void test_default_ctor_basic() {
88   {
89     std::variant<int> v;
90     assert(v.index() == 0);
91     assert(std::get<0>(v) == 0);
92   }
93   {
94     std::variant<int, long> v;
95     assert(v.index() == 0);
96     assert(std::get<0>(v) == 0);
97   }
98   {
99     std::variant<int, NonDefaultConstructible> v;
100     assert(v.index() == 0);
101     assert(std::get<0>(v) == 0);
102   }
103   {
104     using V = std::variant<int, long>;
105     constexpr V v;
106     static_assert(v.index() == 0, "");
107     static_assert(std::get<0>(v) == 0, "");
108   }
109   {
110     using V = std::variant<int, long>;
111     constexpr V v;
112     static_assert(v.index() == 0, "");
113     static_assert(std::get<0>(v) == 0, "");
114   }
115   {
116     using V = std::variant<int, NonDefaultConstructible>;
117     constexpr V v;
118     static_assert(v.index() == 0, "");
119     static_assert(std::get<0>(v) == 0, "");
120   }
121 }
122 
main(int,char **)123 int main(int, char**) {
124   test_default_ctor_basic();
125   test_default_ctor_sfinae();
126   test_default_ctor_noexcept();
127   test_default_ctor_throws();
128 
129   return 0;
130 }
131