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