remove resolve_poly_type, use resolve_type(T&&) instead

This commit is contained in:
BlackMATov
2023-12-29 02:24:11 +07:00
parent 427459dcc6
commit b65e71a6f1
9 changed files with 164 additions and 129 deletions

View File

@@ -6,7 +6,6 @@
- non-linear search of methods/functions/...
- fix all includes to work with the library more flexible
- test and support shared libraries
- remove `resolve_poly_type`, use `resolve_type(T&&)` instead
- add ucast manual
## Version 1.0

View File

@@ -4245,11 +4245,19 @@ namespace meta_hpp::detail
concept check_base_info_enabled //
= requires { typename T::meta_base_info; };
template < check_base_info_enabled T >
using get_meta_base_info = typename T::meta_base_info;
template < typename T >
concept check_poly_info_enabled //
concept poly_info_enabled //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_meta_poly_info(r) } -> std::convertible_to<poly_info>;
{ v.meta_poly_info(r) } -> std::convertible_to<poly_info>;
};
template < poly_info_enabled T >
poly_info get_meta_poly_info(type_registry& r, const T& v) {
return v.meta_poly_info(r);
}
}
#define META_HPP_ENABLE_BASE_INFO(...) \
@@ -4262,7 +4270,7 @@ private:
META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \
public: \
META_HPP_DETAIL_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::poly_info get_most_derived_meta_poly_info(::meta_hpp::detail::type_registry& registry) const { \
virtual ::meta_hpp::detail::poly_info meta_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>()}; \
} \
@@ -4363,10 +4371,23 @@ namespace meta_hpp
template < typename T >
// NOLINTNEXTLINE(*-missing-std-forward)
[[nodiscard]] auto resolve_type(T&&) {
[[nodiscard]] auto resolve_type(T&& from) {
using namespace detail;
using raw_type = std::remove_cvref_t<T>;
type_registry& registry = type_registry::instance();
return registry.resolve_type<std::remove_cvref_t<T>>();
if constexpr ( std::is_class_v<raw_type> && std::is_polymorphic_v<raw_type> ) {
static_assert(
detail::poly_info_enabled<T>,
"The class doesn't support polymorphic type resolving. "
"Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
return detail::get_meta_poly_info(registry, from).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
template < typename... Ts >
@@ -4384,29 +4405,6 @@ namespace meta_hpp
}
}
namespace meta_hpp
{
template < typename T >
// NOLINTNEXTLINE(*-missing-std-forward)
[[nodiscard]] auto resolve_poly_type(T&& from) {
using namespace detail;
using raw_type = std::remove_cvref_t<T>;
type_registry& registry = type_registry::instance();
if constexpr ( std::is_class_v<raw_type> ) {
static_assert(
detail::check_poly_info_enabled<raw_type>,
"The class doesn't support polymorphic type resolving. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
return from.get_most_derived_meta_poly_info(registry).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
}
namespace meta_hpp
{
template < detail::class_kind Class, typename... Args >
@@ -8309,7 +8307,7 @@ namespace meta_hpp::detail::class_type_data_impl
});
if constexpr ( check_base_info_enabled<Target> ) {
using target_base_info = typename Target::meta_base_info;
using target_base_info = get_meta_base_info<Target>;
target_base_info::for_each([&info]<class_kind TargetBase>() { //
add_upcast_info<Class, TargetBase>(info);
});
@@ -8319,7 +8317,7 @@ namespace meta_hpp::detail::class_type_data_impl
template < class_kind Class >
void fill_upcast_info(new_base_info_t& info) {
if constexpr ( check_base_info_enabled<Class> ) {
using class_base_info = typename Class::meta_base_info;
using class_base_info = get_meta_base_info<Class>;
class_base_info::for_each([&info]<class_kind ClassBase>() {
info.base_classes.push_back(resolve_type<ClassBase>());
add_upcast_info<Class, ClassBase>(info);
@@ -9175,8 +9173,9 @@ namespace meta_hpp
using to_data_type = std::remove_pointer_t<To>;
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."
detail::poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. "
"Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
if ( from == nullptr ) {
@@ -9187,7 +9186,7 @@ namespace meta_hpp
return from;
} else {
detail::type_registry& registry{detail::type_registry::instance()};
const detail::poly_info& meta_info{from->get_most_derived_meta_poly_info(registry)};
const detail::poly_info& meta_info{detail::get_meta_poly_info(registry, *from)};
// NOLINTNEXTLINE(*-const-cast)
void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr);
@@ -9209,8 +9208,9 @@ namespace meta_hpp
using to_data_type = std::remove_reference_t<To>;
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."
detail::poly_info_enabled<from_data_type>,
"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)) ) {

View File

@@ -317,7 +317,7 @@ TEST_CASE("meta/meta_features/diamond") {
}
}
SUBCASE("resolve_poly_type") {
SUBCASE("resolve_type") {
D d;
A& ad = d;
@@ -325,34 +325,24 @@ TEST_CASE("meta/meta_features/diamond") {
C& cd = d;
D& dd = d;
CHECK(meta::resolve_type(ad) == meta::resolve_type<A>());
CHECK(meta::resolve_type(bd) == meta::resolve_type<B>());
CHECK(meta::resolve_type(cd) == meta::resolve_type<C>());
CHECK(meta::resolve_type(A{}) == meta::resolve_type<A>());
CHECK(meta::resolve_type(B{}) == meta::resolve_type<B>());
CHECK(meta::resolve_type(C{}) == meta::resolve_type<C>());
CHECK(meta::resolve_type(D{}) == meta::resolve_type<D>());
CHECK(meta::resolve_type(ad) == meta::resolve_type<D>());
CHECK(meta::resolve_type(bd) == meta::resolve_type<D>());
CHECK(meta::resolve_type(cd) == meta::resolve_type<D>());
CHECK(meta::resolve_type(dd) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::as_const(ad)) == meta::resolve_type<A>());
CHECK(meta::resolve_type(std::as_const(bd)) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::as_const(cd)) == meta::resolve_type<C>());
CHECK(meta::resolve_type(std::move(ad)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::move(bd)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::move(cd)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::move(dd)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::as_const(ad)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::as_const(bd)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::as_const(cd)) == meta::resolve_type<D>());
CHECK(meta::resolve_type(std::as_const(dd)) == meta::resolve_type<D>());
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

@@ -0,0 +1,46 @@
/*******************************************************************************
* 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 <meta.hpp/meta_all.hpp>
#include <doctest/doctest.h>
namespace
{
struct base {};
struct derived : base {};
struct poly_base {
virtual ~poly_base() = default;
META_HPP_ENABLE_POLY_INFO()
};
struct poly_derived : poly_base {
META_HPP_ENABLE_POLY_INFO(poly_base)
};
}
TEST_CASE("meta/meta_types/poly_resolving2") {
namespace meta = meta_hpp;
SUBCASE("simple-type") {
int v{};
CHECK(meta::resolve_type(v) == meta::resolve_type<int>());
}
SUBCASE("not-polymorphic-class") {
derived d;
base& b = d;
CHECK(meta::resolve_type(b) == meta::resolve_type<base>());
CHECK(meta::resolve_type(d) == meta::resolve_type<derived>());
}
SUBCASE("polymorphic-class") {
poly_derived d;
poly_base& b = d;
CHECK(meta::resolve_type(b) == meta::resolve_type<poly_derived>());
CHECK(meta::resolve_type(d) == meta::resolve_type<poly_derived>());
}
}

View File

@@ -14,61 +14,61 @@ namespace {
};
struct B : A {
META_HPP_ENABLE_POLY_INFO()
META_HPP_ENABLE_POLY_INFO(A)
};
}
TEST_CASE("meta/meta_types/poly_resolving") {
namespace meta = meta_hpp;
static_assert(std::is_same_v<meta::array_type, decltype(meta::resolve_poly_type(std::declval<int[]>()))>);
static_assert(std::is_same_v<meta::array_type, decltype(meta::resolve_poly_type(std::declval<const int[]>()))>);
static_assert(std::is_same_v<meta::array_type, decltype(meta::resolve_type(std::declval<int[]>()))>);
static_assert(std::is_same_v<meta::array_type, decltype(meta::resolve_type(std::declval<const int[]>()))>);
static_assert(std::is_same_v<meta::pointer_type, decltype(meta::resolve_poly_type(std::declval<int*>()))>);
static_assert(std::is_same_v<meta::pointer_type, decltype(meta::resolve_poly_type(std::declval<const int*>()))>);
static_assert(std::is_same_v<meta::pointer_type, decltype(meta::resolve_type(std::declval<int*>()))>);
static_assert(std::is_same_v<meta::pointer_type, decltype(meta::resolve_type(std::declval<const int*>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_poly_type(std::declval<int>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_poly_type(std::declval<int&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_poly_type(std::declval<int&&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_poly_type(std::declval<const int&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_poly_type(std::declval<const int&&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_type(std::declval<int>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_type(std::declval<int&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_type(std::declval<int&&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_type(std::declval<const int&>()))>);
static_assert(std::is_same_v<meta::number_type, decltype(meta::resolve_type(std::declval<const int&&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_poly_type(std::declval<A>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_poly_type(std::declval<A&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_poly_type(std::declval<A&&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_poly_type(std::declval<const A&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_poly_type(std::declval<const A&&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_type(std::declval<A>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_type(std::declval<A&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_type(std::declval<A&&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_type(std::declval<const A&>()))>);
static_assert(std::is_same_v<meta::class_type, decltype(meta::resolve_type(std::declval<const A&&>()))>);
{
int i{42};
CHECK(meta::resolve_poly_type(i) == meta::resolve_type<int>());
CHECK(meta::resolve_poly_type(std::move(i)) == meta::resolve_type<int>());
CHECK(meta::resolve_poly_type(std::as_const(i)) == meta::resolve_type<int>());
CHECK(meta::resolve_poly_type(std::move(std::as_const(i))) == meta::resolve_type<int>());
CHECK(meta::resolve_type(i) == meta::resolve_type<int>());
CHECK(meta::resolve_type(std::move(i)) == meta::resolve_type<int>());
CHECK(meta::resolve_type(std::as_const(i)) == meta::resolve_type<int>());
CHECK(meta::resolve_type(std::move(std::as_const(i))) == meta::resolve_type<int>());
}
{
A a{};
CHECK(meta::resolve_poly_type(a) == meta::resolve_type<A>());
CHECK(meta::resolve_poly_type(std::move(a)) == meta::resolve_type<A>());
CHECK(meta::resolve_poly_type(std::as_const(a)) == meta::resolve_type<A>());
CHECK(meta::resolve_poly_type(std::move(std::as_const(a))) == meta::resolve_type<A>());
CHECK(meta::resolve_type(a) == meta::resolve_type<A>());
CHECK(meta::resolve_type(std::move(a)) == meta::resolve_type<A>());
CHECK(meta::resolve_type(std::as_const(a)) == meta::resolve_type<A>());
CHECK(meta::resolve_type(std::move(std::as_const(a))) == meta::resolve_type<A>());
}
{
B b{};
A& a{b};
CHECK(meta::resolve_poly_type(a) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::move(a)) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::as_const(a)) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::move(std::as_const(a))) == meta::resolve_type<B>());
CHECK(meta::resolve_type(a) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::move(a)) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::as_const(a)) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::move(std::as_const(a))) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(b) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::move(b)) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::as_const(b)) == meta::resolve_type<B>());
CHECK(meta::resolve_poly_type(std::move(std::as_const(b))) == meta::resolve_type<B>());
CHECK(meta::resolve_type(b) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::move(b)) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::as_const(b)) == meta::resolve_type<B>());
CHECK(meta::resolve_type(std::move(std::as_const(b))) == meta::resolve_type<B>());
}
}

View File

@@ -22,11 +22,19 @@ namespace meta_hpp::detail
concept check_base_info_enabled //
= requires { typename T::meta_base_info; };
template < check_base_info_enabled T >
using get_meta_base_info = typename T::meta_base_info;
template < typename T >
concept check_poly_info_enabled //
concept poly_info_enabled //
= requires(type_registry& r, const T& v) {
{ v.get_most_derived_meta_poly_info(r) } -> std::convertible_to<poly_info>;
{ v.meta_poly_info(r) } -> std::convertible_to<poly_info>;
};
template < poly_info_enabled T >
poly_info get_meta_poly_info(type_registry& r, const T& v) {
return v.meta_poly_info(r);
}
}
#define META_HPP_ENABLE_BASE_INFO(...) \
@@ -39,7 +47,7 @@ private:
META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \
public: \
META_HPP_DETAIL_IGNORE_OVERRIDE_WARNINGS_PUSH() \
virtual ::meta_hpp::detail::poly_info get_most_derived_meta_poly_info(::meta_hpp::detail::type_registry& registry) const { \
virtual ::meta_hpp::detail::poly_info meta_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>()}; \
} \

View File

@@ -37,10 +37,23 @@ namespace meta_hpp
template < typename T >
// NOLINTNEXTLINE(*-missing-std-forward)
[[nodiscard]] auto resolve_type(T&&) {
[[nodiscard]] auto resolve_type(T&& from) {
using namespace detail;
using raw_type = std::remove_cvref_t<T>;
type_registry& registry = type_registry::instance();
return registry.resolve_type<std::remove_cvref_t<T>>();
if constexpr ( std::is_class_v<raw_type> && std::is_polymorphic_v<raw_type> ) {
static_assert(
detail::poly_info_enabled<T>,
"The class doesn't support polymorphic type resolving. "
"Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
return detail::get_meta_poly_info(registry, from).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
template < typename... Ts >
@@ -58,29 +71,6 @@ namespace meta_hpp
}
}
namespace meta_hpp
{
template < typename T >
// NOLINTNEXTLINE(*-missing-std-forward)
[[nodiscard]] auto resolve_poly_type(T&& from) {
using namespace detail;
using raw_type = std::remove_cvref_t<T>;
type_registry& registry = type_registry::instance();
if constexpr ( std::is_class_v<raw_type> ) {
static_assert(
detail::check_poly_info_enabled<raw_type>,
"The class doesn't support polymorphic type resolving. Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
return from.get_most_derived_meta_poly_info(registry).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
}
namespace meta_hpp
{
template < detail::class_kind Class, typename... Args >

View File

@@ -43,7 +43,7 @@ namespace meta_hpp::detail::class_type_data_impl
});
if constexpr ( check_base_info_enabled<Target> ) {
using target_base_info = typename Target::meta_base_info;
using target_base_info = get_meta_base_info<Target>;
target_base_info::for_each([&info]<class_kind TargetBase>() { //
add_upcast_info<Class, TargetBase>(info);
});
@@ -53,7 +53,7 @@ namespace meta_hpp::detail::class_type_data_impl
template < class_kind Class >
void fill_upcast_info(new_base_info_t& info) {
if constexpr ( check_base_info_enabled<Class> ) {
using class_base_info = typename Class::meta_base_info;
using class_base_info = get_meta_base_info<Class>;
class_base_info::for_each([&info]<class_kind ClassBase>() {
info.base_classes.push_back(resolve_type<ClassBase>());
add_upcast_info<Class, ClassBase>(info);

View File

@@ -22,8 +22,9 @@ namespace meta_hpp
using to_data_type = std::remove_pointer_t<To>;
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."
detail::poly_info_enabled<from_data_type>,
"The type doesn't support ucasts. "
"Use the META_HPP_ENABLE_POLY_INFO macro to fix it."
);
if ( from == nullptr ) {
@@ -34,7 +35,7 @@ namespace meta_hpp
return from;
} else {
detail::type_registry& registry{detail::type_registry::instance()};
const detail::poly_info& meta_info{from->get_most_derived_meta_poly_info(registry)};
const detail::poly_info& meta_info{detail::get_meta_poly_info(registry, *from)};
// NOLINTNEXTLINE(*-const-cast)
void* most_derived_object_ptr = const_cast<void*>(meta_info.ptr);
@@ -56,8 +57,9 @@ namespace meta_hpp
using to_data_type = std::remove_reference_t<To>;
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."
detail::poly_info_enabled<from_data_type>,
"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)) ) {