mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
use uerror in is_invokable_with functions
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -128,7 +128,7 @@ namespace
|
|||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
void meta_invoke_function_1(benchmark::State &state) {
|
void meta_invoke_function_1(benchmark::State &state) {
|
||||||
meta::function f = meta_bench_scope.get_function("static_function_1");
|
meta::function f = meta_bench_scope.get_function("static_function_1");
|
||||||
META_HPP_ASSERT(f.is_valid());
|
META_HPP_ASSERT(!f.is_empty());
|
||||||
|
|
||||||
for ( auto _ : state ) {
|
for ( auto _ : state ) {
|
||||||
f(static_angle);
|
f(static_angle);
|
||||||
@@ -138,7 +138,7 @@ namespace
|
|||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
void meta_invoke_function_2(benchmark::State &state) {
|
void meta_invoke_function_2(benchmark::State &state) {
|
||||||
meta::function f = meta_bench_scope.get_function("static_function_2");
|
meta::function f = meta_bench_scope.get_function("static_function_2");
|
||||||
META_HPP_ASSERT(f.is_valid());
|
META_HPP_ASSERT(!f.is_empty());
|
||||||
|
|
||||||
for ( auto _ : state ) {
|
for ( auto _ : state ) {
|
||||||
f(static_angle, vmath::unit3_x<float>);
|
f(static_angle, vmath::unit3_x<float>);
|
||||||
@@ -148,7 +148,7 @@ namespace
|
|||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
void meta_invoke_function_3(benchmark::State &state) {
|
void meta_invoke_function_3(benchmark::State &state) {
|
||||||
meta::function f = meta_bench_scope.get_function("static_function_3");
|
meta::function f = meta_bench_scope.get_function("static_function_3");
|
||||||
META_HPP_ASSERT(f.is_valid());
|
META_HPP_ASSERT(!f.is_empty());
|
||||||
|
|
||||||
for ( auto _ : state ) {
|
for ( auto _ : state ) {
|
||||||
f(static_angle, vmath::unit3_x<float>, 2.f);
|
f(static_angle, vmath::unit3_x<float>, 2.f);
|
||||||
@@ -158,7 +158,7 @@ namespace
|
|||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
void meta_invoke_function_4(benchmark::State &state) {
|
void meta_invoke_function_4(benchmark::State &state) {
|
||||||
meta::function f = meta_bench_scope.get_function("static_function_4");
|
meta::function f = meta_bench_scope.get_function("static_function_4");
|
||||||
META_HPP_ASSERT(f.is_valid());
|
META_HPP_ASSERT(!f.is_empty());
|
||||||
|
|
||||||
for ( auto _ : state ) {
|
for ( auto _ : state ) {
|
||||||
f(static_angle, vmath::unit3_x<float>, 2.f, vmath::midentity3<float>);
|
f(static_angle, vmath::unit3_x<float>, 2.f, vmath::midentity3<float>);
|
||||||
|
|||||||
@@ -59,6 +59,13 @@ TEST_CASE("meta/meta_states/dtor") {
|
|||||||
|
|
||||||
CHECK(dtor.get_type().get_owner_type() == meta::resolve_type<clazz_opened_dtor>());
|
CHECK(dtor.get_type().get_owner_type() == meta::resolve_type<clazz_opened_dtor>());
|
||||||
CHECK(dtor.get_type().get_flags() == meta::destructor_flags::is_noexcept);
|
CHECK(dtor.get_type().get_flags() == meta::destructor_flags::is_noexcept);
|
||||||
|
|
||||||
|
CHECK(dtor.is_invocable_with<clazz_opened_dtor*>());
|
||||||
|
CHECK(dtor.is_invocable_with(meta::make_uvalue<clazz_opened_dtor*>(nullptr)));
|
||||||
|
|
||||||
|
CHECK_FALSE(dtor.is_invocable_with<clazz_opened_dtor>());
|
||||||
|
CHECK_FALSE(dtor.is_invocable_with<clazz_closed_dtor*>());
|
||||||
|
CHECK_FALSE(dtor.is_invocable_with<const clazz_opened_dtor*>());
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("virtual_dtor") {
|
SUBCASE("virtual_dtor") {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace meta_hpp::detail
|
|||||||
enum class error_code {
|
enum class error_code {
|
||||||
no_error,
|
no_error,
|
||||||
|
|
||||||
|
bad_const_access,
|
||||||
bad_uvalue_access,
|
bad_uvalue_access,
|
||||||
bad_uresult_access,
|
bad_uresult_access,
|
||||||
|
|
||||||
@@ -32,13 +33,15 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
arity_mismatch,
|
arity_mismatch,
|
||||||
instance_type_mismatch,
|
instance_type_mismatch,
|
||||||
argument_types_mismatch,
|
argument_type_mismatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char* get_error_code_message(error_code error) noexcept {
|
inline const char* get_error_code_message(error_code error) noexcept {
|
||||||
switch ( error ) {
|
switch ( error ) {
|
||||||
case error_code::no_error:
|
case error_code::no_error:
|
||||||
return "no error";
|
return "no error";
|
||||||
|
case error_code::bad_const_access:
|
||||||
|
return "bad const access";
|
||||||
case error_code::bad_uvalue_access:
|
case error_code::bad_uvalue_access:
|
||||||
return "bad uvalue access";
|
return "bad uvalue access";
|
||||||
case error_code::bad_uresult_access:
|
case error_code::bad_uresult_access:
|
||||||
@@ -53,8 +56,8 @@ namespace meta_hpp::detail
|
|||||||
return "arity mismatch";
|
return "arity mismatch";
|
||||||
case error_code::instance_type_mismatch:
|
case error_code::instance_type_mismatch:
|
||||||
return "instance type mismatch";
|
return "instance type mismatch";
|
||||||
case error_code::argument_types_mismatch:
|
case error_code::argument_type_mismatch:
|
||||||
return "argument types mismatch";
|
return "argument type mismatch";
|
||||||
}
|
}
|
||||||
|
|
||||||
META_HPP_ASSERT(false);
|
META_HPP_ASSERT(false);
|
||||||
|
|||||||
@@ -362,9 +362,8 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
throw_exception(error_code::bad_argument_cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_exception(error_code::bad_argument_cast);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
return raw_function_is_invocable_with<Function>(registry, vargs);
|
return !raw_function_invoke_error<Function>(registry, vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::function_pointer_kind Function, typename... Args >
|
template < detail::function_pointer_kind Function, typename... Args >
|
||||||
@@ -91,7 +91,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
||||||
return raw_function_is_invocable_with<Function>(registry, vargs);
|
return !raw_function_invoke_error<Function>(registry, vargs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, type_list<Instance>{}};
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
return raw_member_is_gettable_with<Member>(registry, vinst);
|
return !raw_member_getter_error<Member>(registry, vinst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::member_pointer_kind Member, typename Instance >
|
template < detail::member_pointer_kind Member, typename Instance >
|
||||||
@@ -120,7 +120,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
||||||
return raw_member_is_gettable_with<Member>(registry, vinst);
|
return !raw_member_getter_error<Member>(registry, vinst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, type_list<Instance>{}};
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
return raw_method_is_invocable_with<Method>(registry, vinst, vargs);
|
return !raw_method_invoke_error<Method>(registry, vinst, vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
|
template < detail::method_pointer_kind Method, typename Instance, typename... Args >
|
||||||
@@ -151,6 +151,6 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, std::forward<Instance>(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)}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
||||||
return raw_method_is_invocable_with<Method>(registry, vinst, vargs);
|
return !raw_method_invoke_error<Method>(registry, vinst, vargs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "meta_base.hpp"
|
#include "meta_base.hpp"
|
||||||
#include "meta_indices.hpp"
|
#include "meta_indices.hpp"
|
||||||
#include "meta_types.hpp"
|
#include "meta_types.hpp"
|
||||||
|
#include "meta_uresult.hpp"
|
||||||
#include "meta_uvalue.hpp"
|
#include "meta_uvalue.hpp"
|
||||||
|
|
||||||
#include "meta_detail/state_family.hpp"
|
#include "meta_detail/state_family.hpp"
|
||||||
@@ -81,34 +82,34 @@ namespace meta_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename Policy >
|
template < typename Policy >
|
||||||
concept constructor_policy_kind //
|
concept constructor_policy_kind //
|
||||||
= std::is_same_v<Policy, constructor_policy::as_object_t> //
|
= std::is_same_v<Policy, constructor_policy::as_object_t> //
|
||||||
|| std::is_same_v<Policy, constructor_policy::as_raw_pointer_t> //
|
|| std::is_same_v<Policy, constructor_policy::as_raw_pointer_t> //
|
||||||
|| std::is_same_v<Policy, constructor_policy::as_shared_pointer_t>; //
|
|| std::is_same_v<Policy, constructor_policy::as_shared_pointer_t>;
|
||||||
|
|
||||||
template < typename Policy >
|
template < typename Policy >
|
||||||
concept function_policy_kind //
|
concept function_policy_kind //
|
||||||
= std::is_same_v<Policy, function_policy::as_copy_t> //
|
= std::is_same_v<Policy, function_policy::as_copy_t> //
|
||||||
|| std::is_same_v<Policy, function_policy::discard_return_t> //
|
|| std::is_same_v<Policy, function_policy::discard_return_t> //
|
||||||
|| std::is_same_v<Policy, function_policy::return_reference_as_pointer_t>; //
|
|| std::is_same_v<Policy, function_policy::return_reference_as_pointer_t>;
|
||||||
|
|
||||||
template < typename Policy >
|
template < typename Policy >
|
||||||
concept member_policy_kind //
|
concept member_policy_kind //
|
||||||
= std::is_same_v<Policy, member_policy::as_copy_t> //
|
= std::is_same_v<Policy, member_policy::as_copy_t> //
|
||||||
|| std::is_same_v<Policy, member_policy::as_pointer_t> //
|
|| std::is_same_v<Policy, member_policy::as_pointer_t> //
|
||||||
|| std::is_same_v<Policy, member_policy::as_reference_wrapper_t>; //
|
|| std::is_same_v<Policy, member_policy::as_reference_wrapper_t>;
|
||||||
|
|
||||||
template < typename Policy >
|
template < typename Policy >
|
||||||
concept method_policy_kind //
|
concept method_policy_kind //
|
||||||
= std::is_same_v<Policy, method_policy::as_copy_t> //
|
= std::is_same_v<Policy, method_policy::as_copy_t> //
|
||||||
|| std::is_same_v<Policy, method_policy::discard_return_t> //
|
|| std::is_same_v<Policy, method_policy::discard_return_t> //
|
||||||
|| std::is_same_v<Policy, method_policy::return_reference_as_pointer_t>; //
|
|| std::is_same_v<Policy, method_policy::return_reference_as_pointer_t>;
|
||||||
|
|
||||||
template < typename Policy >
|
template < typename Policy >
|
||||||
concept variable_policy_kind //
|
concept variable_policy_kind //
|
||||||
= std::is_same_v<Policy, variable_policy::as_copy_t> //
|
= std::is_same_v<Policy, variable_policy::as_copy_t> //
|
||||||
|| std::is_same_v<Policy, variable_policy::as_pointer_t> //
|
|| std::is_same_v<Policy, variable_policy::as_pointer_t> //
|
||||||
|| std::is_same_v<Policy, variable_policy::as_reference_wrapper_t>; //
|
|| std::is_same_v<Policy, variable_policy::as_reference_wrapper_t>;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
@@ -202,9 +203,15 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] destructor_type get_type() const noexcept;
|
[[nodiscard]] destructor_type get_type() const noexcept;
|
||||||
|
|
||||||
template < typename Arg >
|
template < typename Arg >
|
||||||
bool destroy(Arg&& arg) const;
|
void destroy(Arg&& arg) const;
|
||||||
|
|
||||||
void destroy_at(void* mem) const;
|
void destroy_at(void* mem) const;
|
||||||
|
|
||||||
|
template < typename Arg >
|
||||||
|
[[nodiscard]] bool is_invocable_with() const noexcept;
|
||||||
|
|
||||||
|
template < typename Arg >
|
||||||
|
[[nodiscard]] bool is_invocable_with(Arg&& arg) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class evalue final : public state_base<evalue> {
|
class evalue final : public state_base<evalue> {
|
||||||
@@ -313,6 +320,9 @@ namespace meta_hpp
|
|||||||
template < typename Instance, typename... Args >
|
template < typename Instance, typename... Args >
|
||||||
std::optional<uvalue> safe_invoke(Instance&& instance, Args&&... args) const;
|
std::optional<uvalue> safe_invoke(Instance&& instance, Args&&... args) const;
|
||||||
|
|
||||||
|
template < typename Instance, typename... Args >
|
||||||
|
uresult try_invoke(Instance&& instance, Args&&... args) const;
|
||||||
|
|
||||||
template < typename Instance, typename... Args >
|
template < typename Instance, typename... Args >
|
||||||
uvalue operator()(Instance&& instance, Args&&... args) const;
|
uvalue operator()(Instance&& instance, Args&&... args) const;
|
||||||
|
|
||||||
@@ -439,14 +449,14 @@ namespace meta_hpp::detail
|
|||||||
struct constructor_state final : intrusive_ref_counter<constructor_state> {
|
struct constructor_state final : intrusive_ref_counter<constructor_state> {
|
||||||
using create_impl = fixed_function<uvalue(std::span<const uarg>)>;
|
using create_impl = fixed_function<uvalue(std::span<const uarg>)>;
|
||||||
using create_at_impl = fixed_function<uvalue(void*, std::span<const uarg>)>;
|
using create_at_impl = fixed_function<uvalue(void*, std::span<const uarg>)>;
|
||||||
using is_invocable_with_impl = fixed_function<bool(std::span<const uarg_base>)>;
|
using create_error_impl = fixed_function<uerror(std::span<const uarg_base>)>;
|
||||||
|
|
||||||
constructor_index index;
|
constructor_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
create_impl create{};
|
create_impl create{};
|
||||||
create_at_impl create_at{};
|
create_at_impl create_at{};
|
||||||
is_invocable_with_impl is_invocable_with{};
|
create_error_impl create_error{};
|
||||||
argument_list arguments{};
|
argument_list arguments{};
|
||||||
|
|
||||||
template < constructor_policy_kind Policy, class_kind Class, typename... Args >
|
template < constructor_policy_kind Policy, class_kind Class, typename... Args >
|
||||||
@@ -455,14 +465,16 @@ namespace meta_hpp::detail
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct destructor_state final : intrusive_ref_counter<destructor_state> {
|
struct destructor_state final : intrusive_ref_counter<destructor_state> {
|
||||||
using destroy_impl = fixed_function<bool(const uarg&)>;
|
using destroy_impl = fixed_function<void(const uarg&)>;
|
||||||
using destroy_at_impl = fixed_function<void(void*)>;
|
using destroy_at_impl = fixed_function<void(void*)>;
|
||||||
|
using destroy_error_impl = fixed_function<uerror(const uarg_base&)>;
|
||||||
|
|
||||||
destructor_index index;
|
destructor_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
destroy_impl destroy{};
|
destroy_impl destroy{};
|
||||||
destroy_at_impl destroy_at{};
|
destroy_at_impl destroy_at{};
|
||||||
|
destroy_error_impl destroy_error{};
|
||||||
|
|
||||||
template < class_kind Class >
|
template < class_kind Class >
|
||||||
[[nodiscard]] static destructor_state_ptr make(metadata_map metadata);
|
[[nodiscard]] static destructor_state_ptr make(metadata_map metadata);
|
||||||
@@ -483,13 +495,13 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
struct function_state final : intrusive_ref_counter<function_state> {
|
struct function_state final : intrusive_ref_counter<function_state> {
|
||||||
using invoke_impl = fixed_function<uvalue(std::span<const uarg>)>;
|
using invoke_impl = fixed_function<uvalue(std::span<const uarg>)>;
|
||||||
using is_invocable_with_impl = fixed_function<bool(std::span<const uarg_base>)>;
|
using invoke_error_impl = fixed_function<uerror(std::span<const uarg_base>)>;
|
||||||
|
|
||||||
function_index index;
|
function_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
invoke_impl invoke{};
|
invoke_impl invoke{};
|
||||||
is_invocable_with_impl is_invocable_with{};
|
invoke_error_impl invoke_error{};
|
||||||
argument_list arguments{};
|
argument_list arguments{};
|
||||||
|
|
||||||
template < function_policy_kind Policy, function_pointer_kind Function >
|
template < function_policy_kind Policy, function_pointer_kind Function >
|
||||||
@@ -501,16 +513,16 @@ namespace meta_hpp::detail
|
|||||||
using getter_impl = fixed_function<uvalue(const uinst&)>;
|
using getter_impl = fixed_function<uvalue(const uinst&)>;
|
||||||
using setter_impl = fixed_function<void(const uinst&, const uarg&)>;
|
using setter_impl = fixed_function<void(const uinst&, const uarg&)>;
|
||||||
|
|
||||||
using is_gettable_with_impl = fixed_function<bool(const uinst_base&)>;
|
using getter_error_impl = fixed_function<uerror(const uinst_base&)>;
|
||||||
using is_settable_with_impl = fixed_function<bool(const uinst_base&, const uarg_base&)>;
|
using setter_error_impl = fixed_function<uerror(const uinst_base&, const uarg_base&)>;
|
||||||
|
|
||||||
member_index index;
|
member_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
getter_impl getter{};
|
getter_impl getter{};
|
||||||
setter_impl setter{};
|
setter_impl setter{};
|
||||||
is_gettable_with_impl is_gettable_with{};
|
getter_error_impl getter_error{};
|
||||||
is_settable_with_impl is_settable_with{};
|
setter_error_impl setter_error{};
|
||||||
|
|
||||||
template < member_policy_kind Policy, member_pointer_kind Member >
|
template < member_policy_kind Policy, member_pointer_kind Member >
|
||||||
[[nodiscard]] static member_state_ptr make(std::string name, Member member_ptr, metadata_map metadata);
|
[[nodiscard]] static member_state_ptr make(std::string name, Member member_ptr, metadata_map metadata);
|
||||||
@@ -519,13 +531,13 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
struct method_state final : intrusive_ref_counter<method_state> {
|
struct method_state final : intrusive_ref_counter<method_state> {
|
||||||
using invoke_impl = fixed_function<uvalue(const uinst&, std::span<const uarg>)>;
|
using invoke_impl = fixed_function<uvalue(const uinst&, std::span<const uarg>)>;
|
||||||
using is_invocable_with_impl = fixed_function<bool(const uinst_base&, std::span<const uarg_base>)>;
|
using invoke_error_impl = fixed_function<uerror(const uinst_base&, std::span<const uarg_base>)>;
|
||||||
|
|
||||||
method_index index;
|
method_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
invoke_impl invoke{};
|
invoke_impl invoke{};
|
||||||
is_invocable_with_impl is_invocable_with{};
|
invoke_error_impl invoke_error{};
|
||||||
argument_list arguments{};
|
argument_list arguments{};
|
||||||
|
|
||||||
template < method_policy_kind Policy, method_pointer_kind Method >
|
template < method_policy_kind Policy, method_pointer_kind Method >
|
||||||
@@ -548,14 +560,14 @@ namespace meta_hpp::detail
|
|||||||
struct variable_state final : intrusive_ref_counter<variable_state> {
|
struct variable_state final : intrusive_ref_counter<variable_state> {
|
||||||
using getter_impl = fixed_function<uvalue()>;
|
using getter_impl = fixed_function<uvalue()>;
|
||||||
using setter_impl = fixed_function<void(const uarg&)>;
|
using setter_impl = fixed_function<void(const uarg&)>;
|
||||||
using is_settable_with_impl = fixed_function<bool(const uarg_base&)>;
|
using setter_error_impl = fixed_function<uerror(const uarg_base&)>;
|
||||||
|
|
||||||
variable_index index;
|
variable_index index;
|
||||||
metadata_map metadata;
|
metadata_map metadata;
|
||||||
|
|
||||||
getter_impl getter{};
|
getter_impl getter{};
|
||||||
setter_impl setter{};
|
setter_impl setter{};
|
||||||
is_settable_with_impl is_settable_with{};
|
setter_error_impl setter_error{};
|
||||||
|
|
||||||
template < variable_policy_kind Policy, pointer_kind Pointer >
|
template < variable_policy_kind Policy, pointer_kind Pointer >
|
||||||
[[nodiscard]] static variable_state_ptr make(std::string name, Pointer variable_ptr, metadata_map metadata);
|
[[nodiscard]] static variable_state_ptr make(std::string name, Pointer variable_ptr, metadata_map metadata);
|
||||||
|
|||||||
@@ -80,12 +80,19 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < class_kind Class, typename... Args >
|
template < class_kind Class, typename... Args >
|
||||||
bool raw_constructor_is_invocable_with(type_registry& registry, std::span<const uarg_base> args) {
|
uerror raw_constructor_create_error(type_registry& registry, std::span<const uarg_base> args) {
|
||||||
using ct = constructor_traits<Class, Args...>;
|
using ct = constructor_traits<Class, Args...>;
|
||||||
using argument_types = typename ct::argument_types;
|
using argument_types = typename ct::argument_types;
|
||||||
|
|
||||||
return args.size() == ct::arity //
|
if ( args.size() != ct::arity ) {
|
||||||
&& can_cast_all_uargs<argument_types>(registry, args);
|
return uerror{error_code::arity_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !can_cast_all_uargs<argument_types>(registry, args) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,9 +113,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < class_kind Class, typename... Args >
|
template < class_kind Class, typename... Args >
|
||||||
constructor_state::is_invocable_with_impl make_constructor_is_invocable_with(type_registry& registry) {
|
constructor_state::create_error_impl make_constructor_create_error(type_registry& registry) {
|
||||||
return [®istry](std::span<const uarg_base> args) { //
|
return [®istry](std::span<const uarg_base> args) { //
|
||||||
return raw_constructor_is_invocable_with<Class, Args...>(registry, args);
|
return raw_constructor_create_error<Class, Args...>(registry, args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +147,7 @@ namespace meta_hpp::detail
|
|||||||
constructor_state state{constructor_index{registry.resolve_constructor_type<Class, Args...>()}, std::move(metadata)};
|
constructor_state state{constructor_index{registry.resolve_constructor_type<Class, Args...>()}, std::move(metadata)};
|
||||||
state.create = make_constructor_create<Policy, Class, Args...>(registry);
|
state.create = make_constructor_create<Policy, Class, Args...>(registry);
|
||||||
state.create_at = make_constructor_create_at<Class, Args...>(registry);
|
state.create_at = make_constructor_create_at<Class, Args...>(registry);
|
||||||
state.is_invocable_with = make_constructor_is_invocable_with<Class, Args...>(registry);
|
state.create_error = make_constructor_create_error<Class, Args...>(registry);
|
||||||
state.arguments = make_constructor_arguments<Class, Args...>();
|
state.arguments = make_constructor_arguments<Class, Args...>();
|
||||||
return make_intrusive<constructor_state>(std::move(state));
|
return make_intrusive<constructor_state>(std::move(state));
|
||||||
}
|
}
|
||||||
@@ -189,7 +196,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
return state_->is_invocable_with(vargs);
|
return !state_->create_error(vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
@@ -197,7 +204,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
||||||
return state_->is_invocable_with(vargs);
|
return !state_->create_error(vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline argument constructor::get_argument(std::size_t position) const noexcept {
|
inline argument constructor::get_argument(std::size_t position) const noexcept {
|
||||||
|
|||||||
@@ -16,16 +16,16 @@
|
|||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
template < class_kind Class >
|
template < class_kind Class >
|
||||||
bool raw_destructor_destroy(type_registry& registry, const uarg& arg) {
|
void raw_destructor_destroy(type_registry& registry, const uarg& arg) {
|
||||||
using dt = destructor_traits<Class>;
|
using dt = destructor_traits<Class>;
|
||||||
using class_type = typename dt::class_type;
|
using class_type = typename dt::class_type;
|
||||||
|
|
||||||
if ( !arg.can_cast_to<class_type*>(registry) ) {
|
META_HPP_ASSERT( //
|
||||||
return false;
|
arg.can_cast_to<class_type*>(registry) //
|
||||||
}
|
&& "an attempt to call a destructor with an incorrect argument type"
|
||||||
|
);
|
||||||
|
|
||||||
std::unique_ptr<class_type>{arg.cast<class_type*>(registry)}.reset();
|
std::unique_ptr<class_type>{arg.cast<class_type*>(registry)}.reset();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class_kind Class >
|
template < class_kind Class >
|
||||||
@@ -35,6 +35,18 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
std::destroy_at(static_cast<class_type*>(mem));
|
std::destroy_at(static_cast<class_type*>(mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < class_kind Class >
|
||||||
|
uerror raw_destructor_destroy_error(type_registry& registry, const uarg_base& arg) {
|
||||||
|
using dt = destructor_traits<Class>;
|
||||||
|
using class_type = typename dt::class_type;
|
||||||
|
|
||||||
|
if ( !arg.can_cast_to<class_type*>(registry) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
@@ -50,6 +62,13 @@ namespace meta_hpp::detail
|
|||||||
destructor_state::destroy_at_impl make_destructor_destroy_at() {
|
destructor_state::destroy_at_impl make_destructor_destroy_at() {
|
||||||
return &raw_destructor_destroy_at<Class>;
|
return &raw_destructor_destroy_at<Class>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < class_kind Class >
|
||||||
|
destructor_state::destroy_error_impl make_destructor_destroy_error(type_registry& registry) {
|
||||||
|
return [®istry](const uarg_base& arg) { //
|
||||||
|
return raw_destructor_destroy_error<Class>(registry, arg);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
@@ -64,6 +83,7 @@ namespace meta_hpp::detail
|
|||||||
destructor_state state{destructor_index{registry.resolve_destructor_type<Class>()}, std::move(metadata)};
|
destructor_state state{destructor_index{registry.resolve_destructor_type<Class>()}, std::move(metadata)};
|
||||||
state.destroy = make_destructor_destroy<Class>(registry);
|
state.destroy = make_destructor_destroy<Class>(registry);
|
||||||
state.destroy_at = make_destructor_destroy_at<Class>();
|
state.destroy_at = make_destructor_destroy_at<Class>();
|
||||||
|
state.destroy_error = make_destructor_destroy_error<Class>(registry);
|
||||||
return make_intrusive<destructor_state>(std::move(state));
|
return make_intrusive<destructor_state>(std::move(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +95,7 @@ namespace meta_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename Arg >
|
template < typename Arg >
|
||||||
bool destructor::destroy(Arg&& arg) const {
|
void destructor::destroy(Arg&& arg) const {
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uarg varg{registry, std::forward<Arg>(arg)};
|
const uarg varg{registry, std::forward<Arg>(arg)};
|
||||||
@@ -85,4 +105,20 @@ namespace meta_hpp
|
|||||||
inline void destructor::destroy_at(void* mem) const {
|
inline void destructor::destroy_at(void* mem) const {
|
||||||
state_->destroy_at(mem);
|
state_->destroy_at(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename Arg >
|
||||||
|
bool destructor::is_invocable_with() const noexcept {
|
||||||
|
using namespace detail;
|
||||||
|
type_registry& registry{type_registry::instance()};
|
||||||
|
const uarg_base varg{registry, type_list<Arg>{}};
|
||||||
|
return !state_->destroy_error(varg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Arg >
|
||||||
|
bool destructor::is_invocable_with(Arg&& arg) const noexcept {
|
||||||
|
using namespace detail;
|
||||||
|
type_registry& registry{type_registry::instance()};
|
||||||
|
const uarg_base varg{registry, std::forward<Arg>(arg)};
|
||||||
|
return !state_->destroy_error(varg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,19 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < function_pointer_kind Function >
|
template < function_pointer_kind Function >
|
||||||
bool raw_function_is_invocable_with(type_registry& registry, std::span<const uarg_base> args) {
|
uerror raw_function_invoke_error(type_registry& registry, std::span<const uarg_base> args) {
|
||||||
using ft = function_traits<Function>;
|
using ft = function_traits<Function>;
|
||||||
using argument_types = typename ft::argument_types;
|
using argument_types = typename ft::argument_types;
|
||||||
|
|
||||||
return args.size() == ft::arity //
|
if ( args.size() != ft::arity ) {
|
||||||
&& can_cast_all_uargs<argument_types>(registry, args);
|
return uerror{error_code::arity_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !can_cast_all_uargs<argument_types>(registry, args) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,9 +90,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < function_pointer_kind Function >
|
template < function_pointer_kind Function >
|
||||||
function_state::is_invocable_with_impl make_function_is_invocable_with(type_registry& registry) {
|
function_state::invoke_error_impl make_function_invoke_error(type_registry& registry) {
|
||||||
return [®istry](std::span<const uarg_base> args) { //
|
return [®istry](std::span<const uarg_base> args) { //
|
||||||
return raw_function_is_invocable_with<Function>(registry, args);
|
return raw_function_invoke_error<Function>(registry, args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +123,7 @@ namespace meta_hpp::detail
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
function_state state{function_index{registry.resolve_type<Function>(), std::move(name)}, std::move(metadata)};
|
function_state state{function_index{registry.resolve_type<Function>(), std::move(name)}, std::move(metadata)};
|
||||||
state.invoke = make_function_invoke<Policy>(registry, function_ptr);
|
state.invoke = make_function_invoke<Policy>(registry, function_ptr);
|
||||||
state.is_invocable_with = make_function_is_invocable_with<Function>(registry);
|
state.invoke_error = make_function_invoke_error<Function>(registry);
|
||||||
state.arguments = make_function_arguments<Function>();
|
state.arguments = make_function_arguments<Function>();
|
||||||
return make_intrusive<function_state>(std::move(state));
|
return make_intrusive<function_state>(std::move(state));
|
||||||
}
|
}
|
||||||
@@ -158,7 +165,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
return state_->is_invocable_with(vargs);
|
return !state_->invoke_error(vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
@@ -166,7 +173,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
||||||
return state_->is_invocable_with(vargs);
|
return !state_->invoke_error(vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline argument function::get_argument(std::size_t position) const noexcept {
|
inline argument function::get_argument(std::size_t position) const noexcept {
|
||||||
|
|||||||
@@ -76,11 +76,21 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < member_pointer_kind Member >
|
template < member_pointer_kind Member >
|
||||||
bool raw_member_is_gettable_with(type_registry& registry, const uinst_base& inst) {
|
uerror raw_member_getter_error(type_registry& registry, const uinst_base& inst) {
|
||||||
using mt = member_traits<Member>;
|
using mt = member_traits<Member>;
|
||||||
using class_type = typename mt::class_type;
|
using class_type = typename mt::class_type;
|
||||||
|
|
||||||
return inst.can_cast_to<const class_type>(registry);
|
if ( inst.is_inst_const() ) {
|
||||||
|
if ( !inst.can_cast_to<const class_type>(registry) ) {
|
||||||
|
return uerror{error_code::bad_instance_cast};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( !inst.can_cast_to<class_type>(registry) ) {
|
||||||
|
return uerror{error_code::bad_instance_cast};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +129,7 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < member_pointer_kind Member >
|
template < member_pointer_kind Member >
|
||||||
bool raw_member_is_settable_with(type_registry& registry, const uinst_base& inst, const uarg_base& arg) {
|
uerror raw_member_setter_error(type_registry& registry, const uinst_base& inst, const uarg_base& arg) {
|
||||||
using mt = member_traits<Member>;
|
using mt = member_traits<Member>;
|
||||||
using class_type = typename mt::class_type;
|
using class_type = typename mt::class_type;
|
||||||
using value_type = typename mt::value_type;
|
using value_type = typename mt::value_type;
|
||||||
@@ -128,11 +138,21 @@ namespace meta_hpp::detail
|
|||||||
(void)registry;
|
(void)registry;
|
||||||
(void)inst;
|
(void)inst;
|
||||||
(void)arg;
|
(void)arg;
|
||||||
return false;
|
return uerror{error_code::bad_const_access};
|
||||||
} else {
|
} else {
|
||||||
return !inst.is_inst_const() //
|
if ( inst.is_inst_const() ) {
|
||||||
&& inst.can_cast_to<class_type>(registry) //
|
return uerror{error_code::bad_const_access};
|
||||||
&& arg.can_cast_to<value_type>(registry); //
|
}
|
||||||
|
|
||||||
|
if ( !inst.can_cast_to<class_type>(registry) ) {
|
||||||
|
return uerror{error_code::instance_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !arg.can_cast_to<value_type>(registry) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,9 +167,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < member_pointer_kind Member >
|
template < member_pointer_kind Member >
|
||||||
member_state::is_gettable_with_impl make_member_is_gettable_with(type_registry& registry) {
|
member_state::getter_error_impl make_member_getter_error(type_registry& registry) {
|
||||||
return [®istry](const uinst_base& inst) { //
|
return [®istry](const uinst_base& inst) { //
|
||||||
return raw_member_is_gettable_with<Member>(registry, inst);
|
return raw_member_getter_error<Member>(registry, inst);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,9 +181,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < member_pointer_kind Member >
|
template < member_pointer_kind Member >
|
||||||
member_state::is_settable_with_impl make_member_is_settable_with(type_registry& registry) {
|
member_state::setter_error_impl make_member_setter_error(type_registry& registry) {
|
||||||
return [®istry](const uinst_base& inst, const uarg_base& arg) { //
|
return [®istry](const uinst_base& inst, const uarg_base& arg) { //
|
||||||
return raw_member_is_settable_with<Member>(registry, inst, arg);
|
return raw_member_setter_error<Member>(registry, inst, arg);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,8 +200,8 @@ namespace meta_hpp::detail
|
|||||||
member_state state{member_index{registry.resolve_type<Member>(), std::move(name)}, std::move(metadata)};
|
member_state state{member_index{registry.resolve_type<Member>(), std::move(name)}, std::move(metadata)};
|
||||||
state.getter = make_member_getter<Policy>(registry, member_ptr);
|
state.getter = make_member_getter<Policy>(registry, member_ptr);
|
||||||
state.setter = make_member_setter(registry, member_ptr);
|
state.setter = make_member_setter(registry, member_ptr);
|
||||||
state.is_gettable_with = make_member_is_gettable_with<Member>(registry);
|
state.getter_error = make_member_getter_error<Member>(registry);
|
||||||
state.is_settable_with = make_member_is_settable_with<Member>(registry);
|
state.setter_error = make_member_setter_error<Member>(registry);
|
||||||
return make_intrusive<member_state>(std::move(state));
|
return make_intrusive<member_state>(std::move(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,7 +275,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, type_list<Instance>{}};
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
return state_->is_gettable_with(vinst);
|
return !state_->getter_error(vinst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Instance >
|
template < typename Instance >
|
||||||
@@ -263,7 +283,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
||||||
return state_->is_gettable_with(vinst);
|
return !state_->getter_error(vinst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Instance, typename Value >
|
template < typename Instance, typename Value >
|
||||||
@@ -272,7 +292,7 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, type_list<Instance>{}};
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
const uarg_base vvalue{registry, type_list<Value>{}};
|
const uarg_base vvalue{registry, type_list<Value>{}};
|
||||||
return state_->is_settable_with(vinst, vvalue);
|
return !state_->setter_error(vinst, vvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Instance, typename Value >
|
template < typename Instance, typename Value >
|
||||||
@@ -281,6 +301,6 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
const uinst_base vinst{registry, std::forward<Instance>(instance)};
|
||||||
const uarg_base vvalue{registry, std::forward<Value>(value)};
|
const uarg_base vvalue{registry, std::forward<Value>(value)};
|
||||||
return state_->is_settable_with(vinst, vvalue);
|
return !state_->setter_error(vinst, vvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,14 +71,24 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < method_pointer_kind Method >
|
template < method_pointer_kind Method >
|
||||||
bool raw_method_is_invocable_with(type_registry& registry, const uinst_base& inst, std::span<const uarg_base> args) {
|
uerror raw_method_invoke_error(type_registry& registry, const uinst_base& inst, std::span<const uarg_base> args) {
|
||||||
using mt = method_traits<Method>;
|
using mt = method_traits<Method>;
|
||||||
using qualified_type = typename mt::qualified_type;
|
using qualified_type = typename mt::qualified_type;
|
||||||
using argument_types = typename mt::argument_types;
|
using argument_types = typename mt::argument_types;
|
||||||
|
|
||||||
return args.size() == mt::arity //
|
if ( args.size() != mt::arity ) {
|
||||||
&& inst.can_cast_to<qualified_type>(registry) //
|
return uerror{error_code::arity_mismatch};
|
||||||
&& can_cast_all_uargs<argument_types>(registry, args);
|
}
|
||||||
|
|
||||||
|
if ( !inst.can_cast_to<qualified_type>(registry) ) {
|
||||||
|
return uerror{error_code::instance_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !can_cast_all_uargs<argument_types>(registry, args) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +102,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < method_pointer_kind Method >
|
template < method_pointer_kind Method >
|
||||||
method_state::is_invocable_with_impl make_method_is_invocable_with(type_registry& registry) {
|
method_state::invoke_error_impl make_method_invoke_error(type_registry& registry) {
|
||||||
return [®istry](const uinst_base& inst, std::span<const uarg_base> args) {
|
return [®istry](const uinst_base& inst, std::span<const uarg_base> args) {
|
||||||
return raw_method_is_invocable_with<Method>(registry, inst, args);
|
return raw_method_invoke_error<Method>(registry, inst, args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +135,7 @@ namespace meta_hpp::detail
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
method_state state{method_index{registry.resolve_type<Method>(), std::move(name)}, std::move(metadata)};
|
method_state state{method_index{registry.resolve_type<Method>(), std::move(name)}, std::move(metadata)};
|
||||||
state.invoke = make_method_invoke<Policy>(registry, method_ptr);
|
state.invoke = make_method_invoke<Policy>(registry, method_ptr);
|
||||||
state.is_invocable_with = make_method_is_invocable_with<Method>(registry);
|
state.invoke_error = make_method_invoke_error<Method>(registry);
|
||||||
state.arguments = make_method_arguments<Method>();
|
state.arguments = make_method_arguments<Method>();
|
||||||
return make_intrusive<method_state>(std::move(state));
|
return make_intrusive<method_state>(std::move(state));
|
||||||
}
|
}
|
||||||
@@ -158,6 +168,24 @@ namespace meta_hpp
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename Instance, typename... Args >
|
||||||
|
uresult method::try_invoke(Instance&& instance, Args&&... args) const {
|
||||||
|
using namespace detail;
|
||||||
|
type_registry& registry{type_registry::instance()};
|
||||||
|
|
||||||
|
{
|
||||||
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
|
if ( const uerror err = state_->invoke_error(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 state_->invoke(vinst, vargs);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename Instance, typename... Args >
|
template < typename Instance, typename... Args >
|
||||||
uvalue method::operator()(Instance&& instance, Args&&... args) const {
|
uvalue method::operator()(Instance&& instance, Args&&... args) const {
|
||||||
return invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
|
return invoke(std::forward<Instance>(instance), std::forward<Args>(args)...);
|
||||||
@@ -169,7 +197,7 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, type_list<Instance>{}};
|
const uinst_base vinst{registry, type_list<Instance>{}};
|
||||||
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
|
||||||
return state_->is_invocable_with(vinst, vargs);
|
return !state_->invoke_error(vinst, vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Instance, typename... Args >
|
template < typename Instance, typename... Args >
|
||||||
@@ -178,7 +206,7 @@ namespace meta_hpp
|
|||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uinst_base vinst{registry, std::forward<Instance>(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)}...};
|
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, std::forward<Args>(args)}...};
|
||||||
return state_->is_invocable_with(vinst, vargs);
|
return !state_->invoke_error(vinst, vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline argument method::get_argument(std::size_t position) const noexcept {
|
inline argument method::get_argument(std::size_t position) const noexcept {
|
||||||
|
|||||||
@@ -68,16 +68,19 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < pointer_kind Pointer >
|
template < pointer_kind Pointer >
|
||||||
bool raw_variable_is_settable_with(type_registry& registry, const uarg_base& arg) {
|
uerror raw_variable_setter_error(type_registry& registry, const uarg_base& arg) {
|
||||||
using pt = pointer_traits<Pointer>;
|
using pt = pointer_traits<Pointer>;
|
||||||
using data_type = typename pt::data_type;
|
using data_type = typename pt::data_type;
|
||||||
|
|
||||||
if constexpr ( std::is_const_v<data_type> ) {
|
if constexpr ( std::is_const_v<data_type> ) {
|
||||||
(void)registry;
|
(void)registry;
|
||||||
(void)arg;
|
(void)arg;
|
||||||
return false;
|
return uerror{error_code::bad_const_access};
|
||||||
} else {
|
} else {
|
||||||
return arg.can_cast_to<data_type>(registry);
|
if ( !arg.can_cast_to<data_type>(registry) ) {
|
||||||
|
return uerror{error_code::argument_type_mismatch};
|
||||||
|
}
|
||||||
|
return uerror{error_code::no_error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,9 +102,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < pointer_kind Pointer >
|
template < pointer_kind Pointer >
|
||||||
variable_state::is_settable_with_impl make_variable_is_settable_with(type_registry& registry) {
|
variable_state::setter_error_impl make_variable_setter_error(type_registry& registry) {
|
||||||
return [®istry](const uarg_base& arg) { //
|
return [®istry](const uarg_base& arg) { //
|
||||||
return raw_variable_is_settable_with<Pointer>(registry, arg);
|
return raw_variable_setter_error<Pointer>(registry, arg);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +121,7 @@ namespace meta_hpp::detail
|
|||||||
variable_state state{variable_index{registry.resolve_type<Pointer>(), std::move(name)}, std::move(metadata)};
|
variable_state state{variable_index{registry.resolve_type<Pointer>(), std::move(name)}, std::move(metadata)};
|
||||||
state.getter = make_variable_getter<Policy>(registry, variable_ptr);
|
state.getter = make_variable_getter<Policy>(registry, variable_ptr);
|
||||||
state.setter = make_variable_setter(registry, variable_ptr);
|
state.setter = make_variable_setter(registry, variable_ptr);
|
||||||
state.is_settable_with = make_variable_is_settable_with<Pointer>(registry);
|
state.setter_error = make_variable_setter_error<Pointer>(registry);
|
||||||
return make_intrusive<variable_state>(std::move(state));
|
return make_intrusive<variable_state>(std::move(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +185,7 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uarg_base vvalue{registry, type_list<Value>{}};
|
const uarg_base vvalue{registry, type_list<Value>{}};
|
||||||
return state_->is_settable_with(vvalue);
|
return !state_->setter_error(vvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Value >
|
template < typename Value >
|
||||||
@@ -190,6 +193,6 @@ namespace meta_hpp
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry{type_registry::instance()};
|
type_registry& registry{type_registry::instance()};
|
||||||
const uarg_base vvalue{registry, std::forward<Value>(value)};
|
const uarg_base vvalue{registry, std::forward<Value>(value)};
|
||||||
return state_->is_settable_with(vvalue);
|
return !state_->setter_error(vvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,10 @@ namespace meta_hpp
|
|||||||
template < typename Arg >
|
template < typename Arg >
|
||||||
bool class_type::destroy(Arg&& arg) const {
|
bool class_type::destroy(Arg&& arg) const {
|
||||||
if ( const destructor& dtor = get_destructor() ) {
|
if ( const destructor& dtor = get_destructor() ) {
|
||||||
return dtor.destroy(std::forward<Arg>(arg));
|
if ( dtor.is_invocable_with(std::forward<Arg>(arg)) ) {
|
||||||
|
dtor.destroy(std::forward<Arg>(arg));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ namespace meta_hpp
|
|||||||
explicit uerror(error_code error) noexcept;
|
explicit uerror(error_code error) noexcept;
|
||||||
uerror& operator=(error_code error) noexcept;
|
uerror& operator=(error_code error) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool has_error() const noexcept;
|
||||||
|
[[nodiscard]] explicit operator bool() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] error_code get_error() const noexcept;
|
[[nodiscard]] error_code get_error() const noexcept;
|
||||||
|
|
||||||
void reset() noexcept;
|
void reset() noexcept;
|
||||||
@@ -120,9 +123,6 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] bool has_value() const noexcept;
|
[[nodiscard]] bool has_value() const noexcept;
|
||||||
[[nodiscard]] explicit operator bool() const noexcept;
|
[[nodiscard]] explicit operator bool() const noexcept;
|
||||||
|
|
||||||
void reset() noexcept;
|
|
||||||
void swap(uresult& other) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] uvalue& get_value() &;
|
[[nodiscard]] uvalue& get_value() &;
|
||||||
[[nodiscard]] uvalue&& get_value() &&;
|
[[nodiscard]] uvalue&& get_value() &&;
|
||||||
[[nodiscard]] const uvalue& get_value() const&;
|
[[nodiscard]] const uvalue& get_value() const&;
|
||||||
@@ -130,6 +130,9 @@ namespace meta_hpp
|
|||||||
|
|
||||||
[[nodiscard]] error_code get_error() const noexcept;
|
[[nodiscard]] error_code get_error() const noexcept;
|
||||||
|
|
||||||
|
void reset() noexcept;
|
||||||
|
void swap(uresult& other) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uvalue value_{};
|
uvalue value_{};
|
||||||
error_code error_{error_code::no_error};
|
error_code error_{error_code::no_error};
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ namespace meta_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool uerror::has_error() const noexcept {
|
||||||
|
return error_ != error_code::no_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uerror::operator bool() const noexcept {
|
||||||
|
return has_error();
|
||||||
|
}
|
||||||
|
|
||||||
inline error_code uerror::get_error() const noexcept {
|
inline error_code uerror::get_error() const noexcept {
|
||||||
return error_;
|
return error_;
|
||||||
}
|
}
|
||||||
@@ -112,17 +120,6 @@ namespace meta_hpp
|
|||||||
return has_value();
|
return has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void uresult::reset() noexcept {
|
|
||||||
value_ = uvalue{};
|
|
||||||
error_ = error_code::no_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void uresult::swap(uresult& other) noexcept {
|
|
||||||
using std::swap;
|
|
||||||
swap(value_, other.value_);
|
|
||||||
swap(error_, other.error_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uvalue& uresult::get_value() & {
|
inline uvalue& uresult::get_value() & {
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
@@ -143,4 +140,15 @@ namespace meta_hpp
|
|||||||
inline error_code uresult::get_error() const noexcept {
|
inline error_code uresult::get_error() const noexcept {
|
||||||
return error_;
|
return error_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void uresult::reset() noexcept {
|
||||||
|
value_ = uvalue{};
|
||||||
|
error_ = error_code::no_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void uresult::swap(uresult& other) noexcept {
|
||||||
|
using std::swap;
|
||||||
|
swap(value_, other.value_);
|
||||||
|
swap(error_, other.error_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user