1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
12 
13 // <variant>
14 
15 // XFAIL: availability=macosx10.13
16 // XFAIL: availability=macosx10.12
17 // XFAIL: availability=macosx10.11
18 // XFAIL: availability=macosx10.10
19 // XFAIL: availability=macosx10.9
20 // XFAIL: availability=macosx10.8
21 // XFAIL: availability=macosx10.7
22 
23 // template <class ...Types> class variant;
24 
25 // template <class T> constexpr variant(T&&) noexcept(see below);
26 
27 #include <cassert>
28 #include <string>
29 #include <type_traits>
30 #include <variant>
31 
32 #include "test_convertible.hpp"
33 #include "test_macros.h"
34 #include "variant_test_helpers.hpp"
35 
36 struct Dummy {
37   Dummy() = default;
38 };
39 
40 struct ThrowsT {
ThrowsTThrowsT41   ThrowsT(int) noexcept(false) {}
42 };
43 
44 struct NoThrowT {
NoThrowTNoThrowT45   NoThrowT(int) noexcept(true) {}
46 };
47 
AnyConstructibleAnyConstructible48 struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
49 struct NoConstructible { NoConstructible() = delete; };
50 
test_T_ctor_noexcept()51 void test_T_ctor_noexcept() {
52   {
53     using V = std::variant<Dummy, NoThrowT>;
54     static_assert(std::is_nothrow_constructible<V, int>::value, "");
55   }
56   {
57     using V = std::variant<Dummy, ThrowsT>;
58     static_assert(!std::is_nothrow_constructible<V, int>::value, "");
59   }
60 }
61 
test_T_ctor_sfinae()62 void test_T_ctor_sfinae() {
63   {
64     using V = std::variant<long, unsigned>;
65     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
66   }
67   {
68     using V = std::variant<std::string, std::string>;
69     static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
70   }
71   {
72     using V = std::variant<std::string, void *>;
73     static_assert(!std::is_constructible<V, int>::value,
74                   "no matching constructor");
75   }
76   {
77     using V = std::variant<AnyConstructible, NoConstructible>;
78     static_assert(
79         !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
80         "no matching constructor");
81     static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
82                   "no matching constructor");
83   }
84 
85 
86 
87 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
88   {
89     using V = std::variant<int, int &&>;
90     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
91   }
92   {
93     using V = std::variant<int, const int &>;
94     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
95   }
96 #endif
97 }
98 
test_T_ctor_basic()99 void test_T_ctor_basic() {
100   {
101     constexpr std::variant<int> v(42);
102     static_assert(v.index() == 0, "");
103     static_assert(std::get<0>(v) == 42, "");
104   }
105   {
106     constexpr std::variant<int, long> v(42l);
107     static_assert(v.index() == 1, "");
108     static_assert(std::get<1>(v) == 42, "");
109   }
110 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
111   {
112     using V = std::variant<const int &, int &&, long>;
113     static_assert(std::is_convertible<int &, V>::value, "must be implicit");
114     int x = 42;
115     V v(x);
116     assert(v.index() == 0);
117     assert(&std::get<0>(v) == &x);
118   }
119   {
120     using V = std::variant<const int &, int &&, long>;
121     static_assert(std::is_convertible<int, V>::value, "must be implicit");
122     int x = 42;
123     V v(std::move(x));
124     assert(v.index() == 1);
125     assert(&std::get<1>(v) == &x);
126   }
127 #endif
128 }
129 
main()130 int main() {
131   test_T_ctor_basic();
132   test_T_ctor_noexcept();
133   test_T_ctor_sfinae();
134 }
135