Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -1549,6 +1549,48 @@ = is_convertible<_From, _To>::value; #endif +// is_nothrow_convertible + +#if _LIBCPP_STD_VER > 17 + +template , is_function<_To>, is_array<_To> + >::value +> +struct __is_nothrow_convertable_helper +{ + using type = is_void<_To>; +}; + +template +struct __is_nothrow_convertable_helper<_Fm, _To, false> +{ +private: + template + static void __test_noexcept(_Tp) noexcept; + + template + static bool_constant(declval<__Fm>()))> + __test(int); + + template + static false_type + __test(...); + +public: + using type = decltype(__test<_Fm, _To>(0)); +}; + +template +struct is_nothrow_convertible : __is_nothrow_convertable_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/libcxx/type_traits/is_nothrow_convertible.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/type_traits/is_nothrow_convertible.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include + +#include "test_macros.h" + +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**) { + assert((std::is_nothrow_convertible::value)); + assert(!(std::is_nothrow_convertible::value)); + + assert(!(std::is_nothrow_convertible::value)); + assert((std::is_nothrow_convertible::value)); + + assert((std::is_nothrow_convertible_v)); + assert(!(std::is_nothrow_convertible_v)); + + assert(!(std::is_nothrow_convertible_v)); + assert((std::is_nothrow_convertible_v)); + + return 0; +}