]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / tuple / tuple.tuple / tuple.cnstr / UTypes.pass.cpp
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... UTypes>
15 //   explicit tuple(UTypes&&... u);
16
17 // UNSUPPORTED: c++98, c++03
18
19 #include <tuple>
20 #include <cassert>
21 #include <type_traits>
22
23 #include "test_macros.h"
24 #include "test_convertible.hpp"
25 #include "MoveOnly.h"
26
27 #if TEST_STD_VER > 11
28
29 struct Empty {};
30 struct A
31 {
32     int id_;
33     explicit constexpr A(int i) : id_(i) {}
34 };
35
36 #endif
37
38 struct NoDefault { NoDefault() = delete; };
39
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()
45 {
46     {
47         typedef std::tuple<MoveOnly, NoDefault> Tuple;
48
49         static_assert(!std::is_constructible<
50             Tuple,
51             MoveOnly
52         >::value, "");
53
54         static_assert(std::is_constructible<
55             Tuple,
56             MoveOnly, NoDefault
57         >::value, "");
58     }
59     {
60         typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
61
62         static_assert(!std::is_constructible<
63             Tuple,
64             MoveOnly, MoveOnly
65         >::value, "");
66
67         static_assert(std::is_constructible<
68             Tuple,
69             MoveOnly, MoveOnly, NoDefault
70         >::value, "");
71     }
72     {
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;
76
77         static_assert(!std::is_constructible<
78             NestedTuple,
79             MoveOnly, MoveOnly, MoveOnly, MoveOnly
80         >::value, "");
81
82         static_assert(std::is_constructible<
83             NestedTuple,
84             MoveOnly, Tuple, MoveOnly, MoveOnly
85         >::value, "");
86     }
87     // testing extensions
88 #ifdef _LIBCPP_VERSION
89     {
90         typedef std::tuple<MoveOnly, int> Tuple;
91         typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
92
93         static_assert(std::is_constructible<
94             NestedTuple,
95             MoveOnly, MoveOnly, MoveOnly, MoveOnly
96         >::value, "");
97
98         static_assert(std::is_constructible<
99             NestedTuple,
100             MoveOnly, Tuple, MoveOnly, MoveOnly
101         >::value, "");
102     }
103 #endif
104 }
105
106 int main()
107 {
108     {
109         std::tuple<MoveOnly> t(MoveOnly(0));
110         assert(std::get<0>(t) == 0);
111     }
112     {
113         std::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1));
114         assert(std::get<0>(t) == 0);
115         assert(std::get<1>(t) == 1);
116     }
117     {
118         std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0),
119                                                    MoveOnly(1),
120                                                    MoveOnly(2));
121         assert(std::get<0>(t) == 0);
122         assert(std::get<1>(t) == 1);
123         assert(std::get<2>(t) == 2);
124     }
125     // extensions
126 #ifdef _LIBCPP_VERSION
127     {
128         using E = MoveOnly;
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>(), "");
133
134         Tup t(E(0), E(1));
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());
139
140         Tup t2(E(0));
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());
145     }
146 #endif
147 #if TEST_STD_VER > 11
148     {
149         constexpr std::tuple<Empty> t0{Empty()};
150     }
151     {
152         constexpr std::tuple<A, A> t(3, 2);
153         static_assert(std::get<0>(t).id_ == 3, "");
154     }
155 #endif
156     // Check that SFINAE is properly applied with the default reduced arity
157     // constructor extensions.
158     test_default_constructible_extension_sfinae();
159 }