]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / tuple / tuple.tuple / tuple.cnstr / const_Types.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 // explicit tuple(const T&...);
15
16 // UNSUPPORTED: c++98, c++03
17
18 #include <tuple>
19 #include <string>
20 #include <cassert>
21
22 #include "test_macros.h"
23
24 template <class ...>
25 struct never {
26     enum { value = 0 };
27 };
28
29 struct NoValueCtor
30 {
31     NoValueCtor() : id(++count) {}
32     NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
33
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.
36     template <class T>
37     constexpr explicit NoValueCtor(T)
38     { static_assert(never<T>::value, "This should not be instantiated"); }
39
40     static int count;
41     int id;
42 };
43
44 int NoValueCtor::count = 0;
45
46
47 struct NoValueCtorEmpty
48 {
49     NoValueCtorEmpty() {}
50     NoValueCtorEmpty(NoValueCtorEmpty const &) {}
51
52     template <class T>
53     constexpr explicit NoValueCtorEmpty(T)
54     { static_assert(never<T>::value, "This should not be instantiated"); }
55 };
56
57
58 struct ImplicitCopy {
59   explicit ImplicitCopy(int) {}
60   ImplicitCopy(ImplicitCopy const&) {}
61 };
62
63 // Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit
64 // copy conversions in return value expressions.
65 std::tuple<ImplicitCopy> testImplicitCopy1() {
66     ImplicitCopy i(42);
67     return {i};
68 }
69
70 std::tuple<ImplicitCopy> testImplicitCopy2() {
71     const ImplicitCopy i(42);
72     return {i};
73 }
74
75 std::tuple<ImplicitCopy> testImplicitCopy3() {
76     const ImplicitCopy i(42);
77     return i;
78 }
79
80 int main()
81 {
82     {
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);
86     }
87     {
88         std::tuple<int> t(2);
89         assert(std::get<0>(t) == 2);
90     }
91 #if TEST_STD_VER > 11
92     {
93         constexpr std::tuple<int> t(2);
94         static_assert(std::get<0>(t) == 2, "");
95     }
96     {
97         constexpr std::tuple<int> t;
98         static_assert(std::get<0>(t) == 0, "");
99     }
100 #endif
101     {
102         std::tuple<int, char*> t(2, 0);
103         assert(std::get<0>(t) == 2);
104         assert(std::get<1>(t) == nullptr);
105     }
106 #if TEST_STD_VER > 11
107     {
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, "");
111     }
112 #endif
113     {
114         std::tuple<int, char*> t(2, nullptr);
115         assert(std::get<0>(t) == 2);
116         assert(std::get<1>(t) == nullptr);
117     }
118     {
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");
123     }
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.
128     {
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);
134     }
135     {
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);
140     }
141 // extensions
142 #ifdef _LIBCPP_VERSION
143     {
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) == "");
148     }
149     {
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) == "");
154     }
155     {
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);
161     }
162 #endif
163 }