1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <tuple> 11 12 // template <class... Types> class tuple; 13 14 // template <class... UTypes> 15 // explicit tuple(UTypes&&... u); 16 17 // UNSUPPORTED: c++98, c++03 18 19 #include <tuple> 20 #include <cassert> 21 #include <type_traits> 22 23 #include "MoveOnly.h" 24 25 #if _LIBCPP_STD_VER > 11 26 27 struct Empty {}; 28 struct A 29 { 30 int id_; 31 explicit constexpr A(int i) : id_(i) {} 32 }; 33 34 #endif 35 36 struct NoDefault { NoDefault() = delete; }; 37 38 // Make sure the _Up... constructor SFINAEs out when the types that 39 // are not explicitly initialized are not all default constructible. 40 // Otherwise, std::is_constructible would return true but instantiating 41 // the constructor would fail. 42 void test_default_constructible_extension_sfinae() 43 { 44 { 45 typedef std::tuple<MoveOnly, NoDefault> Tuple; 46 47 static_assert(!std::is_constructible< 48 Tuple, 49 MoveOnly 50 >::value, ""); 51 52 static_assert(std::is_constructible< 53 Tuple, 54 MoveOnly, NoDefault 55 >::value, ""); 56 } 57 { 58 typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple; 59 60 static_assert(!std::is_constructible< 61 Tuple, 62 MoveOnly, MoveOnly 63 >::value, ""); 64 65 static_assert(std::is_constructible< 66 Tuple, 67 MoveOnly, MoveOnly, NoDefault 68 >::value, ""); 69 } 70 { 71 // Same idea as above but with a nested tuple type. 72 typedef std::tuple<MoveOnly, NoDefault> Tuple; 73 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; 74 75 static_assert(!std::is_constructible< 76 NestedTuple, 77 MoveOnly, MoveOnly, MoveOnly, MoveOnly 78 >::value, ""); 79 80 static_assert(std::is_constructible< 81 NestedTuple, 82 MoveOnly, Tuple, MoveOnly, MoveOnly 83 >::value, ""); 84 } 85 { 86 typedef std::tuple<MoveOnly, int> Tuple; 87 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; 88 89 static_assert(std::is_constructible< 90 NestedTuple, 91 MoveOnly, MoveOnly, MoveOnly, MoveOnly 92 >::value, ""); 93 94 static_assert(std::is_constructible< 95 NestedTuple, 96 MoveOnly, Tuple, MoveOnly, MoveOnly 97 >::value, ""); 98 } 99 } 100 101 int main() 102 { 103 { 104 std::tuple<MoveOnly> t(MoveOnly(0)); 105 assert(std::get<0>(t) == 0); 106 } 107 { 108 std::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1)); 109 assert(std::get<0>(t) == 0); 110 assert(std::get<1>(t) == 1); 111 } 112 { 113 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0), 114 MoveOnly(1), 115 MoveOnly(2)); 116 assert(std::get<0>(t) == 0); 117 assert(std::get<1>(t) == 1); 118 assert(std::get<2>(t) == 2); 119 } 120 // extensions 121 { 122 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0), 123 MoveOnly(1)); 124 assert(std::get<0>(t) == 0); 125 assert(std::get<1>(t) == 1); 126 assert(std::get<2>(t) == MoveOnly()); 127 } 128 { 129 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0)); 130 assert(std::get<0>(t) == 0); 131 assert(std::get<1>(t) == MoveOnly()); 132 assert(std::get<2>(t) == MoveOnly()); 133 } 134 #if _LIBCPP_STD_VER > 11 135 { 136 constexpr std::tuple<Empty> t0{Empty()}; 137 } 138 { 139 constexpr std::tuple<A, A> t(3, 2); 140 static_assert(std::get<0>(t).id_ == 3, ""); 141 } 142 #endif 143 // Check that SFINAE is properly applied with the default reduced arity 144 // constructor extensions. 145 test_default_constructible_extension_sfinae(); 146 } 147