add is_invocable

This commit is contained in:
2018-12-08 10:39:05 +07:00
parent ef07141ccc
commit c9df9a83e8
4 changed files with 184 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
build/*
.vscode/*
CMakeLists.txt.user

View File

@@ -40,6 +40,10 @@ Analog of [std::invoke](https://en.cppreference.com/w/cpp/utility/functional/inv
Analog of [std::invoke_result](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
### `invoke_hpp::apply(F&& f, Tuple&& args)`
Analog of [std::apply](https://en.cppreference.com/w/cpp/utility/apply) from C++17

View File

@@ -183,6 +183,30 @@ namespace invoke_hpp
using invoke_result_t = typename invoke_result<F, Args...>::type;
}
//
// is_invocable
//
namespace invoke_hpp
{
namespace impl
{
struct is_invocable_impl_tag {};
template < typename Void, typename F, typename... Args >
struct is_invocable_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 F, typename... Args >
struct is_invocable
: impl::is_invocable_impl<void, F, Args...> {};
}
//
// apply
//

155
tests.cpp
View File

@@ -41,6 +41,9 @@ namespace
return v;
}
};
class obj2_t {
};
}
TEST_CASE("invoke"){
@@ -100,6 +103,16 @@ TEST_CASE("invoke_result"){
int,
inv::invoke_result_t<decltype(simple_static_function_r)>>::value,
"unit test fail");
static_assert(
std::is_same<
int,
inv::invoke_result_t<decltype(simple_static_function_r_with_arg), int>>::value,
"unit test fail");
static_assert(
std::is_same<
const int&,
inv::invoke_result_t<decltype(simple_static_function_r_with_ref_arg), const int&>>::value,
"unit test fail");
}
SECTION("invoke_result_members"){
static_assert(
@@ -140,6 +153,148 @@ TEST_CASE("invoke_result"){
std::is_same<int,
inv::invoke_result_t<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>>::value,
"unit test fail");
static_assert(
std::is_same<const int&,
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), obj_t, const int&>>::value,
"unit test fail");
static_assert(
std::is_same<const int&,
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), obj_t*, const int&>>::value,
"unit test fail");
static_assert(
std::is_same<const int&,
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), std::reference_wrapper<obj_t>, const int&>>::value,
"unit test fail");
}
}
TEST_CASE("is_invocable"){
SECTION("is_invocable_functions"){
static_assert(
inv::is_invocable<decltype(simple_static_function)>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(simple_static_function_r)>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(simple_static_function_r_with_arg), int>::value,
"unit test fail");
}
SECTION("is_not_invocable_functions"){
static_assert(
!inv::is_invocable<decltype(simple_static_function), int>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(simple_static_function_r), obj_t>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(simple_static_function_r_with_arg)>::value,
"unit test fail");
}
SECTION("is_invocable_members"){
static_assert(
inv::is_invocable<decltype(&obj_t::member), obj_t>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member), obj_t*>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r), obj_t>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r), obj_t*>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
"unit test fail");
}
SECTION("is_not_invocable_members"){
static_assert(
!inv::is_invocable<decltype(&obj_t::member)>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member), int>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member), std::reference_wrapper<obj_t>*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r), obj_t**>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r), obj2_t*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r), std::reference_wrapper<obj2_t>>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t, char*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj2_t>, int>::value,
"unit test fail");
}
SECTION("is_invocable_objects"){
static_assert(
inv::is_invocable<decltype(&obj_t::value), obj_t>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::value), obj_t*>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::value_c), obj_t>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::value_c), obj_t*>::value,
"unit test fail");
static_assert(
inv::is_invocable<decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
"unit test fail");
}
SECTION("is_not_invocable_objects"){
static_assert(
!inv::is_invocable<decltype(&obj_t::value)>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::value), obj2_t*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::value), obj_t, int>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::value_c), obj_t**>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::value_c), obj_t*, obj_t*>::value,
"unit test fail");
static_assert(
!inv::is_invocable<decltype(&obj_t::value_c), std::reference_wrapper<obj_t**>>::value,
"unit test fail");
}
}