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 { 41 ThrowsT(int) noexcept(false) {} 42 }; 43 44 struct NoThrowT { 45 NoThrowT(int) noexcept(true) {} 46 }; 47 48 struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} }; 49 struct NoConstructible { NoConstructible() = delete; }; 50 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 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 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 130 int main() { 131 test_T_ctor_basic(); 132 test_T_ctor_noexcept(); 133 test_T_ctor_sfinae(); 134 } 135