Util: Implement some integral specifiers
This commit is contained in:
@@ -28,6 +28,64 @@ void Builder::putLiteral(std::string_view literal)
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::putU64(size_t value, size_t width, Align align, char fill, Sign sign, bool isNegative) const
|
||||
{
|
||||
std::string string = (std::stringstream {} << value).str();
|
||||
|
||||
printf("sign {%c}\n", (char)sign);
|
||||
// Sign
|
||||
switch (sign) {
|
||||
case Sign::None:
|
||||
case Sign::Negative:
|
||||
if (isNegative) {
|
||||
string.insert(0, 1, '-');
|
||||
}
|
||||
break;
|
||||
case Sign::Both:
|
||||
string.insert(0, 1, (isNegative) ? '-' : '+');
|
||||
break;
|
||||
case Sign::Space:
|
||||
string.insert(0, 1, (isNegative) ? '-' : ' ');
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
};
|
||||
|
||||
size_t length = string.length();
|
||||
if (width < length) {
|
||||
m_builder.write(string.data(), length);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (align) {
|
||||
case Align::Left:
|
||||
m_builder.write(string.data(), length);
|
||||
m_builder << std::string(width - length, fill);
|
||||
break;
|
||||
case Align::Center: {
|
||||
size_t half = (width - length) / 2;
|
||||
m_builder << std::string(half, fill);
|
||||
m_builder.write(string.data(), length);
|
||||
m_builder << std::string(width - half - length, fill);
|
||||
break;
|
||||
}
|
||||
case Align::None:
|
||||
case Align::Right:
|
||||
m_builder << std::string(width - length, fill);
|
||||
m_builder.write(string.data(), length);
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
};
|
||||
}
|
||||
|
||||
void Builder::putI64(int64_t value, size_t width, Align align, char fill, Sign sign) const
|
||||
{
|
||||
auto const isNegative = value < 0;
|
||||
value = isNegative ? -value : value;
|
||||
putU64(static_cast<uint64_t>(value), width, align, fill, sign, isNegative);
|
||||
}
|
||||
|
||||
void Builder::putF64(double number, uint8_t precision) const
|
||||
{
|
||||
precision = std::min(precision, static_cast<uint8_t>(std::numeric_limits<double>::digits10));
|
||||
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
|
||||
void putLiteral(std::string_view literal);
|
||||
|
||||
void putI64(int64_t number) const { m_builder << number; } // long int
|
||||
void putU64(size_t number) const { m_builder << number; } // long unsigned int
|
||||
void putU64(size_t value, size_t width = 0, Align align = Align::Right, char fill = ' ', Sign sign = Sign::Negative, bool isNegative = false) const;
|
||||
void putI64(int64_t value, size_t width = 0, Align align = Align::Right, char fill = ' ', Sign sign = Sign::Negative) const;
|
||||
void putF64(double number, uint8_t precision = 6) const;
|
||||
void putCharacter(char character) const { m_builder.write(&character, 1); }
|
||||
void putString(std::string_view string, size_t width = 0, Align align = Align::Left, char fill = ' ') const;
|
||||
|
||||
@@ -92,10 +92,12 @@ struct Formatter<T> {
|
||||
void format(Builder& builder, T value) const
|
||||
{
|
||||
if (std::is_signed_v<T>) {
|
||||
builder.putI64(value);
|
||||
builder.putI64(
|
||||
value, specifier.width, specifier.align, specifier.fill, specifier.sign);
|
||||
}
|
||||
if (std::is_unsigned_v<T>) {
|
||||
builder.putU64(value);
|
||||
builder.putU64(
|
||||
value, specifier.width, specifier.align, specifier.fill, specifier.sign);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user