diff --git a/format.cc b/format.cc index caddd3ad..f72cbbcd 100644 --- a/format.cc +++ b/format.cc @@ -160,6 +160,12 @@ void fmt::BasicWriter::FormatDecimal( buffer[0] = internal::DIGITS[index]; } +template +void fmt::BasicWriter::FormatDecimal( + CharPtr buffer, unsigned long long value, unsigned num_digits) { + return fmt::BasicWriter::FormatDecimal(buffer, static_cast(value), num_digits); +} + template typename fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( @@ -400,7 +406,7 @@ void fmt::BasicFormatter::CheckSign(const Char *&s, const Arg &arg) { ReportError(s, Format("format specifier '{0}' requires numeric argument") << *s); } - if (arg.type == UINT || arg.type == ULONG) { + if (arg.type == UINT || arg.type == ULONG || arg.type == ULLONG) { ReportError(s, Format("format specifier '{0}' requires signed argument") << *s); } @@ -519,7 +525,7 @@ void fmt::BasicFormatter::DoFormat() { ++s; ++num_open_braces_; const Arg &precision_arg = ParseArgIndex(s); - unsigned long value = 0; + unsigned long long value = 0; switch (precision_arg.type) { case INT: if (precision_arg.int_value < 0) @@ -537,6 +543,9 @@ void fmt::BasicFormatter::DoFormat() { case ULONG: value = precision_arg.ulong_value; break; + case ULLONG: + value = precision_arg.ulong_long_value; + break; default: ReportError(s, "precision is not integer"); } @@ -578,6 +587,9 @@ void fmt::BasicFormatter::DoFormat() { case ULONG: writer.FormatInt(arg.ulong_value, spec); break; + case ULLONG: + writer.FormatInt(arg.ulong_long_value, spec); + break; case DOUBLE: writer.FormatDouble(arg.double_value, spec, precision); break; @@ -655,6 +667,9 @@ template fmt::BasicWriter::CharPtr template void fmt::BasicWriter::FormatDecimal( CharPtr buffer, uint64_t value, unsigned num_digits); +template void fmt::BasicWriter::FormatDecimal( + CharPtr buffer, unsigned long long value, unsigned num_digits); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); @@ -687,6 +702,9 @@ template fmt::BasicWriter::CharPtr template void fmt::BasicWriter::FormatDecimal( CharPtr buffer, uint64_t value, unsigned num_digits); +template void fmt::BasicWriter::FormatDecimal( + CharPtr buffer, unsigned long long value, unsigned num_digits); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); diff --git a/format.h b/format.h index d7c2b9f4..618484eb 100644 --- a/format.h +++ b/format.h @@ -189,6 +189,9 @@ struct SignedIntTraits { template <> struct IntTraits : SignedIntTraits {}; +template <> +struct IntTraits : SignedIntTraits {}; + template <> struct IntTraits : SignedIntTraits {}; @@ -444,6 +447,7 @@ DEFINE_INT_FORMATTERS(int) DEFINE_INT_FORMATTERS(long) DEFINE_INT_FORMATTERS(unsigned) DEFINE_INT_FORMATTERS(unsigned long) +DEFINE_INT_FORMATTERS(unsigned long long) template class BasicFormatter; @@ -500,6 +504,9 @@ class BasicWriter { static void FormatDecimal( CharPtr buffer, uint64_t value, unsigned num_digits); + static void FormatDecimal( + CharPtr buffer, unsigned long long value, unsigned num_digits); + static CharPtr FillPadding(CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill); @@ -811,7 +818,7 @@ class BasicFormatter { enum Type { // Numeric types should go first. - INT, UINT, LONG, ULONG, DOUBLE, LONG_DOUBLE, + INT, UINT, LONG, ULONG, ULLONG, DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, CHAR, STRING, WSTRING, POINTER, CUSTOM }; @@ -846,6 +853,7 @@ class BasicFormatter { double double_value; long long_value; unsigned long ulong_value; + unsigned long long ulong_long_value; long double long_double_value; const void *pointer_value; struct { @@ -865,6 +873,7 @@ class BasicFormatter { Arg(unsigned value) : type(UINT), uint_value(value), formatter(0) {} Arg(long value) : type(LONG), long_value(value), formatter(0) {} Arg(unsigned long value) : type(ULONG), ulong_value(value), formatter(0) {} + Arg(unsigned long long value) : type(ULLONG), ulong_long_value(value), formatter(0) {} Arg(float value) : type(DOUBLE), double_value(value), formatter(0) {} Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {} Arg(long double value) @@ -1148,7 +1157,7 @@ class FormatInt { enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3}; char buffer_[BUFFER_SIZE]; char *str_; - + // Formats value in reverse and returns the number of digits. char *FormatDecimal(uint64_t value) { char *buffer_end = buffer_ + BUFFER_SIZE; @@ -1183,6 +1192,8 @@ class FormatInt { *--str_ = '-'; } explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {} + explicit FormatInt(uint64_t value) : str_(FormatDecimal(value)) {} + explicit FormatInt(unsigned long long value) : str_(FormatDecimal(value)) {} const char *c_str() const { return str_; } std::string str() const { return str_; }