2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
15 // template <class ...Types> class variant;
17 // variant(variant const&);
20 #include <type_traits>
23 #include "test_macros.h"
26 NonT(int v) : value(v) {}
27 NonT(const NonT &o) : value(o.value) {}
30 static_assert(!std::is_trivially_copy_constructible<NonT>::value, "");
33 NoCopy(const NoCopy &) = delete;
37 MoveOnly(const MoveOnly &) = delete;
38 MoveOnly(MoveOnly &&) = default;
42 MoveOnlyNT(const MoveOnlyNT &) = delete;
43 MoveOnlyNT(MoveOnlyNT &&) {}
46 #ifndef TEST_HAS_NO_EXCEPTIONS
49 MakeEmptyT() { ++alive; }
50 MakeEmptyT(const MakeEmptyT &) {
52 // Don't throw from the copy constructor since variant's assignment
53 // operator performs a copy before committing to the assignment.
55 MakeEmptyT(MakeEmptyT &&) { throw 42; }
56 MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
57 MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
58 ~MakeEmptyT() { --alive; }
61 int MakeEmptyT::alive = 0;
63 template <class Variant> void makeEmpty(Variant &v) {
64 Variant v2(std::in_place_type<MakeEmptyT>);
69 assert(v.valueless_by_exception());
72 #endif // TEST_HAS_NO_EXCEPTIONS
74 void test_copy_ctor_sfinae() {
76 using V = std::variant<int, long>;
77 static_assert(std::is_copy_constructible<V>::value, "");
80 using V = std::variant<int, NoCopy>;
81 static_assert(!std::is_copy_constructible<V>::value, "");
84 using V = std::variant<int, MoveOnly>;
85 static_assert(!std::is_copy_constructible<V>::value, "");
88 using V = std::variant<int, MoveOnlyNT>;
89 static_assert(!std::is_copy_constructible<V>::value, "");
93 void test_copy_ctor_basic() {
95 std::variant<int> v(std::in_place_index<0>, 42);
96 std::variant<int> v2 = v;
97 assert(v2.index() == 0);
98 assert(std::get<0>(v2) == 42);
101 std::variant<int, long> v(std::in_place_index<1>, 42);
102 std::variant<int, long> v2 = v;
103 assert(v2.index() == 1);
104 assert(std::get<1>(v2) == 42);
107 std::variant<NonT> v(std::in_place_index<0>, 42);
108 assert(v.index() == 0);
109 std::variant<NonT> v2(v);
110 assert(v2.index() == 0);
111 assert(std::get<0>(v2).value == 42);
114 std::variant<int, NonT> v(std::in_place_index<1>, 42);
115 assert(v.index() == 1);
116 std::variant<int, NonT> v2(v);
117 assert(v2.index() == 1);
118 assert(std::get<1>(v2).value == 42);
122 void test_copy_ctor_valueless_by_exception() {
123 #ifndef TEST_HAS_NO_EXCEPTIONS
124 using V = std::variant<int, MakeEmptyT>;
129 assert(v.valueless_by_exception());
133 template <size_t Idx>
134 constexpr bool test_constexpr_copy_ctor_extension_imp(
135 std::variant<long, void*, const int> const& v)
138 return v2.index() == v.index() &&
140 std::get<Idx>(v2) == std::get<Idx>(v);
143 void test_constexpr_copy_ctor_extension() {
144 #ifdef _LIBCPP_VERSION
145 using V = std::variant<long, void*, const int>;
146 static_assert(std::is_trivially_copyable<V>::value, "");
147 static_assert(std::is_trivially_copy_constructible<V>::value, "");
148 static_assert(test_constexpr_copy_ctor_extension_imp<0>(V(42l)), "");
149 static_assert(test_constexpr_copy_ctor_extension_imp<1>(V(nullptr)), "");
150 static_assert(test_constexpr_copy_ctor_extension_imp<2>(V(101)), "");
155 test_copy_ctor_basic();
156 test_copy_ctor_valueless_by_exception();
157 test_copy_ctor_sfinae();
158 test_constexpr_copy_ctor_extension();