mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
fix some family id issues
This commit is contained in:
@@ -128,7 +128,7 @@ namespace meta_hpp
|
|||||||
|
|
||||||
template < typename Class >
|
template < typename Class >
|
||||||
class_info(detail::typename_arg_t<Class>, std::string id)
|
class_info(detail::typename_arg_t<Class>, std::string id)
|
||||||
: fid_{get_family_id<Class>()}
|
: fid_{get_type_family_id<Class>()}
|
||||||
, id_{std::move(id)} {}
|
, id_{std::move(id)} {}
|
||||||
private:
|
private:
|
||||||
family_id fid_;
|
family_id fid_;
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ namespace meta_hpp
|
|||||||
template < auto Field >
|
template < auto Field >
|
||||||
friend class field_;
|
friend class field_;
|
||||||
|
|
||||||
template < typename FieldType, FieldType Field >
|
template < auto Field >
|
||||||
field_info(detail::auto_arg_t<Field>, std::string id)
|
field_info(detail::auto_arg_t<Field>, std::string id)
|
||||||
: fid_{get_family_id<FieldType>()}
|
: fid_{get_value_family_id<Field>()}
|
||||||
, id_{std::move(id)}
|
, id_{std::move(id)}
|
||||||
, getter_{&field_detail::getter<Field>}
|
, getter_{&field_detail::getter<Field>}
|
||||||
, setter_{&field_detail::setter<Field>} {}
|
, setter_{&field_detail::setter<Field>} {}
|
||||||
|
|||||||
@@ -119,9 +119,9 @@ namespace meta_hpp
|
|||||||
template < auto Function >
|
template < auto Function >
|
||||||
friend class function_;
|
friend class function_;
|
||||||
|
|
||||||
template < typename FunctionType, FunctionType Function >
|
template < auto Function >
|
||||||
function_info(detail::auto_arg_t<Function>, std::string id)
|
function_info(detail::auto_arg_t<Function>, std::string id)
|
||||||
: fid_{get_family_id<FunctionType>()}
|
: fid_{get_value_family_id<Function>()}
|
||||||
, id_{std::move(id)}
|
, id_{std::move(id)}
|
||||||
, invoke_{&function_detail::invoke<Function>} {}
|
, invoke_{&function_detail::invoke<Function>} {}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace meta_hpp
|
|||||||
namespace family_id_detail
|
namespace family_id_detail
|
||||||
{
|
{
|
||||||
template < typename Void = void >
|
template < typename Void = void >
|
||||||
class type_family_base {
|
class family_base {
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_void_v<Void>,
|
std::is_void_v<Void>,
|
||||||
"unexpected internal error");
|
"unexpected internal error");
|
||||||
@@ -64,7 +64,17 @@ namespace meta_hpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
class type_family final : public type_family_base<> {
|
class type_family final : public family_base<> {
|
||||||
|
public:
|
||||||
|
static family_id id() noexcept {
|
||||||
|
static family_id self_id{++last_id_};
|
||||||
|
assert(self_id.id > 0u && "family_id overflow");
|
||||||
|
return self_id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template < auto V >
|
||||||
|
class value_family final : public family_base<> {
|
||||||
public:
|
public:
|
||||||
static family_id id() noexcept {
|
static family_id id() noexcept {
|
||||||
static family_id self_id{++last_id_};
|
static family_id self_id{++last_id_};
|
||||||
@@ -74,13 +84,18 @@ namespace meta_hpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template < typename Void >
|
template < typename Void >
|
||||||
family_id::underlying_type type_family_base<Void>::last_id_{};
|
family_id::underlying_type family_base<Void>::last_id_{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
family_id get_family_id() noexcept {
|
family_id get_type_family_id() noexcept {
|
||||||
return family_id_detail::type_family<T>::id();
|
return family_id_detail::type_family<T>::id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < auto V >
|
||||||
|
family_id get_value_family_id() noexcept {
|
||||||
|
return family_id_detail::value_family<V>::id();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
|
|||||||
@@ -186,9 +186,9 @@ namespace meta_hpp
|
|||||||
template < auto Method >
|
template < auto Method >
|
||||||
friend class method_;
|
friend class method_;
|
||||||
|
|
||||||
template < typename MethodType, MethodType Method >
|
template < auto Method >
|
||||||
method_info(detail::auto_arg_t<Method>, std::string id)
|
method_info(detail::auto_arg_t<Method>, std::string id)
|
||||||
: fid_{get_family_id<MethodType>()}
|
: fid_{get_value_family_id<Method>()}
|
||||||
, id_{std::move(id)}
|
, id_{std::move(id)}
|
||||||
, invoke_{&method_detail::invoke<Method>}
|
, invoke_{&method_detail::invoke<Method>}
|
||||||
, cinvoke_{&method_detail::cinvoke<Method>} {}
|
, cinvoke_{&method_detail::cinvoke<Method>} {}
|
||||||
|
|||||||
@@ -23,17 +23,20 @@ namespace meta_hpp
|
|||||||
public:
|
public:
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::optional<type> resolve() const {
|
std::optional<type> resolve() const {
|
||||||
return detail::find_opt(family_to_types_, get_family_id<T>());
|
const family_id fid = get_type_family_id<T>();
|
||||||
|
return detail::find_opt(family_to_types_, fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < auto T >
|
template < auto T >
|
||||||
std::optional<type> resolve() const {
|
std::optional<type> resolve() const {
|
||||||
return resolve<decltype(T)>();
|
const family_id fid = get_value_family_id<T>();
|
||||||
|
return detail::find_opt(family_to_types_, fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::optional<type> resolve(T&&) const {
|
std::optional<type> resolve(T&&) const {
|
||||||
return resolve<std::decay_t<T>>();
|
const family_id fid = get_type_family_id<std::decay_t<T>>();
|
||||||
|
return detail::find_opt(family_to_types_, fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<class_info> get_class_by_name(std::string_view name) const {
|
std::optional<class_info> get_class_by_name(std::string_view name) const {
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ namespace meta_hpp
|
|||||||
template < auto Variable >
|
template < auto Variable >
|
||||||
friend class variable_;
|
friend class variable_;
|
||||||
|
|
||||||
template < typename VariableType, VariableType Variable >
|
template < auto Variable >
|
||||||
variable_info(detail::auto_arg_t<Variable>, std::string id)
|
variable_info(detail::auto_arg_t<Variable>, std::string id)
|
||||||
: fid_{get_family_id<VariableType>()}
|
: fid_{get_value_family_id<Variable>()}
|
||||||
, id_{std::move(id)}
|
, id_{std::move(id)}
|
||||||
, getter_{&variable_detail::getter<Variable>}
|
, getter_{&variable_detail::getter<Variable>}
|
||||||
, setter_{&variable_detail::setter<Variable>} {}
|
, setter_{&variable_detail::setter<Variable>} {}
|
||||||
|
|||||||
85
untests/meta_family_tests.cpp
Normal file
85
untests/meta_family_tests.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <meta.hpp/meta_class.hpp>
|
||||||
|
#include <meta.hpp/meta_field.hpp>
|
||||||
|
#include <meta.hpp/meta_function.hpp>
|
||||||
|
#include <meta.hpp/meta_method.hpp>
|
||||||
|
#include <meta.hpp/meta_variable.hpp>
|
||||||
|
|
||||||
|
#include "doctest/doctest.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct ivec2 {
|
||||||
|
int x{};
|
||||||
|
int y{};
|
||||||
|
|
||||||
|
static ivec2 zero;
|
||||||
|
|
||||||
|
int dot(ivec2 other) const {
|
||||||
|
return x * other.x + y * other.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ivec3 {
|
||||||
|
int x{};
|
||||||
|
int y{};
|
||||||
|
int z{};
|
||||||
|
|
||||||
|
static ivec3 zero;
|
||||||
|
|
||||||
|
int dot(ivec3 other) const {
|
||||||
|
return x * other.x + y * other.y + z * other.z;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ivec2 ivec2::zero{};
|
||||||
|
ivec3 ivec3::zero{};
|
||||||
|
|
||||||
|
ivec2 iadd2(ivec2 l, ivec2 r) {
|
||||||
|
return {l.x + r.x, l.y + r.y};
|
||||||
|
}
|
||||||
|
|
||||||
|
ivec3 iadd3(ivec3 l, ivec3 r) {
|
||||||
|
return {l.x + r.x, l.y + r.y, l.z + r.z};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/family") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
SUBCASE("class") {
|
||||||
|
meta::class_info ivec2_info = meta::class_<ivec2>("ivec2");
|
||||||
|
meta::class_info ivec3_info = meta::class_<ivec3>("ivec3");
|
||||||
|
CHECK_FALSE(ivec2_info.fid() == ivec3_info.fid());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("field") {
|
||||||
|
meta::field_info x_info = meta::field_<&ivec2::x>("x");
|
||||||
|
meta::field_info y_info = meta::field_<&ivec2::y>("y");
|
||||||
|
CHECK_FALSE(x_info.fid() == y_info.fid());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("function") {
|
||||||
|
meta::function_info iadd2_info = meta::function_<&iadd2>("iadd2");
|
||||||
|
meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3");
|
||||||
|
CHECK_FALSE(iadd2_info.fid() == iadd3_info.fid());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("method") {
|
||||||
|
meta::method_info dot2_info = meta::method_<&ivec2::dot>("dot");
|
||||||
|
meta::method_info dot3_info = meta::method_<&ivec3::dot>("dot");
|
||||||
|
CHECK_FALSE(dot2_info.fid() == dot3_info.fid());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("variable") {
|
||||||
|
meta::variable_info zero2_info = meta::variable_<&ivec2::zero>("zero");
|
||||||
|
meta::variable_info zero3_info = meta::variable_<&ivec3::zero>("zero");
|
||||||
|
CHECK_FALSE(zero2_info.fid() == zero3_info.fid());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -99,83 +99,66 @@ TEST_CASE("meta/registry") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("field_template") {
|
SUBCASE("field_template") {
|
||||||
CHECK(registry.resolve<&ivec2::x>());
|
REQUIRE(registry.resolve<&ivec2::x>());
|
||||||
|
REQUIRE(registry.resolve<&ivec2::y>());
|
||||||
|
|
||||||
const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value();
|
const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value();
|
||||||
CHECK(ivec2_x_type.is_field());
|
const meta::type ivec2_y_type = registry.resolve<&ivec2::y>().value();
|
||||||
|
|
||||||
|
REQUIRE(ivec2_x_type.is_field());
|
||||||
|
REQUIRE(ivec2_y_type.is_field());
|
||||||
|
|
||||||
const meta::field_info ivec2_x_info = ivec2_x_type.get_field().value();
|
const meta::field_info ivec2_x_info = ivec2_x_type.get_field().value();
|
||||||
|
const meta::field_info ivec2_y_info = ivec2_y_type.get_field().value();
|
||||||
|
|
||||||
CHECK(ivec2_x_info.id() == "x");
|
CHECK(ivec2_x_info.id() == "x");
|
||||||
|
CHECK(ivec2_y_info.id() == "y");
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("field_instance") {
|
SUBCASE("field_instance") {
|
||||||
CHECK(registry.resolve(&ivec3::x));
|
CHECK_FALSE(registry.resolve(&ivec2::x));
|
||||||
|
|
||||||
const meta::type ivec3_x_type = registry.resolve<&ivec3::x>().value();
|
|
||||||
CHECK(ivec3_x_type.is_field());
|
|
||||||
|
|
||||||
const meta::field_info ivec3_x_info = ivec3_x_type.get_field().value();
|
|
||||||
CHECK(ivec3_x_info.id() == "x");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("function_template") {
|
SUBCASE("function_template") {
|
||||||
CHECK(registry.resolve<&iadd2>());
|
REQUIRE(registry.resolve<&iadd2>());
|
||||||
|
|
||||||
const meta::type iadd2_type = registry.resolve<&iadd2>().value();
|
const meta::type iadd2_type = registry.resolve<&iadd2>().value();
|
||||||
CHECK(iadd2_type.is_function());
|
REQUIRE(iadd2_type.is_function());
|
||||||
|
|
||||||
const meta::function_info iadd2_info = iadd2_type.get_function().value();
|
const meta::function_info iadd2_info = iadd2_type.get_function().value();
|
||||||
CHECK(iadd2_info.id() == "iadd2");
|
CHECK(iadd2_info.id() == "iadd2");
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("function_instance") {
|
SUBCASE("function_instance") {
|
||||||
CHECK(registry.resolve(&iadd3));
|
CHECK_FALSE(registry.resolve(&iadd3));
|
||||||
|
|
||||||
const meta::type iadd3_type = registry.resolve<&iadd3>().value();
|
|
||||||
CHECK(iadd3_type.is_function());
|
|
||||||
|
|
||||||
const meta::function_info iadd3_info = iadd3_type.get_function().value();
|
|
||||||
CHECK(iadd3_info.id() == "iadd3");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("method_template") {
|
SUBCASE("method_template") {
|
||||||
CHECK(registry.resolve<&ivec2::dot>());
|
REQUIRE(registry.resolve<&ivec2::dot>());
|
||||||
|
|
||||||
const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value();
|
const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value();
|
||||||
CHECK(ivec2_dot_type.is_method());
|
REQUIRE(ivec2_dot_type.is_method());
|
||||||
|
|
||||||
const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value();
|
const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value();
|
||||||
CHECK(ivec2_dot_info.id() == "dot");
|
CHECK(ivec2_dot_info.id() == "dot");
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("method_instance") {
|
SUBCASE("method_instance") {
|
||||||
CHECK(registry.resolve(&ivec3::dot));
|
CHECK_FALSE(registry.resolve(&ivec3::dot));
|
||||||
|
|
||||||
const meta::type ivec3_dot_type = registry.resolve<&ivec3::dot>().value();
|
|
||||||
CHECK(ivec3_dot_type.is_method());
|
|
||||||
|
|
||||||
const meta::method_info ivec3_dot_info = ivec3_dot_type.get_method().value();
|
|
||||||
CHECK(ivec3_dot_info.id() == "dot");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("variable_template") {
|
SUBCASE("variable_template") {
|
||||||
CHECK(registry.resolve<&ivec2::zero>());
|
REQUIRE(registry.resolve<&ivec2::zero>());
|
||||||
|
|
||||||
const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value();
|
const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value();
|
||||||
CHECK(ivec2_zero_type.is_variable());
|
REQUIRE(ivec2_zero_type.is_variable());
|
||||||
|
|
||||||
const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value();
|
const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value();
|
||||||
CHECK(ivec2_x_info.id() == "zero");
|
CHECK(ivec2_x_info.id() == "zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("variable_instance") {
|
SUBCASE("variable_instance") {
|
||||||
CHECK(registry.resolve(&ivec3::zero));
|
CHECK_FALSE(registry.resolve(&ivec3::zero));
|
||||||
|
|
||||||
const meta::type ivec3_zero_type = registry.resolve<&ivec3::zero>().value();
|
|
||||||
CHECK(ivec3_zero_type.is_variable());
|
|
||||||
|
|
||||||
const meta::variable_info ivec3_x_info = ivec3_zero_type.get_variable().value();
|
|
||||||
CHECK(ivec3_x_info.id() == "zero");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user