1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // template <class... Types> class tuple;
14 // template <class... UTypes>
15 // explicit tuple(UTypes&&... u);
17 // UNSUPPORTED: c++98, c++03
21 #include <type_traits>
23 #include "test_macros.h"
24 #include "test_convertible.hpp"
33 explicit constexpr A(int i) : id_(i) {}
38 struct NoDefault { NoDefault() = delete; };
40 // Make sure the _Up... constructor SFINAEs out when the types that
41 // are not explicitly initialized are not all default constructible.
42 // Otherwise, std::is_constructible would return true but instantiating
43 // the constructor would fail.
44 void test_default_constructible_extension_sfinae()
47 typedef std::tuple<MoveOnly, NoDefault> Tuple;
49 static_assert(!std::is_constructible<
54 static_assert(std::is_constructible<
60 typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
62 static_assert(!std::is_constructible<
67 static_assert(std::is_constructible<
69 MoveOnly, MoveOnly, NoDefault
73 // Same idea as above but with a nested tuple type.
74 typedef std::tuple<MoveOnly, NoDefault> Tuple;
75 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
77 static_assert(!std::is_constructible<
79 MoveOnly, MoveOnly, MoveOnly, MoveOnly
82 static_assert(std::is_constructible<
84 MoveOnly, Tuple, MoveOnly, MoveOnly
88 #ifdef _LIBCPP_VERSION
90 typedef std::tuple<MoveOnly, int> Tuple;
91 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
93 static_assert(std::is_constructible<
95 MoveOnly, MoveOnly, MoveOnly, MoveOnly
98 static_assert(std::is_constructible<
100 MoveOnly, Tuple, MoveOnly, MoveOnly
109 std::tuple<MoveOnly> t(MoveOnly(0));
110 assert(std::get<0>(t) == 0);
113 std::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1));
114 assert(std::get<0>(t) == 0);
115 assert(std::get<1>(t) == 1);
118 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0),
121 assert(std::get<0>(t) == 0);
122 assert(std::get<1>(t) == 1);
123 assert(std::get<2>(t) == 2);
126 #ifdef _LIBCPP_VERSION
129 using Tup = std::tuple<E, E, E>;
130 // Test that the reduced arity initialization extension is only
131 // allowed on the explicit constructor.
132 static_assert(test_convertible<Tup, E, E, E>(), "");
135 static_assert(!test_convertible<Tup, E, E>(), "");
136 assert(std::get<0>(t) == 0);
137 assert(std::get<1>(t) == 1);
138 assert(std::get<2>(t) == MoveOnly());
141 static_assert(!test_convertible<Tup, E>(), "");
142 assert(std::get<0>(t) == 0);
143 assert(std::get<1>(t) == E());
144 assert(std::get<2>(t) == E());
147 #if TEST_STD_VER > 11
149 constexpr std::tuple<Empty> t0{Empty()};
152 constexpr std::tuple<A, A> t(3, 2);
153 static_assert(std::get<0>(t).id_ == 3, "");
156 // Check that SFINAE is properly applied with the default reduced arity
157 // constructor extensions.
158 test_default_constructible_extension_sfinae();