mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
rx/refl: add C arrays support & reduce binary size
Use StaticString constant to keep only used part of template string Use bisect for field count query
This commit is contained in:
parent
593297153a
commit
2df7b3871c
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "StaticString.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
|
||||
|
|
@ -14,24 +16,49 @@
|
|||
namespace rx {
|
||||
namespace detail {
|
||||
struct AnyStructFieldQuery {
|
||||
template <typename T> constexpr operator T &&();
|
||||
template <typename T> constexpr operator T();
|
||||
};
|
||||
|
||||
template <typename StructT, std::size_t N = 1, std::size_t LastValidCount = 0>
|
||||
// clang 21 crashes with concept
|
||||
template <typename, typename, typename = void>
|
||||
struct IsValidFieldCountImpl : std::false_type {};
|
||||
template <typename StructT, std::size_t... I>
|
||||
struct IsValidFieldCountImpl<
|
||||
StructT, std::index_sequence<I...>,
|
||||
std::void_t<decltype(StructT{(I, AnyStructFieldQuery{})...})>>
|
||||
: std::true_type {};
|
||||
template <typename StructT, std::size_t I>
|
||||
static constexpr bool IsValidFieldCount =
|
||||
IsValidFieldCountImpl<StructT,
|
||||
decltype(std::make_index_sequence<I>{})>::value;
|
||||
|
||||
template <typename StructT, std::size_t Min = 1,
|
||||
std::size_t Max = std::min<std::size_t>(sizeof(StructT), 128),
|
||||
std::size_t Mid = (Max - Min) / 2>
|
||||
struct CalcFieldCount;
|
||||
|
||||
template <typename StructT, std::size_t Min, std::size_t Max, std::size_t Mid>
|
||||
requires(Mid < Max && IsValidFieldCount<StructT, Mid>)
|
||||
struct CalcFieldCount<StructT, Min, Max, Mid>
|
||||
: CalcFieldCount<StructT, Mid + 1, Max, (Mid + 1 + Max) / 2> {};
|
||||
|
||||
template <typename StructT, std::size_t Min, std::size_t Max, std::size_t Mid>
|
||||
requires(Mid < Max && !IsValidFieldCount<StructT, Mid>)
|
||||
struct CalcFieldCount<StructT, Min, Max, Mid>
|
||||
: CalcFieldCount<StructT, Min, Mid, (Min + Mid) / 2> {};
|
||||
|
||||
template <typename StructT, std::size_t Min, std::size_t Max, std::size_t Mid>
|
||||
requires(Mid >= Max)
|
||||
struct CalcFieldCount<StructT, Min, Max, Mid> {
|
||||
static constexpr auto count = Min == 0 ? 0
|
||||
: IsValidFieldCount<StructT, Min> ? Min
|
||||
: Min - 1;
|
||||
};
|
||||
|
||||
template <typename StructT>
|
||||
requires std::is_class_v<StructT>
|
||||
constexpr auto calcFieldCount() {
|
||||
|
||||
auto isValidFieldCount = []<std::size_t... I>(std::index_sequence<I...>) {
|
||||
return requires { StructT(((I, AnyStructFieldQuery{}))...); };
|
||||
};
|
||||
|
||||
if constexpr (isValidFieldCount(std::make_index_sequence<N>())) {
|
||||
return calcFieldCount<StructT, N + 1, N>();
|
||||
} else if constexpr (sizeof(StructT) <= N || LastValidCount > 0) {
|
||||
return LastValidCount;
|
||||
} else {
|
||||
return calcFieldCount<StructT, N + 1, LastValidCount>();
|
||||
}
|
||||
return CalcFieldCount<StructT>::count;
|
||||
}
|
||||
|
||||
consteval std::string_view unwrapName(std::string_view prefix,
|
||||
|
|
@ -95,38 +122,45 @@ constexpr bool isField<TypeT(BaseT::*)> = true;
|
|||
|
||||
} // namespace detail
|
||||
|
||||
template <auto &&V> consteval auto getNameOf() {
|
||||
std::string_view prefix;
|
||||
template <auto &&V> constexpr auto getNameOf() {
|
||||
constexpr std::string_view prefix =
|
||||
#ifdef _MSC_VER
|
||||
prefix = "getNameOf<";
|
||||
"getNameOf<";
|
||||
#else
|
||||
prefix = "V = ";
|
||||
"V = ";
|
||||
#endif
|
||||
return detail::unwrapName(prefix, RX_PRETTY_FUNCTION, true);
|
||||
constexpr auto name = detail::unwrapName(prefix, RX_PRETTY_FUNCTION, true);
|
||||
static constexpr auto result = rx::StaticString<name.size() + 1>{name};
|
||||
return std::string_view{result};
|
||||
}
|
||||
|
||||
template <auto V>
|
||||
requires(detail::isField<decltype(V)> ||
|
||||
std::is_enum_v<std::remove_cvref_t<decltype(V)>> ||
|
||||
std::is_pointer_v<std::remove_cvref_t<decltype(V)>>)
|
||||
consteval auto getNameOf() {
|
||||
std::string_view prefix;
|
||||
constexpr auto getNameOf() {
|
||||
constexpr std::string_view prefix =
|
||||
#ifdef _MSC_VER
|
||||
prefix = "getNameOf<";
|
||||
"getNameOf<";
|
||||
#else
|
||||
prefix = "V = ";
|
||||
"V = ";
|
||||
#endif
|
||||
return detail::unwrapName(prefix, RX_PRETTY_FUNCTION, true);
|
||||
|
||||
constexpr auto name = detail::unwrapName(prefix, RX_PRETTY_FUNCTION, true);
|
||||
static constexpr auto result = rx::StaticString<name.size() + 1>{name};
|
||||
return std::string_view{result};
|
||||
}
|
||||
|
||||
template <typename T> consteval auto getNameOf() {
|
||||
std::string_view prefix;
|
||||
template <typename T> constexpr auto getNameOf() {
|
||||
constexpr std::string_view prefix =
|
||||
#ifdef _MSC_VER
|
||||
prefix = "getNameOf<";
|
||||
"getNameOf<";
|
||||
#else
|
||||
prefix = "T = ";
|
||||
"T = ";
|
||||
#endif
|
||||
return detail::unwrapName(prefix, RX_PRETTY_FUNCTION, false);
|
||||
constexpr auto name = detail::unwrapName(prefix, RX_PRETTY_FUNCTION, false);
|
||||
static constexpr auto result = rx::StaticString<name.size() + 1>{name};
|
||||
return std::string_view{result};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
|
|
|||
Loading…
Reference in a new issue