diff --git a/include/fmt/structured.h b/include/fmt/structured.h index 3c469563..26186563 100644 --- a/include/fmt/structured.h +++ b/include/fmt/structured.h @@ -31,46 +31,21 @@ template struct NamedField { template struct Extended { const T& value; }; -// fixme: Would probably be better to visit all name field elements directly in -// the Extended formatter instead of relying on user space specialization -// mechanism -/** - * Format a field name/value pair as ".{name}={value}" - * @tparam T - */ -template struct fmt::formatter> { - template - auto format(NamedField const& t, FormatContext& ctx) { - *ctx.out()++ = '.'; - std::copy(t.name.begin(), t.name.end(), ctx.out()); - *ctx.out()++ = '='; - if constexpr (reflection::available) { - return fmt::formatter>{}.format(t.value, ctx); - } else { - return fmt::formatter{}.format(t.value, ctx); - } - } -}; - /** * Formats objects as they would be written using designated initializers. * - * E.g. {:e} will output Outer{.a=1, b=2, .inner=Inner{.x=3, .y=4, .z=5}} + * E.g. it will output "Outer{.a=1, b=2, .inner=Inner{.x=3, .y=4, .z=5}}" * - * @tparam T The object to format. * @tparam C The character type used. */ -// fixme remove T template parameter -template -struct fmt::formatter, C, - std::enable_if_t::available, void>> { +template struct CStyleFormatter { template constexpr auto parse(ParseContext& ctx) { auto it = ctx.begin(); if (*it != '}') throw format_error("configuration not yet supported"); return it; } - template + template auto format(T const& t, FormatContext& ctx) { std::string name = reflection::name(); @@ -83,22 +58,43 @@ struct fmt::formatter, C, } }; -// fixme remove this class and merge it with the fallback formatter in detail -// namespace +// fixme: Would probably be better to visit all name field elements directly in +// the Extended formatter instead of relying on user space specialization +// mechanism. That also will allow to reuse a configuration of the formatter +// for nested structures. +/** + * Format a field name/value pair as ".{name}={value}" + * @tparam T + */ template -struct fmt::formatter::available, void>> { - using extended = fmt::formatter>; +struct fmt::formatter, Char> { + template + auto format(NamedField const& t, FormatContext& ctx) { + *ctx.out()++ = '.'; + std::copy(t.name.begin(), t.name.end(), ctx.out()); + *ctx.out()++ = '='; + if constexpr (reflection::available) { + return CStyleFormatter{}.format(t.value, ctx); + } else { + return fmt::formatter{}.format(t.value, ctx); + } + } +}; - template constexpr auto parse(ParseContext& ctx) { - // Parse the presentation format and store it in the formatter: +namespace detail { +/** + * Select a formatter matching the style requested in the format string. + */ +template +struct fallback_formatter::available>> { + FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) + -> decltype(ctx.begin()) { auto it = ctx.begin(), end = ctx.end(); - if (*(it++) != 'e') { + if (*(it++) != 'e') { // fixme: e for extended.. rather arbitrary choice... throw format_error("invalid format"); } - _extended = extended{}; ctx.advance_to(it); - _extended.parse(ctx); + it = CStyleFormatter{}.parse(ctx); // Check if reached the end of the range: if (it != end && *it != '}') { @@ -109,34 +105,9 @@ struct fmt::formatter - auto format(T const& t, FormatContext& ctx) { - return _extended.format(t, ctx); - } - - private: - extended _extended; -}; - -namespace detail { -template -struct fallback_formatter::available>> { - using extended = fmt::formatter>; - - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - auto it = formatter, Char>::parse(ctx); - // fixme: not sure what to return, if the closing '}' remains (like required - // for formatter specialization) - // some internals will throw from ErrorHandler::on_error("invalid - // type specifier"); - ctx.advance_to(it++); // fixme: also not sure - return it; - } - template auto format(const T& value, FormatContext& ctx) { - return extended{}.format(value, ctx); + return CStyleFormatter{}.format(value, ctx); } }; } // namespace detail