Skip to content

Commit e8d2bba

Browse files
authored
fix: resolve recursive alias error in Value formatter (#1)
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.
1 parent e692bcf commit e8d2bba

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

include/rift/value.hpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -264,37 +264,51 @@ struct fmt::formatter<rift::Value> {
264264
return ctx.begin();
265265
}
266266

267-
template <typename FormatContext>
268-
auto format(rift::Value const& value, FormatContext& ctx) const noexcept {
267+
private:
268+
// Helper to format a Value without triggering recursive type mapping.
269+
// This avoids MSVC C2968 "recursive alias declaration" errors.
270+
template <typename OutputIt>
271+
OutputIt format_value(rift::Value const& value, OutputIt out) const noexcept {
269272
switch (value.type()) {
270273
case rift::Value::Type::String:
271-
return fmt::format_to(ctx.out(), "{}", value.getString());
274+
return fmt::format_to(out, "{}", value.getString());
272275
case rift::Value::Type::Integer:
273-
return fmt::format_to(ctx.out(), "{}", value.getInteger());
276+
return fmt::format_to(out, "{}", value.getInteger());
274277
case rift::Value::Type::Float:
275-
return fmt::format_to(ctx.out(), "{:.2f}", value.getFloat());
278+
return fmt::format_to(out, "{:.2f}", value.getFloat());
276279
case rift::Value::Type::Boolean:
277-
return fmt::format_to(ctx.out(), "{}", value.getBoolean() ? "true" : "false");
280+
return fmt::format_to(out, "{}", value.getBoolean() ? "true" : "false");
278281
case rift::Value::Type::Array: {
279-
return fmt::format_to(ctx.out(), "[{}]", fmt::join(value.getArray(), ", "));;
282+
auto& arr = value.getArray();
283+
out = fmt::format_to(out, "[");
284+
for (size_t i = 0; i < arr.size(); ++i) {
285+
if (i > 0) out = fmt::format_to(out, ", ");
286+
out = format_value(arr[i], out);
287+
}
288+
return fmt::format_to(out, "]");
280289
}
281290
case rift::Value::Type::Object: {
282291
auto& obj = value.getObject();
292+
out = fmt::format_to(out, "{{");
283293
size_t i = 0;
284-
auto count = obj.size();
285-
fmt::format_to(ctx.out(), "{{");
286294
for (auto const& [key, val] : obj) {
287-
fmt::format_to(ctx.out(), "{}: {}", key, val);
288-
if (i < count - 1) {
289-
fmt::format_to(ctx.out(), ", ");
290-
}
295+
if (i > 0) out = fmt::format_to(out, ", ");
296+
out = fmt::format_to(out, "{}: ", key);
297+
out = format_value(val, out);
298+
++i;
291299
}
292-
return fmt::format_to(ctx.out(), "}}");
300+
return fmt::format_to(out, "}}");
293301
}
294302
default:
295-
return fmt::format_to(ctx.out(), "null");
303+
return fmt::format_to(out, "null");
296304
}
297305
}
306+
307+
public:
308+
template <typename FormatContext>
309+
auto format(rift::Value const& value, FormatContext& ctx) const noexcept {
310+
return format_value(value, ctx.out());
311+
}
298312
};
299313

300314
#endif // RIFT_VALUE_HPP

0 commit comments

Comments
 (0)