From df9722ecf1c1bdffe53f5eff23120647193f033f Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 7 Oct 2014 21:42:12 +0000 Subject: [PATCH] Fix for PR 19616: 'tuple_cat of nested tuples fails in noexcept specification'. Thanks to Louis Dionne for the fix. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@219243 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/type_traits | 21 +++++++++++++------ .../is_nothrow_constructible.pass.cpp | 15 ++++++++++++- .../tuple.creation/tuple_cat.pass.cpp | 14 +++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/include/type_traits b/include/type_traits index bd10697c..5d217289 100644 --- a/include/type_traits +++ b/include/type_traits @@ -2888,29 +2888,38 @@ struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible #if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) -template struct __libcpp_is_nothrow_constructible; +template struct __libcpp_is_nothrow_constructible; template -struct __libcpp_is_nothrow_constructible +struct __libcpp_is_nothrow_constructible : public integral_constant()...))> { }; -template -struct __libcpp_is_nothrow_constructible +template +void __implicit_conversion_to(_Tp) noexcept { } + +template +struct __libcpp_is_nothrow_constructible + : public integral_constant(declval<_Arg>()))> +{ +}; + +template +struct __libcpp_is_nothrow_constructible : public false_type { }; template struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible - : __libcpp_is_nothrow_constructible::value, _Tp, _Args...> + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp, _Args...> { }; template struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]> - : __libcpp_is_nothrow_constructible::value, _Tp> + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp> { }; diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp index 9d3f8298..fe0b5673 100644 --- a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp +++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp @@ -76,15 +76,28 @@ struct C void operator=(C&); // not const }; +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +struct Tuple { + Tuple(Empty&&) noexcept {} +}; +#endif + int main() { test_is_nothrow_constructible (); test_is_nothrow_constructible (); test_is_nothrow_constructible (); test_is_nothrow_constructible (); - +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + test_is_nothrow_constructible (); // See bug #19616. +#endif + test_is_not_nothrow_constructible (); test_is_not_nothrow_constructible (); test_is_not_nothrow_constructible (); test_is_not_nothrow_constructible (); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + static_assert(!std::is_constructible::value, ""); + test_is_not_nothrow_constructible (); // See bug #19616. +#endif } diff --git a/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp index b47842d4..3fca5738 100644 --- a/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp +++ b/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp @@ -213,4 +213,18 @@ int main() assert(std::get<3>(t3) == 4); assert(std::get<4>(t3) == 5); } + { + // See bug #19616. + auto t1 = std::tuple_cat( + std::make_tuple(std::make_tuple(1)), + std::make_tuple() + ); + assert(t1 == std::make_tuple(std::make_tuple(1))); + + auto t2 = std::tuple_cat( + std::make_tuple(std::make_tuple(1)), + std::make_tuple(std::make_tuple(2)) + ); + assert(t2 == std::make_tuple(std::make_tuple(1), std::make_tuple(2))); + } }