mirror of
https://github.com/BlackMATov/invoke.hpp.git
synced 2025-12-12 21:46:18 +07:00
add is_invocable_r
This commit is contained in:
16
README.md
16
README.md
@@ -34,18 +34,26 @@
|
||||
|
||||
### `invoke_hpp::invoke(F&& f, Args&&... args)`
|
||||
|
||||
Analog of [std::invoke](https://en.cppreference.com/w/cpp/utility/functional/invoke) from C++17
|
||||
Analog of [`std::invoke`](https://en.cppreference.com/w/cpp/utility/functional/invoke) from C++17
|
||||
|
||||
### `invoke_hpp::invoke_result<F, Args...>`
|
||||
|
||||
Analog of [std::invoke_result](https://en.cppreference.com/w/cpp/types/result_of) from C++17
|
||||
Analog of [`std::invoke_result`](https://en.cppreference.com/w/cpp/types/result_of) from C++17
|
||||
|
||||
### `invoke_hpp::invoke_result_t<F, Args...>`
|
||||
|
||||
Analog of [`std::invoke_result_t`](https://en.cppreference.com/w/cpp/types/result_of) from C++17
|
||||
|
||||
### `invoke_hpp::is_invocable<F, Args...>`
|
||||
|
||||
Analog of [std::is_invocable](https://en.cppreference.com/w/cpp/types/is_invocable) from C++17
|
||||
Analog of [`std::is_invocable`](https://en.cppreference.com/w/cpp/types/is_invocable) from C++17
|
||||
|
||||
### `invoke_hpp::is_invocable_r<R, F, Args...>`
|
||||
|
||||
Analog of [`std::is_invocable_r`](https://en.cppreference.com/w/cpp/types/is_invocable) from C++17
|
||||
|
||||
### `invoke_hpp::apply(F&& f, Tuple&& args)`
|
||||
|
||||
Analog of [std::apply](https://en.cppreference.com/w/cpp/utility/apply) from C++17
|
||||
Analog of [`std::apply`](https://en.cppreference.com/w/cpp/utility/apply) from C++17
|
||||
|
||||
## [License (MIT)](./LICENSE.md)
|
||||
|
||||
22
invoke.hpp
22
invoke.hpp
@@ -191,20 +191,26 @@ namespace invoke_hpp
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
struct is_invocable_impl_tag {};
|
||||
struct is_invocable_r_impl_tag {};
|
||||
|
||||
template < typename Void, typename F, typename... Args >
|
||||
struct is_invocable_impl
|
||||
template < typename Void, typename R, typename F, typename... Args >
|
||||
struct is_invocable_r_impl
|
||||
: std::false_type {};
|
||||
|
||||
template < typename F, typename... Args >
|
||||
struct is_invocable_impl<void_t<is_invocable_impl_tag, invoke_result_t<F, Args...>>, F, Args...>
|
||||
: std::true_type {};
|
||||
template < typename R, typename F, typename... Args >
|
||||
struct is_invocable_r_impl<void_t<is_invocable_r_impl_tag, invoke_result_t<F, Args...>>, R, F, Args...>
|
||||
: std::conditional_t<
|
||||
std::is_void<R>::value,
|
||||
std::true_type,
|
||||
std::is_convertible<invoke_result_t<F, Args...>, R>> {};
|
||||
}
|
||||
|
||||
template < typename R, typename F, typename... Args >
|
||||
struct is_invocable_r
|
||||
: impl::is_invocable_r_impl<void, R, F, Args...> {};
|
||||
|
||||
template < typename F, typename... Args >
|
||||
struct is_invocable
|
||||
: impl::is_invocable_impl<void, F, Args...> {};
|
||||
using is_invocable = is_invocable_r<void, F, Args...>;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
160
tests.cpp
160
tests.cpp
@@ -298,6 +298,166 @@ TEST_CASE("is_invocable"){
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("is_invocable_r"){
|
||||
SECTION("is_invocable_r_functions"){
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(simple_static_function)>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(simple_static_function_r)>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(simple_static_function_r)>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<const int&, decltype(simple_static_function_r_with_arg), const int&>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
SECTION("is_not_invocable_r_functions"){
|
||||
static_assert(
|
||||
!inv::is_invocable_r<void, decltype(simple_static_function), int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(simple_static_function_r), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<const int&, decltype(simple_static_function_r_with_arg), const obj2_t&>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(simple_static_function)>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(simple_static_function_r)>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(simple_static_function_r_with_arg), const int&>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
SECTION("is_invocable_r_members"){
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::member), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::member), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
SECTION("is_not_invocable_r_members"){
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(&obj_t::member), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(&obj_t::member), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member_r), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(&obj_t::member_r), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(&obj_t::member_r), std::reference_wrapper<obj2_t>>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, obj2_t>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
SECTION("is_invocable_r_objects"){
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
inv::is_invocable_r<void, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
SECTION("is_not_invocable_r_objects"){
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::value), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(&obj_t::value), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int, decltype(&obj_t::value), std::reference_wrapper<obj_t>, obj2_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<void, decltype(&obj_t::value), std::reference_wrapper<obj_t>, obj2_t>::value,
|
||||
"unit test fail");
|
||||
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::value_c), obj_t>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<int*, decltype(&obj_t::value_c), obj_t*>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<obj2_t, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
||||
"unit test fail");
|
||||
static_assert(
|
||||
!inv::is_invocable_r<void, decltype(&obj_t::value_c), std::reference_wrapper<obj_t**>>::value,
|
||||
"unit test fail");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("apply"){
|
||||
SECTION("apply_functions"){
|
||||
inv::apply(simple_static_function, std::make_tuple());
|
||||
|
||||
Reference in New Issue
Block a user