From c9df9a83e83f13d7f948db63a888987c159fb0ac Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Dec 2018 10:39:05 +0700 Subject: [PATCH] add is_invocable --- .gitignore | 1 + README.md | 4 ++ invoke.hpp | 24 +++++++++ tests.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) diff --git a/.gitignore b/.gitignore index 2300a2d..eb695eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/* +.vscode/* CMakeLists.txt.user diff --git a/README.md b/README.md index 307a258..32d3ac0 100644 --- a/README.md +++ b/README.md @@ -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` + +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 diff --git a/invoke.hpp b/invoke.hpp index d365795..e1bbdb4 100644 --- a/invoke.hpp +++ b/invoke.hpp @@ -183,6 +183,30 @@ namespace invoke_hpp using invoke_result_t = typename invoke_result::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>, F, Args...> + : std::true_type {}; + } + + template < typename F, typename... Args > + struct is_invocable + : impl::is_invocable_impl {}; +} + // // apply // diff --git a/tests.cpp b/tests.cpp index b712ec2..8954086 100644 --- a/tests.cpp +++ b/tests.cpp @@ -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>::value, "unit test fail"); + static_assert( + std::is_same< + int, + inv::invoke_result_t>::value, + "unit test fail"); + static_assert( + std::is_same< + const int&, + inv::invoke_result_t>::value, + "unit test fail"); } SECTION("invoke_result_members"){ static_assert( @@ -140,6 +153,148 @@ TEST_CASE("invoke_result"){ std::is_same, int>>::value, "unit test fail"); + + static_assert( + std::is_same>::value, + "unit test fail"); + static_assert( + std::is_same>::value, + "unit test fail"); + static_assert( + std::is_same, const int&>>::value, + "unit test fail"); + } +} + +TEST_CASE("is_invocable"){ + SECTION("is_invocable_functions"){ + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + } + SECTION("is_not_invocable_functions"){ + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + } + SECTION("is_invocable_members"){ + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable>::value, + "unit test fail"); + + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable>::value, + "unit test fail"); + + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable, int>::value, + "unit test fail"); + } + SECTION("is_not_invocable_members"){ + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable*>::value, + "unit test fail"); + + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable>::value, + "unit test fail"); + + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable, int>::value, + "unit test fail"); + } + SECTION("is_invocable_objects"){ + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable>::value, + "unit test fail"); + + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable::value, + "unit test fail"); + static_assert( + inv::is_invocable>::value, + "unit test fail"); + } + SECTION("is_not_invocable_objects"){ + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable::value, + "unit test fail"); + static_assert( + !inv::is_invocable>::value, + "unit test fail"); } }