diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 2ba7475..dce9fad 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -14,13 +14,13 @@ namespace meta_hpp { - template < auto Field > + template < typename FieldType > class field_ { public: - static_assert(std::is_member_object_pointer_v); + static_assert(std::is_member_object_pointer_v); - explicit field_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + explicit field_(std::string id, FieldType field) + : info_{std::move(id), field} {} operator const field_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 093f01c..f498831 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -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; 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; 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; + using field_setter = std::function; + + template < typename FieldType > + field_getter make_getter(FieldType field) { + using namespace std::placeholders; + return std::bind(&raw_getter, field, _1); + } + + template < typename FieldType > + field_setter make_setter(FieldType field) { + using namespace std::placeholders; + return std::bind(&raw_setter, 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, std::string id) + template < typename FieldType > + field_info(std::string id, FieldType field) : id_{std::move(id)} - , getter_{&field_detail::getter} - , setter_{&field_detail::setter} {} + , 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> datas_; }; } diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 2748725..524f30f 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -31,7 +31,7 @@ target_compile_options(${PROJECT_NAME} $<$,$>: -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}) diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 0df71d1..081ba66 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -61,8 +61,8 @@ TEST_CASE("meta/class") { class_( meta::class_("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_("child")( - meta::field_<&clazz::clazz2::field>("field") + meta::field_("field", &clazz::clazz2::field) ) )); CHECK_NOTHROW(clazz_( meta::class_("child")( - meta::field_<&clazz::clazz2::cfield>("cfield") + meta::field_("cfield", &clazz::clazz2::cfield) ) )); CHECK_THROWS_AS(clazz_( meta::class_("child")( - meta::field_<&clazz::clazz3::field>("field") + meta::field_("field", &clazz::clazz3::field) ) ), std::logic_error); diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index c66c520..5a37204 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -100,7 +100,7 @@ TEST_CASE("meta/data/field") { using namespace std::string_literals; const meta::class_info clazz_info = meta::class_("clazz")( - meta::field_<&clazz::field>("field")( + meta::field_("field", &clazz::field)( meta::data_("hello"s, "world"s) ) ); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index ba0959b..7daa2f1 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -89,23 +89,23 @@ TEST_CASE("meta/examples/simple") { namespace_info vmath_info = namespace_("vmath")( class_("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")( - 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")( - 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")( - 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") ) diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 3b0ce40..46c854d 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -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_; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 8ddc085..2d5d121 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -51,15 +51,15 @@ TEST_CASE("meta/registry") { auto registry = meta::registry{}( meta::namespace_("vmath")( meta::class_("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")( - 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")( - meta::field_<&ivec2::x>("x") + meta::field_("x", &ivec2::x) )); registry( meta::class_("ivec2")( - meta::field_<&ivec2::y>("y") + meta::field_("y", &ivec2::y) )); CHECK(registry.resolve()); diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index 4e94218..ff98110 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -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")( - meta::field_<&clazz::field>("field") + meta::field_("field", &clazz::field) ); clazz_type.merge(meta::class_("clazz")(