add free-standing try_invoke

This commit is contained in:
BlackMATov
2023-03-03 23:55:16 +07:00
parent 78c6773ced
commit 956293a9ae
4 changed files with 155 additions and 4 deletions

View File

@@ -7175,6 +7175,11 @@ namespace meta_hpp
return function.invoke(std::forward<Args>(args)...);
}
template < typename... Args >
uresult try_invoke(const function& function, Args&&... args) {
return function.try_invoke(std::forward<Args>(args)...);
}
template < detail::function_pointer_kind Function, typename... Args >
uvalue invoke(Function function_ptr, Args&&... args) {
using namespace detail;
@@ -7182,6 +7187,22 @@ namespace meta_hpp
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
template < detail::function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
if ( const uerror err = raw_function_invoke_error<Function>(registry, vargs) ) {
return err;
}
}
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
}
namespace meta_hpp
@@ -7191,6 +7212,11 @@ namespace meta_hpp
return member.get(std::forward<Instance>(instance));
}
template < typename Instance >
uresult try_invoke(const member& member, Instance&& instance) {
return member.try_get(std::forward<Instance>(instance));
}
template < detail::member_pointer_kind Member, typename Instance >
uvalue invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
@@ -7198,6 +7224,22 @@ namespace meta_hpp
const uinst vinst{registry, std::forward<Instance>(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
}
template < detail::member_pointer_kind Member, typename Instance >
uresult try_invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const uinst_base vinst{registry, std::forward<Instance>(instance)};
if ( const uerror err = raw_member_getter_error<Member>(registry, vinst) ) {
return err;
}
}
const uinst vinst{registry, std::forward<Instance>(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
}
}
namespace meta_hpp
@@ -7207,6 +7249,11 @@ namespace meta_hpp
return method.invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
}
template < typename Instance, typename... Args >
uresult try_invoke(const method& method, Instance&& instance, Args&&... args) {
return method.try_invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
}
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
uvalue invoke(Method method_ptr, Instance&& instance, Args&&... args) {
using namespace detail;
@@ -7215,6 +7262,24 @@ namespace meta_hpp
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const uinst_base vinst{registry, std::forward<Instance>(instance)};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
if ( const uerror err = raw_method_invoke_error<Method>(registry, vinst, vargs) ) {
return err;
}
}
const uinst vinst{registry, std::forward<Instance>(instance)};
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
}
namespace meta_hpp

View File

@@ -31,8 +31,8 @@ TEST_CASE("meta/meta_issues/random/1") {
CHECK(meta::is_invocable_with(+[](const B&){ return true; }, D{}));
CHECK_FALSE(meta::is_invocable_with(+[](const A&){ return true; }, D{}));
CHECK(meta::invoke(+[](const D&){ return true; }, D{}));
CHECK(meta::invoke(+[](const C&){ return true; }, D{}));
CHECK(meta::invoke(+[](const B&){ return true; }, D{}));
CHECK_THROWS(meta::invoke(+[](const A&){ return true; }, D{}));
CHECK(meta::try_invoke(+[](const D&){ return true; }, D{}));
CHECK(meta::try_invoke(+[](const C&){ return true; }, D{}));
CHECK(meta::try_invoke(+[](const B&){ return true; }, D{}));
CHECK_FALSE(meta::try_invoke(+[](const A&){ return true; }, D{}));
}

View File

@@ -40,6 +40,13 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::invoke(clazz_function, meta::uvalue{3}).as<int>() == 3);
CHECK(meta::invoke(clazz_function, meta::uresult{3}).as<int>() == 3);
CHECK(meta::try_invoke(&clazz::function, 3)->as<int>() == 3);
CHECK(meta::try_invoke(&clazz::function, meta::uvalue{3})->as<int>() == 3);
CHECK(meta::try_invoke(&clazz::function, meta::uresult{3})->as<int>() == 3);
CHECK(meta::try_invoke(clazz_function, 3)->as<int>() == 3);
CHECK(meta::try_invoke(clazz_function, meta::uvalue{3})->as<int>() == 3);
CHECK(meta::try_invoke(clazz_function, meta::uresult{3})->as<int>() == 3);
CHECK(meta::is_invocable_with(clazz_function, 3));
CHECK(meta::is_invocable_with(clazz_function, meta::uvalue{3}));
CHECK(meta::is_invocable_with(clazz_function, meta::uresult{3}));
@@ -61,6 +68,13 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::invoke(clazz_member, meta::uvalue{cl}).as<int>() == 1);
CHECK(meta::invoke(clazz_member, meta::uresult{cl}).as<int>() == 1);
CHECK(meta::try_invoke(&clazz::member, cl)->as<int>() == 1);
CHECK(meta::try_invoke(&clazz::member, meta::uvalue{cl})->as<int>() == 1);
CHECK(meta::try_invoke(&clazz::member, meta::uresult{cl})->as<int>() == 1);
CHECK(meta::try_invoke(clazz_member, cl)->as<int>() == 1);
CHECK(meta::try_invoke(clazz_member, meta::uvalue{cl})->as<int>() == 1);
CHECK(meta::try_invoke(clazz_member, meta::uresult{cl})->as<int>() == 1);
CHECK(meta::is_invocable_with(clazz_member, cl));
CHECK(meta::is_invocable_with(clazz_member, meta::uvalue{cl}));
CHECK(meta::is_invocable_with(clazz_member, meta::uresult{cl}));
@@ -82,6 +96,13 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::invoke(clazz_method, meta::uvalue{cl}, meta::uvalue{2}).as<int>() == 2);
CHECK(meta::invoke(clazz_method, meta::uresult{cl}, meta::uresult{2}).as<int>() == 2);
CHECK(meta::try_invoke(&clazz::method, cl, 2)->as<int>() == 2);
CHECK(meta::try_invoke(&clazz::method, meta::uvalue{cl}, meta::uvalue{2})->as<int>() == 2);
CHECK(meta::try_invoke(&clazz::method, meta::uresult{cl}, meta::uresult{2})->as<int>() == 2);
CHECK(meta::try_invoke(clazz_method, cl, 2)->as<int>() == 2);
CHECK(meta::try_invoke(clazz_method, meta::uvalue{cl}, meta::uvalue{2})->as<int>() == 2);
CHECK(meta::try_invoke(clazz_method, meta::uresult{cl}, meta::uresult{2})->as<int>() == 2);
CHECK(meta::is_invocable_with(clazz_method, cl, 2));
CHECK(meta::is_invocable_with(clazz_method, meta::uvalue{cl}, meta::uvalue{2}));
CHECK(meta::is_invocable_with(clazz_method, meta::uresult{cl}, meta::uresult{2}));

View File

@@ -24,6 +24,11 @@ namespace meta_hpp
return function.invoke(std::forward<Args>(args)...);
}
template < typename... Args >
uresult try_invoke(const function& function, Args&&... args) {
return function.try_invoke(std::forward<Args>(args)...);
}
template < detail::function_pointer_kind Function, typename... Args >
uvalue invoke(Function function_ptr, Args&&... args) {
using namespace detail;
@@ -31,6 +36,22 @@ namespace meta_hpp
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
template < detail::function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
if ( const uerror err = raw_function_invoke_error<Function>(registry, vargs) ) {
return err;
}
}
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
}
namespace meta_hpp
@@ -40,6 +61,11 @@ namespace meta_hpp
return member.get(std::forward<Instance>(instance));
}
template < typename Instance >
uresult try_invoke(const member& member, Instance&& instance) {
return member.try_get(std::forward<Instance>(instance));
}
template < detail::member_pointer_kind Member, typename Instance >
uvalue invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
@@ -47,6 +73,22 @@ namespace meta_hpp
const uinst vinst{registry, std::forward<Instance>(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
}
template < detail::member_pointer_kind Member, typename Instance >
uresult try_invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const uinst_base vinst{registry, std::forward<Instance>(instance)};
if ( const uerror err = raw_member_getter_error<Member>(registry, vinst) ) {
return err;
}
}
const uinst vinst{registry, std::forward<Instance>(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
}
}
namespace meta_hpp
@@ -56,6 +98,11 @@ namespace meta_hpp
return method.invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
}
template < typename Instance, typename... Args >
uresult try_invoke(const method& method, Instance&& instance, Args&&... args) {
return method.try_invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
}
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
uvalue invoke(Method method_ptr, Instance&& instance, Args&&... args) {
using namespace detail;
@@ -64,6 +111,24 @@ namespace meta_hpp
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
const uinst_base vinst{registry, std::forward<Instance>(instance)};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
if ( const uerror err = raw_method_invoke_error<Method>(registry, vinst, vargs) ) {
return err;
}
}
const uinst vinst{registry, std::forward<Instance>(instance)};
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, std::forward<Args>(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
}
namespace meta_hpp