diff --git a/include/boost/compat/invoke.hpp b/include/boost/compat/invoke.hpp index c689483..447c56a 100644 --- a/include/boost/compat/invoke.hpp +++ b/include/boost/compat/invoke.hpp @@ -92,6 +92,27 @@ template struct is_invocable_r: conditional_t< std::is_void::value, std::true_type, detail::is_invocable_r_ >> {}; +// is_nothrow_invocable_r + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +template struct is_nothrow_invocable_r: std::false_type {}; + +#else + +namespace detail { + +template struct is_nothrow_invocable_r_ +{ + using type = std::integral_constant( std::declval(), std::declval()... ) )>; +}; + +} // namespace detail + +template struct is_nothrow_invocable_r: conditional_t< is_invocable_r::value, detail::is_nothrow_invocable_r_, std::false_type >::type {}; + +#endif + } // namespace compat } // namespace boost diff --git a/test/Jamfile b/test/Jamfile index 9ea476f..7837868 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -93,3 +93,4 @@ compile invoke_r_md_constexpr_test.cpp : gcc-4.8:no gcc-4.9:no ; run is_invocable_r_test.cpp ; +run is_nothrow_invocable_r_test.cpp ; diff --git a/test/is_nothrow_invocable_r_test.cpp b/test/is_nothrow_invocable_r_test.cpp new file mode 100644 index 0000000..d614cb0 --- /dev/null +++ b/test/is_nothrow_invocable_r_test.cpp @@ -0,0 +1,288 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +struct F +{ + void operator()() + { + } + + char operator()( char x1 ) noexcept + { + return x1; + } + + int operator()( int x1, int x2 ) const + { + return 10*x1+x2; + } + + double operator()( float x1, float x2, float x3 ) const noexcept + { + return 100*x1 + 10*x2 + x3; + } +}; + +struct X +{ +}; + +struct Y +{ + Y( int ); + Y( double ) noexcept; +}; + +int main() +{ + using boost::compat::is_nothrow_invocable_r; + + // nonfunction + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + // function reference + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + +#if defined(__cpp_noexcept_function_type) + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + +#endif + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + // function pointer + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + +#if defined(__cpp_noexcept_function_type) + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + +#endif + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + // object + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + +#endif + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + // member function pointer + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + +#if defined(__cpp_noexcept_function_type) + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + +#endif + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + // member data pointer + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r )); + +#endif + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r )); + + return boost::report_errors(); +}