From 4616ae46d5099177475a0b6f30c484b442597f24 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 21:44:51 +0700 Subject: [PATCH] metadata for infos --- headers/meta.hpp/meta.hpp | 3 ++ headers/meta.hpp/meta_class.hpp | 14 +++++ headers/meta.hpp/meta_class_info.hpp | 11 +++- headers/meta.hpp/meta_data.hpp | 40 +++++++++++++++ headers/meta.hpp/meta_data_info.hpp | 65 ++++++++++++++++++++++++ headers/meta.hpp/meta_field.hpp | 16 ++++++ headers/meta.hpp/meta_field_info.hpp | 16 ++++-- headers/meta.hpp/meta_function.hpp | 16 ++++++ headers/meta.hpp/meta_function_info.hpp | 15 ++++-- headers/meta.hpp/meta_fwd.hpp | 22 +++----- headers/meta.hpp/meta_method.hpp | 16 ++++++ headers/meta.hpp/meta_method_info.hpp | 15 ++++-- headers/meta.hpp/meta_namespace.hpp | 17 ++++++- headers/meta.hpp/meta_namespace_info.hpp | 11 +++- headers/meta.hpp/meta_variable.hpp | 16 ++++++ headers/meta.hpp/meta_variable_info.hpp | 17 +++++-- untests/meta_examples.cpp | 58 +++++++++++++-------- 17 files changed, 310 insertions(+), 58 deletions(-) create mode 100644 headers/meta.hpp/meta_data.hpp create mode 100644 headers/meta.hpp/meta_data_info.hpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 04605e9..420cd6b 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -13,6 +13,9 @@ #include "meta_class.hpp" #include "meta_class_info.hpp" +#include "meta_data.hpp" +#include "meta_data_info.hpp" + #include "meta_field.hpp" #include "meta_field_info.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index b7362ae..3d2c155 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -8,6 +8,12 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" +#include "meta_field.hpp" +#include "meta_function.hpp" +#include "meta_method.hpp" +#include "meta_variable.hpp" + #include "meta_class_info.hpp" namespace meta_hpp @@ -37,6 +43,14 @@ namespace meta_hpp &class_info::merge_with_); } + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + template < auto InternalField > void add_(const field_& internal) { detail::merge_with( diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 8964d70..46cc4c5 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -7,7 +7,9 @@ #pragma once #include "meta_fwd.hpp" +#include "meta_value.hpp" +#include "meta_data_info.hpp" #include "meta_field_info.hpp" #include "meta_function_info.hpp" #include "meta_method_info.hpp" @@ -27,7 +29,7 @@ namespace meta_hpp class_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } @@ -36,6 +38,10 @@ namespace meta_hpp return detail::find_opt(classes_, id); } + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + std::optional get_field(std::string_view id) const { return detail::find_opt(fields_, id); } @@ -53,11 +59,13 @@ namespace meta_hpp } private: friend class namespace_info; + template < typename Class > friend class class_; friend class namespace_; private: void merge_with_(const class_info& other) { detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); detail::merge_with(fields_, other.fields_, &field_info::merge_with_); detail::merge_with(functions_, other.functions_, &function_info::merge_with_); detail::merge_with(methods_, other.methods_, &method_info::merge_with_); @@ -66,6 +74,7 @@ namespace meta_hpp private: std::string id_; std::map> classes_; + std::map> datas_; std::map> fields_; std::map> functions_; std::map> methods_; diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp new file mode 100644 index 0000000..5a172b1 --- /dev/null +++ b/headers/meta.hpp/meta_data.hpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_data_info.hpp" + +namespace meta_hpp +{ + class data_ { + public: + explicit data_(std::string id, value value) + : info_(std::move(id), std::move(value)) {} + + const data_info& info() const noexcept { + return info_; + } + + template < typename... Internals > + data_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + private: + data_info info_; + }; +} diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp new file mode 100644 index 0000000..0c26133 --- /dev/null +++ b/headers/meta.hpp/meta_data_info.hpp @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" +#include "meta_value.hpp" + +namespace meta_hpp +{ + class data_info { + public: + data_info() = delete; + + data_info(data_info&&) = default; + data_info(const data_info&) = default; + + data_info& operator=(data_info&&) = default; + data_info& operator=(const data_info&) = default; + + data_info(std::string id, value value) + : id_(std::move(id)) + , value_(std::move(value)) {} + public: + const std::string& id() const noexcept { + return id_; + } + + const value& get() const noexcept { + return value_; + } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + private: + friend class class_info; + friend class field_info; + friend class function_info; + friend class method_info; + friend class namespace_info; + friend class variable_info; + + template < typename Class > friend class class_; + template < auto Field > friend class field_; + template < auto Function > friend class function_; + template < auto Method > friend class method_; + friend class namespace_; + template < auto Variable > friend class variable_; + + friend class data_; + private: + void merge_with_(const data_info& other) { + value_ = other.value_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + } + private: + std::string id_; + value value_; + std::map> datas_; + }; +} diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 228fc0f..07c9417 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_field_info.hpp" namespace meta_hpp @@ -26,6 +28,20 @@ namespace meta_hpp const field_info& info() const noexcept { return info_; } + + template < typename... Internals > + field_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: field_info info_; }; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 0bfc86e..8a0a57e 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::field_detail { template < typename Field > @@ -69,11 +70,10 @@ namespace meta_hpp field_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: value get(const void* instance) const { return getter_(instance); } @@ -82,17 +82,25 @@ namespace meta_hpp void set(void* instance, Value&& value) const { return setter_(instance, std::forward(value)); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; + template < typename Class > friend class class_; template < auto Field > friend class field_; private: void merge_with_(const field_info& other) { - (void)other; + getter_ = other.getter_; + setter_ = other.setter_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*getter_)(const void*); void(*setter_)(void*, value); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index c87be3f..35d3fe1 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_function_info.hpp" namespace meta_hpp @@ -25,6 +27,20 @@ namespace meta_hpp const function_info& info() const noexcept { return info_; } + + template < typename... Internals > + function_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: function_info info_; }; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 5e95977..c208022 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::function_detail { template < typename Function > @@ -76,16 +77,20 @@ namespace meta_hpp function_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: + template < typename... Args > value invoke(Args&&... args) const { std::array vargs{{std::forward(args)...}}; return invoke_(vargs.data(), vargs.size()); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; friend class namespace_info; @@ -96,10 +101,12 @@ namespace meta_hpp template < auto Function > friend class function_; private: void merge_with_(const function_info& other) { - (void)other; + invoke_ = other.invoke_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*invoke_)(value*, std::size_t); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 7ba6e3d..ab9ac34 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -23,28 +23,20 @@ namespace meta_hpp class value; class class_info; + class data_info; class field_info; class function_info; class method_info; class namespace_info; class variable_info; - template < typename Class > - class class_; - - template < auto Field > - class field_; - - template < auto Function > - class function_; - - template < auto Method > - class method_; - + template < typename Class > class class_; + class data_; + template < auto Field > class field_; + template < auto Function > class function_; + template < auto Method > class method_; class namespace_; - - template < auto Variable > - class variable_; + template < auto Variable > class variable_; } namespace meta_hpp diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 1447385..740c7a4 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_method_info.hpp" namespace meta_hpp @@ -26,6 +28,20 @@ namespace meta_hpp const method_info& info() const noexcept { return info_; } + + template < typename... Internals > + method_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: method_info info_; }; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 3fca6c2..9d3758c 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::method_detail { template < typename Method > @@ -133,11 +134,10 @@ namespace meta_hpp method_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: template < typename... Args > value invoke(void* instance, Args&&... args) const { std::array vargs{{std::forward(args)...}}; @@ -149,17 +149,24 @@ namespace meta_hpp std::array vargs{{std::forward(args)...}}; return cinvoke_(instance, vargs.data(), vargs.size()); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; template < typename Class > friend class class_; template < auto Method > friend class method_; private: void merge_with_(const method_info& other) { - (void)other; + invoke_ = other.invoke_; + cinvoke_ = other.cinvoke_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*invoke_)(void*, value*, std::size_t); value(*cinvoke_)(const void*, value*, std::size_t); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index e3280a9..1fd5cb9 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -8,6 +8,11 @@ #include "meta_fwd.hpp" +#include "meta_class.hpp" +#include "meta_data.hpp" +#include "meta_function.hpp" +#include "meta_variable.hpp" + #include "meta_namespace_info.hpp" namespace meta_hpp @@ -36,6 +41,14 @@ namespace meta_hpp &class_info::merge_with_); } + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + template < auto InternalFunction > void add_(const function_& internal) { detail::merge_with( @@ -53,8 +66,8 @@ namespace meta_hpp &namespace_info::merge_with_); } - template < auto Internalvariable > - void add_(const variable_& internal) { + template < auto InternalVariable > + void add_(const variable_& internal) { detail::merge_with( info_.variables_, internal.info().id(), diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index 4ad5bb2..cec5528 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -7,8 +7,10 @@ #pragma once #include "meta_fwd.hpp" +#include "meta_value.hpp" #include "meta_class_info.hpp" +#include "meta_data_info.hpp" #include "meta_function_info.hpp" #include "meta_variable_info.hpp" @@ -26,15 +28,18 @@ namespace meta_hpp namespace_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + std::optional get_function(std::string_view id) const { return detail::find_opt(functions_, id); } @@ -51,6 +56,7 @@ namespace meta_hpp private: void merge_with_(const namespace_info& other) { detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); detail::merge_with(functions_, other.functions_, &function_info::merge_with_); detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); @@ -58,6 +64,7 @@ namespace meta_hpp private: std::string id_; std::map> classes_; + std::map> datas_; std::map> functions_; std::map> namespaces_; std::map> variables_; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 78fe289..7ba050a 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_variable_info.hpp" namespace meta_hpp @@ -24,6 +26,20 @@ namespace meta_hpp const variable_info& info() const noexcept { return info_; } + + template < typename... Internals > + variable_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: variable_info info_; }; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index f9c6767..96e0486 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::variable_detail { template < typename Variable > @@ -64,11 +65,10 @@ namespace meta_hpp variable_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: value get() const { return getter_(); } @@ -77,19 +77,28 @@ namespace meta_hpp void set(Value&& value) const { return setter_(std::forward(value)); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; friend class namespace_info; + template < typename Class > friend class class_; friend class namespace_; + template < auto Variable > friend class variable_; private: void merge_with_(const variable_info& other) { - (void)other; + getter_ = other.getter_; + setter_ = other.setter_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*getter_)(); void(*setter_)(value); + std::map> datas_; }; } diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index e8332e7..e72e439 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -85,35 +85,49 @@ TEST_CASE("meta/examples/ivec3") { } TEST_CASE("meta/examples/simple") { - namespace meta = meta_hpp; + using namespace meta_hpp; - meta::namespace_info vmath_info = meta::namespace_("vmath")( - meta::class_("ivec2")( - meta::field_<&ivec2::x>("x"), - meta::field_<&ivec2::y>("y"), - meta::method_<&ivec2::dot>("dot"), - meta::method_<&ivec2::length2>("length2") + namespace_info vmath_info = namespace_("vmath")( + class_("ivec2")( + field_<&ivec2::x>("x")( + data_("tooltip", "x-coordinate field") + ), + field_<&ivec2::y>("y")( + data_("tooltip", "y-coordinate field") + ), + method_<&ivec2::dot>("dot"), + method_<&ivec2::length2>("length2") ), - meta::class_("ivec3")( - meta::field_<&ivec3::x>("x"), - meta::field_<&ivec3::y>("y"), - meta::field_<&ivec3::z>("z"), - meta::method_<&ivec3::dot>("dot"), - meta::method_<&ivec3::length2>("length2") + class_("ivec3")( + field_<&ivec3::x>("x")( + data_("tooltip", "x-coordinate field") + ), + field_<&ivec3::y>("y")( + data_("tooltip", "y-coordinate field") + ), + field_<&ivec3::z>("z")( + data_("tooltip", "z-coordinate field") + ), + method_<&ivec3::dot>("dot"), + method_<&ivec3::length2>("length2") ), - meta::function_(&add)>("iadd2"), - meta::function_(&add)>("iadd3") + function_(&add)>("iadd2"), + function_(&add)>("iadd3") ).info(); - meta::class_info ivec2_info = vmath_info.get_class("ivec2").value(); - meta::field_info ivec2_x_info = ivec2_info.get_field("x").value(); - meta::field_info ivec2_y_info = ivec2_info.get_field("y").value(); + class_info ivec2_info = vmath_info.get_class("ivec2").value(); - meta::method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); - meta::method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); + field_info ivec2_x_info = ivec2_info.get_field("x").value(); + field_info ivec2_y_info = ivec2_info.get_field("y").value(); - meta::function_info iadd2_info = vmath_info.get_function("iadd2").value(); - meta::function_info iadd3_info = vmath_info.get_function("iadd3").value(); + data_info ivec2_x_tooltip_info = ivec2_x_info.get_data("tooltip").value(); + data_info ivec2_y_tooltip_info = ivec2_y_info.get_data("tooltip").value(); + + method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); + method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); + + function_info iadd2_info = vmath_info.get_function("iadd2").value(); + function_info iadd3_info = vmath_info.get_function("iadd3").value(); { ivec2 v2{1,2};