• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 // UNSUPPORTED: libcpp-no-deduction-guides
12 
13 // GCC's implementation of class template deduction is still immature and runs
14 // into issues with libc++. However GCC accepts this code when compiling
15 // against libstdc++.
16 // XFAIL: gcc
17 
18 // <tuple>
19 
20 // Test that the constructors offered by std::tuple are formulated
21 // so they're compatible with implicit deduction guides, or if that's not
22 // possible that they provide explicit guides to make it work.
23 
24 #include <tuple>
25 #include <memory>
26 #include <cassert>
27 
28 #include "test_macros.h"
29 #include "archetypes.hpp"
30 
31 
32 // Overloads
33 //  using A = Allocator
34 //  using AT = std::allocator_arg_t
35 // ---------------
36 // (1)  tuple(const Types&...) -> tuple<Types...>
37 // (2)  explicit tuple(const Types&...) -> tuple<Types...>
38 // (3)  tuple(AT, A const&, Types const&...) -> tuple<Types...>
39 // (4)  explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
40 // (5)  tuple(tuple const& t) -> decltype(t)
41 // (6)  tuple(tuple&& t) -> decltype(t)
42 // (7)  tuple(AT, A const&, tuple const& t) -> decltype(t)
43 // (8)  tuple(AT, A const&, tuple&& t) -> decltype(t)
test_primary_template()44 void test_primary_template()
45 {
46   const std::allocator<int> A;
47   const auto AT = std::allocator_arg;
48   { // Testing (1)
49     int x = 101;
50     std::tuple t1(42);
51     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
52     std::tuple t2(x, 0.0, nullptr);
53     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>);
54   }
55   { // Testing (2)
56     using T = ExplicitTestTypes::TestType;
57     static_assert(!std::is_convertible<T const&, T>::value, "");
58 
59     std::tuple t1(T{});
60     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
61 
62     const T v{};
63     std::tuple t2(T{}, 101l, v);
64     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
65   }
66   { // Testing (3)
67     int x = 101;
68     std::tuple t1(AT, A, 42);
69     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
70 
71     std::tuple t2(AT, A, 42, 0.0, x);
72     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>);
73   }
74   { // Testing (4)
75     using T = ExplicitTestTypes::TestType;
76     static_assert(!std::is_convertible<T const&, T>::value, "");
77 
78     std::tuple t1(AT, A, T{});
79     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
80 
81     const T v{};
82     std::tuple t2(AT, A, T{}, 101l, v);
83     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
84   }
85   { // Testing (5)
86     using Tup = std::tuple<int, decltype(nullptr)>;
87     const Tup t(42, nullptr);
88 
89     std::tuple t1(t);
90     ASSERT_SAME_TYPE(decltype(t1), Tup);
91   }
92   { // Testing (6)
93     using Tup = std::tuple<void*, unsigned, char>;
94     std::tuple t1(Tup(nullptr, 42, 'a'));
95     ASSERT_SAME_TYPE(decltype(t1), Tup);
96   }
97   { // Testing (7)
98     using Tup = std::tuple<int, decltype(nullptr)>;
99     const Tup t(42, nullptr);
100 
101     std::tuple t1(AT, A, t);
102     ASSERT_SAME_TYPE(decltype(t1), Tup);
103   }
104   { // Testing (8)
105     using Tup = std::tuple<void*, unsigned, char>;
106     std::tuple t1(AT, A, Tup(nullptr, 42, 'a'));
107     ASSERT_SAME_TYPE(decltype(t1), Tup);
108   }
109 }
110 
111 // Overloads
112 //  using A = Allocator
113 //  using AT = std::allocator_arg_t
114 // ---------------
115 // (1)  tuple() -> tuple<>
116 // (2)  tuple(AT, A const&) -> tuple<>
117 // (3)  tuple(tuple const&) -> tuple<>
118 // (4)  tuple(tuple&&) -> tuple<>
119 // (5)  tuple(AT, A const&, tuple const&) -> tuple<>
120 // (6)  tuple(AT, A const&, tuple&&) -> tuple<>
test_empty_specialization()121 void test_empty_specialization()
122 {
123   std::allocator<int> A;
124   const auto AT = std::allocator_arg;
125   { // Testing (1)
126     std::tuple t1{};
127     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
128   }
129   { // Testing (2)
130     std::tuple t1{AT, A};
131     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
132   }
133   { // Testing (3)
134     const std::tuple<> t{};
135     std::tuple t1(t);
136     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
137   }
138   { // Testing (4)
139     std::tuple t1(std::tuple<>{});
140     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
141   }
142   { // Testing (5)
143     const std::tuple<> t{};
144     std::tuple t1(AT, A, t);
145     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
146   }
147   { // Testing (6)
148     std::tuple t1(AT, A, std::tuple<>{});
149     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
150   }
151 }
152 
main()153 int main() {
154   test_primary_template();
155   test_empty_specialization();
156 }
157