From 2df7b3871cb07136d01601c5f2cedeeb16dbf382 Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 4 Oct 2025 14:29:29 +0300 Subject: [PATCH] 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 --- rx/include/rx/refl.hpp | 92 +++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/rx/include/rx/refl.hpp b/rx/include/rx/refl.hpp index 1341bd364..c81a5a665 100644 --- a/rx/include/rx/refl.hpp +++ b/rx/include/rx/refl.hpp @@ -1,5 +1,7 @@ #pragma once +#include "StaticString.hpp" +#include #include #include @@ -14,24 +16,49 @@ namespace rx { namespace detail { struct AnyStructFieldQuery { - template constexpr operator T &&(); + template constexpr operator T(); }; -template +// clang 21 crashes with concept +template +struct IsValidFieldCountImpl : std::false_type {}; +template +struct IsValidFieldCountImpl< + StructT, std::index_sequence, + std::void_t> + : std::true_type {}; +template +static constexpr bool IsValidFieldCount = + IsValidFieldCountImpl{})>::value; + +template (sizeof(StructT), 128), + std::size_t Mid = (Max - Min) / 2> +struct CalcFieldCount; + +template + requires(Mid < Max && IsValidFieldCount) +struct CalcFieldCount + : CalcFieldCount {}; + +template + requires(Mid < Max && !IsValidFieldCount) +struct CalcFieldCount + : CalcFieldCount {}; + +template + requires(Mid >= Max) +struct CalcFieldCount { + static constexpr auto count = Min == 0 ? 0 + : IsValidFieldCount ? Min + : Min - 1; +}; + +template requires std::is_class_v constexpr auto calcFieldCount() { - - auto isValidFieldCount = [](std::index_sequence) { - return requires { StructT(((I, AnyStructFieldQuery{}))...); }; - }; - - if constexpr (isValidFieldCount(std::make_index_sequence())) { - return calcFieldCount(); - } else if constexpr (sizeof(StructT) <= N || LastValidCount > 0) { - return LastValidCount; - } else { - return calcFieldCount(); - } + return CalcFieldCount::count; } consteval std::string_view unwrapName(std::string_view prefix, @@ -95,38 +122,45 @@ constexpr bool isField = true; } // namespace detail -template consteval auto getNameOf() { - std::string_view prefix; +template 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}; + return std::string_view{result}; } template requires(detail::isField || std::is_enum_v> || std::is_pointer_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}; + return std::string_view{result}; } -template consteval auto getNameOf() { - std::string_view prefix; +template 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}; + return std::string_view{result}; } namespace detail {