diff --git a/format.cc b/format.cc index 8e23701d..0ecc0b53 100644 --- a/format.cc +++ b/format.cc @@ -582,6 +582,9 @@ const char fmt::internal::BasicData::DIGITS[] = "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"; +template +const uint16_t *fmt::internal::BasicData::U16_DIGITS = (const uint16_t*)DIGITS; + #define FMT_POWERS_OF_10(factor) \ factor * 10, \ factor * 100, \ diff --git a/format.h b/format.h index bde8878c..0ca12d2d 100644 --- a/format.h +++ b/format.h @@ -726,6 +726,7 @@ struct BasicData { static const uint32_t POWERS_OF_10_32[]; static const uint64_t POWERS_OF_10_64[]; static const char DIGITS[]; + static const uint16_t* U16_DIGITS; }; typedef BasicData<> Data; @@ -2802,30 +2803,28 @@ class FormatInt { private: // Buffer should be large enough to hold all digits (digits10 + 1), // a sign and a null character. - enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3}; + enum {BUFFER_SIZE = std::numeric_limits::digits10 + 4}; mutable char buffer_[BUFFER_SIZE]; char *str_; // Formats value in reverse and returns the number of digits. char *format_decimal(ULongLong value) { - char *buffer_end = buffer_ + BUFFER_SIZE - 1; + uint16_t* buffer_end = (uint16_t*)(buffer_ + BUFFER_SIZE - 1); while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = static_cast((value % 100) * 2); + unsigned index = value%100; value /= 100; - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; + *--buffer_end = internal::Data::U16_DIGITS[index]; } - if (value < 10) { - *--buffer_end = static_cast('0' + value); - return buffer_end; + + *--buffer_end = internal::Data::U16_DIGITS[value]; + if ( value < 10 ) { + return ((char*)buffer_end)+1; + } else { + return ((char*)buffer_end); } - unsigned index = static_cast(value * 2); - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; - return buffer_end; } void FormatSigned(LongLong value) {