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 // explicit tuple(const T&...);
16 // UNSUPPORTED: c++98, c++03
22 #include "test_macros.h"
31 NoValueCtor() : id(++count) {}
32 NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
34 // The constexpr is required to make is_constructible instantiate this template.
35 // The explicit is needed to test-around a similar bug with is_convertible.
37 constexpr explicit NoValueCtor(T)
38 { static_assert(never<T>::value, "This should not be instantiated"); }
44 int NoValueCtor::count = 0;
47 struct NoValueCtorEmpty
50 NoValueCtorEmpty(NoValueCtorEmpty const &) {}
53 constexpr explicit NoValueCtorEmpty(T)
54 { static_assert(never<T>::value, "This should not be instantiated"); }
59 explicit ImplicitCopy(int) {}
60 ImplicitCopy(ImplicitCopy const&) {}
63 // Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit
64 // copy conversions in return value expressions.
65 std::tuple<ImplicitCopy> testImplicitCopy1() {
70 std::tuple<ImplicitCopy> testImplicitCopy2() {
71 const ImplicitCopy i(42);
75 std::tuple<ImplicitCopy> testImplicitCopy3() {
76 const ImplicitCopy i(42);
83 // check that the literal '0' can implicitly initialize a stored pointer.
84 std::tuple<int*> t = 0;
85 assert(std::get<0>(t) == nullptr);
89 assert(std::get<0>(t) == 2);
93 constexpr std::tuple<int> t(2);
94 static_assert(std::get<0>(t) == 2, "");
97 constexpr std::tuple<int> t;
98 static_assert(std::get<0>(t) == 0, "");
102 std::tuple<int, char*> t(2, 0);
103 assert(std::get<0>(t) == 2);
104 assert(std::get<1>(t) == nullptr);
106 #if TEST_STD_VER > 11
108 constexpr std::tuple<int, char*> t(2, nullptr);
109 static_assert(std::get<0>(t) == 2, "");
110 static_assert(std::get<1>(t) == nullptr, "");
114 std::tuple<int, char*> t(2, nullptr);
115 assert(std::get<0>(t) == 2);
116 assert(std::get<1>(t) == nullptr);
119 std::tuple<int, char*, std::string> t(2, nullptr, "text");
120 assert(std::get<0>(t) == 2);
121 assert(std::get<1>(t) == nullptr);
122 assert(std::get<2>(t) == "text");
124 // __tuple_leaf<T> uses is_constructible<T, U> to disable its explicit converting
125 // constructor overload __tuple_leaf(U &&). Evaluating is_constructible can cause a compile error.
126 // This overload is evaluated when __tuple_leafs copy or move ctor is called.
127 // This checks that is_constructible is not evaluated when U == __tuple_leaf.
129 std::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
130 assert(std::get<0>(t) == 1);
131 assert(std::get<1>(t).id == 1);
132 assert(std::get<2>(t) == 2);
133 assert(std::get<3>(t) == 3);
136 std::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
137 assert(std::get<0>(t) == 1);
138 assert(std::get<2>(t) == 2);
139 assert(std::get<3>(t) == 3);
142 #ifdef _LIBCPP_VERSION
144 std::tuple<int, char*, std::string> t(2);
145 assert(std::get<0>(t) == 2);
146 assert(std::get<1>(t) == nullptr);
147 assert(std::get<2>(t) == "");
150 std::tuple<int, char*, std::string> t(2, nullptr);
151 assert(std::get<0>(t) == 2);
152 assert(std::get<1>(t) == nullptr);
153 assert(std::get<2>(t) == "");
156 std::tuple<int, char*, std::string, double> t(2, nullptr, "text");
157 assert(std::get<0>(t) == 2);
158 assert(std::get<1>(t) == nullptr);
159 assert(std::get<2>(t) == "text");
160 assert(std::get<3>(t) == 0.0);