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 Alloc, class... UTypes>
15 // tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
16
17 // UNSUPPORTED: c++98, c++03
18
19 #include <tuple>
20 #include <cassert>
21
22 #include "MoveOnly.h"
23 #include "allocators.h"
24 #include "../alloc_first.h"
25 #include "../alloc_last.h"
26
27 struct NoDefault { NoDefault() = delete; };
28
29 // Make sure the _Up... constructor SFINAEs out when the types that
30 // are not explicitly initialized are not all default constructible.
31 // Otherwise, std::is_constructible would return true but instantiating
32 // the constructor would fail.
test_default_constructible_extension_sfinae()33 void test_default_constructible_extension_sfinae()
34 {
35 {
36 typedef std::tuple<MoveOnly, NoDefault> Tuple;
37
38 static_assert(!std::is_constructible<
39 Tuple,
40 std::allocator_arg_t, A1<int>, MoveOnly
41 >::value, "");
42
43 static_assert(std::is_constructible<
44 Tuple,
45 std::allocator_arg_t, A1<int>, MoveOnly, NoDefault
46 >::value, "");
47 }
48 {
49 typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
50
51 static_assert(!std::is_constructible<
52 Tuple,
53 std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly
54 >::value, "");
55
56 static_assert(std::is_constructible<
57 Tuple,
58 std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, NoDefault
59 >::value, "");
60 }
61 {
62 // Same idea as above but with a nested tuple
63 typedef std::tuple<MoveOnly, NoDefault> Tuple;
64 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
65
66 static_assert(!std::is_constructible<
67 NestedTuple,
68 std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly
69 >::value, "");
70
71 static_assert(std::is_constructible<
72 NestedTuple,
73 std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly
74 >::value, "");
75 }
76 {
77 typedef std::tuple<MoveOnly, int> Tuple;
78 typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
79
80 static_assert(std::is_constructible<
81 NestedTuple,
82 std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly
83 >::value, "");
84
85 static_assert(std::is_constructible<
86 NestedTuple,
87 std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly
88 >::value, "");
89 }
90 }
91
main()92 int main()
93 {
94 {
95 std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0));
96 assert(std::get<0>(t) == 0);
97 }
98 {
99 std::tuple<MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
100 MoveOnly(0), MoveOnly(1));
101 assert(std::get<0>(t) == 0);
102 assert(std::get<1>(t) == 1);
103 }
104 {
105 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
106 MoveOnly(0),
107 1, 2);
108 assert(std::get<0>(t) == 0);
109 assert(std::get<1>(t) == 1);
110 assert(std::get<2>(t) == 2);
111 }
112 {
113 alloc_first::allocator_constructed = false;
114 alloc_last::allocator_constructed = false;
115 std::tuple<int, alloc_first, alloc_last> t(std::allocator_arg,
116 A1<int>(5), 1, 2, 3);
117 assert(std::get<0>(t) == 1);
118 assert(alloc_first::allocator_constructed);
119 assert(std::get<1>(t) == alloc_first(2));
120 assert(alloc_last::allocator_constructed);
121 assert(std::get<2>(t) == alloc_last(3));
122 }
123 // extensions
124 {
125 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
126 0, 1);
127 assert(std::get<0>(t) == 0);
128 assert(std::get<1>(t) == 1);
129 assert(std::get<2>(t) == MoveOnly());
130 }
131 {
132 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
133 0);
134 assert(std::get<0>(t) == 0);
135 assert(std::get<1>(t) == MoveOnly());
136 assert(std::get<2>(t) == MoveOnly());
137 }
138 // Check that SFINAE is properly applied with the default reduced arity
139 // constructor extensions.
140 test_default_constructible_extension_sfinae();
141 }
142