Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -144,6 +144,10 @@ template struct is_same; template struct is_base_of; template struct is_convertible; + + template struct is_nothrow_convertible; // C++20 + template inline constexpr bool is_nothrow_convertible_v; // C++20 + template struct is_invocable; template struct is_invocable_r; @@ -1578,6 +1582,32 @@ = is_convertible<_From, _To>::value; #endif +// is_nothrow_convertible + +#if _LIBCPP_STD_VER > 17 + +template +static void __test_noexcept(_Tp) noexcept; + +template +static bool_constant(declval<_Fm>()))> +__is_nothrow_convertible_test(); + +template +struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>()) +{ }; + +template +struct is_nothrow_convertible : __or_< + __and_, is_void<_Fm>>, + __and_, __is_nothrow_convertible_helper<_Fm, _To>> +>::type { }; + +template +inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value; + +#endif // _LIBCPP_STD_VER > 17 + // is_empty #if __has_feature(is_empty) || (_GNUC_VER >= 407) Index: test/std/type_traits/is_nothrow_convertible.pass.cpp =================================================================== --- /dev/null +++ test/std/type_traits/is_nothrow_convertible.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include + +struct A {}; +struct B { +public: + operator A() { return a; } A a; +}; + +class C { }; +class D { +public: + operator C() noexcept { return c; } C c; +}; + +int main(int, char**) { + static_assert((std::is_nothrow_convertible::value), ""); + static_assert(!(std::is_nothrow_convertible::value), ""); + + static_assert(!(std::is_nothrow_convertible::value), ""); + static_assert((std::is_nothrow_convertible::value), ""); + + static_assert((std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert((std::is_nothrow_convertible_v), ""); + + static_assert((std::is_nothrow_convertible_v), ""); + static_assert((std::is_nothrow_convertible_v), ""); + static_assert((std::is_nothrow_convertible_v), ""); + static_assert((std::is_nothrow_convertible_v), ""); + + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + + typedef void V(); + typedef int I(); + static_assert(!(std::is_nothrow_convertible_v), ""); + static_assert(!(std::is_nothrow_convertible_v), ""); + + return 0; +} Index: www/cxx2a_status.html =================================================================== --- www/cxx2a_status.html +++ www/cxx2a_status.html @@ -92,7 +92,7 @@ P0619R4LWGReviewing Deprecated Facilities of C++17 for C++20Rapperswil P0646R1LWGImproving the Return Value of Erase-Like AlgorithmsRapperswil P0722R3CWGEfficient sized delete for variable sized classesRapperswil - P0758R1LWGImplicit conversion traits and utility functionsRapperswil + P0758R1LWGImplicit conversion traits and utility functionsRapperswilComplete P0759R1LWGfpos RequirementsRapperswil P0769R2LWGAdd shift to <algorithm>Rapperswil P0788R3LWGStandard Library Specification in a Concepts and Contracts WorldRapperswil