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 <class T, class U, class ...Args> 25 // T& emplace(initializer_list<U> il,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 36 struct InitList { 37 std::size_t size; 38 constexpr InitList(std::initializer_list<int> il) : size(il.size()) {} 39 }; 40 41 struct InitListArg { 42 std::size_t size; 43 int value; 44 constexpr InitListArg(std::initializer_list<int> il, int v) 45 : size(il.size()), value(v) {} 46 }; 47 48 template <class Var, class T, class... Args> 49 constexpr auto test_emplace_exists_imp(int) -> decltype( 50 std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) { 51 return true; 52 } 53 54 template <class, class, class...> 55 constexpr auto test_emplace_exists_imp(long) -> bool { 56 return false; 57 } 58 59 template <class... Args> constexpr bool emplace_exists() { 60 return test_emplace_exists_imp<Args...>(0); 61 } 62 63 void test_emplace_sfinae() { 64 using V = 65 std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>; 66 using IL = std::initializer_list<int>; 67 static_assert(emplace_exists<V, InitList, IL>(), ""); 68 static_assert(!emplace_exists<V, InitList, int>(), "args don't match"); 69 static_assert(!emplace_exists<V, InitList, IL, int>(), "too many args"); 70 static_assert(emplace_exists<V, InitListArg, IL, int>(), ""); 71 static_assert(!emplace_exists<V, InitListArg, int>(), "args don't match"); 72 static_assert(!emplace_exists<V, InitListArg, IL>(), "too few args"); 73 static_assert(!emplace_exists<V, InitListArg, IL, int, int>(), 74 "too many args"); 75 } 76 77 void test_basic() { 78 using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>; 79 V v; 80 auto& ref1 = v.emplace<InitList>({1, 2, 3}); 81 static_assert(std::is_same_v<InitList&,decltype(ref1)>, ""); 82 assert(std::get<InitList>(v).size == 3); 83 assert(&ref1 == &std::get<InitList>(v)); 84 auto& ref2 = v.emplace<InitListArg>({1, 2, 3, 4}, 42); 85 static_assert(std::is_same_v<InitListArg&,decltype(ref2)>, ""); 86 assert(std::get<InitListArg>(v).size == 4); 87 assert(std::get<InitListArg>(v).value == 42); 88 assert(&ref2 == &std::get<InitListArg>(v)); 89 auto& ref3 = v.emplace<InitList>({1}); 90 static_assert(std::is_same_v<InitList&,decltype(ref3)>, ""); 91 assert(std::get<InitList>(v).size == 1); 92 assert(&ref3 == &std::get<InitList>(v)); 93 } 94 95 int main() { 96 test_basic(); 97 test_emplace_sfinae(); 98 } 99