From 53776b30eb2b7617bd98aa4d4e8b76615160ef47 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 04:52:29 +0700 Subject: [PATCH] internal classes and enums for class_type --- headers/meta.hpp/meta_binds.hpp | 18 +++++-- headers/meta.hpp/meta_binds/class_bind.hpp | 48 ++++++++++++++----- headers/meta.hpp/meta_binds/scope_bind.hpp | 12 ++++- .../meta.hpp/meta_detail/state_registry.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 10 +++- headers/meta.hpp/meta_types/class_type.hpp | 26 +++++++++- untests/meta_types/class_type2_tests.cpp | 37 ++++++++++++++ 7 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 untests/meta_types/class_type2_tests.cpp diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index cb1bddc..15bb5af 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -100,6 +100,17 @@ namespace meta_hpp explicit class_bind(metadata_map metadata); operator class_type() const noexcept; + // class_ + + template < detail::class_kind InternalClass > + class_bind& class_(std::string name); + + // base_ + + template < detail::class_kind Base > + class_bind& base_() + requires detail::class_bind_base_kind; + // constructor_ template < typename... Args @@ -120,11 +131,10 @@ namespace meta_hpp class_bind& destructor_(destructor_opts opts) requires detail::class_bind_destructor_kind; - // base_ + // enum_ - template < detail::class_kind Base > - class_bind& base_() - requires detail::class_bind_base_kind; + template < detail::enum_kind InternalEnum > + class_bind& enum_(std::string name); // function_ diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 6a7b37a..29ae9ba 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -25,6 +25,39 @@ namespace meta_hpp return class_type{data_}; } + // class_ + + template < detail::class_kind Class > + template < detail::class_kind InternalClass > + class_bind& class_bind::class_(std::string name) { + data_->classes.insert_or_assign(std::move(name), detail::resolve_type()); + return *this; + } + + // + // base_ + // + + template < detail::class_kind Class > + template < detail::class_kind Base > + class_bind& class_bind::base_() + requires detail::class_bind_base_kind + { + const class_type base_type = detail::resolve_type(); + if ( data_->bases.contains(base_type) ) { + return *this; + } + + data_->bases.emplace(base_type); + data_->bases_info.emplace(base_type, detail::class_type_data::base_info{ + .upcast = +[](void* derived) -> void* { + return static_cast(static_cast(derived)); + } + }); + + return *this; + } + // // constructor_ // @@ -81,20 +114,13 @@ namespace meta_hpp } // - // base_ + // enum_ // template < detail::class_kind Class > - template < detail::class_kind Base > - class_bind& class_bind::base_() - requires detail::class_bind_base_kind - { - data_->bases.emplace(detail::resolve_type()); - data_->bases_info.emplace(detail::resolve_type(), detail::class_type_data::base_info{ - .upcast = +[](void* derived) -> void* { - return static_cast(static_cast(derived)); - } - }); + template < detail::enum_kind InternalEnum > + class_bind& class_bind::enum_(std::string name) { + data_->enums.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 4f25d51..d5d6a2b 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -29,15 +29,23 @@ namespace meta_hpp return scope{state_}; } + // + // class_ + // + template < detail::class_kind Class > scope_bind& scope_bind::class_(std::string name) { - state_->classes.emplace(std::move(name), detail::resolve_type()); + state_->classes.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } + // + // enum_ + // + template < detail::enum_kind Enum > scope_bind& scope_bind::enum_(std::string name) { - state_->enums.emplace(std::move(name), detail::resolve_type()); + state_->enums.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index 077c6ec..0c2a56f 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -36,7 +36,7 @@ namespace meta_hpp::detail } auto state = scope_state::make(std::string{name}, metadata_map{}); - return scopes_.emplace(std::string{name}, std::move(state)).first->second; + return scopes_.insert_or_assign(std::string{name}, std::move(state)).first->second; } public: class locker : noncopyable { diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 52034c4..d2260ce 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -155,9 +155,11 @@ namespace meta_hpp [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; + [[nodiscard]] const class_map& get_classes() const noexcept; + [[nodiscard]] const class_set& get_bases() const noexcept; [[nodiscard]] const constructor_map& get_ctors() const noexcept; [[nodiscard]] const destructor_map& get_dtors() const noexcept; - [[nodiscard]] const class_set& get_bases() const noexcept; + [[nodiscard]] const enum_map& get_enums() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; [[nodiscard]] const member_map& get_members() const noexcept; [[nodiscard]] const method_map& get_methods() const noexcept; @@ -180,6 +182,8 @@ namespace meta_hpp [[nodiscard]] bool is_derived_from() const noexcept; [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; + [[nodiscard]] class_type get_class(std::string_view name) const noexcept; + [[nodiscard]] enum_type get_enum(std::string_view name) const noexcept; [[nodiscard]] function get_function(std::string_view name) const noexcept; [[nodiscard]] member get_member(std::string_view name) const noexcept; [[nodiscard]] method get_method(std::string_view name) const noexcept; @@ -483,9 +487,11 @@ namespace meta_hpp::detail const std::size_t size; const std::vector argument_types; + class_map classes; + class_set bases; constructor_map constructors; destructor_map destructors; - class_set bases; + enum_map enums; function_map functions; member_map members; method_map methods; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 9723be0..8b46b1d 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -73,6 +73,14 @@ namespace meta_hpp return data_->argument_types; } + inline const class_map& class_type::get_classes() const noexcept { + return data_->classes; + } + + inline const class_set& class_type::get_bases() const noexcept { + return data_->bases; + } + inline const constructor_map& class_type::get_ctors() const noexcept { return data_->constructors; } @@ -81,8 +89,8 @@ namespace meta_hpp return data_->destructors; } - inline const class_set& class_type::get_bases() const noexcept { - return data_->bases; + inline const enum_map& class_type::get_enums() const noexcept { + return data_->enums; } inline const function_map& class_type::get_functions() const noexcept { @@ -173,6 +181,20 @@ namespace meta_hpp return false; } + inline class_type class_type::get_class(std::string_view name) const noexcept { + if ( auto iter = data_->classes.find(name); iter != data_->classes.end() ) { + return iter->second; + } + return class_type{}; + } + + inline enum_type class_type::get_enum(std::string_view name) const noexcept { + if ( auto iter = data_->enums.find(name); iter != data_->enums.end() ) { + return iter->second; + } + return enum_type{}; + } + inline function class_type::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : data_->functions ) { if ( index.get_name() == name ) { diff --git a/untests/meta_types/class_type2_tests.cpp b/untests/meta_types/class_type2_tests.cpp new file mode 100644 index 0000000..f4870c1 --- /dev/null +++ b/untests/meta_types/class_type2_tests.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "../meta_untests.hpp" + +namespace +{ + struct clazz { + struct internal_clazz {}; + enum class internal_enum {}; + }; +} + +TEST_CASE("meta/meta_types/class_type2") { + namespace meta = meta_hpp; + + meta::class_() + .class_("internal_clazz") + .enum_("internal_enum"); + + const meta::class_type clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + CHECK(clazz_type.get_class("internal_clazz") == meta::resolve_type()); + CHECK(clazz_type.get_enum("internal_enum") == meta::resolve_type()); + + CHECK(clazz_type.get_classes() == meta::class_map{ + {"internal_clazz", meta::resolve_type()} + }); + + CHECK(clazz_type.get_enums() == meta::enum_map{ + {"internal_enum", meta::resolve_type()} + }); +}