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 // XFAIL: with_system_cxx_lib=macosx10.12 14 // XFAIL: with_system_cxx_lib=macosx10.11 15 // XFAIL: with_system_cxx_lib=macosx10.10 16 // XFAIL: with_system_cxx_lib=macosx10.9 17 // XFAIL: with_system_cxx_lib=macosx10.7 18 // XFAIL: with_system_cxx_lib=macosx10.8 19 20 // <variant> 21 22 // template <class ...Types> class variant; 23 24 // template <size_t I, class ...Args> 25 // variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args); 26 27 #include <cassert> 28 #include <string> 29 #include <type_traits> 30 #include <variant> 31 32 #include "archetypes.hpp" 33 #include "test_convertible.hpp" 34 #include "test_macros.h" 35 #include "variant_test_helpers.hpp" 36 37 template <class Var, size_t I, class... Args> 38 constexpr auto test_emplace_exists_imp(int) -> decltype( 39 std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) { 40 return true; 41 } 42 43 template <class, size_t, class...> 44 constexpr auto test_emplace_exists_imp(long) -> bool { 45 return false; 46 } 47 48 template <class Var, size_t I, class... Args> constexpr bool emplace_exists() { 49 return test_emplace_exists_imp<Var, I, Args...>(0); 50 } 51 52 void test_emplace_sfinae() { 53 { 54 using V = std::variant<int, void *, const void *, TestTypes::NoCtors>; 55 static_assert(emplace_exists<V, 0>(), ""); 56 static_assert(emplace_exists<V, 0, int>(), ""); 57 static_assert(!emplace_exists<V, 0, decltype(nullptr)>(), 58 "cannot construct"); 59 static_assert(emplace_exists<V, 1, decltype(nullptr)>(), ""); 60 static_assert(emplace_exists<V, 1, int *>(), ""); 61 static_assert(!emplace_exists<V, 1, const int *>(), ""); 62 static_assert(!emplace_exists<V, 1, int>(), "cannot construct"); 63 static_assert(emplace_exists<V, 2, const int *>(), ""); 64 static_assert(emplace_exists<V, 2, int *>(), ""); 65 static_assert(!emplace_exists<V, 3>(), "cannot construct"); 66 } 67 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 68 { 69 using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>; 70 static_assert(emplace_exists<V, 0>(), ""); 71 static_assert(emplace_exists<V, 0, int>(), ""); 72 static_assert(emplace_exists<V, 0, long long>(), ""); 73 static_assert(!emplace_exists<V, 0, int, int>(), "too many args"); 74 static_assert(emplace_exists<V, 1, int &>(), ""); 75 static_assert(!emplace_exists<V, 1>(), "cannot default construct ref"); 76 static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref"); 77 static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref"); 78 static_assert(emplace_exists<V, 2, int &>(), ""); 79 static_assert(emplace_exists<V, 2, const int &>(), ""); 80 static_assert(emplace_exists<V, 2, int &&>(), ""); 81 static_assert(!emplace_exists<V, 2, void *>(), 82 "not constructible from void*"); 83 static_assert(emplace_exists<V, 3, int>(), ""); 84 static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref"); 85 static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref"); 86 static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref"); 87 static_assert(!emplace_exists<V, 4>(), "no ctors"); 88 } 89 #endif 90 } 91 92 void test_basic() { 93 { 94 using V = std::variant<int>; 95 V v(42); 96 auto& ref1 = v.emplace<0>(); 97 static_assert(std::is_same_v<int&, decltype(ref1)>, ""); 98 assert(std::get<0>(v) == 0); 99 assert(&ref1 == &std::get<0>(v)); 100 auto& ref2 = v.emplace<0>(42); 101 static_assert(std::is_same_v<int&, decltype(ref2)>, ""); 102 assert(std::get<0>(v) == 42); 103 assert(&ref2 == &std::get<0>(v)); 104 } 105 { 106 using V = 107 std::variant<int, long, const void *, TestTypes::NoCtors, std::string>; 108 const int x = 100; 109 V v(std::in_place_index<0>, -1); 110 // default emplace a value 111 auto& ref1 = v.emplace<1>(); 112 static_assert(std::is_same_v<long&, decltype(ref1)>, ""); 113 assert(std::get<1>(v) == 0); 114 assert(&ref1 == &std::get<1>(v)); 115 auto& ref2 = v.emplace<2>(&x); 116 static_assert(std::is_same_v<const void*&, decltype(ref2)>, ""); 117 assert(std::get<2>(v) == &x); 118 assert(&ref2 == &std::get<2>(v)); 119 // emplace with multiple args 120 auto& ref3 = v.emplace<4>(3, 'a'); 121 static_assert(std::is_same_v<std::string&, decltype(ref3)>, ""); 122 assert(std::get<4>(v) == "aaa"); 123 assert(&ref3 == &std::get<4>(v)); 124 } 125 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 126 { 127 using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors, 128 std::string>; 129 const int x = 100; 130 int y = 42; 131 int z = 43; 132 V v(std::in_place_index<0>, -1); 133 // default emplace a value 134 auto& ref1 = v.emplace<1>(); 135 static_assert(std::is_same_v<long&, decltype(ref1)>, ""); 136 assert(std::get<1>(v) == 0); 137 assert(&ref1 == &std::get<1>(v)); 138 // emplace a reference 139 auto& ref2 = v.emplace<2>(x); 140 static_assert(std::is_same_v<&, decltype(ref)>, ""); 141 assert(&std::get<2>(v) == &x); 142 assert(&ref2 == &std::get<2>(v)); 143 // emplace an rvalue reference 144 auto& ref3 = v.emplace<3>(std::move(y)); 145 static_assert(std::is_same_v<&, decltype(ref)>, ""); 146 assert(&std::get<3>(v) == &y); 147 assert(&ref3 == &std::get<3>(v)); 148 // re-emplace a new reference over the active member 149 auto& ref4 = v.emplace<3>(std::move(z)); 150 static_assert(std::is_same_v<&, decltype(ref)>, ""); 151 assert(&std::get<3>(v) == &z); 152 assert(&ref4 == &std::get<3>(v)); 153 // emplace with multiple args 154 auto& ref5 = v.emplace<5>(3, 'a'); 155 static_assert(std::is_same_v<std::string&, decltype(ref5)>, ""); 156 assert(std::get<5>(v) == "aaa"); 157 assert(&ref5 == &std::get<5>(v)); 158 } 159 #endif 160 } 161 162 int main() { 163 test_basic(); 164 test_emplace_sfinae(); 165 } 166