universal resolve_poly_type for all types

This commit is contained in:
BlackMATov
2023-03-11 05:30:41 +07:00
parent 02f344197d
commit 7954964ed3
3 changed files with 118 additions and 30 deletions

View File

@@ -4457,6 +4457,28 @@ namespace meta_hpp
}
}
namespace meta_hpp
{
template < typename T >
[[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_poly_info(registry).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
}
namespace meta_hpp
{
template < detail::class_kind Class, typename... Args >
@@ -4472,21 +4494,6 @@ namespace meta_hpp
type_registry& registry = type_registry::instance();
return registry.resolve_destructor_type<Class>();
}
template < typename From >
requires std::is_class_v<std::remove_reference_t<From>>
[[nodiscard]] class_type resolve_poly_type(From&& from) {
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;
type_registry& registry = type_registry::instance();
return from.get_most_derived_poly_info(registry).type;
}
}
namespace meta_hpp

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* 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 A {
virtual ~A() = default;
META_HPP_ENABLE_POLY_INFO()
};
struct B : A {
META_HPP_ENABLE_POLY_INFO()
};
}
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::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::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::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&&>()))>);
{
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>());
}
{
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>());
}
{
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_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>());
}
}

View File

@@ -52,6 +52,28 @@ namespace meta_hpp
}
}
namespace meta_hpp
{
template < typename T >
[[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_poly_info(registry).type;
} else {
(void)from;
return registry.resolve_type<raw_type>();
}
}
}
namespace meta_hpp
{
template < detail::class_kind Class, typename... Args >
@@ -67,21 +89,6 @@ namespace meta_hpp
type_registry& registry = type_registry::instance();
return registry.resolve_destructor_type<Class>();
}
template < typename From >
requires std::is_class_v<std::remove_reference_t<From>>
[[nodiscard]] class_type resolve_poly_type(From&& from) {
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;
type_registry& registry = type_registry::instance();
return from.get_most_derived_poly_info(registry).type;
}
}
namespace meta_hpp