From e89e8b9560f896666551aa45065de01e06c353f9 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Sat, 8 Jan 2022 02:03:48 +0100 Subject: Replace anonymous struct in format_specifier with flags struct --- include/cxxformat/core.hpp | 44 +++++++++++++++++++++------------------- include/cxxformat/formatters.hpp | 44 ++++++++++++++++++++-------------------- include/cxxformat/runtime.hpp | 8 ++++---- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/include/cxxformat/core.hpp b/include/cxxformat/core.hpp index 9781970..55d1629 100644 --- a/include/cxxformat/core.hpp +++ b/include/cxxformat/core.hpp @@ -137,13 +137,13 @@ namespace format { char conversion; char addSign; char padding; - struct { + struct Flags { bool leftJustified : 1; bool alternative : 1; bool widthAsArg : 1; bool precisionAsArg : 1; Length length : 4; - }; + } flags; }; } @@ -246,12 +246,14 @@ namespace format { .precision = std::nullopt, .addSign = '\0', .padding = ' ', + .flags = { + .leftJustified = false, + .alternative = false, + .widthAsArg = false, + .precisionAsArg = false, + .length = format_specifier::None + } }; - spec.leftJustified = false; - spec.alternative = false; - spec.widthAsArg = false; - spec.precisionAsArg = false; - spec.length = format_specifier::None; bool hasExplicitArgIndex = false; const auto argIndex = parseNumber(fmt, pos); @@ -276,7 +278,7 @@ namespace format { const auto c = fmt[pos]; if (c == '-') { - spec.leftJustified = true; + spec.flags.leftJustified = true; } else if (c == '+') { @@ -288,7 +290,7 @@ namespace format { } else if (c == '#') { - spec.alternative = true; + spec.flags.alternative = true; } else if (c == '0') { @@ -299,7 +301,7 @@ namespace format { break; } } - if (spec.leftJustified) + if (spec.flags.leftJustified) { spec.padding = ' '; } @@ -351,14 +353,14 @@ namespace format { } return asArg; }; - spec.widthAsArg = handleWidthPrecision(spec.minWidth); + spec.flags.widthAsArg = handleWidthPrecision(spec.minWidth); if (fmt[pos] == '.') { ++pos; checkEos(); - spec.precisionAsArg = handleWidthPrecision(spec.precision, true); + spec.flags.precisionAsArg = handleWidthPrecision(spec.precision, true); } { @@ -370,33 +372,33 @@ namespace format { { ++pos; checkEos(); - spec.length = (c == 'h' ? L::Quarter : L::LongLong); + spec.flags.length = (c == 'h' ? L::Quarter : L::LongLong); ++pos; } else { - spec.length = (c == 'h' ? L::Half : L::Long); + spec.flags.length = (c == 'h' ? L::Half : L::Long); ++pos; } } else if (c == 'L') { - spec.length = L::LongDouble; + spec.flags.length = L::LongDouble; ++pos; } else if (c == 'j') { - spec.length = L::Maximum; + spec.flags.length = L::Maximum; ++pos; } else if (c == 'z') { - spec.length = L::SizeT; + spec.flags.length = L::SizeT; ++pos; } else if (c == 't') { - spec.length = L::PtrDiff; + spec.flags.length = L::PtrDiff; ++pos; } } @@ -450,7 +452,7 @@ namespace format { const auto format_arg = [&args..., &out](holder) -> decltype(auto) { optional_int minWidth = spec.minWidth; - if constexpr (spec.widthAsArg) + if constexpr (spec.flags.widthAsArg) { using Arg = std::decay_t>; static_assert(std::unsigned_integral, "Width argument must be an unsigned integral"); @@ -458,7 +460,7 @@ namespace format { minWidth = nth_argument<*spec.minWidth>(std::forward(args)...); } optional_int precision = spec.precision; - if constexpr (spec.precisionAsArg) + if constexpr (spec.flags.precisionAsArg) { using Arg = std::decay_t>; static_assert(std::unsigned_integral, "Precision argument must be an unsigned integral"); @@ -522,7 +524,7 @@ namespace format { } else { - return parts.argIndex == i || (parts.widthAsArg && parts.minWidth == i) || (parts.precisionAsArg && parts.precision == i); + return parts.argIndex == i || (parts.flags.widthAsArg && parts.minWidth == i) || (parts.flags.precisionAsArg && parts.precision == i); } }() || ...)>(); } diff --git a/include/cxxformat/formatters.hpp b/include/cxxformat/formatters.hpp index ea0c08b..c9461e3 100644 --- a/include/cxxformat/formatters.hpp +++ b/include/cxxformat/formatters.hpp @@ -92,7 +92,7 @@ namespace format { if (conv == 'c') { char converted = static_cast(static_cast(t)); - formatPadded(out, {&converted, 1}, ' ', spec.leftJustified, minWidth); + formatPadded(out, {&converted, 1}, ' ', spec.flags.leftJustified, minWidth); return; } @@ -129,7 +129,7 @@ namespace format { { prefix = "-"; } - else if (base != 10 && spec.alternative) + else if (base != 10 && spec.flags.alternative) { if (spec.conversion == 'o') { @@ -162,7 +162,7 @@ namespace format { precisionPadding = *precision - converted.size(); } } - else if (minWidth && (spec.alternative && base != 10 && spec.padding == '0')) + else if (minWidth && (spec.flags.alternative && base != 10 && spec.padding == '0')) { const auto totalLength = converted.size() + prefix.size(); if (*minWidth > totalLength) @@ -182,7 +182,7 @@ namespace format { } const auto padding = precision ? ' ' : spec.padding; - if(!spec.leftJustified) + if(!spec.flags.leftJustified) { out(padding, normalPadding); } @@ -192,7 +192,7 @@ namespace format { out(converted); - if(spec.leftJustified) + if(spec.flags.leftJustified) { out(padding, normalPadding); } @@ -216,7 +216,7 @@ namespace format { simpleConversionSpecifierCheck("coxXuv", conv, "unsigned integral type"); } - if (spec.alternative && !"oxX"_contains(conv)) + if (spec.flags.alternative && !"oxX"_contains(conv)) { throw std::invalid_argument{"‘#’ (alternative) flag is only allowed for %x, %X and %o"}; } @@ -305,10 +305,10 @@ namespace format { } const bool hasDot = mantissa.find('.') != std::string_view::npos; - const bool addDot = spec.alternative && !hasDot; + const bool addDot = spec.flags.alternative && !hasDot; std::size_t extraZeros{0}; - if (spec.alternative && format == std::chars_format::general && precision) + if (spec.flags.alternative && format == std::chars_format::general && precision) { const auto currentMantissaPrecision = mantissa.size() - (hasDot ? 1 : 0); if (*precision > currentMantissaPrecision) @@ -349,7 +349,7 @@ namespace format { } } - if(!spec.leftJustified && spec.padding != '0') + if(!spec.flags.leftJustified && spec.padding != '0') { out(spec.padding, paddingLength); } @@ -360,7 +360,7 @@ namespace format { } out(hexPrefix); - if(!spec.leftJustified && spec.padding == '0') + if(!spec.flags.leftJustified && spec.padding == '0') { out(spec.padding, paddingLength); } @@ -373,7 +373,7 @@ namespace format { out('0', extraZeros); out(exponent); - if(spec.leftJustified) + if(spec.flags.leftJustified) { out(spec.padding, paddingLength); } @@ -403,13 +403,13 @@ namespace format { val = val.substr(0, *precision); } - formatPadded(out, val, ' ', spec.leftJustified, minWidth); + formatPadded(out, val, ' ', spec.flags.leftJustified, minWidth); } static constexpr void conversionSupported(format_specifier spec) { simpleConversionSpecifierCheck("sv", spec.conversion, "stringy type"); - noAlternative(spec.alternative, "stringy types"); + noAlternative(spec.flags.alternative, "stringy types"); noSignFlags(spec.addSign, "stringy types"); } }; @@ -419,14 +419,14 @@ namespace format { template struct formatter { - static constexpr inline format_specifier delegateSpec{.conversion = 'x', .alternative = true}; + static constexpr inline format_specifier delegateSpec{.conversion = 'x', .flags = {.alternative = true}}; using delegated_formatter = formatter; static constexpr void format(const format_output auto& out, const std::remove_pointer_t* t, format_specifier spec, optional_int minWidth, optional_int) { if (t == nullptr) { - formatPadded(out, "(nil)", ' ', spec.leftJustified, minWidth); + formatPadded(out, "(nil)", ' ', spec.flags.leftJustified, minWidth); } else { @@ -437,7 +437,7 @@ namespace format { static constexpr void conversionSupported(format_specifier spec) { simpleConversionSpecifierCheck("pv", spec.conversion, "pointer type"); - noAlternative(spec.alternative, "pointer types"); + noAlternative(spec.flags.alternative, "pointer types"); noSignFlags(spec.addSign, "pointer types"); noPrecision(spec.precision, "pointer types"); delegated_formatter::conversionSupported(delegateSpec); @@ -448,7 +448,7 @@ namespace format { struct formatter { static constexpr void format(const format_output auto& out, std::nullptr_t, format_specifier spec, optional_int minWidth, optional_int) { - formatPadded(out, "(nil)", ' ', spec.leftJustified, minWidth); + formatPadded(out, "(nil)", ' ', spec.flags.leftJustified, minWidth); } static constexpr void conversionSupported(format_specifier spec) @@ -467,11 +467,11 @@ namespace format { } else { - assert(spec.conversion == 's' || spec.alternative == 'v'); + assert(spec.conversion == 's' || spec.flags.alternative == 'v'); if (s == nullptr) { - formatPadded(out, "(nil)", ' ', spec.leftJustified, minWidth); + formatPadded(out, "(nil)", ' ', spec.flags.leftJustified, minWidth); } else { @@ -483,7 +483,7 @@ namespace format { static constexpr void conversionSupported(format_specifier spec) { simpleConversionSpecifierCheck("spv", spec.conversion, "char pointer"); - noAlternative(spec.alternative, "char pointer"); + noAlternative(spec.flags.alternative, "char pointer"); noSignFlags(spec.addSign, "char pointer"); } }; @@ -512,14 +512,14 @@ namespace format { std::ostringstream stream; stream << t; - formatPadded(out, stream.view(), ' ', spec.leftJustified, minWidth); + formatPadded(out, stream.view(), ' ', spec.flags.leftJustified, minWidth); } static constexpr void conversionSupported(format_specifier spec) { constexpr std::string_view fallbackName{"operator<<(std::ostream&) fallback"}; simpleConversionSpecifierCheck("sv", spec.conversion, fallbackName); - noAlternative(spec.alternative, fallbackName); + noAlternative(spec.flags.alternative, fallbackName); noSignFlags(spec.addSign, fallbackName); noPrecision(spec.precision, fallbackName); noZeroPadding(spec.padding, fallbackName); diff --git a/include/cxxformat/runtime.hpp b/include/cxxformat/runtime.hpp index cc09b7e..23f2b96 100644 --- a/include/cxxformat/runtime.hpp +++ b/include/cxxformat/runtime.hpp @@ -42,14 +42,14 @@ namespace format { { if (index == spec.argIndex) { - if (spec.widthAsArg) + if (spec.flags.widthAsArg) { if (!indexArgs[*spec.minWidth]) { throw std::invalid_argument{"Width argument must be an unsigned integral at most as big as std::size_t"}; } } - if (spec.precisionAsArg) + if (spec.flags.precisionAsArg) { if (!indexArgs[*spec.precision]) { @@ -81,13 +81,13 @@ namespace format { if (index == spec.argIndex) { optional_int minWidth = spec.minWidth; - if (spec.widthAsArg) + if (spec.flags.widthAsArg) { minWidth = indexArgs[*minWidth]; assert(minWidth); } optional_int precision = spec.precision; - if (spec.precisionAsArg) + if (spec.flags.precisionAsArg) { precision = indexArgs[*precision]; assert(precision); -- cgit v1.2.3-54-g00ecf