From 718b95d9890556461962494deaf15b7e0b230db9 Mon Sep 17 00:00:00 2001 From: tonytranrp <100391458+tonytranrp@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:01:52 -1000 Subject: [PATCH] fix: resolve recursive alias error in Value formatter Introduce a private helper function to handle formatting of nested Value types. This change prevents MSVC C2968 "recursive alias declaration" errors caused by recursive type mapping when using fmt::join or direct formatting of nested containers. --- include/rift/value.hpp | 44 ++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/include/rift/value.hpp b/include/rift/value.hpp index 7e89b90..806e493 100644 --- a/include/rift/value.hpp +++ b/include/rift/value.hpp @@ -264,37 +264,51 @@ struct fmt::formatter { return ctx.begin(); } - template - auto format(rift::Value const& value, FormatContext& ctx) const noexcept { +private: + // Helper to format a Value without triggering recursive type mapping. + // This avoids MSVC C2968 "recursive alias declaration" errors. + template + OutputIt format_value(rift::Value const& value, OutputIt out) const noexcept { switch (value.type()) { case rift::Value::Type::String: - return fmt::format_to(ctx.out(), "{}", value.getString()); + return fmt::format_to(out, "{}", value.getString()); case rift::Value::Type::Integer: - return fmt::format_to(ctx.out(), "{}", value.getInteger()); + return fmt::format_to(out, "{}", value.getInteger()); case rift::Value::Type::Float: - return fmt::format_to(ctx.out(), "{:.2f}", value.getFloat()); + return fmt::format_to(out, "{:.2f}", value.getFloat()); case rift::Value::Type::Boolean: - return fmt::format_to(ctx.out(), "{}", value.getBoolean() ? "true" : "false"); + return fmt::format_to(out, "{}", value.getBoolean() ? "true" : "false"); case rift::Value::Type::Array: { - return fmt::format_to(ctx.out(), "[{}]", fmt::join(value.getArray(), ", "));; + auto& arr = value.getArray(); + out = fmt::format_to(out, "["); + for (size_t i = 0; i < arr.size(); ++i) { + if (i > 0) out = fmt::format_to(out, ", "); + out = format_value(arr[i], out); + } + return fmt::format_to(out, "]"); } case rift::Value::Type::Object: { auto& obj = value.getObject(); + out = fmt::format_to(out, "{{"); size_t i = 0; - auto count = obj.size(); - fmt::format_to(ctx.out(), "{{"); for (auto const& [key, val] : obj) { - fmt::format_to(ctx.out(), "{}: {}", key, val); - if (i < count - 1) { - fmt::format_to(ctx.out(), ", "); - } + if (i > 0) out = fmt::format_to(out, ", "); + out = fmt::format_to(out, "{}: ", key); + out = format_value(val, out); + ++i; } - return fmt::format_to(ctx.out(), "}}"); + return fmt::format_to(out, "}}"); } default: - return fmt::format_to(ctx.out(), "null"); + return fmt::format_to(out, "null"); } } + +public: + template + auto format(rift::Value const& value, FormatContext& ctx) const noexcept { + return format_value(value, ctx.out()); + } }; #endif // RIFT_VALUE_HPP