| 879 | // separator if necessary. |
| 880 | template <typename UInt, typename Char, typename F> |
| 881 | inline Char* format_decimal(Char* buffer, UInt value, int num_digits, |
| 882 | F add_thousands_sep) { |
| 883 | FMT_ASSERT(num_digits >= 0, "invalid digit count"); |
| 884 | buffer += num_digits; |
| 885 | Char* end = buffer; |
| 886 | while (value >= 100) { |
| 887 | // Integer division is slow so do it for a group of two digits instead |
| 888 | // of for every digit. The idea comes from the talk by Alexandrescu |
| 889 | // "Three Optimization Tips for C++". See speed-test for a comparison. |
| 890 | auto index = static_cast<unsigned>((value % 100) * 2); |
| 891 | value /= 100; |
| 892 | *--buffer = static_cast<Char>(data::digits[index + 1]); |
| 893 | add_thousands_sep(buffer); |
| 894 | *--buffer = static_cast<Char>(data::digits[index]); |
| 895 | add_thousands_sep(buffer); |
| 896 | } |
| 897 | if (value < 10) { |
| 898 | *--buffer = static_cast<Char>('0' + value); |
| 899 | return end; |
| 900 | } |
| 901 | auto index = static_cast<unsigned>(value * 2); |
| 902 | *--buffer = static_cast<Char>(data::digits[index + 1]); |
| 903 | add_thousands_sep(buffer); |
| 904 | *--buffer = static_cast<Char>(data::digits[index]); |
| 905 | return end; |
| 906 | } |
| 907 | |
| 908 | template <typename Int> constexpr int digits10() FMT_NOEXCEPT { |
| 909 | return std::numeric_limits<Int>::digits10; |
no outgoing calls
no test coverage detected