remove "auto Field"

This commit is contained in:
BlackMATov
2021-07-07 02:36:45 +07:00
parent 788ce044dc
commit 0a173e55a1
9 changed files with 67 additions and 45 deletions

View File

@@ -14,13 +14,13 @@
namespace meta_hpp
{
template < auto Field >
template < typename FieldType >
class field_ {
public:
static_assert(std::is_member_object_pointer_v<decltype(Field)>);
static_assert(std::is_member_object_pointer_v<FieldType>);
explicit field_(std::string id)
: info_{detail::auto_arg<META_HPP_AUTO_T(Field)>, std::move(id)} {}
explicit field_(std::string id, FieldType field)
: info_{std::move(id), field} {}
operator const field_info&() const noexcept {
return info_;

View File

@@ -15,8 +15,11 @@
namespace meta_hpp::field_detail
{
template < typename FieldType, FieldType Field >
value getter(cinstance instance) {
template < typename FieldType >
value raw_getter(
FieldType field,
cinstance instance)
{
using ft = detail::field_traits<FieldType>;
using value_type = typename ft::value_type;
using instance_type = typename ft::instance_type;
@@ -26,12 +29,16 @@ namespace meta_hpp::field_detail
throw std::logic_error("an attempt to get a field with incorrect instance type");
}
value_type typed_value{std::invoke(Field, *typed_instance)};
value_type typed_value{std::invoke(field, *typed_instance)};
return value{std::move(typed_value)};
}
template < typename FieldType, FieldType Field >
void setter([[maybe_unused]] instance instance, value value) {
template < typename FieldType >
void raw_setter(
[[maybe_unused]] FieldType field,
[[maybe_unused]] instance instance,
value value)
{
using ft = detail::field_traits<FieldType>;
using value_type = typename ft::value_type;
using instance_type = typename ft::instance_type;
@@ -47,11 +54,26 @@ namespace meta_hpp::field_detail
throw std::logic_error("an attempt to set a field with incorrect argument type");
}
std::invoke(Field, *typed_instance) = std::move(*typed_value);
std::invoke(field, *typed_instance) = std::move(*typed_value);
} else {
throw std::logic_error("an attempt to change a constant field");
}
}
using field_getter = std::function<value(cinstance)>;
using field_setter = std::function<void(instance, value)>;
template < typename FieldType >
field_getter make_getter(FieldType field) {
using namespace std::placeholders;
return std::bind(&raw_getter<FieldType>, field, _1);
}
template < typename FieldType >
field_setter make_setter(FieldType field) {
using namespace std::placeholders;
return std::bind(&raw_setter<FieldType>, field, _1, _2);
}
}
namespace meta_hpp
@@ -102,18 +124,18 @@ namespace meta_hpp
detail::merge_with(datas_, other.datas_, &data_info::merge);
}
private:
template < auto Field >
template < typename FieldType >
friend class field_;
template < typename FieldType, FieldType Field >
field_info(detail::auto_arg_t<FieldType, Field>, std::string id)
template < typename FieldType >
field_info(std::string id, FieldType field)
: id_{std::move(id)}
, getter_{&field_detail::getter<FieldType, Field>}
, setter_{&field_detail::setter<FieldType, Field>} {}
, getter_{field_detail::make_getter(field)}
, setter_{field_detail::make_setter(field)} {}
private:
std::string id_;
value(*getter_)(cinstance);
void(*setter_)(instance, value);
field_detail::field_getter getter_;
field_detail::field_setter setter_;
std::map<std::string, data_info, std::less<>> datas_;
};
}

View File

@@ -31,7 +31,7 @@ target_compile_options(${PROJECT_NAME}
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Werror -Weverything -Wno-unknown-warning-option
-Wconversion -Wimplicit-int-float-conversion
-Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported
-Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported -Wno-padded
-Wno-float-equal -Wno-double-promotion -Wno-shadow-field-in-constructor>)
add_test(${PROJECT_NAME} ${PROJECT_NAME})

View File

@@ -61,8 +61,8 @@ TEST_CASE("meta/class") {
class_(
meta::class_<clazz::clazz2>("clazz2"),
meta::field_<&clazz::field>("field"),
meta::field_<&clazz::cfield>("cfield"),
meta::field_("field", &clazz::field),
meta::field_("cfield", &clazz::cfield),
meta::function_<&clazz::func>("func"),
meta::method_<&clazz::method>("method"),
meta::method_<&clazz::cmethod>("cmethod"),
@@ -128,19 +128,19 @@ TEST_CASE("meta/class/merge") {
SUBCASE("merge") {
CHECK_NOTHROW(clazz_(
meta::class_<clazz::clazz2>("child")(
meta::field_<&clazz::clazz2::field>("field")
meta::field_("field", &clazz::clazz2::field)
)
));
CHECK_NOTHROW(clazz_(
meta::class_<clazz::clazz2>("child")(
meta::field_<&clazz::clazz2::cfield>("cfield")
meta::field_("cfield", &clazz::clazz2::cfield)
)
));
CHECK_THROWS_AS(clazz_(
meta::class_<clazz::clazz3>("child")(
meta::field_<&clazz::clazz3::field>("field")
meta::field_("field", &clazz::clazz3::field)
)
), std::logic_error);

View File

@@ -100,7 +100,7 @@ TEST_CASE("meta/data/field") {
using namespace std::string_literals;
const meta::class_info clazz_info = meta::class_<clazz>("clazz")(
meta::field_<&clazz::field>("field")(
meta::field_("field", &clazz::field)(
meta::data_("hello"s, "world"s)
)
);

View File

@@ -89,23 +89,23 @@ TEST_CASE("meta/examples/simple") {
namespace_info vmath_info = namespace_("vmath")(
class_<ivec2>("ivec2")(
field_<&ivec2::x>("x")(
field_("x", &ivec2::x)(
data_("tooltip", "x-coordinate field")
),
field_<&ivec2::y>("y")(
field_("y", &ivec2::y)(
data_("tooltip", "y-coordinate field")
),
method_<&ivec2::dot>("dot"),
method_<&ivec2::length2>("length2")
),
class_<ivec3>("ivec3")(
field_<&ivec3::x>("x")(
field_("x", &ivec3::x)(
data_("tooltip", "x-coordinate field")
),
field_<&ivec3::y>("y")(
field_("y", &ivec3::y)(
data_("tooltip", "y-coordinate field")
),
field_<&ivec3::z>("z")(
field_("z", &ivec3::z)(
data_("tooltip", "z-coordinate field")
),
method_<&ivec3::dot>("dot"),
@@ -156,15 +156,15 @@ TEST_CASE("meta/examples/advanced") {
auto db = registry{}(
class_<ivec2>("ivec2")(
field_<&ivec2::x>("x"),
field_<&ivec2::y>("y"),
field_("x", &ivec2::x),
field_("y", &ivec2::y),
method_<&ivec2::dot>("dot"),
method_<&ivec2::length2>("length2")
),
class_<ivec3>("ivec3")(
field_<&ivec3::x>("x"),
field_<&ivec3::y>("y"),
field_<&ivec3::z>("z"),
field_("x", &ivec3::x),
field_("y", &ivec3::y),
field_("z", &ivec3::z),
method_<&ivec3::dot>("dot"),
method_<&ivec3::length2>("length2")
)

View File

@@ -19,8 +19,8 @@ namespace
TEST_CASE("meta/field") {
namespace meta = meta_hpp;
meta::field_<&clazz::field> field_{"field"};
meta::field_<&clazz::cfield> cfield_{"cfield"};
meta::field_ field_{"field", &clazz::field};
meta::field_ cfield_{"cfield", &clazz::cfield};
const meta::field_info& field_info = field_;
const meta::field_info& cfield_info = cfield_;

View File

@@ -51,15 +51,15 @@ TEST_CASE("meta/registry") {
auto registry = meta::registry{}(
meta::namespace_("vmath")(
meta::class_<ivec2>("ivec2")(
meta::field_<&ivec2::x>("x"),
meta::field_<&ivec2::y>("y"),
meta::field_("x", &ivec2::x),
meta::field_("y", &ivec2::y),
meta::method_<&ivec2::dot>("dot"),
meta::variable_<&ivec2::zero>("zero")
),
meta::class_<ivec3>("ivec3")(
meta::field_<&ivec3::x>("x"),
meta::field_<&ivec3::y>("y"),
meta::field_<&ivec3::z>("z"),
meta::field_("x", &ivec3::x),
meta::field_("y", &ivec3::y),
meta::field_("z", &ivec3::z),
meta::method_<&ivec3::dot>("dot"),
meta::variable_<&ivec3::zero>("zero")
),
@@ -172,12 +172,12 @@ TEST_CASE("meta/registry/merge") {
SUBCASE("class") {
registry(
meta::class_<ivec2>("ivec2")(
meta::field_<&ivec2::x>("x")
meta::field_("x", &ivec2::x)
));
registry(
meta::class_<ivec2>("ivec2")(
meta::field_<&ivec2::y>("y")
meta::field_("y", &ivec2::y)
));
CHECK(registry.resolve<ivec2>());

View File

@@ -35,7 +35,7 @@ TEST_CASE("meta/type") {
CHECK(class_type.is_class());
CHECK(class_type.get_class()->id() == "clazz");
meta::type field_type = meta::field_<&clazz::field>("field");
meta::type field_type = meta::field_("field", &clazz::field);
CHECK(field_type.is_field());
CHECK(field_type.get_field()->id() == "field");
@@ -62,7 +62,7 @@ TEST_CASE("meta/type/merge") {
{
meta::type clazz_type = meta::class_<clazz>("clazz")(
meta::field_<&clazz::field>("field")
meta::field_("field", &clazz::field)
);
clazz_type.merge(meta::class_<clazz>("clazz")(