blob: bbadf8de16001c16ccb1eea277156b3fb2b03c85 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001//===----------------------------------------------------------------------===//
2//
Howard Hinnantf5256e12010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10// <tuple>
11
12// template <class... Types> class tuple;
13
14// explicit tuple(const T&...);
15
Eric Fiselierf0630522015-02-19 02:10:42 +000016// UNSUPPORTED: c++98, c++03
17
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000018#include <tuple>
19#include <string>
20#include <cassert>
21
Eric Fiselier9020c082014-07-24 18:48:34 +000022
23template <class ...>
24struct never {
25 enum { value = 0 };
26};
27
28struct NoValueCtor
29{
30 NoValueCtor() : id(++count) {}
31 NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
32
33 // The constexpr is required to make is_constructible instantiate this template.
34 // The explicit is needed to test-around a similar bug with is_convertible.
35 template <class T>
36 constexpr explicit NoValueCtor(T)
37 { static_assert(never<T>::value, "This should not be instantiated"); }
38
39 static int count;
40 int id;
41};
42
43int NoValueCtor::count = 0;
44
45
46struct NoValueCtorEmpty
47{
48 NoValueCtorEmpty() {}
49 NoValueCtorEmpty(NoValueCtorEmpty const &) {}
50
51 template <class T>
52 constexpr explicit NoValueCtorEmpty(T)
53 { static_assert(never<T>::value, "This should not be instantiated"); }
54};
55
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056int main()
57{
58 {
59 std::tuple<int> t(2);
60 assert(std::get<0>(t) == 2);
61 }
Marshall Clowda0a0e82013-07-22 16:02:19 +000062#if _LIBCPP_STD_VER > 11
63 {
64 constexpr std::tuple<int> t(2);
65 static_assert(std::get<0>(t) == 2, "");
66 }
67 {
68 constexpr std::tuple<int> t;
69 static_assert(std::get<0>(t) == 0, "");
70 }
71#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000072 {
73 std::tuple<int, char*> t(2, 0);
74 assert(std::get<0>(t) == 2);
75 assert(std::get<1>(t) == nullptr);
76 }
Marshall Clowda0a0e82013-07-22 16:02:19 +000077#if _LIBCPP_STD_VER > 11
78 {
79 constexpr std::tuple<int, char*> t(2, nullptr);
80 static_assert(std::get<0>(t) == 2, "");
81 static_assert(std::get<1>(t) == nullptr, "");
82 }
83#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000084 {
85 std::tuple<int, char*> t(2, nullptr);
86 assert(std::get<0>(t) == 2);
87 assert(std::get<1>(t) == nullptr);
88 }
89 {
90 std::tuple<int, char*, std::string> t(2, nullptr, "text");
91 assert(std::get<0>(t) == 2);
92 assert(std::get<1>(t) == nullptr);
93 assert(std::get<2>(t) == "text");
94 }
Eric Fiselier9020c082014-07-24 18:48:34 +000095 // __tuple_leaf<T> uses is_constructible<T, U> to disable its explicit converting
96 // constructor overload __tuple_leaf(U &&). Evaluating is_constructible can cause a compile error.
97 // This overload is evaluated when __tuple_leafs copy or move ctor is called.
98 // This checks that is_constructible is not evaluated when U == __tuple_leaf.
99 {
100 std::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
101 assert(std::get<0>(t) == 1);
102 assert(std::get<1>(t).id == 1);
103 assert(std::get<2>(t) == 2);
104 assert(std::get<3>(t) == 3);
105 }
106 {
107 std::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
108 assert(std::get<0>(t) == 1);
109 assert(std::get<2>(t) == 2);
110 assert(std::get<3>(t) == 3);
111 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000112 // extensions
113 {
114 std::tuple<int, char*, std::string> t(2);
115 assert(std::get<0>(t) == 2);
116 assert(std::get<1>(t) == nullptr);
117 assert(std::get<2>(t) == "");
118 }
119 {
120 std::tuple<int, char*, std::string> t(2, nullptr);
121 assert(std::get<0>(t) == 2);
122 assert(std::get<1>(t) == nullptr);
123 assert(std::get<2>(t) == "");
124 }
125 {
126 std::tuple<int, char*, std::string, double> t(2, nullptr, "text");
127 assert(std::get<0>(t) == 2);
128 assert(std::get<1>(t) == nullptr);
129 assert(std::get<2>(t) == "text");
130 assert(std::get<3>(t) == 0.0);
131 }
132}