blob: 3929965cd2735b836e767ce5597615dc65b99a39 [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// template <class Alloc, class... UTypes>
15// tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
16
Eric Fiselierf0630522015-02-19 02:10:42 +000017// UNSUPPORTED: c++98, c++03
18
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000019#include <tuple>
20#include <cassert>
21
Marshall Clowdf00d5e2015-01-28 21:22:53 +000022#include "MoveOnly.h"
Marshall Clowebedffd2013-12-02 18:08:31 +000023#include "allocators.h"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000024#include "../alloc_first.h"
25#include "../alloc_last.h"
26
Dan Albert1d4a1ed2016-05-25 22:36:09 -070027struct NoDefault { NoDefault() = delete; };
Marshall Clowbbc7c742014-10-15 10:33:02 +000028
Dan Albert1d4a1ed2016-05-25 22:36:09 -070029// 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.
33void test_default_constructible_extension_sfinae()
Eric Fiselierf2215ae2014-11-18 23:01:57 +000034{
35 {
Dan Albert1d4a1ed2016-05-25 22:36:09 -070036 typedef std::tuple<MoveOnly, NoDefault> Tuple;
Eric Fiselierf2215ae2014-11-18 23:01:57 +000037
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,
Dan Albert1d4a1ed2016-05-25 22:36:09 -070045 std::allocator_arg_t, A1<int>, MoveOnly, NoDefault
Eric Fiselierf2215ae2014-11-18 23:01:57 +000046 >::value, "");
47 }
48 {
Dan Albert1d4a1ed2016-05-25 22:36:09 -070049 typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
Eric Fiselierf2215ae2014-11-18 23:01:57 +000050
51 static_assert(!std::is_constructible<
Eric Fiselier75fdf0e2015-02-05 20:28:37 +000052 Tuple,
Eric Fiselierf2215ae2014-11-18 23:01:57 +000053 std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly
54 >::value, "");
55
56 static_assert(std::is_constructible<
Eric Fiselier75fdf0e2015-02-05 20:28:37 +000057 Tuple,
Dan Albert1d4a1ed2016-05-25 22:36:09 -070058 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
Eric Fiselierf2215ae2014-11-18 23:01:57 +000088 >::value, "");
89 }
90}
91
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000092int 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 {
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000105 std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106 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 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700123 // extensions
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124 {
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700125 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());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000130 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700131 {
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();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000141}