diff --git a/src/util/format/builder.cpp b/src/util/format/builder.cpp index 85ddc62..bed899a 100644 --- a/src/util/format/builder.cpp +++ b/src/util/format/builder.cpp @@ -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(value), width, align, fill, sign, isNegative); +} + void Builder::putF64(double number, uint8_t precision) const { precision = std::min(precision, static_cast(std::numeric_limits::digits10)); diff --git a/src/util/format/builder.h b/src/util/format/builder.h index aaeded3..a6848ce 100644 --- a/src/util/format/builder.h +++ b/src/util/format/builder.h @@ -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; diff --git a/src/util/format/formatter.h b/src/util/format/formatter.h index 8c602c3..def836c 100644 --- a/src/util/format/formatter.h +++ b/src/util/format/formatter.h @@ -92,10 +92,12 @@ struct Formatter { void format(Builder& builder, T value) const { if (std::is_signed_v) { - builder.putI64(value); + builder.putI64( + value, specifier.width, specifier.align, specifier.fill, specifier.sign); } if (std::is_unsigned_v) { - builder.putU64(value); + builder.putU64( + value, specifier.width, specifier.align, specifier.fill, specifier.sign); } } };