add variadic variants of universal invoke functions

This commit is contained in:
BlackMATov
2024-02-10 12:40:02 +07:00
parent 8e220c0ee9
commit 468b2abb36
7 changed files with 496 additions and 109 deletions

View File

@@ -25,6 +25,20 @@ namespace meta_hpp
template < function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args);
//
template < typename Iter >
uvalue invoke_variadic(const function& function, Iter first, Iter last);
template < typename Iter >
uresult try_invoke_variadic(const function& function, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uvalue invoke_variadic(Function function_ptr, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uresult try_invoke_variadic(Function function_ptr, Iter first, Iter last);
}
namespace meta_hpp
@@ -55,6 +69,20 @@ namespace meta_hpp
template < method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args);
//
template < typename Instance, typename Iter >
uvalue invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter >
uresult try_invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uvalue invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uresult try_invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
}
namespace meta_hpp
@@ -82,6 +110,20 @@ namespace meta_hpp
template < typename... Args, function_pointer_kind Function >
uerror check_invocable_error(Function function_ptr, Args&&... args) noexcept;
//
template < typename Iter >
bool is_variadic_invocable_with(const function& function, Iter first, Iter last) noexcept;
template < typename Iter, function_pointer_kind Function >
bool is_variadic_invocable_with(Function function_ptr, Iter first, Iter last) noexcept;
template < typename Iter >
uerror check_variadic_invocable_error(const function& function, Iter first, Iter last) noexcept;
template < typename Iter, function_pointer_kind Function >
uerror check_variadic_invocable_error(Function function_ptr, Iter first, Iter last) noexcept;
}
namespace meta_hpp
@@ -136,4 +178,18 @@ namespace meta_hpp
template < typename Instance, typename... Args, method_pointer_kind Method >
uerror check_invocable_error(Method method_ptr, Instance&& instance, Args&&... args) noexcept;
//
template < typename Instance, typename Iter >
bool is_variadic_invocable_with(const method& method, Instance&& instance, Iter first, Iter last) noexcept;
template < typename Instance, typename Iter, method_pointer_kind Method >
bool is_variadic_invocable_with(Method method_ptr, Instance&& instance, Iter first, Iter last) noexcept;
template < typename Instance, typename Iter >
uerror check_variadic_invocable_error(const method& method, Instance&& instance, Iter first, Iter last) noexcept;
template < typename Instance, typename Iter, method_pointer_kind Method >
uerror check_variadic_invocable_error(Method method_ptr, Instance&& instance, Iter first, Iter last) noexcept;
}

View File

@@ -41,20 +41,47 @@ namespace meta_hpp
template < function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args) {
// doesn't actually move 'args', just checks conversion errors
if ( const uerror err = check_invocable_error(function_ptr, META_HPP_FWD(args)...) ) {
return err;
}
return invoke(function_ptr, META_HPP_FWD(args)...);
}
template < typename Iter >
uvalue invoke_variadic(const function& function, Iter first, Iter last) {
return function.invoke_variadic(first, last);
}
template < typename Iter >
uresult try_invoke_variadic(const function& function, Iter first, Iter last) {
return function.try_invoke_variadic(first, last);
}
template < function_pointer_kind Function, typename Iter >
uvalue invoke_variadic(Function function_ptr, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move 'args', just checks conversion errors
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
if ( const uerror err = raw_function_invoke_error<Function>(registry, vargs) ) {
return err;
}
static thread_local std::vector<uarg> vargs;
vargs.clear();
vargs.reserve(function_traits<std::remove_pointer_t<Function>>::arity);
for ( ; first != last; ++first ) {
vargs.emplace_back(registry, *first);
}
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, META_HPP_FWD(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
template < function_pointer_kind Function, typename Iter >
uresult try_invoke_variadic(Function function_ptr, Iter first, Iter last) {
if ( const uerror err = check_variadic_invocable_error(function_ptr, first, last) ) {
return err;
}
return invoke_variadic(function_ptr, first, last);
}
}
namespace meta_hpp
@@ -79,19 +106,11 @@ namespace meta_hpp
template < member_pointer_kind Member, typename Instance >
uresult try_invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
if ( const uerror err = raw_member_getter_error<Member>(registry, vinst) ) {
return err;
}
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_invocable_error(member_ptr, META_HPP_FWD(instance)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
return invoke(member_ptr, META_HPP_FWD(instance));
}
}
@@ -118,22 +137,49 @@ namespace meta_hpp
template < method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args) {
// doesn't actually move an 'instance' and 'args', just checks conversion errors
if ( const uerror err = check_invocable_error(method_ptr, META_HPP_FWD(instance), META_HPP_FWD(args)...) ) {
return err;
}
return invoke(method_ptr, META_HPP_FWD(instance), META_HPP_FWD(args)...);
}
template < typename Instance, typename Iter >
uvalue invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last) {
return method.invoke_variadic(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter >
uresult try_invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last) {
return method.try_invoke_variadic(META_HPP_FWD(instance), first, last);
}
template < method_pointer_kind Method, typename Instance, typename Iter >
uvalue invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance' and 'args', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
if ( const uerror err = raw_method_invoke_error<Method>(registry, vinst, vargs) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
static thread_local std::vector<uarg> vargs;
vargs.clear();
vargs.reserve(method_traits<Method>::arity);
for ( ; first != last; ++first ) {
vargs.emplace_back(registry, *first);
}
const uinst vinst{registry, META_HPP_FWD(instance)};
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, META_HPP_FWD(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
template < method_pointer_kind Method, typename Instance, typename Iter >
uresult try_invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last) {
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_variadic_invocable_error(method_ptr, META_HPP_FWD(instance), first, last) ) {
return err;
}
return invoke_variadic(method_ptr, META_HPP_FWD(instance), first, last);
}
}
namespace meta_hpp
@@ -183,6 +229,38 @@ namespace meta_hpp
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
return raw_function_invoke_error<Function>(registry, vargs);
}
template < typename Iter >
bool is_variadic_invocable_with(const function& function, Iter first, Iter last) noexcept {
return function.is_variadic_invocable_with(first, last);
}
template < typename Iter, function_pointer_kind Function >
bool is_variadic_invocable_with(Function function_ptr, Iter first, Iter last) noexcept {
return !check_variadic_invocable_error(function_ptr, first, last);
}
template < typename Iter >
uerror check_variadic_invocable_error(const function& function, Iter first, Iter last) noexcept {
return function.check_variadic_invocable_error(first, last);
}
template < typename Iter, function_pointer_kind Function >
uerror check_variadic_invocable_error(Function, Iter first, Iter last) noexcept {
using namespace detail;
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg_base> vargs;
vargs.clear();
vargs.reserve(function_traits<std::remove_pointer_t<Function>>::arity);
for ( ; first != last; ++first ) {
vargs.emplace_back(registry, *first);
}
return raw_function_invoke_error<Function>(registry, vargs);
}
}
namespace meta_hpp
@@ -283,4 +361,37 @@ namespace meta_hpp
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
return raw_method_invoke_error<Method>(registry, vinst, vargs);
}
template < typename Instance, typename Iter >
bool is_variadic_invocable_with(const method& method, Instance&& instance, Iter first, Iter last) noexcept {
return method.is_variadic_invocable_with(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter, method_pointer_kind Method >
bool is_variadic_invocable_with(Method method_ptr, Instance&& instance, Iter first, Iter last) noexcept {
return !check_variadic_invocable_error(method_ptr, META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter >
uerror check_variadic_invocable_error(const method& method, Instance&& instance, Iter first, Iter last) noexcept {
return method.check_variadic_invocable_error(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter, method_pointer_kind Method >
uerror check_variadic_invocable_error(Method, Instance&& instance, Iter first, Iter last) noexcept {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, META_HPP_FWD(instance)};
static thread_local std::vector<uarg_base> vargs;
vargs.clear();
vargs.reserve(method_traits<Method>::arity);
for ( ; first != last; ++first ) {
vargs.emplace_back(registry, *first);
}
return raw_method_invoke_error<Method>(registry, vinst, vargs);
}
}

View File

@@ -232,19 +232,11 @@ namespace meta_hpp
template < typename Instance >
uresult member::try_get(Instance&& instance) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
if ( const uerror err = state_->getter_error(vinst) ) {
return err;
}
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_gettable_error(META_HPP_FWD(instance)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
return state_->getter(vinst);
return get(META_HPP_FWD(instance));
}
template < typename Instance >
@@ -263,21 +255,11 @@ namespace meta_hpp
template < typename Instance, typename Value >
uresult member::try_set(Instance&& instance, Value&& value) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance' and 'args', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
const uarg_base vvalue{registry, META_HPP_FWD(value)};
if ( const uerror err = state_->setter_error(vinst, vvalue) ) {
return err;
}
// doesn't actually move an 'instance' and a 'value', just checks conversion errors
if ( const uerror err = check_settable_error(META_HPP_FWD(instance), META_HPP_FWD(value)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
const uarg vvalue{registry, META_HPP_FWD(value)};
state_->setter(vinst, vvalue);
set(META_HPP_FWD(instance), META_HPP_FWD(value));
return uerror{error_code::no_error};
}

View File

@@ -239,6 +239,7 @@ namespace meta_hpp
template < typename Instance, typename Iter >
uresult method::try_invoke_variadic(Instance&& instance, Iter first, Iter last) const {
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_variadic_invocable_error(META_HPP_FWD(instance), first, last) ) {
return err;
}