summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/tuple28
-rw-r--r--libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp (renamed from libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/implicit_deduction_guides.pass.cpp)70
2 files changed, 78 insertions, 20 deletions
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 65065872991..32bc86913aa 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -69,6 +69,17 @@ public:
void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
};
+template <class ...T>
+tuple(T...) -> tuple<T...>; // since C++17
+template <class T1, class T2>
+tuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17
+template <class Alloc, class ...T>
+tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17
+template <class Alloc, class T1, class T2>
+tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17
+template <class Alloc, class ...T>
+tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17
+
inline constexpr unspecified ignore;
template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14
@@ -943,13 +954,16 @@ public:
};
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
-// NOTE: These are not yet standardized, but are required to simulate the
-// implicit deduction guide that should be generated had libc++ declared the
-// tuple-like constructors "correctly"
-template <class _Alloc, class ..._Args>
-tuple(allocator_arg_t, const _Alloc&, tuple<_Args...> const&) -> tuple<_Args...>;
-template <class _Alloc, class ..._Args>
-tuple(allocator_arg_t, const _Alloc&, tuple<_Args...>&&) -> tuple<_Args...>;
+template <class ..._Tp>
+tuple(_Tp...) -> tuple<_Tp...>;
+template <class _Tp1, class _Tp2>
+tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
+template <class _Alloc, class ..._Tp>
+tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
+template <class _Alloc, class _Tp1, class _Tp2>
+tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
+template <class _Alloc, class ..._Tp>
+tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
#endif
template <class ..._Tp>
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/deduct.pass.cpp
index 3ff089a0b31..e903cd0b476 100644
--- 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/deduct.pass.cpp
@@ -33,13 +33,15 @@
// using AT = std::allocator_arg_t
// ---------------
// (1) tuple(const Types&...) -> tuple<Types...>
-// (2) explicit tuple(const Types&...) -> tuple<Types...>
-// (3) tuple(AT, A const&, Types const&...) -> tuple<Types...>
-// (4) explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
-// (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)
+// (2) tuple(pair<T1, T2>) -> tuple<T1, T2>;
+// (3) explicit tuple(const Types&...) -> tuple<Types...>
+// (4) tuple(AT, A const&, Types const&...) -> tuple<Types...>
+// (5) explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
+// (6) tuple(AT, A, pair<T1, T2>) -> tuple<T1, T2>
+// (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<int> A;
@@ -52,6 +54,27 @@ void test_primary_template()
ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>);
}
{ // Testing (2)
+ std::pair<int, char> p1(1, 'c');
+ std::tuple t1(p1);
+ ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
+
+ std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
+ std::tuple t2(p2);
+ ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
+
+ int i = 3;
+ std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
+ std::tuple t3(p3);
+ ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
+
+ std::pair<int&, char> p4(i, 'c');
+ std::tuple t4(p4);
+ ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
+
+ std::tuple t5(std::pair<int, char>(1, 'c'));
+ ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
+ }
+ { // Testing (3)
using T = ExplicitTestTypes::TestType;
static_assert(!std::is_convertible<T const&, T>::value, "");
@@ -62,7 +85,7 @@ void test_primary_template()
std::tuple t2(T{}, 101l, v);
ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
}
- { // Testing (3)
+ { // Testing (4)
int x = 101;
std::tuple t1(AT, A, 42);
ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
@@ -70,7 +93,7 @@ void test_primary_template()
std::tuple t2(AT, A, 42, 0.0, x);
ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>);
}
- { // Testing (4)
+ { // Testing (5)
using T = ExplicitTestTypes::TestType;
static_assert(!std::is_convertible<T const&, T>::value, "");
@@ -81,26 +104,47 @@ void test_primary_template()
std::tuple t2(AT, A, T{}, 101l, v);
ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
}
- { // Testing (5)
+ { // Testing (6)
+ std::pair<int, char> p1(1, 'c');
+ std::tuple t1(AT, A, p1);
+ ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
+
+ std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
+ std::tuple t2(AT, A, p2);
+ ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
+
+ int i = 3;
+ std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
+ std::tuple t3(AT, A, p3);
+ ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
+
+ std::pair<int&, char> p4(i, 'c');
+ std::tuple t4(AT, A, p4);
+ ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
+
+ std::tuple t5(AT, A, std::pair<int, char>(1, 'c'));
+ ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
+ }
+ { // Testing (7)
using Tup = std::tuple<int, decltype(nullptr)>;
const Tup t(42, nullptr);
std::tuple t1(t);
ASSERT_SAME_TYPE(decltype(t1), Tup);
}
- { // Testing (6)
+ { // Testing (8)
using Tup = std::tuple<void*, unsigned, char>;
std::tuple t1(Tup(nullptr, 42, 'a'));
ASSERT_SAME_TYPE(decltype(t1), Tup);
}
- { // Testing (7)
+ { // Testing (9)
using Tup = std::tuple<int, decltype(nullptr)>;
const Tup t(42, nullptr);
std::tuple t1(AT, A, t);
ASSERT_SAME_TYPE(decltype(t1), Tup);
}
- { // Testing (8)
+ { // Testing (10)
using Tup = std::tuple<void*, unsigned, char>;
std::tuple t1(AT, A, Tup(nullptr, 42, 'a'));
ASSERT_SAME_TYPE(decltype(t1), Tup);
OpenPOWER on IntegriCloud