remove rtti types from type registry

This commit is contained in:
BlackMATov
2023-03-10 20:06:50 +07:00
parent 29a823aa2f
commit 6be7c9239c
8 changed files with 211 additions and 238 deletions

View File

@@ -30,8 +30,6 @@
#include <string_view> #include <string_view>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <version> #include <version>
@@ -4152,76 +4150,6 @@ namespace meta_hpp::detail
}; };
} }
namespace meta_hpp::detail
{
class state_registry final {
public:
class locker final {
public:
explicit locker()
: lock_{instance().mutex_} {}
~locker() = default;
locker(locker&&) = default;
locker& operator=(locker&&) = default;
locker(const locker&) = delete;
locker& operator=(const locker&) = delete;
private:
std::unique_lock<std::recursive_mutex> lock_;
};
[[nodiscard]] static state_registry& instance() {
static state_registry instance;
return instance;
}
public:
template < typename F >
void for_each_scope(F&& f) const {
const locker lock;
for ( auto&& [name, scope] : scopes_ ) {
std::invoke(f, scope);
}
}
[[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept {
const locker lock;
if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) {
return iter->second;
}
return scope{};
}
[[nodiscard]] scope resolve_scope(std::string_view name) {
const locker lock;
if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) {
return iter->second;
}
auto&& [iter, _] = scopes_.emplace( //
std::string{name},
scope_state::make(std::string{name}, metadata_map{})
);
return iter->second;
}
private:
state_registry() = default;
private:
std::recursive_mutex mutex_;
std::map<std::string, scope, std::less<>> scopes_;
};
}
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
class type_registry final { class type_registry final {
@@ -4268,18 +4196,6 @@ namespace meta_hpp::detail
return any_type{}; return any_type{};
} }
#if !defined(META_HPP_NO_RTTI)
[[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept {
const locker lock;
if ( auto iter{rtti_types_.find(index)}; iter != rtti_types_.end() ) {
return iter->second;
}
return any_type{};
}
#endif
public: public:
template < array_kind Array > template < array_kind Array >
[[nodiscard]] array_type resolve_type() { [[nodiscard]] array_type resolve_type() {
@@ -4487,29 +4403,106 @@ namespace meta_hpp::detail
template < typename Type, typename TypeData > template < typename Type, typename TypeData >
void ensure_type(TypeData& type_data) { void ensure_type(TypeData& type_data) {
const locker lock; const locker lock;
types_.emplace(any_type{&type_data});
auto&& [position, emplaced] = types_.emplace(any_type{&type_data});
if ( !emplaced ) {
return;
}
#if !defined(META_HPP_NO_RTTI)
META_HPP_TRY {
rtti_types_.emplace(typeid(Type), any_type{&type_data});
}
META_HPP_CATCH(...) {
types_.erase(position);
META_HPP_RETHROW();
}
#endif
} }
private: private:
std::recursive_mutex mutex_; std::recursive_mutex mutex_;
std::set<any_type, std::less<>> types_; std::set<any_type, std::less<>> types_;
#if !defined(META_HPP_NO_RTTI) };
std::map<std::type_index, any_type, std::less<>> rtti_types_; }
#endif
namespace meta_hpp::detail
{
struct poly_info final {
const void* ptr{};
class_type type{};
};
template < typename T >
concept check_poly_info_enabled //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_poly_info(r) } -> std::convertible_to<poly_info>;
};
}
#define META_HPP_ENABLE_POLY_INFO() \
public: \
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
using self_type = std::remove_cvref_t<decltype(*this)>; \
return ::meta_hpp::detail::poly_info{.ptr = this, .type = registry.resolve_class_type<self_type>()}; \
} \
META_HPP_IGNORE_OVERRIDE_WARNINGS_POP() \
private:
namespace meta_hpp::detail
{
class state_registry final {
public:
class locker final {
public:
explicit locker()
: lock_{instance().mutex_} {}
~locker() = default;
locker(locker&&) = default;
locker& operator=(locker&&) = default;
locker(const locker&) = delete;
locker& operator=(const locker&) = delete;
private:
std::unique_lock<std::recursive_mutex> lock_;
};
[[nodiscard]] static state_registry& instance() {
static state_registry instance;
return instance;
}
public:
template < typename F >
void for_each_scope(F&& f) const {
const locker lock;
for ( auto&& [name, scope] : scopes_ ) {
std::invoke(f, scope);
}
}
[[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept {
const locker lock;
if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) {
return iter->second;
}
return scope{};
}
[[nodiscard]] scope resolve_scope(std::string_view name) {
const locker lock;
if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) {
return iter->second;
}
auto&& [iter, _] = scopes_.emplace( //
std::string{name},
scope_state::make(std::string{name}, metadata_map{})
);
return iter->second;
}
private:
state_registry() = default;
private:
std::recursive_mutex mutex_;
std::map<std::string, scope, std::less<>> scopes_;
}; };
} }
@@ -4567,16 +4560,19 @@ namespace meta_hpp
return registry.resolve_destructor_type<Class>(); return registry.resolve_destructor_type<Class>();
} }
template < typename T > template < typename From >
[[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept { requires std::is_class_v<std::remove_reference_t<From>>
#if !defined(META_HPP_NO_RTTI) [[nodiscard]] class_type resolve_poly_type(From&& from) noexcept {
using from_data_type = std::remove_reference_t<From>;
static_assert(
detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
using namespace detail; using namespace detail;
type_registry& registry = type_registry::instance(); type_registry& registry = type_registry::instance();
return registry.get_type_by_rtti(typeid(v)); return from.get_most_derived_poly_info(registry).type;
#else
(void)v;
return any_type{};
#endif
} }
} }
@@ -9133,20 +9129,6 @@ namespace meta_hpp
To ucast(From&& from); To ucast(From&& from);
} }
namespace meta_hpp::detail
{
struct polymorphic_meta_info {
const void* ptr{};
class_type type{};
};
template < typename T >
concept check_polymorphic_cast_support //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_polymorphic_meta_info(r) } -> std::convertible_to<polymorphic_meta_info>;
};
}
namespace meta_hpp namespace meta_hpp
{ {
template < typename To, typename From > template < typename To, typename From >
@@ -9156,8 +9138,8 @@ namespace meta_hpp
using to_data_type = std::remove_pointer_t<To>; using to_data_type = std::remove_pointer_t<To>;
static_assert( static_assert(
detail::check_polymorphic_cast_support<from_data_type>, detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLYMORPHIC_CAST macro to fix it." "The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
); );
if ( from == nullptr ) { if ( from == nullptr ) {
@@ -9168,12 +9150,12 @@ namespace meta_hpp
return from; return from;
} else { } else {
detail::type_registry& registry{detail::type_registry::instance()}; detail::type_registry& registry{detail::type_registry::instance()};
const detail::polymorphic_meta_info& meta_info{from->get_most_derived_polymorphic_meta_info(registry)}; const detail::poly_info& meta_info{from->get_most_derived_poly_info(registry)};
// NOLINTNEXTLINE(*-const-cast) // NOLINTNEXTLINE(*-const-cast)
void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr); void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr);
if constexpr ( std::is_void_v<std::remove_cv_t<to_data_type>> ) { if constexpr ( std::is_void_v<to_data_type> ) {
return most_derived_object_ptr; return most_derived_object_ptr;
} else { } else {
const class_type& to_class_type = registry.resolve_class_type<to_data_type>(); const class_type& to_class_type = registry.resolve_class_type<to_data_type>();
@@ -9189,8 +9171,8 @@ namespace meta_hpp
using to_data_type = std::remove_reference_t<To>; using to_data_type = std::remove_reference_t<To>;
static_assert( static_assert(
detail::check_polymorphic_cast_support<from_data_type>, detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLYMORPHIC_CAST macro to fix it." "The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
); );
if ( to_data_type* ptr = ucast<to_data_type*>(std::addressof(from)) ) { if ( to_data_type* ptr = ucast<to_data_type*>(std::addressof(from)) ) {
@@ -9201,18 +9183,6 @@ namespace meta_hpp
} }
} }
#define META_HPP_ENABLE_POLYMORPHIC_CAST() \
public: \
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::polymorphic_meta_info get_most_derived_polymorphic_meta_info( \
::meta_hpp::detail::type_registry& registry \
) const { \
using self_type = std::remove_cvref_t<decltype(*this)>; \
return ::meta_hpp::detail::polymorphic_meta_info{.ptr = this, .type = registry.resolve_class_type<self_type>()}; \
} \
META_HPP_IGNORE_OVERRIDE_WARNINGS_POP() \
private:
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
template < typename T > template < typename T >

View File

@@ -19,11 +19,12 @@ namespace
A& operator=(const A&) = delete; A& operator=(const A&) = delete;
virtual ~A() = default; virtual ~A() = default;
META_HPP_ENABLE_POLY_INFO()
}; };
struct B : virtual A {}; struct B : virtual A { META_HPP_ENABLE_POLY_INFO() };
struct C : virtual A {}; struct C : virtual A { META_HPP_ENABLE_POLY_INFO() };
struct D : B, C {}; struct D : B, C { META_HPP_ENABLE_POLY_INFO() };
struct E {}; struct E {};
} }
@@ -322,24 +323,42 @@ TEST_CASE("meta/meta_features/diamond") {
} }
} }
SUBCASE("resolve_polymorphic_type") { SUBCASE("resolve_poly_type") {
const D d; D d;
const A& ad = d; A& ad = d;
const B& bd = d; B& bd = d;
const C& cd = d; C& cd = d;
const D& dd = d; D& dd = d;
CHECK(meta::resolve_type(ad) == meta::resolve_type<A>()); CHECK(meta::resolve_type(ad) == meta::resolve_type<A>());
CHECK(meta::resolve_type(bd) == meta::resolve_type<B>()); CHECK(meta::resolve_type(bd) == meta::resolve_type<B>());
CHECK(meta::resolve_type(cd) == meta::resolve_type<C>()); CHECK(meta::resolve_type(cd) == meta::resolve_type<C>());
CHECK(meta::resolve_type(dd) == meta::resolve_type<D>()); CHECK(meta::resolve_type(dd) == meta::resolve_type<D>());
#if !defined(META_HPP_NO_RTTI) CHECK(meta::resolve_type(std::as_const(ad)) == meta::resolve_type<A>());
CHECK(meta::resolve_polymorphic_type(ad) == meta::resolve_type<D>()); CHECK(meta::resolve_type(std::as_const(bd)) == meta::resolve_type<B>());
CHECK(meta::resolve_polymorphic_type(bd) == meta::resolve_type<D>()); CHECK(meta::resolve_type(std::as_const(cd)) == meta::resolve_type<C>());
CHECK(meta::resolve_polymorphic_type(cd) == meta::resolve_type<D>()); CHECK(meta::resolve_type(std::as_const(dd)) == meta::resolve_type<D>());
CHECK(meta::resolve_polymorphic_type(dd) == meta::resolve_type<D>());
#endif CHECK(meta::resolve_poly_type(A{}) == meta::resolve_type<A>());
CHECK(meta::resolve_poly_type(B{}) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(C{}) == meta::resolve_type<C>());
CHECK(meta::resolve_poly_type(D{}) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(ad) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(bd) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(cd) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(dd) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::move(ad)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::move(bd)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::move(cd)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::move(dd)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::as_const(ad)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::as_const(bd)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::as_const(cd)) == meta::resolve_type<D>());
CHECK(meta::resolve_poly_type(std::as_const(dd)) == meta::resolve_type<D>());
} }
} }

View File

@@ -14,21 +14,21 @@ namespace
A1(const A1&) = default; A1(const A1&) = default;
virtual ~A1() = default; virtual ~A1() = default;
char a{'a'}; char a{'a'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct B1 : A1 { struct B1 : A1 {
B1() = default; B1() = default;
B1(const B1&) = default; B1(const B1&) = default;
char b{'b'}; char b{'b'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct C1 : B1 { struct C1 : B1 {
C1() = default; C1() = default;
C1(const C1&) = default; C1(const C1&) = default;
char c{'c'}; char c{'c'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
// A1 <- B1 <- C1 // A1 <- B1 <- C1
@@ -38,21 +38,21 @@ namespace
A2(const A2&) = default; A2(const A2&) = default;
virtual ~A2() = default; virtual ~A2() = default;
char a{'a'}; char a{'a'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct B2 : virtual A2 { struct B2 : virtual A2 {
B2() = default; B2() = default;
B2(const B2&) = default; B2(const B2&) = default;
char b{'b'}; char b{'b'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct C2 : virtual A2 { struct C2 : virtual A2 {
C2() = default; C2() = default;
C2(const C2&) = default; C2(const C2&) = default;
char c{'c'}; char c{'c'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
@@ -61,21 +61,21 @@ namespace
D2(const D2&) = default; D2(const D2&) = default;
virtual ~D2() = default; virtual ~D2() = default;
char d{'d'}; char d{'d'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct E2 : D2 { struct E2 : D2 {
E2() = default; E2() = default;
E2(const E2&) = default; E2(const E2&) = default;
char e{'e'}; char e{'e'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };
struct F2 : B2, C2, E2 { struct F2 : B2, C2, E2 {
F2() = default; F2() = default;
F2(const F2&) = default; F2(const F2&) = default;
char f{'f'}; char f{'f'};
META_HPP_ENABLE_POLYMORPHIC_CAST() META_HPP_ENABLE_POLY_INFO()
}; };

View File

@@ -31,8 +31,6 @@
#include <string_view> #include <string_view>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <version> #include <version>

View File

@@ -0,0 +1,36 @@
/*******************************************************************************
* 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)
******************************************************************************/
#pragma once
#include "../meta_base.hpp"
#include "../meta_types.hpp"
#include "type_registry.hpp"
namespace meta_hpp::detail
{
struct poly_info final {
const void* ptr{};
class_type type{};
};
template < typename T >
concept check_poly_info_enabled //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_poly_info(r) } -> std::convertible_to<poly_info>;
};
}
#define META_HPP_ENABLE_POLY_INFO() \
public: \
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
using self_type = std::remove_cvref_t<decltype(*this)>; \
return ::meta_hpp::detail::poly_info{.ptr = this, .type = registry.resolve_class_type<self_type>()}; \
} \
META_HPP_IGNORE_OVERRIDE_WARNINGS_POP() \
private:

View File

@@ -55,18 +55,6 @@ namespace meta_hpp::detail
return any_type{}; return any_type{};
} }
#if !defined(META_HPP_NO_RTTI)
[[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept {
const locker lock;
if ( auto iter{rtti_types_.find(index)}; iter != rtti_types_.end() ) {
return iter->second;
}
return any_type{};
}
#endif
public: public:
template < array_kind Array > template < array_kind Array >
[[nodiscard]] array_type resolve_type() { [[nodiscard]] array_type resolve_type() {
@@ -274,28 +262,11 @@ namespace meta_hpp::detail
template < typename Type, typename TypeData > template < typename Type, typename TypeData >
void ensure_type(TypeData& type_data) { void ensure_type(TypeData& type_data) {
const locker lock; const locker lock;
types_.emplace(any_type{&type_data});
auto&& [position, emplaced] = types_.emplace(any_type{&type_data});
if ( !emplaced ) {
return;
}
#if !defined(META_HPP_NO_RTTI)
META_HPP_TRY {
rtti_types_.emplace(typeid(Type), any_type{&type_data});
}
META_HPP_CATCH(...) {
types_.erase(position);
META_HPP_RETHROW();
}
#endif
} }
private: private:
std::recursive_mutex mutex_; std::recursive_mutex mutex_;
std::set<any_type, std::less<>> types_; std::set<any_type, std::less<>> types_;
#if !defined(META_HPP_NO_RTTI)
std::map<std::type_index, any_type, std::less<>> rtti_types_;
#endif
}; };
} }

View File

@@ -10,6 +10,7 @@
#include "meta_states.hpp" #include "meta_states.hpp"
#include "meta_types.hpp" #include "meta_types.hpp"
#include "meta_detail/poly_info.hpp"
#include "meta_detail/state_registry.hpp" #include "meta_detail/state_registry.hpp"
#include "meta_detail/type_registry.hpp" #include "meta_detail/type_registry.hpp"
@@ -67,16 +68,19 @@ namespace meta_hpp
return registry.resolve_destructor_type<Class>(); return registry.resolve_destructor_type<Class>();
} }
template < typename T > template < typename From >
[[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept { requires std::is_class_v<std::remove_reference_t<From>>
#if !defined(META_HPP_NO_RTTI) [[nodiscard]] class_type resolve_poly_type(From&& from) noexcept {
using from_data_type = std::remove_reference_t<From>;
static_assert(
detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
using namespace detail; using namespace detail;
type_registry& registry = type_registry::instance(); type_registry& registry = type_registry::instance();
return registry.get_type_by_rtti(typeid(v)); return from.get_most_derived_poly_info(registry).type;
#else
(void)v;
return any_type{};
#endif
} }
} }

View File

@@ -9,23 +9,10 @@
#include "../meta_base.hpp" #include "../meta_base.hpp"
#include "../meta_ucast.hpp" #include "../meta_ucast.hpp"
#include "../meta_detail/poly_info.hpp"
#include "../meta_detail/type_registry.hpp" #include "../meta_detail/type_registry.hpp"
#include "../meta_detail/value_utilities/utraits.hpp" #include "../meta_detail/value_utilities/utraits.hpp"
namespace meta_hpp::detail
{
struct polymorphic_meta_info {
const void* ptr{};
class_type type{};
};
template < typename T >
concept check_polymorphic_cast_support //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_polymorphic_meta_info(r) } -> std::convertible_to<polymorphic_meta_info>;
};
}
namespace meta_hpp namespace meta_hpp
{ {
template < typename To, typename From > template < typename To, typename From >
@@ -35,8 +22,8 @@ namespace meta_hpp
using to_data_type = std::remove_pointer_t<To>; using to_data_type = std::remove_pointer_t<To>;
static_assert( static_assert(
detail::check_polymorphic_cast_support<from_data_type>, detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLYMORPHIC_CAST macro to fix it." "The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
); );
if ( from == nullptr ) { if ( from == nullptr ) {
@@ -47,12 +34,12 @@ namespace meta_hpp
return from; return from;
} else { } else {
detail::type_registry& registry{detail::type_registry::instance()}; detail::type_registry& registry{detail::type_registry::instance()};
const detail::polymorphic_meta_info& meta_info{from->get_most_derived_polymorphic_meta_info(registry)}; const detail::poly_info& meta_info{from->get_most_derived_poly_info(registry)};
// NOLINTNEXTLINE(*-const-cast) // NOLINTNEXTLINE(*-const-cast)
void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr); void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr);
if constexpr ( std::is_void_v<std::remove_cv_t<to_data_type>> ) { if constexpr ( std::is_void_v<to_data_type> ) {
return most_derived_object_ptr; return most_derived_object_ptr;
} else { } else {
const class_type& to_class_type = registry.resolve_class_type<to_data_type>(); const class_type& to_class_type = registry.resolve_class_type<to_data_type>();
@@ -68,8 +55,8 @@ namespace meta_hpp
using to_data_type = std::remove_reference_t<To>; using to_data_type = std::remove_reference_t<To>;
static_assert( static_assert(
detail::check_polymorphic_cast_support<from_data_type>, detail::check_poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. Use the META_HPP_ENABLE_POLYMORPHIC_CAST macro to fix it." "The type doesn't support ucasts. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
); );
if ( to_data_type* ptr = ucast<to_data_type*>(std::addressof(from)) ) { if ( to_data_type* ptr = ucast<to_data_type*>(std::addressof(from)) ) {
@@ -79,15 +66,3 @@ namespace meta_hpp
throw_exception(error_code::bad_cast); throw_exception(error_code::bad_cast);
} }
} }
#define META_HPP_ENABLE_POLYMORPHIC_CAST() \
public: \
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::polymorphic_meta_info get_most_derived_polymorphic_meta_info( \
::meta_hpp::detail::type_registry& registry \
) const { \
using self_type = std::remove_cvref_t<decltype(*this)>; \
return ::meta_hpp::detail::polymorphic_meta_info{.ptr = this, .type = registry.resolve_class_type<self_type>()}; \
} \
META_HPP_IGNORE_OVERRIDE_WARNINGS_POP() \
private: