From 14e57acfd8d7de95466068564be08e55f924ee35 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Mon, 8 Aug 2022 21:44:24 +0200 Subject: [PATCH] Util: Add format specifier logic to container types --- src/util/format/formatter.h | 98 +++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/src/util/format/formatter.h b/src/util/format/formatter.h index fdeada8..384f484 100644 --- a/src/util/format/formatter.h +++ b/src/util/format/formatter.h @@ -8,7 +8,7 @@ #include #include // size_t -#include // int8_t, int32_t, int64_t, uint8_t, uint32_t, uintptr_t +#include // int8_t, uint8_t, uintptr_t #include #include #include @@ -66,7 +66,7 @@ template struct Formatter { Specifier specifier; - constexpr void parse(Parser& parser) + void parse(Parser& parser) { if constexpr (std::is_same_v) { parser.parseSpecifier(specifier, Parser::ParameterType::Char); @@ -197,7 +197,7 @@ struct Formatter : Formatter { template struct Formatter : Formatter { - constexpr void parse(Parser& parser) + void parse(Parser& parser) { parser.parseSpecifier(specifier, Parser::ParameterType::Pointer); specifier.alternativeForm = true; @@ -219,47 +219,85 @@ struct Formatter : Formatter { template struct Formatter> : Formatter { + Specifier specifier; + + void parse(Parser& parser) + { + parser.parseSpecifier(specifier, Parser::ParameterType::Container); + } + void format(Builder& builder, const std::vector& value) const { - builder.putString("{\n"); + std::string indent = std::string(specifier.width, specifier.fill); + + builder.putCharacter('{'); + if (specifier.alternativeForm) { + builder.putCharacter('\n'); + } for (auto it = value.cbegin(); it != value.cend(); ++it) { - builder.putString(" "); + builder.putString(indent); + Formatter::format(builder, *it); // Add comma, except after the last element if (it != std::prev(value.end(), 1)) { builder.putCharacter(','); } - builder.putCharacter('\n'); + else if (!specifier.alternativeForm) { + builder.putString(indent); + } + + if (specifier.alternativeForm) { + builder.putCharacter('\n'); + } } builder.putCharacter('}'); } }; -#define UTIL_FORMAT_FORMAT_AS_MAP(type) \ - template \ - struct Formatter> \ - : Formatter \ - , Formatter { \ - void format(Builder& builder, const type& value) const \ - { \ - builder.putString("{\n"); \ - auto last = value.end(); \ - for (auto it = value.begin(); it != last; ++it) { \ - builder.putString(R"( ")"); \ - Formatter::format(builder, it->first); \ - builder.putString(R"(": )"); \ - Formatter::format(builder, it->second); \ - \ - /* Add comma, except after the last element */ \ - if (std::next(it) != last) { \ - builder.putCharacter(','); \ - } \ - \ - builder.putCharacter('\n'); \ - } \ - builder.putCharacter('}'); \ - } \ +#define UTIL_FORMAT_FORMAT_AS_MAP(type) \ + template \ + struct Formatter> \ + : Formatter \ + , Formatter { \ + Specifier specifier; \ + \ + void parse(Parser& parser) \ + { \ + parser.parseSpecifier(specifier, Parser::ParameterType::Container); \ + } \ + \ + void format(Builder& builder, const type& value) const \ + { \ + std::string indent = std::string(specifier.width, specifier.fill); \ + \ + builder.putCharacter('{'); \ + if (specifier.alternativeForm) { \ + builder.putCharacter('\n'); \ + } \ + auto last = value.end(); \ + for (auto it = value.begin(); it != last; ++it) { \ + builder.putString(indent); \ + builder.putCharacter('"'); \ + Formatter::format(builder, it->first); \ + builder.putCharacter('"'); \ + builder.putString((specifier.width > 0) ? ": " : ":"); \ + Formatter::format(builder, it->second); \ + \ + /* Add comma, except after the last element */ \ + if (std::next(it) != last) { \ + builder.putCharacter(','); \ + } \ + else if (!specifier.alternativeForm) { \ + builder.putString(indent); \ + } \ + \ + if (specifier.alternativeForm) { \ + builder.putCharacter('\n'); \ + } \ + } \ + builder.putCharacter('}'); \ + } \ } UTIL_FORMAT_FORMAT_AS_MAP(std::map);