mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 11:17:06 +07:00
reflect class template argument values
This commit is contained in:
217
develop/untests/meta_issues/random_issue_6.cpp
Normal file
217
develop/untests/meta_issues/random_issue_6.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*******************************************************************************
|
||||
* 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-2024, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <meta.hpp/meta_all.hpp>
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
template < auto v0 >
|
||||
struct v {};
|
||||
template < typename t0 >
|
||||
struct t {};
|
||||
|
||||
template < auto v1, auto v0 >
|
||||
struct vv {};
|
||||
template < auto v0, typename t0 >
|
||||
struct vt {};
|
||||
template < typename t0, auto v0 >
|
||||
struct tv {};
|
||||
template < typename t1, typename t0 >
|
||||
struct tt {};
|
||||
|
||||
template < auto v2, auto v1, auto v0 >
|
||||
struct vvv {};
|
||||
template < auto v1, auto v0, typename t0 >
|
||||
struct vvt {};
|
||||
template < auto v1, typename t0, auto v0 >
|
||||
struct vtv {};
|
||||
template < auto v0, typename t1, typename t0 >
|
||||
struct vtt {};
|
||||
template < typename t0, auto v1, auto v0 >
|
||||
struct tvv {};
|
||||
template < typename t1, auto v0, typename t0 >
|
||||
struct tvt {};
|
||||
template < typename t1, typename t0, auto v0 >
|
||||
struct ttv {};
|
||||
template < typename t2, typename t1, typename t0 >
|
||||
struct ttt {};
|
||||
|
||||
template < auto v2, auto v1, auto v0, typename t0, typename t1 >
|
||||
struct vvvtt {};
|
||||
template < typename t2, typename t1, typename t0, auto v0, auto v1 >
|
||||
struct tttvv {};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_issues/random/6") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<v<42>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>()});
|
||||
CHECK(type.get_argument_value(0).is<int>());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<t<int>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>()});
|
||||
CHECK_FALSE(type.get_argument_value(0));
|
||||
}
|
||||
//
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vv<42, 21u>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>(),
|
||||
meta::resolve_type<unsigned>()});
|
||||
CHECK(type.get_argument_value(0).is<int>());
|
||||
CHECK(type.get_argument_value(1).is<unsigned>());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vt<42, unsigned>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>(),
|
||||
meta::resolve_type<unsigned>()});
|
||||
CHECK(type.get_argument_value(0).is<int>());
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<tv<int, 42u>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>(),
|
||||
meta::resolve_type<unsigned>()});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK(type.get_argument_value(1).is<unsigned>());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<tt<int, unsigned>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>(),
|
||||
meta::resolve_type<unsigned>()});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
}
|
||||
//
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vvv<std::int32_t{42}, std::uint32_t{21}, std::int64_t{10}>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
meta::resolve_type<std::int64_t>(),
|
||||
});
|
||||
CHECK(type.get_argument_value(0).as<std::int32_t>() == 42);
|
||||
CHECK(type.get_argument_value(1).as<std::uint32_t>() == 21);
|
||||
CHECK(type.get_argument_value(2).as<std::int64_t>() == 10);
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vvt<std::int32_t{42}, std::uint32_t{21}, float>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
meta::resolve_type<float>(),
|
||||
});
|
||||
CHECK(type.get_argument_value(0).as<std::int32_t>() == 42);
|
||||
CHECK(type.get_argument_value(1).as<std::uint32_t>() == 21);
|
||||
CHECK_FALSE(type.get_argument_value(2).has_value());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vtv<std::int32_t{42}, float, std::uint32_t{21}>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
});
|
||||
CHECK(type.get_argument_value(0).as<std::int32_t>() == 42);
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
CHECK(type.get_argument_value(2).as<std::uint32_t>() == 21);
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vtt<std::int32_t{42}, float, double>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<double>(),
|
||||
});
|
||||
CHECK(type.get_argument_value(0).as<std::int32_t>() == 42);
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(2).has_value());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<tvv<float, std::int32_t{42}, std::uint32_t{21}>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK(type.get_argument_value(1).as<std::int32_t>() == 42);
|
||||
CHECK(type.get_argument_value(2).as<std::uint32_t>() == 21);
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<tvt<float, std::int32_t{42}, double>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<double>(),
|
||||
});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK(type.get_argument_value(1).as<std::int32_t>() == 42);
|
||||
CHECK_FALSE(type.get_argument_value(2).has_value());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<ttv<float, double, std::int32_t{42}>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<double>(),
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
CHECK(type.get_argument_value(2).as<std::int32_t>() == 42);
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<ttt<int, float, double>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<int>(),
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<double>(),
|
||||
});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(2).has_value());
|
||||
}
|
||||
//
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<vvvtt<std::int32_t{42}, std::uint32_t{21}, std::uint64_t{10}, float, double>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
meta::resolve_type<std::uint64_t>(),
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<double>(),
|
||||
});
|
||||
CHECK(type.get_argument_value(0).as<std::int32_t>() == 42);
|
||||
CHECK(type.get_argument_value(1).as<std::uint32_t>() == 21);
|
||||
CHECK(type.get_argument_value(2).as<std::uint64_t>() == 10);
|
||||
CHECK_FALSE(type.get_argument_value(3).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(4).has_value());
|
||||
}
|
||||
{
|
||||
meta::class_type type = meta::resolve_type<tttvv<float, double, long double, std::int32_t{42}, std::uint32_t{21}>>();
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{
|
||||
meta::resolve_type<float>(),
|
||||
meta::resolve_type<double>(),
|
||||
meta::resolve_type<long double>(),
|
||||
meta::resolve_type<std::int32_t>(),
|
||||
meta::resolve_type<std::uint32_t>(),
|
||||
});
|
||||
CHECK_FALSE(type.get_argument_value(0).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(1).has_value());
|
||||
CHECK_FALSE(type.get_argument_value(2).has_value());
|
||||
CHECK(type.get_argument_value(3).as<std::int32_t>() == 42);
|
||||
CHECK(type.get_argument_value(4).as<std::uint32_t>() == 21);
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,7 @@ namespace meta_hpp
|
||||
|
||||
using metadata_map = std::map<std::string, uvalue, std::less<>>;
|
||||
using typedef_map = std::map<std::string, any_type, std::less<>>;
|
||||
using uvalue_list = std::vector<uvalue>;
|
||||
|
||||
using any_type_list = std::vector<any_type>;
|
||||
using class_list = std::vector<class_type>;
|
||||
|
||||
@@ -27,33 +27,242 @@ namespace meta_hpp::detail
|
||||
namespace impl
|
||||
{
|
||||
template < class_kind Class >
|
||||
struct class_traits_impl {
|
||||
static constexpr std::size_t arity{0};
|
||||
|
||||
struct class_argument_traits_impl {
|
||||
using argument_types = type_list<>;
|
||||
|
||||
[[nodiscard]] static constexpr class_bitflags make_flags() noexcept {
|
||||
return {};
|
||||
}
|
||||
static constexpr std::tuple argument_values{};
|
||||
};
|
||||
|
||||
template < template < typename... > typename Class, typename... Args >
|
||||
struct class_traits_impl<Class<Args...>> {
|
||||
static constexpr std::size_t arity{sizeof...(Args)};
|
||||
template < typename T >
|
||||
inline constexpr decltype(std::ignore) type_to_ignore_v = std::ignore;
|
||||
|
||||
using argument_types = type_list<Args...>;
|
||||
//
|
||||
// typename...
|
||||
//
|
||||
|
||||
[[nodiscard]] static constexpr class_bitflags make_flags() noexcept {
|
||||
return class_flags::is_template_instantiation;
|
||||
}
|
||||
template < //
|
||||
template < typename... >
|
||||
typename Class,
|
||||
typename... Ts >
|
||||
struct class_argument_traits_impl<Class<Ts...>> {
|
||||
using argument_types = type_list<Ts...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(type_to_ignore_v<Ts>...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto, typename...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto, typename... >
|
||||
typename Class,
|
||||
auto A,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto, auto, typename...
|
||||
// typename, auto, typename...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto, auto, typename... >
|
||||
typename Class,
|
||||
auto A,
|
||||
auto B,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), decltype(B), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, B, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, auto, typename... >
|
||||
typename Class,
|
||||
typename A,
|
||||
auto B,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, Zs...>> {
|
||||
using argument_types = type_list<A, decltype(B), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, B, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto, auto, auto, typename...
|
||||
// typename, auto, auto, typename...
|
||||
// auto, typename, auto, typename...
|
||||
// typename, typename, auto, typename...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto, auto, auto, typename... >
|
||||
typename Class,
|
||||
auto A,
|
||||
auto B,
|
||||
auto C,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), decltype(B), decltype(C), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, B, C, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, auto, auto, typename... >
|
||||
typename Class,
|
||||
typename A,
|
||||
auto B,
|
||||
auto C,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<A, decltype(B), decltype(C), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, B, C, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < auto, typename, auto, typename... >
|
||||
typename Class,
|
||||
auto A,
|
||||
typename B,
|
||||
auto C,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), B, decltype(C), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, std::ignore, C, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, typename, auto, typename... >
|
||||
typename Class,
|
||||
typename A,
|
||||
typename B,
|
||||
auto C,
|
||||
typename... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<A, B, decltype(C), Zs...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, std::ignore, C, type_to_ignore_v<Zs>...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto... >
|
||||
typename Class,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<Zs...>> {
|
||||
using argument_types = type_list<decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(Zs...);
|
||||
};
|
||||
|
||||
//
|
||||
// typename, auto...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < typename, auto... >
|
||||
typename Class,
|
||||
typename A,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, Zs...>> {
|
||||
using argument_types = type_list<A, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, Zs...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto, typename, auto...
|
||||
// typename, typename, auto...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto, typename, auto... >
|
||||
typename Class,
|
||||
auto A,
|
||||
typename B,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), B, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, std::ignore, Zs...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, typename, auto... >
|
||||
typename Class,
|
||||
typename A,
|
||||
typename B,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, Zs...>> {
|
||||
using argument_types = type_list<A, B, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, std::ignore, Zs...);
|
||||
};
|
||||
|
||||
//
|
||||
// auto, auto, typename, auto...
|
||||
// typename, auto, typename, auto...
|
||||
// auto, typename, typename, auto...
|
||||
// typename, typename, typename, auto...
|
||||
//
|
||||
|
||||
template < //
|
||||
template < auto, auto, typename, auto... >
|
||||
typename Class,
|
||||
auto A,
|
||||
auto B,
|
||||
typename C,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), decltype(B), C, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, B, std::ignore, Zs...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, auto, typename, auto... >
|
||||
typename Class,
|
||||
typename A,
|
||||
auto B,
|
||||
typename C,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<A, decltype(B), C, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, B, std::ignore, Zs...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < auto, typename, typename, auto... >
|
||||
typename Class,
|
||||
auto A,
|
||||
typename B,
|
||||
typename C,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<decltype(A), B, C, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(A, std::ignore, std::ignore, Zs...);
|
||||
};
|
||||
|
||||
template < //
|
||||
template < typename, typename, typename, auto... >
|
||||
typename Class,
|
||||
typename A,
|
||||
typename B,
|
||||
typename C,
|
||||
auto... Zs >
|
||||
struct class_argument_traits_impl<Class<A, B, C, Zs...>> {
|
||||
using argument_types = type_list<A, B, C, decltype(Zs)...>;
|
||||
static constexpr std::tuple argument_values = std::make_tuple(std::ignore, std::ignore, std::ignore, Zs...);
|
||||
};
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
struct class_traits : impl::class_traits_impl<Class> {
|
||||
struct class_traits {
|
||||
static constexpr std::size_t size{sizeof(Class)};
|
||||
static constexpr std::size_t align{alignof(Class)};
|
||||
|
||||
using argument_types = impl::class_argument_traits_impl<Class>::argument_types;
|
||||
static constexpr std::tuple argument_values = impl::class_argument_traits_impl<Class>::argument_values;
|
||||
static_assert(type_list_arity_v<argument_types> == std::tuple_size_v<decltype(argument_values)>);
|
||||
|
||||
[[nodiscard]] static constexpr class_bitflags make_flags() noexcept {
|
||||
class_bitflags flags{};
|
||||
|
||||
@@ -73,7 +282,11 @@ namespace meta_hpp::detail
|
||||
flags.set(class_flags::is_polymorphic);
|
||||
}
|
||||
|
||||
return flags | impl::class_traits_impl<Class>::make_flags();
|
||||
if constexpr ( type_list_arity_v<argument_types> ) {
|
||||
flags.set(class_flags::is_template_instantiation);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -208,7 +208,9 @@ namespace meta_hpp
|
||||
|
||||
[[nodiscard]] std::size_t get_arity() const noexcept;
|
||||
[[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept;
|
||||
[[nodiscard]] const uvalue& get_argument_value(std::size_t position) const noexcept;
|
||||
[[nodiscard]] const any_type_list& get_argument_types() const noexcept;
|
||||
[[nodiscard]] const uvalue_list& get_argument_values() const noexcept;
|
||||
|
||||
[[nodiscard]] const class_list& get_base_classes() const noexcept;
|
||||
[[nodiscard]] const constructor_list& get_constructors() const noexcept;
|
||||
@@ -492,6 +494,7 @@ namespace meta_hpp::detail
|
||||
const std::size_t size;
|
||||
const std::size_t align;
|
||||
const any_type_list argument_types;
|
||||
const uvalue_list argument_values;
|
||||
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
||||
|
||||
class_list base_classes;
|
||||
|
||||
@@ -60,6 +60,45 @@ namespace meta_hpp::detail::class_type_data_impl
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
any_type_list make_argument_types() {
|
||||
using ct = class_traits<Class>;
|
||||
using ct_argument_types = typename ct::argument_types;
|
||||
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
any_type_list argument_types;
|
||||
argument_types.reserve(type_list_arity_v<ct_argument_types>);
|
||||
|
||||
[[maybe_unused]] const auto make_argument_type = []<std::size_t I>(index_constant<I>) {
|
||||
return resolve_type<type_list_at_t<I, ct_argument_types>>();
|
||||
};
|
||||
|
||||
(argument_types.emplace_back(make_argument_type(index_constant<Is>{})), ...);
|
||||
return argument_types;
|
||||
}(std::make_index_sequence<type_list_arity_v<ct_argument_types>>());
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
uvalue_list make_argument_values() {
|
||||
using ct = class_traits<Class>;
|
||||
using ct_argument_values = decltype(ct::argument_values);
|
||||
|
||||
return []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
uvalue_list argument_values;
|
||||
argument_values.reserve(std::tuple_size_v<ct_argument_values>);
|
||||
|
||||
[[maybe_unused]] const auto make_argument_value = []<std::size_t I>(index_constant<I>) {
|
||||
return overloaded{
|
||||
[](decltype(std::ignore)) { return uvalue{}; },
|
||||
[](auto&& value) { return uvalue{META_HPP_FWD(value)}; },
|
||||
}(std::get<I>(ct::argument_values));
|
||||
};
|
||||
|
||||
(argument_values.emplace_back(make_argument_value(index_constant<Is>{})), ...);
|
||||
return argument_values;
|
||||
}(std::make_index_sequence<std::tuple_size_v<ct_argument_values>>());
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
@@ -70,7 +109,8 @@ namespace meta_hpp::detail
|
||||
, flags{class_traits<Class>::make_flags()}
|
||||
, size{class_traits<Class>::size}
|
||||
, align{class_traits<Class>::align}
|
||||
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {
|
||||
, argument_types{class_type_data_impl::make_argument_types<Class>()}
|
||||
, argument_values{class_type_data_impl::make_argument_values<Class>()} {
|
||||
class_type_data_impl::new_base_info_t new_base_info;
|
||||
class_type_data_impl::fill_upcast_info<Class>(new_base_info);
|
||||
base_classes.swap(new_base_info.base_classes);
|
||||
@@ -112,10 +152,18 @@ namespace meta_hpp
|
||||
return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{};
|
||||
}
|
||||
|
||||
inline const uvalue& class_type::get_argument_value(std::size_t position) const noexcept {
|
||||
return position < data_->argument_values.size() ? data_->argument_values[position] : uvalue::empty_value;
|
||||
}
|
||||
|
||||
inline const any_type_list& class_type::get_argument_types() const noexcept {
|
||||
return data_->argument_types;
|
||||
}
|
||||
|
||||
inline const uvalue_list& class_type::get_argument_values() const noexcept {
|
||||
return data_->argument_values;
|
||||
}
|
||||
|
||||
inline const class_list& class_type::get_base_classes() const noexcept {
|
||||
return data_->base_classes;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user