xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp (revision eb12ad9d7ff64398add1a9cc84e56cc20aed09f8)
11308011eSLouis Dionne //===----------------------------------------------------------------------===//
21308011eSLouis Dionne //
31308011eSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41308011eSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
51308011eSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61308011eSLouis Dionne //
71308011eSLouis Dionne //===----------------------------------------------------------------------===//
81308011eSLouis Dionne 
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
101308011eSLouis Dionne 
111308011eSLouis Dionne // <tuple>
121308011eSLouis Dionne 
131308011eSLouis Dionne // Test that the constructors offered by std::tuple are formulated
141308011eSLouis Dionne // so they're compatible with implicit deduction guides, or if that's not
151308011eSLouis Dionne // possible that they provide explicit guides to make it work.
161308011eSLouis Dionne 
171308011eSLouis Dionne #include <tuple>
181308011eSLouis Dionne #include <cassert>
19*050b064fSChristopher Di Bella #include <functional>
20*050b064fSChristopher Di Bella #include <memory>
211308011eSLouis Dionne 
221308011eSLouis Dionne #include "test_macros.h"
23cc89063bSNico Weber #include "archetypes.h"
241308011eSLouis Dionne 
251308011eSLouis Dionne 
261308011eSLouis Dionne // Overloads
271308011eSLouis Dionne //  using A = Allocator
281308011eSLouis Dionne //  using AT = std::allocator_arg_t
291308011eSLouis Dionne // ---------------
301308011eSLouis Dionne // (1)  tuple(const Types&...) -> tuple<Types...>
311308011eSLouis Dionne // (2)  tuple(pair<T1, T2>) -> tuple<T1, T2>;
321308011eSLouis Dionne // (3)  explicit tuple(const Types&...) -> tuple<Types...>
331308011eSLouis Dionne // (4)  tuple(AT, A const&, Types const&...) -> tuple<Types...>
341308011eSLouis Dionne // (5)  explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
351308011eSLouis Dionne // (6)  tuple(AT, A, pair<T1, T2>) -> tuple<T1, T2>
361308011eSLouis Dionne // (7)  tuple(tuple const& t) -> decltype(t)
371308011eSLouis Dionne // (8)  tuple(tuple&& t) -> decltype(t)
381308011eSLouis Dionne // (9)  tuple(AT, A const&, tuple const& t) -> decltype(t)
391308011eSLouis Dionne // (10) tuple(AT, A const&, tuple&& t) -> decltype(t)
test_primary_template()401308011eSLouis Dionne void test_primary_template()
411308011eSLouis Dionne {
421308011eSLouis Dionne   const std::allocator<int> A;
431308011eSLouis Dionne   const auto AT = std::allocator_arg;
441308011eSLouis Dionne   { // Testing (1)
451308011eSLouis Dionne     int x = 101;
461308011eSLouis Dionne     std::tuple t1(42);
471308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
481308011eSLouis Dionne     std::tuple t2(x, 0.0, nullptr);
491308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>);
501308011eSLouis Dionne   }
511308011eSLouis Dionne   { // Testing (2)
521308011eSLouis Dionne     std::pair<int, char> p1(1, 'c');
531308011eSLouis Dionne     std::tuple t1(p1);
541308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
551308011eSLouis Dionne 
561308011eSLouis Dionne     std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
571308011eSLouis Dionne     std::tuple t2(p2);
581308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
591308011eSLouis Dionne 
601308011eSLouis Dionne     int i = 3;
611308011eSLouis Dionne     std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
621308011eSLouis Dionne     std::tuple t3(p3);
631308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
641308011eSLouis Dionne 
651308011eSLouis Dionne     std::pair<int&, char> p4(i, 'c');
661308011eSLouis Dionne     std::tuple t4(p4);
671308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
681308011eSLouis Dionne 
691308011eSLouis Dionne     std::tuple t5(std::pair<int, char>(1, 'c'));
701308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
711308011eSLouis Dionne   }
721308011eSLouis Dionne   { // Testing (3)
731308011eSLouis Dionne     using T = ExplicitTestTypes::TestType;
741308011eSLouis Dionne     static_assert(!std::is_convertible<T const&, T>::value, "");
751308011eSLouis Dionne 
761308011eSLouis Dionne     std::tuple t1(T{});
771308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
781308011eSLouis Dionne 
791308011eSLouis Dionne     const T v{};
801308011eSLouis Dionne     std::tuple t2(T{}, 101l, v);
811308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
821308011eSLouis Dionne   }
831308011eSLouis Dionne   { // Testing (4)
841308011eSLouis Dionne     int x = 101;
851308011eSLouis Dionne     std::tuple t1(AT, A, 42);
861308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
871308011eSLouis Dionne 
881308011eSLouis Dionne     std::tuple t2(AT, A, 42, 0.0, x);
891308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>);
901308011eSLouis Dionne   }
911308011eSLouis Dionne   { // Testing (5)
921308011eSLouis Dionne     using T = ExplicitTestTypes::TestType;
931308011eSLouis Dionne     static_assert(!std::is_convertible<T const&, T>::value, "");
941308011eSLouis Dionne 
951308011eSLouis Dionne     std::tuple t1(AT, A, T{});
961308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
971308011eSLouis Dionne 
981308011eSLouis Dionne     const T v{};
991308011eSLouis Dionne     std::tuple t2(AT, A, T{}, 101l, v);
1001308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
1011308011eSLouis Dionne   }
1021308011eSLouis Dionne   { // Testing (6)
1031308011eSLouis Dionne     std::pair<int, char> p1(1, 'c');
1041308011eSLouis Dionne     std::tuple t1(AT, A, p1);
1051308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
1061308011eSLouis Dionne 
1071308011eSLouis Dionne     std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
1081308011eSLouis Dionne     std::tuple t2(AT, A, p2);
1091308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
1101308011eSLouis Dionne 
1111308011eSLouis Dionne     int i = 3;
1121308011eSLouis Dionne     std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
1131308011eSLouis Dionne     std::tuple t3(AT, A, p3);
1141308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
1151308011eSLouis Dionne 
1161308011eSLouis Dionne     std::pair<int&, char> p4(i, 'c');
1171308011eSLouis Dionne     std::tuple t4(AT, A, p4);
1181308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
1191308011eSLouis Dionne 
1201308011eSLouis Dionne     std::tuple t5(AT, A, std::pair<int, char>(1, 'c'));
1211308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
1221308011eSLouis Dionne   }
1231308011eSLouis Dionne   { // Testing (7)
1241308011eSLouis Dionne     using Tup = std::tuple<int, decltype(nullptr)>;
1251308011eSLouis Dionne     const Tup t(42, nullptr);
1261308011eSLouis Dionne 
1271308011eSLouis Dionne     std::tuple t1(t);
1281308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), Tup);
1291308011eSLouis Dionne   }
1301308011eSLouis Dionne   { // Testing (8)
1311308011eSLouis Dionne     using Tup = std::tuple<void*, unsigned, char>;
1321308011eSLouis Dionne     std::tuple t1(Tup(nullptr, 42, 'a'));
1331308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), Tup);
1341308011eSLouis Dionne   }
1351308011eSLouis Dionne   { // Testing (9)
1361308011eSLouis Dionne     using Tup = std::tuple<int, decltype(nullptr)>;
1371308011eSLouis Dionne     const Tup t(42, nullptr);
1381308011eSLouis Dionne 
1391308011eSLouis Dionne     std::tuple t1(AT, A, t);
1401308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), Tup);
1411308011eSLouis Dionne   }
1421308011eSLouis Dionne   { // Testing (10)
1431308011eSLouis Dionne     using Tup = std::tuple<void*, unsigned, char>;
1441308011eSLouis Dionne     std::tuple t1(AT, A, Tup(nullptr, 42, 'a'));
1451308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), Tup);
1461308011eSLouis Dionne   }
1471308011eSLouis Dionne }
1481308011eSLouis Dionne 
1491308011eSLouis Dionne // Overloads
1501308011eSLouis Dionne //  using A = Allocator
1511308011eSLouis Dionne //  using AT = std::allocator_arg_t
1521308011eSLouis Dionne // ---------------
1531308011eSLouis Dionne // (1)  tuple() -> tuple<>
1541308011eSLouis Dionne // (2)  tuple(AT, A const&) -> tuple<>
1551308011eSLouis Dionne // (3)  tuple(tuple const&) -> tuple<>
1561308011eSLouis Dionne // (4)  tuple(tuple&&) -> tuple<>
1571308011eSLouis Dionne // (5)  tuple(AT, A const&, tuple const&) -> tuple<>
1581308011eSLouis Dionne // (6)  tuple(AT, A const&, tuple&&) -> tuple<>
test_empty_specialization()1591308011eSLouis Dionne void test_empty_specialization()
1601308011eSLouis Dionne {
1611308011eSLouis Dionne   std::allocator<int> A;
1621308011eSLouis Dionne   const auto AT = std::allocator_arg;
1631308011eSLouis Dionne   { // Testing (1)
1641308011eSLouis Dionne     std::tuple t1{};
1651308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1661308011eSLouis Dionne   }
1671308011eSLouis Dionne   { // Testing (2)
1681308011eSLouis Dionne     std::tuple t1{AT, A};
1691308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1701308011eSLouis Dionne   }
1711308011eSLouis Dionne   { // Testing (3)
1721308011eSLouis Dionne     const std::tuple<> t{};
1731308011eSLouis Dionne     std::tuple t1(t);
1741308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1751308011eSLouis Dionne   }
1761308011eSLouis Dionne   { // Testing (4)
1771308011eSLouis Dionne     std::tuple t1(std::tuple<>{});
1781308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1791308011eSLouis Dionne   }
1801308011eSLouis Dionne   { // Testing (5)
1811308011eSLouis Dionne     const std::tuple<> t{};
1821308011eSLouis Dionne     std::tuple t1(AT, A, t);
1831308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1841308011eSLouis Dionne   }
1851308011eSLouis Dionne   { // Testing (6)
1861308011eSLouis Dionne     std::tuple t1(AT, A, std::tuple<>{});
1871308011eSLouis Dionne     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
1881308011eSLouis Dionne   }
1891308011eSLouis Dionne }
1901308011eSLouis Dionne 
main(int,char **)1911308011eSLouis Dionne int main(int, char**) {
1921308011eSLouis Dionne   test_primary_template();
1931308011eSLouis Dionne   test_empty_specialization();
1941308011eSLouis Dionne 
1951308011eSLouis Dionne   return 0;
1961308011eSLouis Dionne }
197