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 // template <class ...Types> class variant;
16
17 // template <class T> constexpr variant(T&&) noexcept(see below);
18
19 #include <cassert>
20 #include <string>
21 #include <type_traits>
22 #include <variant>
23
24 #include "test_convertible.hpp"
25 #include "test_macros.h"
26 #include "variant_test_helpers.hpp"
27
28 struct Dummy {
29 Dummy() = default;
30 };
31
32 struct ThrowsT {
ThrowsTThrowsT33 ThrowsT(int) noexcept(false) {}
34 };
35
36 struct NoThrowT {
NoThrowTNoThrowT37 NoThrowT(int) noexcept(true) {}
38 };
39
test_T_ctor_noexcept()40 void test_T_ctor_noexcept() {
41 {
42 using V = std::variant<Dummy, NoThrowT>;
43 static_assert(std::is_nothrow_constructible<V, int>::value, "");
44 }
45 {
46 using V = std::variant<Dummy, ThrowsT>;
47 static_assert(!std::is_nothrow_constructible<V, int>::value, "");
48 }
49 }
50
test_T_ctor_sfinae()51 void test_T_ctor_sfinae() {
52 {
53 using V = std::variant<long, unsigned>;
54 static_assert(!std::is_constructible<V, int>::value, "ambiguous");
55 }
56 {
57 using V = std::variant<std::string, std::string>;
58 static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
59 }
60 {
61 using V = std::variant<std::string, void *>;
62 static_assert(!std::is_constructible<V, int>::value,
63 "no matching constructor");
64 }
65 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
66 {
67 using V = std::variant<int, int &&>;
68 static_assert(!std::is_constructible<V, int>::value, "ambiguous");
69 }
70 {
71 using V = std::variant<int, const int &>;
72 static_assert(!std::is_constructible<V, int>::value, "ambiguous");
73 }
74 #endif
75 }
76
test_T_ctor_basic()77 void test_T_ctor_basic() {
78 {
79 constexpr std::variant<int> v(42);
80 static_assert(v.index() == 0, "");
81 static_assert(std::get<0>(v) == 42, "");
82 }
83 {
84 constexpr std::variant<int, long> v(42l);
85 static_assert(v.index() == 1, "");
86 static_assert(std::get<1>(v) == 42, "");
87 }
88 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
89 {
90 using V = std::variant<const int &, int &&, long>;
91 static_assert(std::is_convertible<int &, V>::value, "must be implicit");
92 int x = 42;
93 V v(x);
94 assert(v.index() == 0);
95 assert(&std::get<0>(v) == &x);
96 }
97 {
98 using V = std::variant<const int &, int &&, long>;
99 static_assert(std::is_convertible<int, V>::value, "must be implicit");
100 int x = 42;
101 V v(std::move(x));
102 assert(v.index() == 1);
103 assert(&std::get<1>(v) == &x);
104 }
105 #endif
106 }
107
main()108 int main() {
109 test_T_ctor_basic();
110 test_T_ctor_noexcept();
111 test_T_ctor_sfinae();
112 }
113