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