summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxx/include/type_traits21
-rw-r--r--libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp15
-rw-r--r--libcxx/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp14
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)));
+ }
}
OpenPOWER on IntegriCloud