[FMV][GlobalOpt] Enable static resolution of non-FMV callers. (#124314)
[llvm-project.git] / libcxx / test / std / utilities / variant / variant.variant / variant.ctor / T.pass.cpp
blob142da1d820d9a75ad62a489bcc027d8d6441c1b1
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
11 // <variant>
13 // template <class ...Types> class variant;
15 // template <class T> constexpr variant(T&&) noexcept(see below);
17 #include <cassert>
18 #include <string>
19 #include <type_traits>
20 #include <variant>
21 #include <memory>
22 #include <vector>
24 #include "test_macros.h"
25 #include "variant_test_helpers.h"
27 struct Dummy {
28 Dummy() = default;
31 struct ThrowsT {
32 ThrowsT(int) noexcept(false) {}
35 struct NoThrowT {
36 NoThrowT(int) noexcept(true) {}
39 struct AnyConstructible {
40 template <typename T>
41 AnyConstructible(T&&) {}
43 struct NoConstructible {
44 NoConstructible() = delete;
46 template <class T>
47 struct RValueConvertibleFrom {
48 RValueConvertibleFrom(T&&) {}
51 void test_T_ctor_noexcept() {
53 using V = std::variant<Dummy, NoThrowT>;
54 static_assert(std::is_nothrow_constructible<V, int>::value, "");
57 using V = std::variant<Dummy, ThrowsT>;
58 static_assert(!std::is_nothrow_constructible<V, int>::value, "");
62 void test_T_ctor_sfinae() {
64 using V = std::variant<long, long long>;
65 static_assert(!std::is_constructible<V, int>::value, "ambiguous");
68 using V = std::variant<std::string, std::string>;
69 static_assert(!std::is_constructible<V, const char*>::value, "ambiguous");
72 using V = std::variant<std::string, void*>;
73 static_assert(!std::is_constructible<V, int>::value, "no matching constructor");
76 using V = std::variant<std::string, float>;
77 static_assert(!std::is_constructible<V, int>::value, "no matching constructor");
80 using V = std::variant<std::unique_ptr<int>, bool>;
81 static_assert(!std::is_constructible<V, std::unique_ptr<char>>::value, "no explicit bool in constructor");
82 struct X {
83 operator void*();
85 static_assert(!std::is_constructible<V, X>::value, "no boolean conversion in constructor");
86 static_assert(std::is_constructible<V, std::false_type>::value, "converted to bool in constructor");
89 struct X {};
90 struct Y {
91 operator X();
93 using V = std::variant<X>;
94 static_assert(std::is_constructible<V, Y>::value, "regression on user-defined conversions in constructor");
97 using V = std::variant<AnyConstructible, NoConstructible>;
98 static_assert(!std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value, "no matching constructor");
99 static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value, "no matching constructor");
103 void test_T_ctor_basic() {
105 constexpr std::variant<int> v(42);
106 static_assert(v.index() == 0, "");
107 static_assert(std::get<0>(v) == 42, "");
110 constexpr std::variant<int, long> v(42l);
111 static_assert(v.index() == 1, "");
112 static_assert(std::get<1>(v) == 42, "");
115 constexpr std::variant<unsigned, long> v(42);
116 static_assert(v.index() == 1, "");
117 static_assert(std::get<1>(v) == 42, "");
120 std::variant<std::string, bool const> v = "foo";
121 assert(v.index() == 0);
122 assert(std::get<0>(v) == "foo");
125 std::variant<bool, std::unique_ptr<int>> v = nullptr;
126 assert(v.index() == 1);
127 assert(std::get<1>(v) == nullptr);
130 std::variant<bool const, int> v = true;
131 assert(v.index() == 0);
132 assert(std::get<0>(v));
135 std::variant<RValueConvertibleFrom<int>> v1 = 42;
136 assert(v1.index() == 0);
138 int x = 42;
139 std::variant<RValueConvertibleFrom<int>, AnyConstructible> v2 = x;
140 assert(v2.index() == 1);
144 struct BoomOnAnything {
145 template <class T>
146 constexpr BoomOnAnything(T) {
147 static_assert(!std::is_same<T, T>::value, "");
151 void test_no_narrowing_check_for_class_types() {
152 using V = std::variant<int, BoomOnAnything>;
153 V v(42);
154 assert(v.index() == 0);
155 assert(std::get<0>(v) == 42);
158 struct Bar {};
159 struct Baz {};
160 void test_construction_with_repeated_types() {
161 using V = std::variant<int, Bar, Baz, int, Baz, int, int>;
162 static_assert(!std::is_constructible<V, int>::value, "");
163 static_assert(!std::is_constructible<V, Baz>::value, "");
164 // OK, the selected type appears only once and so it shouldn't
165 // be affected by the duplicate types.
166 static_assert(std::is_constructible<V, Bar>::value, "");
169 void test_vector_bool() {
170 std::vector<bool> vec = {true};
171 std::variant<bool, int> v = vec[0];
172 assert(v.index() == 0);
173 assert(std::get<0>(v) == true);
176 int main(int, char**) {
177 test_T_ctor_basic();
178 test_T_ctor_noexcept();
179 test_T_ctor_sfinae();
180 test_no_narrowing_check_for_class_types();
181 test_construction_with_repeated_types();
182 test_vector_bool();
183 return 0;