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 { 33 ThrowsT(int) noexcept(false) {} 34 }; 35 36 struct NoThrowT { 37 NoThrowT(int) noexcept(true) {} 38 }; 39 40 struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} }; 41 struct NoConstructible { NoConstructible() = delete; }; 42 43 void test_T_ctor_noexcept() { 44 { 45 using V = std::variant<Dummy, NoThrowT>; 46 static_assert(std::is_nothrow_constructible<V, int>::value, ""); 47 } 48 { 49 using V = std::variant<Dummy, ThrowsT>; 50 static_assert(!std::is_nothrow_constructible<V, int>::value, ""); 51 } 52 } 53 54 void test_T_ctor_sfinae() { 55 { 56 using V = std::variant<long, unsigned>; 57 static_assert(!std::is_constructible<V, int>::value, "ambiguous"); 58 } 59 { 60 using V = std::variant<std::string, std::string>; 61 static_assert(!std::is_constructible<V, const char *>::value, "ambiguous"); 62 } 63 { 64 using V = std::variant<std::string, void *>; 65 static_assert(!std::is_constructible<V, int>::value, 66 "no matching constructor"); 67 } 68 { 69 using V = std::variant<AnyConstructible, NoConstructible>; 70 static_assert( 71 !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value, 72 "no matching constructor"); 73 static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value, 74 "no matching constructor"); 75 } 76 77 78 79 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 80 { 81 using V = std::variant<int, int &&>; 82 static_assert(!std::is_constructible<V, int>::value, "ambiguous"); 83 } 84 { 85 using V = std::variant<int, const int &>; 86 static_assert(!std::is_constructible<V, int>::value, "ambiguous"); 87 } 88 #endif 89 } 90 91 void test_T_ctor_basic() { 92 { 93 constexpr std::variant<int> v(42); 94 static_assert(v.index() == 0, ""); 95 static_assert(std::get<0>(v) == 42, ""); 96 } 97 { 98 constexpr std::variant<int, long> v(42l); 99 static_assert(v.index() == 1, ""); 100 static_assert(std::get<1>(v) == 42, ""); 101 } 102 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 103 { 104 using V = std::variant<const int &, int &&, long>; 105 static_assert(std::is_convertible<int &, V>::value, "must be implicit"); 106 int x = 42; 107 V v(x); 108 assert(v.index() == 0); 109 assert(&std::get<0>(v) == &x); 110 } 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(std::move(x)); 116 assert(v.index() == 1); 117 assert(&std::get<1>(v) == &x); 118 } 119 #endif 120 } 121 122 int main() { 123 test_T_ctor_basic(); 124 test_T_ctor_noexcept(); 125 test_T_ctor_sfinae(); 126 } 127