summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <maxmitti@maxmitti.tk>2022-01-08 02:03:48 +0100
committerMarkus Mittendrein <maxmitti@maxmitti.tk>2022-01-08 02:03:48 +0100
commite89e8b9560f896666551aa45065de01e06c353f9 (patch)
treee0ac9e0235337a85e4bd89ccd9a3aa895a18daa3
parent54dfcc50fb6fffca6daaa0e0d70cb558e3efd3e5 (diff)
downloadcxxformat-e89e8b9560f896666551aa45065de01e06c353f9.tar.gz
cxxformat-e89e8b9560f896666551aa45065de01e06c353f9.zip
Replace anonymous struct in format_specifier with flags struct
-rw-r--r--include/cxxformat/core.hpp44
-rw-r--r--include/cxxformat/formatters.hpp44
-rw-r--r--include/cxxformat/runtime.hpp8
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<ArgIndex>(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]<format_specifier spec>(holder<spec>) -> decltype(auto)
{
optional_int<std::size_t> minWidth = spec.minWidth;
- if constexpr (spec.widthAsArg)
+ if constexpr (spec.flags.widthAsArg)
{
using Arg = std::decay_t<nth_type<*spec.minWidth, Args...>>;
static_assert(std::unsigned_integral<Arg>, "Width argument must be an unsigned integral");
@@ -458,7 +460,7 @@ namespace format {
minWidth = nth_argument<*spec.minWidth>(std::forward<Args>(args)...);
}
optional_int<std::size_t> precision = spec.precision;
- if constexpr (spec.precisionAsArg)
+ if constexpr (spec.flags.precisionAsArg)
{
using Arg = std::decay_t<nth_type<*spec.precision, Args...>>;
static_assert(std::unsigned_integral<Arg>, "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<char>(static_cast<unsigned char>(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<pointer T>
struct formatter<T> {
- 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<std::uintptr_t>;
static constexpr void format(const format_output auto& out, const std::remove_pointer_t<T>* t, format_specifier spec, optional_int<std::size_t> minWidth, optional_int<std::size_t>)
{
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<std::nullptr_t> {
static constexpr void format(const format_output auto& out, std::nullptr_t, format_specifier spec, optional_int<std::size_t> minWidth, optional_int<std::size_t>)
{
- 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<std::size_t> minWidth = spec.minWidth;
- if (spec.widthAsArg)
+ if (spec.flags.widthAsArg)
{
minWidth = indexArgs[*minWidth];
assert(minWidth);
}
optional_int<std::size_t> precision = spec.precision;
- if (spec.precisionAsArg)
+ if (spec.flags.precisionAsArg)
{
precision = indexArgs[*precision];
assert(precision);