mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 11:17:06 +07:00
universal resolve_poly_type for all types
This commit is contained in:
@@ -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
|
||||
|
||||
74
develop/untests/meta_types/poly_resolving_tests.cpp
Normal file
74
develop/untests/meta_types/poly_resolving_tests.cpp
Normal 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>());
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user