From 1308011e1b5c5382281a63dd4191a1784f8d2295 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 12 Aug 2019 18:30:31 +0000 Subject: [libc++] Implement CTAD for std::tuple Summary: We were using implicit deduction guides instead of explicit ones, however the implicit ones don't do work anymore when changing the constructors. This commit adds the actual guides specified in the Standard to make libc++ (1) closer to the Standard and (2) more resistent to changes in std::tuple's constructors. Reviewers: Quuxplusone Subscribers: christof, jkorous, dexonsmith, libcxx-commits Tags: #libc Differential Revision: https://reviews.llvm.org/D65225 llvm-svn: 368599 --- .../tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp | 201 +++++++++++++++++++++ .../tuple.cnstr/implicit_deduction_guides.pass.cpp | 157 ---------------- 2 files changed, 201 insertions(+), 157 deletions(-) create mode 100644 libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp delete mode 100644 libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/implicit_deduction_guides.pass.cpp (limited to 'libcxx/test/std') diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp new file mode 100644 index 00000000000..e903cd0b476 --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp @@ -0,0 +1,201 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// GCC's implementation of class template deduction is still immature and runs +// into issues with libc++. However GCC accepts this code when compiling +// against libstdc++. +// XFAIL: gcc + +// + +// Test that the constructors offered by std::tuple are formulated +// so they're compatible with implicit deduction guides, or if that's not +// possible that they provide explicit guides to make it work. + +#include +#include +#include + +#include "test_macros.h" +#include "archetypes.hpp" + + +// Overloads +// using A = Allocator +// using AT = std::allocator_arg_t +// --------------- +// (1) tuple(const Types&...) -> tuple +// (2) tuple(pair) -> tuple; +// (3) explicit tuple(const Types&...) -> tuple +// (4) tuple(AT, A const&, Types const&...) -> tuple +// (5) explicit tuple(AT, A const&, Types const&...) -> tuple +// (6) tuple(AT, A, pair) -> tuple +// (7) tuple(tuple const& t) -> decltype(t) +// (8) tuple(tuple&& t) -> decltype(t) +// (9) tuple(AT, A const&, tuple const& t) -> decltype(t) +// (10) tuple(AT, A const&, tuple&& t) -> decltype(t) +void test_primary_template() +{ + const std::allocator A; + const auto AT = std::allocator_arg; + { // Testing (1) + int x = 101; + std::tuple t1(42); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + std::tuple t2(x, 0.0, nullptr); + ASSERT_SAME_TYPE(decltype(t2), std::tuple); + } + { // Testing (2) + std::pair p1(1, 'c'); + std::tuple t1(p1); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + + std::pair> p2(1, std::tuple('c', 3l, nullptr)); + std::tuple t2(p2); + ASSERT_SAME_TYPE(decltype(t2), std::tuple>); + + int i = 3; + std::pair, char> p3(std::ref(i), 'c'); + std::tuple t3(p3); + ASSERT_SAME_TYPE(decltype(t3), std::tuple, char>); + + std::pair p4(i, 'c'); + std::tuple t4(p4); + ASSERT_SAME_TYPE(decltype(t4), std::tuple); + + std::tuple t5(std::pair(1, 'c')); + ASSERT_SAME_TYPE(decltype(t5), std::tuple); + } + { // Testing (3) + using T = ExplicitTestTypes::TestType; + static_assert(!std::is_convertible::value, ""); + + std::tuple t1(T{}); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + + const T v{}; + std::tuple t2(T{}, 101l, v); + ASSERT_SAME_TYPE(decltype(t2), std::tuple); + } + { // Testing (4) + int x = 101; + std::tuple t1(AT, A, 42); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + + std::tuple t2(AT, A, 42, 0.0, x); + ASSERT_SAME_TYPE(decltype(t2), std::tuple); + } + { // Testing (5) + using T = ExplicitTestTypes::TestType; + static_assert(!std::is_convertible::value, ""); + + std::tuple t1(AT, A, T{}); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + + const T v{}; + std::tuple t2(AT, A, T{}, 101l, v); + ASSERT_SAME_TYPE(decltype(t2), std::tuple); + } + { // Testing (6) + std::pair p1(1, 'c'); + std::tuple t1(AT, A, p1); + ASSERT_SAME_TYPE(decltype(t1), std::tuple); + + std::pair> p2(1, std::tuple('c', 3l, nullptr)); + std::tuple t2(AT, A, p2); + ASSERT_SAME_TYPE(decltype(t2), std::tuple>); + + int i = 3; + std::pair, char> p3(std::ref(i), 'c'); + std::tuple t3(AT, A, p3); + ASSERT_SAME_TYPE(decltype(t3), std::tuple, char>); + + std::pair p4(i, 'c'); + std::tuple t4(AT, A, p4); + ASSERT_SAME_TYPE(decltype(t4), std::tuple); + + std::tuple t5(AT, A, std::pair(1, 'c')); + ASSERT_SAME_TYPE(decltype(t5), std::tuple); + } + { // Testing (7) + using Tup = std::tuple; + const Tup t(42, nullptr); + + std::tuple t1(t); + ASSERT_SAME_TYPE(decltype(t1), Tup); + } + { // Testing (8) + using Tup = std::tuple; + std::tuple t1(Tup(nullptr, 42, 'a')); + ASSERT_SAME_TYPE(decltype(t1), Tup); + } + { // Testing (9) + using Tup = std::tuple; + const Tup t(42, nullptr); + + std::tuple t1(AT, A, t); + ASSERT_SAME_TYPE(decltype(t1), Tup); + } + { // Testing (10) + using Tup = std::tuple; + std::tuple t1(AT, A, Tup(nullptr, 42, 'a')); + ASSERT_SAME_TYPE(decltype(t1), Tup); + } +} + +// Overloads +// using A = Allocator +// using AT = std::allocator_arg_t +// --------------- +// (1) tuple() -> tuple<> +// (2) tuple(AT, A const&) -> tuple<> +// (3) tuple(tuple const&) -> tuple<> +// (4) tuple(tuple&&) -> tuple<> +// (5) tuple(AT, A const&, tuple const&) -> tuple<> +// (6) tuple(AT, A const&, tuple&&) -> tuple<> +void test_empty_specialization() +{ + std::allocator A; + const auto AT = std::allocator_arg; + { // Testing (1) + std::tuple t1{}; + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } + { // Testing (2) + std::tuple t1{AT, A}; + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } + { // Testing (3) + const std::tuple<> t{}; + std::tuple t1(t); + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } + { // Testing (4) + std::tuple t1(std::tuple<>{}); + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } + { // Testing (5) + const std::tuple<> t{}; + std::tuple t1(AT, A, t); + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } + { // Testing (6) + std::tuple t1(AT, A, std::tuple<>{}); + ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); + } +} + +int main(int, char**) { + test_primary_template(); + test_empty_specialization(); + + return 0; +} diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/implicit_deduction_guides.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/implicit_deduction_guides.pass.cpp deleted file mode 100644 index 3ff089a0b31..00000000000 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/implicit_deduction_guides.pass.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 -// UNSUPPORTED: libcpp-no-deduction-guides - -// GCC's implementation of class template deduction is still immature and runs -// into issues with libc++. However GCC accepts this code when compiling -// against libstdc++. -// XFAIL: gcc - -// - -// Test that the constructors offered by std::tuple are formulated -// so they're compatible with implicit deduction guides, or if that's not -// possible that they provide explicit guides to make it work. - -#include -#include -#include - -#include "test_macros.h" -#include "archetypes.hpp" - - -// Overloads -// using A = Allocator -// using AT = std::allocator_arg_t -// --------------- -// (1) tuple(const Types&...) -> tuple -// (2) explicit tuple(const Types&...) -> tuple -// (3) tuple(AT, A const&, Types const&...) -> tuple -// (4) explicit tuple(AT, A const&, Types const&...) -> tuple -// (5) tuple(tuple const& t) -> decltype(t) -// (6) tuple(tuple&& t) -> decltype(t) -// (7) tuple(AT, A const&, tuple const& t) -> decltype(t) -// (8) tuple(AT, A const&, tuple&& t) -> decltype(t) -void test_primary_template() -{ - const std::allocator A; - const auto AT = std::allocator_arg; - { // Testing (1) - int x = 101; - std::tuple t1(42); - ASSERT_SAME_TYPE(decltype(t1), std::tuple); - std::tuple t2(x, 0.0, nullptr); - ASSERT_SAME_TYPE(decltype(t2), std::tuple); - } - { // Testing (2) - using T = ExplicitTestTypes::TestType; - static_assert(!std::is_convertible::value, ""); - - std::tuple t1(T{}); - ASSERT_SAME_TYPE(decltype(t1), std::tuple); - - const T v{}; - std::tuple t2(T{}, 101l, v); - ASSERT_SAME_TYPE(decltype(t2), std::tuple); - } - { // Testing (3) - int x = 101; - std::tuple t1(AT, A, 42); - ASSERT_SAME_TYPE(decltype(t1), std::tuple); - - std::tuple t2(AT, A, 42, 0.0, x); - ASSERT_SAME_TYPE(decltype(t2), std::tuple); - } - { // Testing (4) - using T = ExplicitTestTypes::TestType; - static_assert(!std::is_convertible::value, ""); - - std::tuple t1(AT, A, T{}); - ASSERT_SAME_TYPE(decltype(t1), std::tuple); - - const T v{}; - std::tuple t2(AT, A, T{}, 101l, v); - ASSERT_SAME_TYPE(decltype(t2), std::tuple); - } - { // Testing (5) - using Tup = std::tuple; - const Tup t(42, nullptr); - - std::tuple t1(t); - ASSERT_SAME_TYPE(decltype(t1), Tup); - } - { // Testing (6) - using Tup = std::tuple; - std::tuple t1(Tup(nullptr, 42, 'a')); - ASSERT_SAME_TYPE(decltype(t1), Tup); - } - { // Testing (7) - using Tup = std::tuple; - const Tup t(42, nullptr); - - std::tuple t1(AT, A, t); - ASSERT_SAME_TYPE(decltype(t1), Tup); - } - { // Testing (8) - using Tup = std::tuple; - std::tuple t1(AT, A, Tup(nullptr, 42, 'a')); - ASSERT_SAME_TYPE(decltype(t1), Tup); - } -} - -// Overloads -// using A = Allocator -// using AT = std::allocator_arg_t -// --------------- -// (1) tuple() -> tuple<> -// (2) tuple(AT, A const&) -> tuple<> -// (3) tuple(tuple const&) -> tuple<> -// (4) tuple(tuple&&) -> tuple<> -// (5) tuple(AT, A const&, tuple const&) -> tuple<> -// (6) tuple(AT, A const&, tuple&&) -> tuple<> -void test_empty_specialization() -{ - std::allocator A; - const auto AT = std::allocator_arg; - { // Testing (1) - std::tuple t1{}; - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } - { // Testing (2) - std::tuple t1{AT, A}; - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } - { // Testing (3) - const std::tuple<> t{}; - std::tuple t1(t); - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } - { // Testing (4) - std::tuple t1(std::tuple<>{}); - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } - { // Testing (5) - const std::tuple<> t{}; - std::tuple t1(AT, A, t); - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } - { // Testing (6) - std::tuple t1(AT, A, std::tuple<>{}); - ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); - } -} - -int main(int, char**) { - test_primary_template(); - test_empty_specialization(); - - return 0; -} -- cgit v1.2.3