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
This commit is contained in:
parent
4c88839716
commit
df9722ecf1
@ -2888,29 +2888,38 @@ struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
|
|||||||
|
|
||||||
#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
|
#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>
|
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>()...))>
|
: public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class... _Args>
|
template <class _Tp>
|
||||||
struct __libcpp_is_nothrow_constructible<false, _Tp, _Args...>
|
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
|
: public false_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class... _Args>
|
template <class _Tp, class... _Args>
|
||||||
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
|
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>
|
template <class _Tp, size_t _Ns>
|
||||||
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_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>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,15 +76,28 @@ struct C
|
|||||||
void operator=(C&); // not const
|
void operator=(C&); // not const
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||||
|
struct Tuple {
|
||||||
|
Tuple(Empty&&) noexcept {}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_is_nothrow_constructible<int> ();
|
test_is_nothrow_constructible<int> ();
|
||||||
test_is_nothrow_constructible<int, const int&> ();
|
test_is_nothrow_constructible<int, const int&> ();
|
||||||
test_is_nothrow_constructible<Empty> ();
|
test_is_nothrow_constructible<Empty> ();
|
||||||
test_is_nothrow_constructible<Empty, const 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> ();
|
||||||
test_is_not_nothrow_constructible<A, int, double> ();
|
test_is_not_nothrow_constructible<A, int, double> ();
|
||||||
test_is_not_nothrow_constructible<A> ();
|
test_is_not_nothrow_constructible<A> ();
|
||||||
test_is_not_nothrow_constructible<C> ();
|
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
|
||||||
}
|
}
|
||||||
|
@ -213,4 +213,18 @@ int main()
|
|||||||
assert(std::get<3>(t3) == 4);
|
assert(std::get<3>(t3) == 4);
|
||||||
assert(std::get<4>(t3) == 5);
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user