Commit a65542bd authored by Gregory Czajkowski's avatar Gregory Czajkowski Committed by Victor Zverovich

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;
parent 75e8fea0
......@@ -400,7 +400,7 @@ void fmt::BasicFormatter<Char>::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 +519,7 @@ void fmt::BasicFormatter<Char>::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,12 +537,15 @@ void fmt::BasicFormatter<Char>::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<int>(value);
if (*s++ != '}')
throw FormatError("unmatched '{' in format");
--num_open_braces_;
......@@ -578,6 +581,9 @@ void fmt::BasicFormatter<Char>::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;
......
......@@ -189,6 +189,9 @@ struct SignedIntTraits {
template <>
struct IntTraits<int> : SignedIntTraits<int, unsigned> {};
template <>
struct IntTraits<uint32_t> : SignedIntTraits<uint32_t, unsigned> {};
template <>
struct IntTraits<long> : SignedIntTraits<long, unsigned long> {};
......@@ -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 <typename Char>
class BasicFormatter;
......@@ -811,7 +815,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 +850,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 +870,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 +1154,7 @@ class FormatInt {
enum {BUFFER_SIZE = std::numeric_limits<uint64_t>::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 +1189,7 @@ class FormatInt {
*--str_ = '-';
}
explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {}
explicit FormatInt(uint64_t value) : str_(FormatDecimal(value)) {}
const char *c_str() const { return str_; }
std::string str() const { return str_; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment