diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index d339945..1b6f321 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -4197,213 +4197,126 @@ namespace meta_hpp::detail } public: - template < array_kind Array > - [[nodiscard]] array_type resolve_type() { - return resolve_array_type(); - } - - template < class_kind Class > - [[nodiscard]] class_type resolve_type() { - return resolve_class_type(); - } - - template < enum_kind Enum > - [[nodiscard]] enum_type resolve_type() { - return resolve_enum_type(); - } - - template < function_pointer_kind Function > - [[nodiscard]] function_type resolve_type() { - return resolve_function_type(); - } - - template < member_pointer_kind Member > - [[nodiscard]] member_type resolve_type() { - return resolve_member_type(); - } - - template < method_pointer_kind Method > - [[nodiscard]] method_type resolve_type() { - return resolve_method_type(); - } - - template < nullptr_kind Nullptr > - [[nodiscard]] nullptr_type resolve_type() { - return resolve_nullptr_type(); - } - - template < number_kind Number > - [[nodiscard]] number_type resolve_type() { - return resolve_number_type(); - } - - template < pointer_kind Pointer > - [[nodiscard]] pointer_type resolve_type() { - return resolve_pointer_type(); - } - - template < reference_kind Reference > - [[nodiscard]] reference_type resolve_type() { - return resolve_reference_type(); - } - - template < void_kind Void > - [[nodiscard]] void_type resolve_type() { - return resolve_void_type(); + template < typename T > + [[nodiscard]] auto resolve_type() { + // clang-format off + if constexpr ( array_kind ) { return resolve_array_type(); } + if constexpr ( class_kind ) { return resolve_class_type(); } + if constexpr ( enum_kind ) { return resolve_enum_type(); } + if constexpr ( function_pointer_kind ) { return resolve_function_type(); } + if constexpr ( member_pointer_kind ) { return resolve_member_type(); } + if constexpr ( method_pointer_kind ) { return resolve_method_type(); } + if constexpr ( nullptr_kind ) { return resolve_nullptr_type(); } + if constexpr ( number_kind ) { return resolve_number_type(); } + if constexpr ( pointer_kind ) { return resolve_pointer_type(); } + if constexpr ( reference_kind ) { return resolve_reference_type(); } + if constexpr ( void_kind ) { return resolve_void_type(); } + // clang-format on } public: template < array_kind Array > [[nodiscard]] array_type resolve_array_type() { - return array_type{resolve_array_type_data>()}; + using array_t = std::remove_cv_t; + static array_type type{ensure_type(type_list{})}; + return type; } template < class_kind Class > [[nodiscard]] class_type resolve_class_type() { - return class_type{resolve_class_type_data>()}; + using class_t = std::remove_cv_t; + static class_type type{ensure_type(type_list{})}; + return type; } template < class_kind Class, typename... Args > [[nodiscard]] constructor_type resolve_constructor_type() { - return constructor_type{resolve_constructor_type_data, Args...>()}; + using class_t = std::remove_cv_t; + static constructor_type type{ensure_type(type_list{}, type_list{})}; + return type; } template < class_kind Class > [[nodiscard]] destructor_type resolve_destructor_type() { - return destructor_type{resolve_destructor_type_data>()}; + using class_t = std::remove_cv_t; + static destructor_type type{ensure_type(type_list{})}; + return type; } template < enum_kind Enum > [[nodiscard]] enum_type resolve_enum_type() { - return enum_type{resolve_enum_type_data>()}; + using enum_t = std::remove_cv_t; + static enum_type type{ensure_type(type_list{})}; + return type; } template < function_pointer_kind Function > [[nodiscard]] function_type resolve_function_type() { - return function_type{resolve_function_type_data>()}; + using function_t = std::remove_cv_t; + static function_type type{ensure_type(type_list{})}; + return type; } template < member_pointer_kind Member > [[nodiscard]] member_type resolve_member_type() { - return member_type{resolve_member_type_data>()}; + using member_t = std::remove_cv_t; + static member_type type{ensure_type(type_list{})}; + return type; } template < method_pointer_kind Method > [[nodiscard]] method_type resolve_method_type() { - return method_type{resolve_method_type_data>()}; + using method_t = std::remove_cv_t; + static method_type type{ensure_type(type_list{})}; + return type; } template < nullptr_kind Nullptr > [[nodiscard]] nullptr_type resolve_nullptr_type() { - return nullptr_type{resolve_nullptr_type_data>()}; + using nullptr_t = std::remove_cv_t; + static nullptr_type type{ensure_type(type_list{})}; + return type; } template < number_kind Number > [[nodiscard]] number_type resolve_number_type() { - return number_type{resolve_number_type_data>()}; + using number_t = std::remove_cv_t; + static number_type type{ensure_type(type_list{})}; + return type; } template < pointer_kind Pointer > [[nodiscard]] pointer_type resolve_pointer_type() { - return pointer_type{resolve_pointer_type_data>()}; + using pointer_t = std::remove_cv_t; + static pointer_type type{ensure_type(type_list{})}; + return type; } template < reference_kind Reference > [[nodiscard]] reference_type resolve_reference_type() { - return reference_type{resolve_reference_type_data>()}; + using reference_t = std::remove_cv_t; + static reference_type type{ensure_type(type_list{})}; + return type; } template < void_kind Void > [[nodiscard]] void_type resolve_void_type() { - return void_type{resolve_void_type_data>()}; - } - - private: - template < array_kind Array > - [[nodiscard]] array_type_data* resolve_array_type_data() { - static array_type_data data = (ensure_type(data), array_type_data{type_list{}}); - return &data; - } - - template < class_kind Class > - [[nodiscard]] class_type_data* resolve_class_type_data() { - static class_type_data data = (ensure_type(data), class_type_data{type_list{}}); - return &data; - } - - template < class_kind Class, typename... Args > - [[nodiscard]] constructor_type_data* resolve_constructor_type_data() { - static constructor_type_data data{type_list{}, type_list{}}; - return &data; - } - - template < class_kind Class > - [[nodiscard]] destructor_type_data* resolve_destructor_type_data() { - static destructor_type_data data{type_list{}}; - return &data; - } - - template < enum_kind Enum > - [[nodiscard]] enum_type_data* resolve_enum_type_data() { - static enum_type_data data = (ensure_type(data), enum_type_data{type_list{}}); - return &data; - } - - template < function_pointer_kind Function > - [[nodiscard]] function_type_data* resolve_function_type_data() { - static function_type_data data = (ensure_type(data), function_type_data{type_list{}}); - return &data; - } - - template < member_pointer_kind Member > - [[nodiscard]] member_type_data* resolve_member_type_data() { - static member_type_data data = (ensure_type(data), member_type_data{type_list{}}); - return &data; - } - - template < method_pointer_kind Method > - [[nodiscard]] method_type_data* resolve_method_type_data() { - static method_type_data data = (ensure_type(data), method_type_data{type_list{}}); - return &data; - } - - template < nullptr_kind Nullptr > - [[nodiscard]] nullptr_type_data* resolve_nullptr_type_data() { - static nullptr_type_data data = (ensure_type(data), nullptr_type_data{type_list{}}); - return &data; - } - - template < number_kind Number > - [[nodiscard]] number_type_data* resolve_number_type_data() { - static number_type_data data = (ensure_type(data), number_type_data{type_list{}}); - return &data; - } - - template < pointer_kind Pointer > - [[nodiscard]] pointer_type_data* resolve_pointer_type_data() { - static pointer_type_data data = (ensure_type(data), pointer_type_data{type_list{}}); - return &data; - } - - template < reference_kind Reference > - [[nodiscard]] reference_type_data* resolve_reference_type_data() { - static reference_type_data data = (ensure_type(data), reference_type_data{type_list{}}); - return &data; - } - - template < void_kind Void > - [[nodiscard]] void_type_data* resolve_void_type_data() { - static void_type_data data = (ensure_type(data), void_type_data{type_list{}}); - return &data; + using void_t = std::remove_cv_t; + static void_type type{ensure_type(type_list{})}; + return type; } private: type_registry() = default; - template < typename Type, typename TypeData > - void ensure_type(TypeData& type_data) { + template < typename TypeData, typename... Args > + TypeData* ensure_type(Args&&... args) { + static auto data{std::make_unique(std::forward(args)...)}; + const locker lock; - types_.emplace(any_type{&type_data}); + types_.emplace(any_type{data.get()}); + + return data.get(); } private: @@ -4562,7 +4475,7 @@ namespace meta_hpp template < typename From > requires std::is_class_v> - [[nodiscard]] class_type resolve_poly_type(From&& from) noexcept { + [[nodiscard]] class_type resolve_poly_type(From&& from) { using from_data_type = std::remove_reference_t; static_assert( diff --git a/develop/unbench/dynamic_cast_bench.cpp b/develop/unbench/dynamic_cast_bench.cpp index 4c7a82e..9c5d681 100644 --- a/develop/unbench/dynamic_cast_bench.cpp +++ b/develop/unbench/dynamic_cast_bench.cpp @@ -27,25 +27,25 @@ namespace base1& operator=(const base1&) = default; RTTR_ENABLE() - META_HPP_ENABLE_POLYMORPHIC_CAST() + META_HPP_ENABLE_POLY_INFO() }; struct base2 : base1 { unsigned b2{2}; RTTR_ENABLE(base1) - META_HPP_ENABLE_POLYMORPHIC_CAST() + META_HPP_ENABLE_POLY_INFO() }; struct base3 : base2 { unsigned b3{3}; RTTR_ENABLE(base2) - META_HPP_ENABLE_POLYMORPHIC_CAST() + META_HPP_ENABLE_POLY_INFO() }; struct base4 : base3 { unsigned b4{4}; RTTR_ENABLE(base3) - META_HPP_ENABLE_POLYMORPHIC_CAST() + META_HPP_ENABLE_POLY_INFO() }; base4* dynamic_cast_1(base1* b1) { diff --git a/develop/untests/meta_issues/random_issue_3.cpp b/develop/untests/meta_issues/random_issue_3.cpp new file mode 100644 index 0000000..6c0e18c --- /dev/null +++ b/develop/untests/meta_issues/random_issue_3.cpp @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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-2023, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include +#include + +namespace +{ + struct A {}; + struct B {}; +} + +TEST_CASE("meta/meta_issues/random/3") { + namespace meta = meta_hpp; + + meta::detail::type_registry& registry{meta::detail::type_registry::instance()}; + + meta::class_type a_type = registry.resolve_class_type(); + meta::class_type b_type = registry.resolve_class_type(); + + CHECK(registry.get_type_by_id(a_type.get_id()) == a_type); + CHECK(registry.get_type_by_id(b_type.get_id()) == b_type); +} diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index 05911ac..ca11295 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -56,213 +56,126 @@ namespace meta_hpp::detail } public: - template < array_kind Array > - [[nodiscard]] array_type resolve_type() { - return resolve_array_type(); - } - - template < class_kind Class > - [[nodiscard]] class_type resolve_type() { - return resolve_class_type(); - } - - template < enum_kind Enum > - [[nodiscard]] enum_type resolve_type() { - return resolve_enum_type(); - } - - template < function_pointer_kind Function > - [[nodiscard]] function_type resolve_type() { - return resolve_function_type(); - } - - template < member_pointer_kind Member > - [[nodiscard]] member_type resolve_type() { - return resolve_member_type(); - } - - template < method_pointer_kind Method > - [[nodiscard]] method_type resolve_type() { - return resolve_method_type(); - } - - template < nullptr_kind Nullptr > - [[nodiscard]] nullptr_type resolve_type() { - return resolve_nullptr_type(); - } - - template < number_kind Number > - [[nodiscard]] number_type resolve_type() { - return resolve_number_type(); - } - - template < pointer_kind Pointer > - [[nodiscard]] pointer_type resolve_type() { - return resolve_pointer_type(); - } - - template < reference_kind Reference > - [[nodiscard]] reference_type resolve_type() { - return resolve_reference_type(); - } - - template < void_kind Void > - [[nodiscard]] void_type resolve_type() { - return resolve_void_type(); + template < typename T > + [[nodiscard]] auto resolve_type() { + // clang-format off + if constexpr ( array_kind ) { return resolve_array_type(); } + if constexpr ( class_kind ) { return resolve_class_type(); } + if constexpr ( enum_kind ) { return resolve_enum_type(); } + if constexpr ( function_pointer_kind ) { return resolve_function_type(); } + if constexpr ( member_pointer_kind ) { return resolve_member_type(); } + if constexpr ( method_pointer_kind ) { return resolve_method_type(); } + if constexpr ( nullptr_kind ) { return resolve_nullptr_type(); } + if constexpr ( number_kind ) { return resolve_number_type(); } + if constexpr ( pointer_kind ) { return resolve_pointer_type(); } + if constexpr ( reference_kind ) { return resolve_reference_type(); } + if constexpr ( void_kind ) { return resolve_void_type(); } + // clang-format on } public: template < array_kind Array > [[nodiscard]] array_type resolve_array_type() { - return array_type{resolve_array_type_data>()}; + using array_t = std::remove_cv_t; + static array_type type{ensure_type(type_list{})}; + return type; } template < class_kind Class > [[nodiscard]] class_type resolve_class_type() { - return class_type{resolve_class_type_data>()}; + using class_t = std::remove_cv_t; + static class_type type{ensure_type(type_list{})}; + return type; } template < class_kind Class, typename... Args > [[nodiscard]] constructor_type resolve_constructor_type() { - return constructor_type{resolve_constructor_type_data, Args...>()}; + using class_t = std::remove_cv_t; + static constructor_type type{ensure_type(type_list{}, type_list{})}; + return type; } template < class_kind Class > [[nodiscard]] destructor_type resolve_destructor_type() { - return destructor_type{resolve_destructor_type_data>()}; + using class_t = std::remove_cv_t; + static destructor_type type{ensure_type(type_list{})}; + return type; } template < enum_kind Enum > [[nodiscard]] enum_type resolve_enum_type() { - return enum_type{resolve_enum_type_data>()}; + using enum_t = std::remove_cv_t; + static enum_type type{ensure_type(type_list{})}; + return type; } template < function_pointer_kind Function > [[nodiscard]] function_type resolve_function_type() { - return function_type{resolve_function_type_data>()}; + using function_t = std::remove_cv_t; + static function_type type{ensure_type(type_list{})}; + return type; } template < member_pointer_kind Member > [[nodiscard]] member_type resolve_member_type() { - return member_type{resolve_member_type_data>()}; + using member_t = std::remove_cv_t; + static member_type type{ensure_type(type_list{})}; + return type; } template < method_pointer_kind Method > [[nodiscard]] method_type resolve_method_type() { - return method_type{resolve_method_type_data>()}; + using method_t = std::remove_cv_t; + static method_type type{ensure_type(type_list{})}; + return type; } template < nullptr_kind Nullptr > [[nodiscard]] nullptr_type resolve_nullptr_type() { - return nullptr_type{resolve_nullptr_type_data>()}; + using nullptr_t = std::remove_cv_t; + static nullptr_type type{ensure_type(type_list{})}; + return type; } template < number_kind Number > [[nodiscard]] number_type resolve_number_type() { - return number_type{resolve_number_type_data>()}; + using number_t = std::remove_cv_t; + static number_type type{ensure_type(type_list{})}; + return type; } template < pointer_kind Pointer > [[nodiscard]] pointer_type resolve_pointer_type() { - return pointer_type{resolve_pointer_type_data>()}; + using pointer_t = std::remove_cv_t; + static pointer_type type{ensure_type(type_list{})}; + return type; } template < reference_kind Reference > [[nodiscard]] reference_type resolve_reference_type() { - return reference_type{resolve_reference_type_data>()}; + using reference_t = std::remove_cv_t; + static reference_type type{ensure_type(type_list{})}; + return type; } template < void_kind Void > [[nodiscard]] void_type resolve_void_type() { - return void_type{resolve_void_type_data>()}; - } - - private: - template < array_kind Array > - [[nodiscard]] array_type_data* resolve_array_type_data() { - static array_type_data data = (ensure_type(data), array_type_data{type_list{}}); - return &data; - } - - template < class_kind Class > - [[nodiscard]] class_type_data* resolve_class_type_data() { - static class_type_data data = (ensure_type(data), class_type_data{type_list{}}); - return &data; - } - - template < class_kind Class, typename... Args > - [[nodiscard]] constructor_type_data* resolve_constructor_type_data() { - static constructor_type_data data{type_list{}, type_list{}}; - return &data; - } - - template < class_kind Class > - [[nodiscard]] destructor_type_data* resolve_destructor_type_data() { - static destructor_type_data data{type_list{}}; - return &data; - } - - template < enum_kind Enum > - [[nodiscard]] enum_type_data* resolve_enum_type_data() { - static enum_type_data data = (ensure_type(data), enum_type_data{type_list{}}); - return &data; - } - - template < function_pointer_kind Function > - [[nodiscard]] function_type_data* resolve_function_type_data() { - static function_type_data data = (ensure_type(data), function_type_data{type_list{}}); - return &data; - } - - template < member_pointer_kind Member > - [[nodiscard]] member_type_data* resolve_member_type_data() { - static member_type_data data = (ensure_type(data), member_type_data{type_list{}}); - return &data; - } - - template < method_pointer_kind Method > - [[nodiscard]] method_type_data* resolve_method_type_data() { - static method_type_data data = (ensure_type(data), method_type_data{type_list{}}); - return &data; - } - - template < nullptr_kind Nullptr > - [[nodiscard]] nullptr_type_data* resolve_nullptr_type_data() { - static nullptr_type_data data = (ensure_type(data), nullptr_type_data{type_list{}}); - return &data; - } - - template < number_kind Number > - [[nodiscard]] number_type_data* resolve_number_type_data() { - static number_type_data data = (ensure_type(data), number_type_data{type_list{}}); - return &data; - } - - template < pointer_kind Pointer > - [[nodiscard]] pointer_type_data* resolve_pointer_type_data() { - static pointer_type_data data = (ensure_type(data), pointer_type_data{type_list{}}); - return &data; - } - - template < reference_kind Reference > - [[nodiscard]] reference_type_data* resolve_reference_type_data() { - static reference_type_data data = (ensure_type(data), reference_type_data{type_list{}}); - return &data; - } - - template < void_kind Void > - [[nodiscard]] void_type_data* resolve_void_type_data() { - static void_type_data data = (ensure_type(data), void_type_data{type_list{}}); - return &data; + using void_t = std::remove_cv_t; + static void_type type{ensure_type(type_list{})}; + return type; } private: type_registry() = default; - template < typename Type, typename TypeData > - void ensure_type(TypeData& type_data) { + template < typename TypeData, typename... Args > + TypeData* ensure_type(Args&&... args) { + static auto data{std::make_unique(std::forward(args)...)}; + const locker lock; - types_.emplace(any_type{&type_data}); + types_.emplace(any_type{data.get()}); + + return data.get(); } private: diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index ef89bdc..565a010 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -70,7 +70,7 @@ namespace meta_hpp template < typename From > requires std::is_class_v> - [[nodiscard]] class_type resolve_poly_type(From&& from) noexcept { + [[nodiscard]] class_type resolve_poly_type(From&& from) { using from_data_type = std::remove_reference_t; static_assert(