mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +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
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class, typename... Args >
|
template < detail::class_kind Class, typename... Args >
|
||||||
@@ -4472,21 +4494,6 @@ namespace meta_hpp
|
|||||||
type_registry& registry = type_registry::instance();
|
type_registry& registry = type_registry::instance();
|
||||||
return registry.resolve_destructor_type<Class>();
|
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
|
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
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class, typename... Args >
|
template < detail::class_kind Class, typename... Args >
|
||||||
@@ -67,21 +89,6 @@ namespace meta_hpp
|
|||||||
type_registry& registry = type_registry::instance();
|
type_registry& registry = type_registry::instance();
|
||||||
return registry.resolve_destructor_type<Class>();
|
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
|
namespace meta_hpp
|
||||||
|
|||||||
Reference in New Issue
Block a user