From 225d4f7032076548c73455fb2fd9c7d5cd030f16 Mon Sep 17 00:00:00 2001 From: Gregory Czajkowski Date: Mon, 18 Nov 2013 22:58:39 -0800 Subject: [PATCH] add support for unsigned long long Want to be able to format the following without any casting std::cout << fmt::str(fmt::Format("{:x}") << 0xAEull) << std::endl; std::cout << fmt::str(fmt::Format("{:x}") << 0xAEul) << std::endl; std::cout << fmt::str(fmt::Format("{:x}") << uint64_t(0xae)) << std::endl; --- format.cc | 12 +++++++++--- format.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/format.cc b/format.cc index f58ef6187eca..7eccd4f0ff29 100644 --- a/format.cc +++ b/format.cc @@ -400,7 +400,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); } @@ -520,7 +520,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) @@ -538,12 +538,15 @@ 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"); } if (value > INT_MAX) ReportError(s, "number is too big in format"); - precision = value; + precision = static_cast(value); if (*s++ != '}') throw FormatError("unmatched '{' in format"); --num_open_braces_; @@ -579,6 +582,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; diff --git a/format.h b/format.h index da01030218a4..2160e4acc6f7 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 {}; @@ -451,6 +454,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; @@ -819,7 +823,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 }; @@ -854,6 +858,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 { @@ -873,6 +878,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) @@ -1151,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; @@ -1186,6 +1192,7 @@ class FormatInt { *--str_ = '-'; } explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {} + explicit FormatInt(uint64_t value) : str_(FormatDecimal(value)) {} inline const char *c_str() const { return str_; } inline std::string str() const { return str_; }