// { dg-options "-std=gnu++2b" } // { dg-do compile { target c++23 } } #include #ifndef __cpp_lib_invoke_r # error Feature-test macro for invoke_r is missing in #elif __cpp_lib_invoke_r < 202106L # error Feature-test macro for invoke_r has the wrong value in #endif constexpr int sq(int i) { return i * i; } template constexpr bool chk(Val&& val, Expected&& exp) { return std::is_same_v && val == exp; } void test01() { static_assert( chk( std::invoke(sq, 2), 4 ) ); static_assert( chk( std::invoke_r(sq, 3), 9 ) ); static_assert( chk( std::invoke_r(sq, 4), '\x10' ) ); } struct abstract { virtual ~abstract() = 0; void operator()() noexcept; }; static_assert( noexcept(std::invoke(std::declval())), "It should be possible to use abstract types with INVOKE" ); static_assert( noexcept(std::invoke_r(std::declval())), "It should be possible to use abstract types with INVOKE" ); struct F { void operator()() &; void operator()() && noexcept; int operator()(int); double* operator()(int, int) noexcept; }; struct D { D(void*); }; static_assert( !noexcept(std::invoke(std::declval())) ); static_assert( noexcept(std::invoke(std::declval())) ); static_assert( !noexcept(std::invoke(std::declval(), 1)) ); static_assert( noexcept(std::invoke(std::declval(), 1, 2)) ); static_assert( !noexcept(std::invoke_r(std::declval())) ); static_assert( noexcept(std::invoke_r(std::declval())) ); static_assert( !noexcept(std::invoke_r(std::declval(), 1)) ); static_assert( !noexcept(std::invoke_r(std::declval(), 1)) ); static_assert( !noexcept(std::invoke_r(std::declval(), 1)) ); static_assert( noexcept(std::invoke_r(std::declval(), 1, 2)) ); static_assert( noexcept(std::invoke_r(std::declval(), 1, 2)) ); static_assert( !noexcept(std::invoke_r(std::declval(), 1, 2)) );