1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <tuple>
10 
11 // template <class... Types> class tuple;
12 
13 // constexpr tuple();
14 
15 // UNSUPPORTED: c++98, c++03
16 
17 #include <tuple>
18 #include <string>
19 #include <cassert>
20 #include <type_traits>
21 
22 #include "DefaultOnly.h"
23 
24 struct NoDefault {
25     NoDefault() = delete;
26     explicit NoDefault(int) { }
27 };
28 
29 struct NoExceptDefault {
30     NoExceptDefault() noexcept = default;
31 };
32 
33 struct ThrowingDefault {
34     ThrowingDefault() { }
35 };
36 
37 struct IllFormedDefault {
38     IllFormedDefault(int x) : value(x) {}
39     template <bool Pred = false>
40     constexpr IllFormedDefault() {
41         static_assert(Pred,
42             "The default constructor should not be instantiated");
43     }
44     int value;
45 };
46 
47 int main(int, char**)
48 {
49     {
50         std::tuple<> t;
51         (void)t;
52     }
53     {
54         std::tuple<int> t;
55         assert(std::get<0>(t) == 0);
56     }
57     {
58         std::tuple<int, char*> t;
59         assert(std::get<0>(t) == 0);
60         assert(std::get<1>(t) == nullptr);
61     }
62     {
63         std::tuple<int, char*, std::string> t;
64         assert(std::get<0>(t) == 0);
65         assert(std::get<1>(t) == nullptr);
66         assert(std::get<2>(t) == "");
67     }
68     {
69         std::tuple<int, char*, std::string, DefaultOnly> t;
70         assert(std::get<0>(t) == 0);
71         assert(std::get<1>(t) == nullptr);
72         assert(std::get<2>(t) == "");
73         assert(std::get<3>(t) == DefaultOnly());
74     }
75     {
76         // See bug #21157.
77         static_assert(!std::is_default_constructible<std::tuple<NoDefault>>(), "");
78         static_assert(!std::is_default_constructible<std::tuple<DefaultOnly, NoDefault>>(), "");
79         static_assert(!std::is_default_constructible<std::tuple<NoDefault, DefaultOnly, NoDefault>>(), "");
80     }
81     {
82         static_assert(noexcept(std::tuple<NoExceptDefault>()), "");
83         static_assert(noexcept(std::tuple<NoExceptDefault, NoExceptDefault>()), "");
84 
85         static_assert(!noexcept(std::tuple<ThrowingDefault, NoExceptDefault>()), "");
86         static_assert(!noexcept(std::tuple<NoExceptDefault, ThrowingDefault>()), "");
87         static_assert(!noexcept(std::tuple<ThrowingDefault, ThrowingDefault>()), "");
88     }
89     {
90         constexpr std::tuple<> t;
91         (void)t;
92     }
93     {
94         constexpr std::tuple<int> t;
95         assert(std::get<0>(t) == 0);
96     }
97     {
98         constexpr std::tuple<int, char*> t;
99         assert(std::get<0>(t) == 0);
100         assert(std::get<1>(t) == nullptr);
101     }
102     {
103     // Check that the SFINAE on the default constructor is not evaluated when
104     // it isn't needed. If the default constructor is evaluated then this test
105     // should fail to compile.
106         IllFormedDefault v(0);
107         std::tuple<IllFormedDefault> t(v);
108     }
109 
110   return 0;
111 }
112