diff options
3 files changed, 43 insertions, 7 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index bd10697cae7..5d2172896fc 100644 --- a/libcxx/include/type_traits +++ b/libcxx/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 <bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible; +template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible; template <class _Tp, class... _Args> -struct __libcpp_is_nothrow_constructible<true, _Tp, _Args...> +struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...> : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> { }; -template <class _Tp, class... _Args> -struct __libcpp_is_nothrow_constructible<false, _Tp, _Args...> +template <class _Tp> +void __implicit_conversion_to(_Tp) noexcept { } + +template <class _Tp, class _Arg> +struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg> + : public integral_constant<bool, noexcept(__implicit_conversion_to<_Tp>(declval<_Arg>()))> +{ +}; + +template <class _Tp, bool _IsReference, class... _Args> +struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...> : public false_type { }; template <class _Tp, class... _Args> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible - : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, _Tp, _Args...> + : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...> { }; template <class _Tp, size_t _Ns> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]> - : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, _Tp> + : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> { }; diff --git a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp index 9d3f8298757..fe0b5673bc4 100644 --- a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp +++ b/libcxx/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<int> (); test_is_nothrow_constructible<int, const int&> (); test_is_nothrow_constructible<Empty> (); test_is_nothrow_constructible<Empty, const Empty&> (); - +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616. +#endif + test_is_not_nothrow_constructible<A, int> (); test_is_not_nothrow_constructible<A, int, double> (); test_is_not_nothrow_constructible<A> (); test_is_not_nothrow_constructible<C> (); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + static_assert(!std::is_constructible<Tuple&, Empty>::value, ""); + test_is_not_nothrow_constructible<Tuple &, Empty> (); // See bug #19616. +#endif } diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp index b47842d419c..3fca5738929 100644 --- a/libcxx/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp +++ b/libcxx/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))); + } } |

