xref: /aosp_15_r20/external/armnn/third-party/fmt/format-inl.h (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker // Formatting library for C++ - implementation
2*89c4ff92SAndroid Build Coastguard Worker //
3*89c4ff92SAndroid Build Coastguard Worker // Copyright (c) 2012 - 2016, Victor Zverovich
4*89c4ff92SAndroid Build Coastguard Worker // All rights reserved.
5*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
6*89c4ff92SAndroid Build Coastguard Worker //
7*89c4ff92SAndroid Build Coastguard Worker // For the license information refer to format.h.
8*89c4ff92SAndroid Build Coastguard Worker 
9*89c4ff92SAndroid Build Coastguard Worker #ifndef FMT_FORMAT_INL_H_
10*89c4ff92SAndroid Build Coastguard Worker #define FMT_FORMAT_INL_H_
11*89c4ff92SAndroid Build Coastguard Worker 
12*89c4ff92SAndroid Build Coastguard Worker #include <cassert>
13*89c4ff92SAndroid Build Coastguard Worker #include <cctype>
14*89c4ff92SAndroid Build Coastguard Worker #include <climits>
15*89c4ff92SAndroid Build Coastguard Worker #include <cmath>
16*89c4ff92SAndroid Build Coastguard Worker #include <cstdarg>
17*89c4ff92SAndroid Build Coastguard Worker #include <cstring>  // for std::memmove
18*89c4ff92SAndroid Build Coastguard Worker #include <cwchar>
19*89c4ff92SAndroid Build Coastguard Worker #include <exception>
20*89c4ff92SAndroid Build Coastguard Worker 
21*89c4ff92SAndroid Build Coastguard Worker #include "format.h"
22*89c4ff92SAndroid Build Coastguard Worker #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
23*89c4ff92SAndroid Build Coastguard Worker #  include <locale>
24*89c4ff92SAndroid Build Coastguard Worker #endif
25*89c4ff92SAndroid Build Coastguard Worker 
26*89c4ff92SAndroid Build Coastguard Worker #ifdef _WIN32
27*89c4ff92SAndroid Build Coastguard Worker #  if !defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN)
28*89c4ff92SAndroid Build Coastguard Worker #    define NOMINMAX
29*89c4ff92SAndroid Build Coastguard Worker #    define WIN32_LEAN_AND_MEAN
30*89c4ff92SAndroid Build Coastguard Worker #    include <windows.h>
31*89c4ff92SAndroid Build Coastguard Worker #    undef WIN32_LEAN_AND_MEAN
32*89c4ff92SAndroid Build Coastguard Worker #    undef NOMINMAX
33*89c4ff92SAndroid Build Coastguard Worker #  else
34*89c4ff92SAndroid Build Coastguard Worker #    include <windows.h>
35*89c4ff92SAndroid Build Coastguard Worker #  endif
36*89c4ff92SAndroid Build Coastguard Worker #  include <io.h>
37*89c4ff92SAndroid Build Coastguard Worker #endif
38*89c4ff92SAndroid Build Coastguard Worker 
39*89c4ff92SAndroid Build Coastguard Worker #ifdef _MSC_VER
40*89c4ff92SAndroid Build Coastguard Worker #  pragma warning(push)
41*89c4ff92SAndroid Build Coastguard Worker #  pragma warning(disable : 4702)  // unreachable code
42*89c4ff92SAndroid Build Coastguard Worker #endif
43*89c4ff92SAndroid Build Coastguard Worker 
44*89c4ff92SAndroid Build Coastguard Worker // Dummy implementations of strerror_r and strerror_s called if corresponding
45*89c4ff92SAndroid Build Coastguard Worker // system functions are not available.
strerror_r(int,char *,...)46*89c4ff92SAndroid Build Coastguard Worker inline fmt::detail::null<> strerror_r(int, char*, ...) { return {}; }
strerror_s(char *,size_t,...)47*89c4ff92SAndroid Build Coastguard Worker inline fmt::detail::null<> strerror_s(char*, size_t, ...) { return {}; }
48*89c4ff92SAndroid Build Coastguard Worker 
49*89c4ff92SAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
50*89c4ff92SAndroid Build Coastguard Worker namespace detail {
51*89c4ff92SAndroid Build Coastguard Worker 
assert_fail(const char * file,int line,const char * message)52*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
53*89c4ff92SAndroid Build Coastguard Worker   // Use unchecked std::fprintf to avoid triggering another assertion when
54*89c4ff92SAndroid Build Coastguard Worker   // writing to stderr fails
55*89c4ff92SAndroid Build Coastguard Worker   std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
56*89c4ff92SAndroid Build Coastguard Worker   // Chosen instead of std::abort to satisfy Clang in CUDA mode during device
57*89c4ff92SAndroid Build Coastguard Worker   // code pass.
58*89c4ff92SAndroid Build Coastguard Worker   std::terminate();
59*89c4ff92SAndroid Build Coastguard Worker }
60*89c4ff92SAndroid Build Coastguard Worker 
61*89c4ff92SAndroid Build Coastguard Worker #ifndef _MSC_VER
62*89c4ff92SAndroid Build Coastguard Worker #  define FMT_SNPRINTF snprintf
63*89c4ff92SAndroid Build Coastguard Worker #else  // _MSC_VER
fmt_snprintf(char * buffer,size_t size,const char * format,...)64*89c4ff92SAndroid Build Coastguard Worker inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) {
65*89c4ff92SAndroid Build Coastguard Worker   va_list args;
66*89c4ff92SAndroid Build Coastguard Worker   va_start(args, format);
67*89c4ff92SAndroid Build Coastguard Worker   int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
68*89c4ff92SAndroid Build Coastguard Worker   va_end(args);
69*89c4ff92SAndroid Build Coastguard Worker   return result;
70*89c4ff92SAndroid Build Coastguard Worker }
71*89c4ff92SAndroid Build Coastguard Worker #  define FMT_SNPRINTF fmt_snprintf
72*89c4ff92SAndroid Build Coastguard Worker #endif  // _MSC_VER
73*89c4ff92SAndroid Build Coastguard Worker 
74*89c4ff92SAndroid Build Coastguard Worker // A portable thread-safe version of strerror.
75*89c4ff92SAndroid Build Coastguard Worker // Sets buffer to point to a string describing the error code.
76*89c4ff92SAndroid Build Coastguard Worker // This can be either a pointer to a string stored in buffer,
77*89c4ff92SAndroid Build Coastguard Worker // or a pointer to some static immutable string.
78*89c4ff92SAndroid Build Coastguard Worker // Returns one of the following values:
79*89c4ff92SAndroid Build Coastguard Worker //   0      - success
80*89c4ff92SAndroid Build Coastguard Worker //   ERANGE - buffer is not large enough to store the error message
81*89c4ff92SAndroid Build Coastguard Worker //   other  - failure
82*89c4ff92SAndroid Build Coastguard Worker // Buffer should be at least of size 1.
safe_strerror(int error_code,char * & buffer,size_t buffer_size)83*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC int safe_strerror(int error_code, char*& buffer,
84*89c4ff92SAndroid Build Coastguard Worker                            size_t buffer_size) FMT_NOEXCEPT {
85*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer");
86*89c4ff92SAndroid Build Coastguard Worker 
87*89c4ff92SAndroid Build Coastguard Worker   class dispatcher {
88*89c4ff92SAndroid Build Coastguard Worker    private:
89*89c4ff92SAndroid Build Coastguard Worker     int error_code_;
90*89c4ff92SAndroid Build Coastguard Worker     char*& buffer_;
91*89c4ff92SAndroid Build Coastguard Worker     size_t buffer_size_;
92*89c4ff92SAndroid Build Coastguard Worker 
93*89c4ff92SAndroid Build Coastguard Worker     // A noop assignment operator to avoid bogus warnings.
94*89c4ff92SAndroid Build Coastguard Worker     void operator=(const dispatcher&) {}
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker     // Handle the result of XSI-compliant version of strerror_r.
97*89c4ff92SAndroid Build Coastguard Worker     int handle(int result) {
98*89c4ff92SAndroid Build Coastguard Worker       // glibc versions before 2.13 return result in errno.
99*89c4ff92SAndroid Build Coastguard Worker       return result == -1 ? errno : result;
100*89c4ff92SAndroid Build Coastguard Worker     }
101*89c4ff92SAndroid Build Coastguard Worker 
102*89c4ff92SAndroid Build Coastguard Worker     // Handle the result of GNU-specific version of strerror_r.
103*89c4ff92SAndroid Build Coastguard Worker     FMT_MAYBE_UNUSED
104*89c4ff92SAndroid Build Coastguard Worker     int handle(char* message) {
105*89c4ff92SAndroid Build Coastguard Worker       // If the buffer is full then the message is probably truncated.
106*89c4ff92SAndroid Build Coastguard Worker       if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
107*89c4ff92SAndroid Build Coastguard Worker         return ERANGE;
108*89c4ff92SAndroid Build Coastguard Worker       buffer_ = message;
109*89c4ff92SAndroid Build Coastguard Worker       return 0;
110*89c4ff92SAndroid Build Coastguard Worker     }
111*89c4ff92SAndroid Build Coastguard Worker 
112*89c4ff92SAndroid Build Coastguard Worker     // Handle the case when strerror_r is not available.
113*89c4ff92SAndroid Build Coastguard Worker     FMT_MAYBE_UNUSED
114*89c4ff92SAndroid Build Coastguard Worker     int handle(detail::null<>) {
115*89c4ff92SAndroid Build Coastguard Worker       return fallback(strerror_s(buffer_, buffer_size_, error_code_));
116*89c4ff92SAndroid Build Coastguard Worker     }
117*89c4ff92SAndroid Build Coastguard Worker 
118*89c4ff92SAndroid Build Coastguard Worker     // Fallback to strerror_s when strerror_r is not available.
119*89c4ff92SAndroid Build Coastguard Worker     FMT_MAYBE_UNUSED
120*89c4ff92SAndroid Build Coastguard Worker     int fallback(int result) {
121*89c4ff92SAndroid Build Coastguard Worker       // If the buffer is full then the message is probably truncated.
122*89c4ff92SAndroid Build Coastguard Worker       return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
123*89c4ff92SAndroid Build Coastguard Worker                                                                 : result;
124*89c4ff92SAndroid Build Coastguard Worker     }
125*89c4ff92SAndroid Build Coastguard Worker 
126*89c4ff92SAndroid Build Coastguard Worker #if !FMT_MSC_VER
127*89c4ff92SAndroid Build Coastguard Worker     // Fallback to strerror if strerror_r and strerror_s are not available.
128*89c4ff92SAndroid Build Coastguard Worker     int fallback(detail::null<>) {
129*89c4ff92SAndroid Build Coastguard Worker       errno = 0;
130*89c4ff92SAndroid Build Coastguard Worker       buffer_ = strerror(error_code_);
131*89c4ff92SAndroid Build Coastguard Worker       return errno;
132*89c4ff92SAndroid Build Coastguard Worker     }
133*89c4ff92SAndroid Build Coastguard Worker #endif
134*89c4ff92SAndroid Build Coastguard Worker 
135*89c4ff92SAndroid Build Coastguard Worker    public:
136*89c4ff92SAndroid Build Coastguard Worker     dispatcher(int err_code, char*& buf, size_t buf_size)
137*89c4ff92SAndroid Build Coastguard Worker         : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
138*89c4ff92SAndroid Build Coastguard Worker 
139*89c4ff92SAndroid Build Coastguard Worker     int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
140*89c4ff92SAndroid Build Coastguard Worker   };
141*89c4ff92SAndroid Build Coastguard Worker   return dispatcher(error_code, buffer, buffer_size).run();
142*89c4ff92SAndroid Build Coastguard Worker }
143*89c4ff92SAndroid Build Coastguard Worker 
format_error_code(detail::buffer<char> & out,int error_code,string_view message)144*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
145*89c4ff92SAndroid Build Coastguard Worker                                 string_view message) FMT_NOEXCEPT {
146*89c4ff92SAndroid Build Coastguard Worker   // Report error code making sure that the output fits into
147*89c4ff92SAndroid Build Coastguard Worker   // inline_buffer_size to avoid dynamic memory allocation and potential
148*89c4ff92SAndroid Build Coastguard Worker   // bad_alloc.
149*89c4ff92SAndroid Build Coastguard Worker   out.try_resize(0);
150*89c4ff92SAndroid Build Coastguard Worker   static const char SEP[] = ": ";
151*89c4ff92SAndroid Build Coastguard Worker   static const char ERROR_STR[] = "error ";
152*89c4ff92SAndroid Build Coastguard Worker   // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
153*89c4ff92SAndroid Build Coastguard Worker   size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
154*89c4ff92SAndroid Build Coastguard Worker   auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
155*89c4ff92SAndroid Build Coastguard Worker   if (detail::is_negative(error_code)) {
156*89c4ff92SAndroid Build Coastguard Worker     abs_value = 0 - abs_value;
157*89c4ff92SAndroid Build Coastguard Worker     ++error_code_size;
158*89c4ff92SAndroid Build Coastguard Worker   }
159*89c4ff92SAndroid Build Coastguard Worker   error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
160*89c4ff92SAndroid Build Coastguard Worker   auto it = buffer_appender<char>(out);
161*89c4ff92SAndroid Build Coastguard Worker   if (message.size() <= inline_buffer_size - error_code_size)
162*89c4ff92SAndroid Build Coastguard Worker     format_to(it, "{}{}", message, SEP);
163*89c4ff92SAndroid Build Coastguard Worker   format_to(it, "{}{}", ERROR_STR, error_code);
164*89c4ff92SAndroid Build Coastguard Worker   assert(out.size() <= inline_buffer_size);
165*89c4ff92SAndroid Build Coastguard Worker }
166*89c4ff92SAndroid Build Coastguard Worker 
report_error(format_func func,int error_code,string_view message)167*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void report_error(format_func func, int error_code,
168*89c4ff92SAndroid Build Coastguard Worker                            string_view message) FMT_NOEXCEPT {
169*89c4ff92SAndroid Build Coastguard Worker   memory_buffer full_message;
170*89c4ff92SAndroid Build Coastguard Worker   func(full_message, error_code, message);
171*89c4ff92SAndroid Build Coastguard Worker   // Don't use fwrite_fully because the latter may throw.
172*89c4ff92SAndroid Build Coastguard Worker   (void)std::fwrite(full_message.data(), full_message.size(), 1, stderr);
173*89c4ff92SAndroid Build Coastguard Worker   std::fputc('\n', stderr);
174*89c4ff92SAndroid Build Coastguard Worker }
175*89c4ff92SAndroid Build Coastguard Worker 
176*89c4ff92SAndroid Build Coastguard Worker // A wrapper around fwrite that throws on error.
fwrite_fully(const void * ptr,size_t size,size_t count,FILE * stream)177*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void fwrite_fully(const void* ptr, size_t size, size_t count,
178*89c4ff92SAndroid Build Coastguard Worker                            FILE* stream) {
179*89c4ff92SAndroid Build Coastguard Worker   size_t written = std::fwrite(ptr, size, count, stream);
180*89c4ff92SAndroid Build Coastguard Worker   if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
181*89c4ff92SAndroid Build Coastguard Worker }
182*89c4ff92SAndroid Build Coastguard Worker }  // namespace detail
183*89c4ff92SAndroid Build Coastguard Worker 
184*89c4ff92SAndroid Build Coastguard Worker #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
185*89c4ff92SAndroid Build Coastguard Worker namespace detail {
186*89c4ff92SAndroid Build Coastguard Worker 
187*89c4ff92SAndroid Build Coastguard Worker template <typename Locale>
locale_ref(const Locale & loc)188*89c4ff92SAndroid Build Coastguard Worker locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
189*89c4ff92SAndroid Build Coastguard Worker   static_assert(std::is_same<Locale, std::locale>::value, "");
190*89c4ff92SAndroid Build Coastguard Worker }
191*89c4ff92SAndroid Build Coastguard Worker 
get()192*89c4ff92SAndroid Build Coastguard Worker template <typename Locale> Locale locale_ref::get() const {
193*89c4ff92SAndroid Build Coastguard Worker   static_assert(std::is_same<Locale, std::locale>::value, "");
194*89c4ff92SAndroid Build Coastguard Worker   return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
195*89c4ff92SAndroid Build Coastguard Worker }
196*89c4ff92SAndroid Build Coastguard Worker 
grouping_impl(locale_ref loc)197*89c4ff92SAndroid Build Coastguard Worker template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref loc) {
198*89c4ff92SAndroid Build Coastguard Worker   return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()).grouping();
199*89c4ff92SAndroid Build Coastguard Worker }
thousands_sep_impl(locale_ref loc)200*89c4ff92SAndroid Build Coastguard Worker template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
201*89c4ff92SAndroid Build Coastguard Worker   return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
202*89c4ff92SAndroid Build Coastguard Worker       .thousands_sep();
203*89c4ff92SAndroid Build Coastguard Worker }
decimal_point_impl(locale_ref loc)204*89c4ff92SAndroid Build Coastguard Worker template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
205*89c4ff92SAndroid Build Coastguard Worker   return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
206*89c4ff92SAndroid Build Coastguard Worker       .decimal_point();
207*89c4ff92SAndroid Build Coastguard Worker }
208*89c4ff92SAndroid Build Coastguard Worker }  // namespace detail
209*89c4ff92SAndroid Build Coastguard Worker #else
210*89c4ff92SAndroid Build Coastguard Worker template <typename Char>
grouping_impl(locale_ref)211*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC std::string detail::grouping_impl(locale_ref) {
212*89c4ff92SAndroid Build Coastguard Worker   return "\03";
213*89c4ff92SAndroid Build Coastguard Worker }
thousands_sep_impl(locale_ref)214*89c4ff92SAndroid Build Coastguard Worker template <typename Char> FMT_FUNC Char detail::thousands_sep_impl(locale_ref) {
215*89c4ff92SAndroid Build Coastguard Worker   return FMT_STATIC_THOUSANDS_SEPARATOR;
216*89c4ff92SAndroid Build Coastguard Worker }
decimal_point_impl(locale_ref)217*89c4ff92SAndroid Build Coastguard Worker template <typename Char> FMT_FUNC Char detail::decimal_point_impl(locale_ref) {
218*89c4ff92SAndroid Build Coastguard Worker   return '.';
219*89c4ff92SAndroid Build Coastguard Worker }
220*89c4ff92SAndroid Build Coastguard Worker #endif
221*89c4ff92SAndroid Build Coastguard Worker 
222*89c4ff92SAndroid Build Coastguard Worker FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default;
223*89c4ff92SAndroid Build Coastguard Worker FMT_API FMT_FUNC system_error::~system_error() FMT_NOEXCEPT = default;
224*89c4ff92SAndroid Build Coastguard Worker 
init(int err_code,string_view format_str,format_args args)225*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void system_error::init(int err_code, string_view format_str,
226*89c4ff92SAndroid Build Coastguard Worker                                  format_args args) {
227*89c4ff92SAndroid Build Coastguard Worker   error_code_ = err_code;
228*89c4ff92SAndroid Build Coastguard Worker   memory_buffer buffer;
229*89c4ff92SAndroid Build Coastguard Worker   format_system_error(buffer, err_code, vformat(format_str, args));
230*89c4ff92SAndroid Build Coastguard Worker   std::runtime_error& base = *this;
231*89c4ff92SAndroid Build Coastguard Worker   base = std::runtime_error(to_string(buffer));
232*89c4ff92SAndroid Build Coastguard Worker }
233*89c4ff92SAndroid Build Coastguard Worker 
234*89c4ff92SAndroid Build Coastguard Worker namespace detail {
235*89c4ff92SAndroid Build Coastguard Worker 
236*89c4ff92SAndroid Build Coastguard Worker template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) {
237*89c4ff92SAndroid Build Coastguard Worker   // fallback_uintptr is always stored in little endian.
238*89c4ff92SAndroid Build Coastguard Worker   int i = static_cast<int>(sizeof(void*)) - 1;
239*89c4ff92SAndroid Build Coastguard Worker   while (i > 0 && n.value[i] == 0) --i;
240*89c4ff92SAndroid Build Coastguard Worker   auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
241*89c4ff92SAndroid Build Coastguard Worker   return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1;
242*89c4ff92SAndroid Build Coastguard Worker }
243*89c4ff92SAndroid Build Coastguard Worker 
244*89c4ff92SAndroid Build Coastguard Worker template <typename T>
245*89c4ff92SAndroid Build Coastguard Worker const typename basic_data<T>::digit_pair basic_data<T>::digits[] = {
246*89c4ff92SAndroid Build Coastguard Worker     {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
247*89c4ff92SAndroid Build Coastguard Worker     {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
248*89c4ff92SAndroid Build Coastguard Worker     {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
249*89c4ff92SAndroid Build Coastguard Worker     {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'},
250*89c4ff92SAndroid Build Coastguard Worker     {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
251*89c4ff92SAndroid Build Coastguard Worker     {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'},
252*89c4ff92SAndroid Build Coastguard Worker     {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'},
253*89c4ff92SAndroid Build Coastguard Worker     {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'},
254*89c4ff92SAndroid Build Coastguard Worker     {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'},
255*89c4ff92SAndroid Build Coastguard Worker     {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
256*89c4ff92SAndroid Build Coastguard Worker     {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'},
257*89c4ff92SAndroid Build Coastguard Worker     {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'},
258*89c4ff92SAndroid Build Coastguard Worker     {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'},
259*89c4ff92SAndroid Build Coastguard Worker     {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'},
260*89c4ff92SAndroid Build Coastguard Worker     {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
261*89c4ff92SAndroid Build Coastguard Worker     {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'},
262*89c4ff92SAndroid Build Coastguard Worker     {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
263*89c4ff92SAndroid Build Coastguard Worker 
264*89c4ff92SAndroid Build Coastguard Worker template <typename T>
265*89c4ff92SAndroid Build Coastguard Worker const char basic_data<T>::hex_digits[] = "0123456789abcdef";
266*89c4ff92SAndroid Build Coastguard Worker 
267*89c4ff92SAndroid Build Coastguard Worker #define FMT_POWERS_OF_10(factor)                                             \
268*89c4ff92SAndroid Build Coastguard Worker   factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
269*89c4ff92SAndroid Build Coastguard Worker       (factor)*1000000, (factor)*10000000, (factor)*100000000,               \
270*89c4ff92SAndroid Build Coastguard Worker       (factor)*1000000000
271*89c4ff92SAndroid Build Coastguard Worker 
272*89c4ff92SAndroid Build Coastguard Worker template <typename T>
273*89c4ff92SAndroid Build Coastguard Worker const uint64_t basic_data<T>::powers_of_10_64[] = {
274*89c4ff92SAndroid Build Coastguard Worker     1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
275*89c4ff92SAndroid Build Coastguard Worker     10000000000000000000ULL};
276*89c4ff92SAndroid Build Coastguard Worker 
277*89c4ff92SAndroid Build Coastguard Worker template <typename T>
278*89c4ff92SAndroid Build Coastguard Worker const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
279*89c4ff92SAndroid Build Coastguard Worker                                                            FMT_POWERS_OF_10(1)};
280*89c4ff92SAndroid Build Coastguard Worker 
281*89c4ff92SAndroid Build Coastguard Worker template <typename T>
282*89c4ff92SAndroid Build Coastguard Worker const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
283*89c4ff92SAndroid Build Coastguard Worker     0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
284*89c4ff92SAndroid Build Coastguard Worker     10000000000000000000ULL};
285*89c4ff92SAndroid Build Coastguard Worker 
286*89c4ff92SAndroid Build Coastguard Worker // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
287*89c4ff92SAndroid Build Coastguard Worker // These are generated by support/compute-powers.py.
288*89c4ff92SAndroid Build Coastguard Worker template <typename T>
289*89c4ff92SAndroid Build Coastguard Worker const uint64_t basic_data<T>::pow10_significands[] = {
290*89c4ff92SAndroid Build Coastguard Worker     0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
291*89c4ff92SAndroid Build Coastguard Worker     0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
292*89c4ff92SAndroid Build Coastguard Worker     0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
293*89c4ff92SAndroid Build Coastguard Worker     0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
294*89c4ff92SAndroid Build Coastguard Worker     0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
295*89c4ff92SAndroid Build Coastguard Worker     0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
296*89c4ff92SAndroid Build Coastguard Worker     0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
297*89c4ff92SAndroid Build Coastguard Worker     0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
298*89c4ff92SAndroid Build Coastguard Worker     0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
299*89c4ff92SAndroid Build Coastguard Worker     0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
300*89c4ff92SAndroid Build Coastguard Worker     0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
301*89c4ff92SAndroid Build Coastguard Worker     0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
302*89c4ff92SAndroid Build Coastguard Worker     0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
303*89c4ff92SAndroid Build Coastguard Worker     0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
304*89c4ff92SAndroid Build Coastguard Worker     0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
305*89c4ff92SAndroid Build Coastguard Worker     0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
306*89c4ff92SAndroid Build Coastguard Worker     0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
307*89c4ff92SAndroid Build Coastguard Worker     0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
308*89c4ff92SAndroid Build Coastguard Worker     0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
309*89c4ff92SAndroid Build Coastguard Worker     0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
310*89c4ff92SAndroid Build Coastguard Worker     0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
311*89c4ff92SAndroid Build Coastguard Worker     0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
312*89c4ff92SAndroid Build Coastguard Worker     0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
313*89c4ff92SAndroid Build Coastguard Worker     0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
314*89c4ff92SAndroid Build Coastguard Worker     0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
315*89c4ff92SAndroid Build Coastguard Worker     0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
316*89c4ff92SAndroid Build Coastguard Worker     0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
317*89c4ff92SAndroid Build Coastguard Worker     0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
318*89c4ff92SAndroid Build Coastguard Worker     0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
319*89c4ff92SAndroid Build Coastguard Worker };
320*89c4ff92SAndroid Build Coastguard Worker 
321*89c4ff92SAndroid Build Coastguard Worker // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
322*89c4ff92SAndroid Build Coastguard Worker // to significands above.
323*89c4ff92SAndroid Build Coastguard Worker template <typename T>
324*89c4ff92SAndroid Build Coastguard Worker const int16_t basic_data<T>::pow10_exponents[] = {
325*89c4ff92SAndroid Build Coastguard Worker     -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
326*89c4ff92SAndroid Build Coastguard Worker     -927,  -901,  -874,  -847,  -821,  -794,  -768,  -741,  -715,  -688, -661,
327*89c4ff92SAndroid Build Coastguard Worker     -635,  -608,  -582,  -555,  -529,  -502,  -475,  -449,  -422,  -396, -369,
328*89c4ff92SAndroid Build Coastguard Worker     -343,  -316,  -289,  -263,  -236,  -210,  -183,  -157,  -130,  -103, -77,
329*89c4ff92SAndroid Build Coastguard Worker     -50,   -24,   3,     30,    56,    83,    109,   136,   162,   189,  216,
330*89c4ff92SAndroid Build Coastguard Worker     242,   269,   295,   322,   348,   375,   402,   428,   455,   481,  508,
331*89c4ff92SAndroid Build Coastguard Worker     534,   561,   588,   614,   641,   667,   694,   720,   747,   774,  800,
332*89c4ff92SAndroid Build Coastguard Worker     827,   853,   880,   907,   933,   960,   986,   1013,  1039,  1066};
333*89c4ff92SAndroid Build Coastguard Worker 
334*89c4ff92SAndroid Build Coastguard Worker template <typename T>
335*89c4ff92SAndroid Build Coastguard Worker const char basic_data<T>::foreground_color[] = "\x1b[38;2;";
336*89c4ff92SAndroid Build Coastguard Worker template <typename T>
337*89c4ff92SAndroid Build Coastguard Worker const char basic_data<T>::background_color[] = "\x1b[48;2;";
338*89c4ff92SAndroid Build Coastguard Worker template <typename T> const char basic_data<T>::reset_color[] = "\x1b[0m";
339*89c4ff92SAndroid Build Coastguard Worker template <typename T> const wchar_t basic_data<T>::wreset_color[] = L"\x1b[0m";
340*89c4ff92SAndroid Build Coastguard Worker template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};
341*89c4ff92SAndroid Build Coastguard Worker template <typename T>
342*89c4ff92SAndroid Build Coastguard Worker const char basic_data<T>::left_padding_shifts[] = {31, 31, 0, 1, 0};
343*89c4ff92SAndroid Build Coastguard Worker template <typename T>
344*89c4ff92SAndroid Build Coastguard Worker const char basic_data<T>::right_padding_shifts[] = {0, 31, 0, 1, 0};
345*89c4ff92SAndroid Build Coastguard Worker 
346*89c4ff92SAndroid Build Coastguard Worker template <typename T> struct bits {
347*89c4ff92SAndroid Build Coastguard Worker   static FMT_CONSTEXPR_DECL const int value =
348*89c4ff92SAndroid Build Coastguard Worker       static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
349*89c4ff92SAndroid Build Coastguard Worker };
350*89c4ff92SAndroid Build Coastguard Worker 
351*89c4ff92SAndroid Build Coastguard Worker class fp;
352*89c4ff92SAndroid Build Coastguard Worker template <int SHIFT = 0> fp normalize(fp value);
353*89c4ff92SAndroid Build Coastguard Worker 
354*89c4ff92SAndroid Build Coastguard Worker // Lower (upper) boundary is a value half way between a floating-point value
355*89c4ff92SAndroid Build Coastguard Worker // and its predecessor (successor). Boundaries have the same exponent as the
356*89c4ff92SAndroid Build Coastguard Worker // value so only significands are stored.
357*89c4ff92SAndroid Build Coastguard Worker struct boundaries {
358*89c4ff92SAndroid Build Coastguard Worker   uint64_t lower;
359*89c4ff92SAndroid Build Coastguard Worker   uint64_t upper;
360*89c4ff92SAndroid Build Coastguard Worker };
361*89c4ff92SAndroid Build Coastguard Worker 
362*89c4ff92SAndroid Build Coastguard Worker // A handmade floating-point number f * pow(2, e).
363*89c4ff92SAndroid Build Coastguard Worker class fp {
364*89c4ff92SAndroid Build Coastguard Worker  private:
365*89c4ff92SAndroid Build Coastguard Worker   using significand_type = uint64_t;
366*89c4ff92SAndroid Build Coastguard Worker 
367*89c4ff92SAndroid Build Coastguard Worker  public:
368*89c4ff92SAndroid Build Coastguard Worker   significand_type f;
369*89c4ff92SAndroid Build Coastguard Worker   int e;
370*89c4ff92SAndroid Build Coastguard Worker 
371*89c4ff92SAndroid Build Coastguard Worker   // All sizes are in bits.
372*89c4ff92SAndroid Build Coastguard Worker   // Subtract 1 to account for an implicit most significant bit in the
373*89c4ff92SAndroid Build Coastguard Worker   // normalized form.
374*89c4ff92SAndroid Build Coastguard Worker   static FMT_CONSTEXPR_DECL const int double_significand_size =
375*89c4ff92SAndroid Build Coastguard Worker       std::numeric_limits<double>::digits - 1;
376*89c4ff92SAndroid Build Coastguard Worker   static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
377*89c4ff92SAndroid Build Coastguard Worker       1ULL << double_significand_size;
378*89c4ff92SAndroid Build Coastguard Worker   static FMT_CONSTEXPR_DECL const int significand_size =
379*89c4ff92SAndroid Build Coastguard Worker       bits<significand_type>::value;
380*89c4ff92SAndroid Build Coastguard Worker 
fp()381*89c4ff92SAndroid Build Coastguard Worker   fp() : f(0), e(0) {}
fp(uint64_t f_val,int e_val)382*89c4ff92SAndroid Build Coastguard Worker   fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
383*89c4ff92SAndroid Build Coastguard Worker 
384*89c4ff92SAndroid Build Coastguard Worker   // Constructs fp from an IEEE754 double. It is a template to prevent compile
385*89c4ff92SAndroid Build Coastguard Worker   // errors on platforms where double is not IEEE754.
fp(Double d)386*89c4ff92SAndroid Build Coastguard Worker   template <typename Double> explicit fp(Double d) { assign(d); }
387*89c4ff92SAndroid Build Coastguard Worker 
388*89c4ff92SAndroid Build Coastguard Worker   // Assigns d to this and return true iff predecessor is closer than successor.
389*89c4ff92SAndroid Build Coastguard Worker   template <typename Double, FMT_ENABLE_IF(sizeof(Double) == sizeof(uint64_t))>
assign(Double d)390*89c4ff92SAndroid Build Coastguard Worker   bool assign(Double d) {
391*89c4ff92SAndroid Build Coastguard Worker     // Assume double is in the format [sign][exponent][significand].
392*89c4ff92SAndroid Build Coastguard Worker     using limits = std::numeric_limits<Double>;
393*89c4ff92SAndroid Build Coastguard Worker     const int exponent_size =
394*89c4ff92SAndroid Build Coastguard Worker         bits<Double>::value - double_significand_size - 1;  // -1 for sign
395*89c4ff92SAndroid Build Coastguard Worker     const uint64_t significand_mask = implicit_bit - 1;
396*89c4ff92SAndroid Build Coastguard Worker     const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask;
397*89c4ff92SAndroid Build Coastguard Worker     const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
398*89c4ff92SAndroid Build Coastguard Worker     auto u = bit_cast<uint64_t>(d);
399*89c4ff92SAndroid Build Coastguard Worker     f = u & significand_mask;
400*89c4ff92SAndroid Build Coastguard Worker     int biased_e =
401*89c4ff92SAndroid Build Coastguard Worker         static_cast<int>((u & exponent_mask) >> double_significand_size);
402*89c4ff92SAndroid Build Coastguard Worker     // Predecessor is closer if d is a normalized power of 2 (f == 0) other than
403*89c4ff92SAndroid Build Coastguard Worker     // the smallest normalized number (biased_e > 1).
404*89c4ff92SAndroid Build Coastguard Worker     bool is_predecessor_closer = f == 0 && biased_e > 1;
405*89c4ff92SAndroid Build Coastguard Worker     if (biased_e != 0)
406*89c4ff92SAndroid Build Coastguard Worker       f += implicit_bit;
407*89c4ff92SAndroid Build Coastguard Worker     else
408*89c4ff92SAndroid Build Coastguard Worker       biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
409*89c4ff92SAndroid Build Coastguard Worker     e = biased_e - exponent_bias - double_significand_size;
410*89c4ff92SAndroid Build Coastguard Worker     return is_predecessor_closer;
411*89c4ff92SAndroid Build Coastguard Worker   }
412*89c4ff92SAndroid Build Coastguard Worker 
413*89c4ff92SAndroid Build Coastguard Worker   template <typename Double, FMT_ENABLE_IF(sizeof(Double) != sizeof(uint64_t))>
assign(Double)414*89c4ff92SAndroid Build Coastguard Worker   bool assign(Double) {
415*89c4ff92SAndroid Build Coastguard Worker     *this = fp();
416*89c4ff92SAndroid Build Coastguard Worker     return false;
417*89c4ff92SAndroid Build Coastguard Worker   }
418*89c4ff92SAndroid Build Coastguard Worker 
419*89c4ff92SAndroid Build Coastguard Worker   // Assigns d to this together with computing lower and upper boundaries,
420*89c4ff92SAndroid Build Coastguard Worker   // where a boundary is a value half way between the number and its predecessor
421*89c4ff92SAndroid Build Coastguard Worker   // (lower) or successor (upper). The upper boundary is normalized and lower
422*89c4ff92SAndroid Build Coastguard Worker   // has the same exponent but may be not normalized.
assign_with_boundaries(Double d)423*89c4ff92SAndroid Build Coastguard Worker   template <typename Double> boundaries assign_with_boundaries(Double d) {
424*89c4ff92SAndroid Build Coastguard Worker     bool is_lower_closer = assign(d);
425*89c4ff92SAndroid Build Coastguard Worker     fp lower =
426*89c4ff92SAndroid Build Coastguard Worker         is_lower_closer ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
427*89c4ff92SAndroid Build Coastguard Worker     // 1 in normalize accounts for the exponent shift above.
428*89c4ff92SAndroid Build Coastguard Worker     fp upper = normalize<1>(fp((f << 1) + 1, e - 1));
429*89c4ff92SAndroid Build Coastguard Worker     lower.f <<= lower.e - upper.e;
430*89c4ff92SAndroid Build Coastguard Worker     return boundaries{lower.f, upper.f};
431*89c4ff92SAndroid Build Coastguard Worker   }
432*89c4ff92SAndroid Build Coastguard Worker 
assign_float_with_boundaries(Double d)433*89c4ff92SAndroid Build Coastguard Worker   template <typename Double> boundaries assign_float_with_boundaries(Double d) {
434*89c4ff92SAndroid Build Coastguard Worker     assign(d);
435*89c4ff92SAndroid Build Coastguard Worker     constexpr int min_normal_e = std::numeric_limits<float>::min_exponent -
436*89c4ff92SAndroid Build Coastguard Worker                                  std::numeric_limits<double>::digits;
437*89c4ff92SAndroid Build Coastguard Worker     significand_type half_ulp = 1 << (std::numeric_limits<double>::digits -
438*89c4ff92SAndroid Build Coastguard Worker                                       std::numeric_limits<float>::digits - 1);
439*89c4ff92SAndroid Build Coastguard Worker     if (min_normal_e > e) half_ulp <<= min_normal_e - e;
440*89c4ff92SAndroid Build Coastguard Worker     fp upper = normalize<0>(fp(f + half_ulp, e));
441*89c4ff92SAndroid Build Coastguard Worker     fp lower = fp(
442*89c4ff92SAndroid Build Coastguard Worker         f - (half_ulp >> ((f == implicit_bit && e > min_normal_e) ? 1 : 0)), e);
443*89c4ff92SAndroid Build Coastguard Worker     lower.f <<= lower.e - upper.e;
444*89c4ff92SAndroid Build Coastguard Worker     return boundaries{lower.f, upper.f};
445*89c4ff92SAndroid Build Coastguard Worker   }
446*89c4ff92SAndroid Build Coastguard Worker };
447*89c4ff92SAndroid Build Coastguard Worker 
448*89c4ff92SAndroid Build Coastguard Worker // Normalizes the value converted from double and multiplied by (1 << SHIFT).
normalize(fp value)449*89c4ff92SAndroid Build Coastguard Worker template <int SHIFT> fp normalize(fp value) {
450*89c4ff92SAndroid Build Coastguard Worker   // Handle subnormals.
451*89c4ff92SAndroid Build Coastguard Worker   const auto shifted_implicit_bit = fp::implicit_bit << SHIFT;
452*89c4ff92SAndroid Build Coastguard Worker   while ((value.f & shifted_implicit_bit) == 0) {
453*89c4ff92SAndroid Build Coastguard Worker     value.f <<= 1;
454*89c4ff92SAndroid Build Coastguard Worker     --value.e;
455*89c4ff92SAndroid Build Coastguard Worker   }
456*89c4ff92SAndroid Build Coastguard Worker   // Subtract 1 to account for hidden bit.
457*89c4ff92SAndroid Build Coastguard Worker   const auto offset =
458*89c4ff92SAndroid Build Coastguard Worker       fp::significand_size - fp::double_significand_size - SHIFT - 1;
459*89c4ff92SAndroid Build Coastguard Worker   value.f <<= offset;
460*89c4ff92SAndroid Build Coastguard Worker   value.e -= offset;
461*89c4ff92SAndroid Build Coastguard Worker   return value;
462*89c4ff92SAndroid Build Coastguard Worker }
463*89c4ff92SAndroid Build Coastguard Worker 
464*89c4ff92SAndroid Build Coastguard Worker inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; }
465*89c4ff92SAndroid Build Coastguard Worker 
466*89c4ff92SAndroid Build Coastguard Worker // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
multiply(uint64_t lhs,uint64_t rhs)467*89c4ff92SAndroid Build Coastguard Worker inline uint64_t multiply(uint64_t lhs, uint64_t rhs) {
468*89c4ff92SAndroid Build Coastguard Worker #if FMT_USE_INT128
469*89c4ff92SAndroid Build Coastguard Worker   auto product = static_cast<__uint128_t>(lhs) * rhs;
470*89c4ff92SAndroid Build Coastguard Worker   auto f = static_cast<uint64_t>(product >> 64);
471*89c4ff92SAndroid Build Coastguard Worker   return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
472*89c4ff92SAndroid Build Coastguard Worker #else
473*89c4ff92SAndroid Build Coastguard Worker   // Multiply 32-bit parts of significands.
474*89c4ff92SAndroid Build Coastguard Worker   uint64_t mask = (1ULL << 32) - 1;
475*89c4ff92SAndroid Build Coastguard Worker   uint64_t a = lhs >> 32, b = lhs & mask;
476*89c4ff92SAndroid Build Coastguard Worker   uint64_t c = rhs >> 32, d = rhs & mask;
477*89c4ff92SAndroid Build Coastguard Worker   uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
478*89c4ff92SAndroid Build Coastguard Worker   // Compute mid 64-bit of result and round.
479*89c4ff92SAndroid Build Coastguard Worker   uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
480*89c4ff92SAndroid Build Coastguard Worker   return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
481*89c4ff92SAndroid Build Coastguard Worker #endif
482*89c4ff92SAndroid Build Coastguard Worker }
483*89c4ff92SAndroid Build Coastguard Worker 
484*89c4ff92SAndroid Build Coastguard Worker inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; }
485*89c4ff92SAndroid Build Coastguard Worker 
486*89c4ff92SAndroid Build Coastguard Worker // Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
487*89c4ff92SAndroid Build Coastguard Worker // (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
get_cached_power(int min_exponent,int & pow10_exponent)488*89c4ff92SAndroid Build Coastguard Worker inline fp get_cached_power(int min_exponent, int& pow10_exponent) {
489*89c4ff92SAndroid Build Coastguard Worker   const int64_t one_over_log2_10 = 0x4d104d42;  // round(pow(2, 32) / log2(10))
490*89c4ff92SAndroid Build Coastguard Worker   int index = static_cast<int>(
491*89c4ff92SAndroid Build Coastguard Worker       ((min_exponent + fp::significand_size - 1) * one_over_log2_10 +
492*89c4ff92SAndroid Build Coastguard Worker        ((int64_t(1) << 32) - 1))  // ceil
493*89c4ff92SAndroid Build Coastguard Worker       >> 32                       // arithmetic shift
494*89c4ff92SAndroid Build Coastguard Worker   );
495*89c4ff92SAndroid Build Coastguard Worker   // Decimal exponent of the first (smallest) cached power of 10.
496*89c4ff92SAndroid Build Coastguard Worker   const int first_dec_exp = -348;
497*89c4ff92SAndroid Build Coastguard Worker   // Difference between 2 consecutive decimal exponents in cached powers of 10.
498*89c4ff92SAndroid Build Coastguard Worker   const int dec_exp_step = 8;
499*89c4ff92SAndroid Build Coastguard Worker   index = (index - first_dec_exp - 1) / dec_exp_step + 1;
500*89c4ff92SAndroid Build Coastguard Worker   pow10_exponent = first_dec_exp + index * dec_exp_step;
501*89c4ff92SAndroid Build Coastguard Worker   return {data::pow10_significands[index], data::pow10_exponents[index]};
502*89c4ff92SAndroid Build Coastguard Worker }
503*89c4ff92SAndroid Build Coastguard Worker 
504*89c4ff92SAndroid Build Coastguard Worker // A simple accumulator to hold the sums of terms in bigint::square if uint128_t
505*89c4ff92SAndroid Build Coastguard Worker // is not available.
506*89c4ff92SAndroid Build Coastguard Worker struct accumulator {
507*89c4ff92SAndroid Build Coastguard Worker   uint64_t lower;
508*89c4ff92SAndroid Build Coastguard Worker   uint64_t upper;
509*89c4ff92SAndroid Build Coastguard Worker 
accumulatoraccumulator510*89c4ff92SAndroid Build Coastguard Worker   accumulator() : lower(0), upper(0) {}
uint32_taccumulator511*89c4ff92SAndroid Build Coastguard Worker   explicit operator uint32_t() const { return static_cast<uint32_t>(lower); }
512*89c4ff92SAndroid Build Coastguard Worker 
513*89c4ff92SAndroid Build Coastguard Worker   void operator+=(uint64_t n) {
514*89c4ff92SAndroid Build Coastguard Worker     lower += n;
515*89c4ff92SAndroid Build Coastguard Worker     if (lower < n) ++upper;
516*89c4ff92SAndroid Build Coastguard Worker   }
517*89c4ff92SAndroid Build Coastguard Worker   void operator>>=(int shift) {
518*89c4ff92SAndroid Build Coastguard Worker     assert(shift == 32);
519*89c4ff92SAndroid Build Coastguard Worker     (void)shift;
520*89c4ff92SAndroid Build Coastguard Worker     lower = (upper << 32) | (lower >> 32);
521*89c4ff92SAndroid Build Coastguard Worker     upper >>= 32;
522*89c4ff92SAndroid Build Coastguard Worker   }
523*89c4ff92SAndroid Build Coastguard Worker };
524*89c4ff92SAndroid Build Coastguard Worker 
525*89c4ff92SAndroid Build Coastguard Worker class bigint {
526*89c4ff92SAndroid Build Coastguard Worker  private:
527*89c4ff92SAndroid Build Coastguard Worker   // A bigint is stored as an array of bigits (big digits), with bigit at index
528*89c4ff92SAndroid Build Coastguard Worker   // 0 being the least significant one.
529*89c4ff92SAndroid Build Coastguard Worker   using bigit = uint32_t;
530*89c4ff92SAndroid Build Coastguard Worker   using double_bigit = uint64_t;
531*89c4ff92SAndroid Build Coastguard Worker   enum { bigits_capacity = 32 };
532*89c4ff92SAndroid Build Coastguard Worker   basic_memory_buffer<bigit, bigits_capacity> bigits_;
533*89c4ff92SAndroid Build Coastguard Worker   int exp_;
534*89c4ff92SAndroid Build Coastguard Worker 
535*89c4ff92SAndroid Build Coastguard Worker   bigit operator[](int index) const { return bigits_[to_unsigned(index)]; }
536*89c4ff92SAndroid Build Coastguard Worker   bigit& operator[](int index) { return bigits_[to_unsigned(index)]; }
537*89c4ff92SAndroid Build Coastguard Worker 
538*89c4ff92SAndroid Build Coastguard Worker   static FMT_CONSTEXPR_DECL const int bigit_bits = bits<bigit>::value;
539*89c4ff92SAndroid Build Coastguard Worker 
540*89c4ff92SAndroid Build Coastguard Worker   friend struct formatter<bigint>;
541*89c4ff92SAndroid Build Coastguard Worker 
542*89c4ff92SAndroid Build Coastguard Worker   void subtract_bigits(int index, bigit other, bigit& borrow) {
543*89c4ff92SAndroid Build Coastguard Worker     auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
544*89c4ff92SAndroid Build Coastguard Worker     (*this)[index] = static_cast<bigit>(result);
545*89c4ff92SAndroid Build Coastguard Worker     borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
546*89c4ff92SAndroid Build Coastguard Worker   }
547*89c4ff92SAndroid Build Coastguard Worker 
548*89c4ff92SAndroid Build Coastguard Worker   void remove_leading_zeros() {
549*89c4ff92SAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size()) - 1;
550*89c4ff92SAndroid Build Coastguard Worker     while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
551*89c4ff92SAndroid Build Coastguard Worker     bigits_.resize(to_unsigned(num_bigits + 1));
552*89c4ff92SAndroid Build Coastguard Worker   }
553*89c4ff92SAndroid Build Coastguard Worker 
554*89c4ff92SAndroid Build Coastguard Worker   // Computes *this -= other assuming aligned bigints and *this >= other.
555*89c4ff92SAndroid Build Coastguard Worker   void subtract_aligned(const bigint& other) {
556*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
557*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(compare(*this, other) >= 0, "");
558*89c4ff92SAndroid Build Coastguard Worker     bigit borrow = 0;
559*89c4ff92SAndroid Build Coastguard Worker     int i = other.exp_ - exp_;
560*89c4ff92SAndroid Build Coastguard Worker     for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) {
561*89c4ff92SAndroid Build Coastguard Worker       subtract_bigits(i, other.bigits_[j], borrow);
562*89c4ff92SAndroid Build Coastguard Worker     }
563*89c4ff92SAndroid Build Coastguard Worker     while (borrow > 0) subtract_bigits(i, 0, borrow);
564*89c4ff92SAndroid Build Coastguard Worker     remove_leading_zeros();
565*89c4ff92SAndroid Build Coastguard Worker   }
566*89c4ff92SAndroid Build Coastguard Worker 
567*89c4ff92SAndroid Build Coastguard Worker   void multiply(uint32_t value) {
568*89c4ff92SAndroid Build Coastguard Worker     const double_bigit wide_value = value;
569*89c4ff92SAndroid Build Coastguard Worker     bigit carry = 0;
570*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
571*89c4ff92SAndroid Build Coastguard Worker       double_bigit result = bigits_[i] * wide_value + carry;
572*89c4ff92SAndroid Build Coastguard Worker       bigits_[i] = static_cast<bigit>(result);
573*89c4ff92SAndroid Build Coastguard Worker       carry = static_cast<bigit>(result >> bigit_bits);
574*89c4ff92SAndroid Build Coastguard Worker     }
575*89c4ff92SAndroid Build Coastguard Worker     if (carry != 0) bigits_.push_back(carry);
576*89c4ff92SAndroid Build Coastguard Worker   }
577*89c4ff92SAndroid Build Coastguard Worker 
578*89c4ff92SAndroid Build Coastguard Worker   void multiply(uint64_t value) {
579*89c4ff92SAndroid Build Coastguard Worker     const bigit mask = ~bigit(0);
580*89c4ff92SAndroid Build Coastguard Worker     const double_bigit lower = value & mask;
581*89c4ff92SAndroid Build Coastguard Worker     const double_bigit upper = value >> bigit_bits;
582*89c4ff92SAndroid Build Coastguard Worker     double_bigit carry = 0;
583*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
584*89c4ff92SAndroid Build Coastguard Worker       double_bigit result = bigits_[i] * lower + (carry & mask);
585*89c4ff92SAndroid Build Coastguard Worker       carry =
586*89c4ff92SAndroid Build Coastguard Worker           bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits);
587*89c4ff92SAndroid Build Coastguard Worker       bigits_[i] = static_cast<bigit>(result);
588*89c4ff92SAndroid Build Coastguard Worker     }
589*89c4ff92SAndroid Build Coastguard Worker     while (carry != 0) {
590*89c4ff92SAndroid Build Coastguard Worker       bigits_.push_back(carry & mask);
591*89c4ff92SAndroid Build Coastguard Worker       carry >>= bigit_bits;
592*89c4ff92SAndroid Build Coastguard Worker     }
593*89c4ff92SAndroid Build Coastguard Worker   }
594*89c4ff92SAndroid Build Coastguard Worker 
595*89c4ff92SAndroid Build Coastguard Worker  public:
596*89c4ff92SAndroid Build Coastguard Worker   bigint() : exp_(0) {}
597*89c4ff92SAndroid Build Coastguard Worker   explicit bigint(uint64_t n) { assign(n); }
598*89c4ff92SAndroid Build Coastguard Worker   ~bigint() { assert(bigits_.capacity() <= bigits_capacity); }
599*89c4ff92SAndroid Build Coastguard Worker 
600*89c4ff92SAndroid Build Coastguard Worker   bigint(const bigint&) = delete;
601*89c4ff92SAndroid Build Coastguard Worker   void operator=(const bigint&) = delete;
602*89c4ff92SAndroid Build Coastguard Worker 
603*89c4ff92SAndroid Build Coastguard Worker   void assign(const bigint& other) {
604*89c4ff92SAndroid Build Coastguard Worker     auto size = other.bigits_.size();
605*89c4ff92SAndroid Build Coastguard Worker     bigits_.resize(size);
606*89c4ff92SAndroid Build Coastguard Worker     auto data = other.bigits_.data();
607*89c4ff92SAndroid Build Coastguard Worker     std::copy(data, data + size, make_checked(bigits_.data(), size));
608*89c4ff92SAndroid Build Coastguard Worker     exp_ = other.exp_;
609*89c4ff92SAndroid Build Coastguard Worker   }
610*89c4ff92SAndroid Build Coastguard Worker 
611*89c4ff92SAndroid Build Coastguard Worker   void assign(uint64_t n) {
612*89c4ff92SAndroid Build Coastguard Worker     size_t num_bigits = 0;
613*89c4ff92SAndroid Build Coastguard Worker     do {
614*89c4ff92SAndroid Build Coastguard Worker       bigits_[num_bigits++] = n & ~bigit(0);
615*89c4ff92SAndroid Build Coastguard Worker       n >>= bigit_bits;
616*89c4ff92SAndroid Build Coastguard Worker     } while (n != 0);
617*89c4ff92SAndroid Build Coastguard Worker     bigits_.resize(num_bigits);
618*89c4ff92SAndroid Build Coastguard Worker     exp_ = 0;
619*89c4ff92SAndroid Build Coastguard Worker   }
620*89c4ff92SAndroid Build Coastguard Worker 
621*89c4ff92SAndroid Build Coastguard Worker   int num_bigits() const { return static_cast<int>(bigits_.size()) + exp_; }
622*89c4ff92SAndroid Build Coastguard Worker 
623*89c4ff92SAndroid Build Coastguard Worker   FMT_NOINLINE bigint& operator<<=(int shift) {
624*89c4ff92SAndroid Build Coastguard Worker     assert(shift >= 0);
625*89c4ff92SAndroid Build Coastguard Worker     exp_ += shift / bigit_bits;
626*89c4ff92SAndroid Build Coastguard Worker     shift %= bigit_bits;
627*89c4ff92SAndroid Build Coastguard Worker     if (shift == 0) return *this;
628*89c4ff92SAndroid Build Coastguard Worker     bigit carry = 0;
629*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
630*89c4ff92SAndroid Build Coastguard Worker       bigit c = bigits_[i] >> (bigit_bits - shift);
631*89c4ff92SAndroid Build Coastguard Worker       bigits_[i] = (bigits_[i] << shift) + carry;
632*89c4ff92SAndroid Build Coastguard Worker       carry = c;
633*89c4ff92SAndroid Build Coastguard Worker     }
634*89c4ff92SAndroid Build Coastguard Worker     if (carry != 0) bigits_.push_back(carry);
635*89c4ff92SAndroid Build Coastguard Worker     return *this;
636*89c4ff92SAndroid Build Coastguard Worker   }
637*89c4ff92SAndroid Build Coastguard Worker 
638*89c4ff92SAndroid Build Coastguard Worker   template <typename Int> bigint& operator*=(Int value) {
639*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(value > 0, "");
640*89c4ff92SAndroid Build Coastguard Worker     multiply(uint32_or_64_or_128_t<Int>(value));
641*89c4ff92SAndroid Build Coastguard Worker     return *this;
642*89c4ff92SAndroid Build Coastguard Worker   }
643*89c4ff92SAndroid Build Coastguard Worker 
644*89c4ff92SAndroid Build Coastguard Worker   friend int compare(const bigint& lhs, const bigint& rhs) {
645*89c4ff92SAndroid Build Coastguard Worker     int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
646*89c4ff92SAndroid Build Coastguard Worker     if (num_lhs_bigits != num_rhs_bigits)
647*89c4ff92SAndroid Build Coastguard Worker       return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
648*89c4ff92SAndroid Build Coastguard Worker     int i = static_cast<int>(lhs.bigits_.size()) - 1;
649*89c4ff92SAndroid Build Coastguard Worker     int j = static_cast<int>(rhs.bigits_.size()) - 1;
650*89c4ff92SAndroid Build Coastguard Worker     int end = i - j;
651*89c4ff92SAndroid Build Coastguard Worker     if (end < 0) end = 0;
652*89c4ff92SAndroid Build Coastguard Worker     for (; i >= end; --i, --j) {
653*89c4ff92SAndroid Build Coastguard Worker       bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
654*89c4ff92SAndroid Build Coastguard Worker       if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
655*89c4ff92SAndroid Build Coastguard Worker     }
656*89c4ff92SAndroid Build Coastguard Worker     if (i != j) return i > j ? 1 : -1;
657*89c4ff92SAndroid Build Coastguard Worker     return 0;
658*89c4ff92SAndroid Build Coastguard Worker   }
659*89c4ff92SAndroid Build Coastguard Worker 
660*89c4ff92SAndroid Build Coastguard Worker   // Returns compare(lhs1 + lhs2, rhs).
661*89c4ff92SAndroid Build Coastguard Worker   friend int add_compare(const bigint& lhs1, const bigint& lhs2,
662*89c4ff92SAndroid Build Coastguard Worker                          const bigint& rhs) {
663*89c4ff92SAndroid Build Coastguard Worker     int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits());
664*89c4ff92SAndroid Build Coastguard Worker     int num_rhs_bigits = rhs.num_bigits();
665*89c4ff92SAndroid Build Coastguard Worker     if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
666*89c4ff92SAndroid Build Coastguard Worker     if (max_lhs_bigits > num_rhs_bigits) return 1;
667*89c4ff92SAndroid Build Coastguard Worker     auto get_bigit = [](const bigint& n, int i) -> bigit {
668*89c4ff92SAndroid Build Coastguard Worker       return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
669*89c4ff92SAndroid Build Coastguard Worker     };
670*89c4ff92SAndroid Build Coastguard Worker     double_bigit borrow = 0;
671*89c4ff92SAndroid Build Coastguard Worker     int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_);
672*89c4ff92SAndroid Build Coastguard Worker     for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
673*89c4ff92SAndroid Build Coastguard Worker       double_bigit sum =
674*89c4ff92SAndroid Build Coastguard Worker           static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
675*89c4ff92SAndroid Build Coastguard Worker       bigit rhs_bigit = get_bigit(rhs, i);
676*89c4ff92SAndroid Build Coastguard Worker       if (sum > rhs_bigit + borrow) return 1;
677*89c4ff92SAndroid Build Coastguard Worker       borrow = rhs_bigit + borrow - sum;
678*89c4ff92SAndroid Build Coastguard Worker       if (borrow > 1) return -1;
679*89c4ff92SAndroid Build Coastguard Worker       borrow <<= bigit_bits;
680*89c4ff92SAndroid Build Coastguard Worker     }
681*89c4ff92SAndroid Build Coastguard Worker     return borrow != 0 ? -1 : 0;
682*89c4ff92SAndroid Build Coastguard Worker   }
683*89c4ff92SAndroid Build Coastguard Worker 
684*89c4ff92SAndroid Build Coastguard Worker   // Assigns pow(10, exp) to this bigint.
685*89c4ff92SAndroid Build Coastguard Worker   void assign_pow10(int exp) {
686*89c4ff92SAndroid Build Coastguard Worker     assert(exp >= 0);
687*89c4ff92SAndroid Build Coastguard Worker     if (exp == 0) return assign(1);
688*89c4ff92SAndroid Build Coastguard Worker     // Find the top bit.
689*89c4ff92SAndroid Build Coastguard Worker     int bitmask = 1;
690*89c4ff92SAndroid Build Coastguard Worker     while (exp >= bitmask) bitmask <<= 1;
691*89c4ff92SAndroid Build Coastguard Worker     bitmask >>= 1;
692*89c4ff92SAndroid Build Coastguard Worker     // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
693*89c4ff92SAndroid Build Coastguard Worker     // repeated squaring and multiplication.
694*89c4ff92SAndroid Build Coastguard Worker     assign(5);
695*89c4ff92SAndroid Build Coastguard Worker     bitmask >>= 1;
696*89c4ff92SAndroid Build Coastguard Worker     while (bitmask != 0) {
697*89c4ff92SAndroid Build Coastguard Worker       square();
698*89c4ff92SAndroid Build Coastguard Worker       if ((exp & bitmask) != 0) *this *= 5;
699*89c4ff92SAndroid Build Coastguard Worker       bitmask >>= 1;
700*89c4ff92SAndroid Build Coastguard Worker     }
701*89c4ff92SAndroid Build Coastguard Worker     *this <<= exp;  // Multiply by pow(2, exp) by shifting.
702*89c4ff92SAndroid Build Coastguard Worker   }
703*89c4ff92SAndroid Build Coastguard Worker 
704*89c4ff92SAndroid Build Coastguard Worker   void square() {
705*89c4ff92SAndroid Build Coastguard Worker     basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
706*89c4ff92SAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size());
707*89c4ff92SAndroid Build Coastguard Worker     int num_result_bigits = 2 * num_bigits;
708*89c4ff92SAndroid Build Coastguard Worker     bigits_.resize(to_unsigned(num_result_bigits));
709*89c4ff92SAndroid Build Coastguard Worker     using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>;
710*89c4ff92SAndroid Build Coastguard Worker     auto sum = accumulator_t();
711*89c4ff92SAndroid Build Coastguard Worker     for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
712*89c4ff92SAndroid Build Coastguard Worker       // Compute bigit at position bigit_index of the result by adding
713*89c4ff92SAndroid Build Coastguard Worker       // cross-product terms n[i] * n[j] such that i + j == bigit_index.
714*89c4ff92SAndroid Build Coastguard Worker       for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
715*89c4ff92SAndroid Build Coastguard Worker         // Most terms are multiplied twice which can be optimized in the future.
716*89c4ff92SAndroid Build Coastguard Worker         sum += static_cast<double_bigit>(n[i]) * n[j];
717*89c4ff92SAndroid Build Coastguard Worker       }
718*89c4ff92SAndroid Build Coastguard Worker       (*this)[bigit_index] = static_cast<bigit>(sum);
719*89c4ff92SAndroid Build Coastguard Worker       sum >>= bits<bigit>::value;  // Compute the carry.
720*89c4ff92SAndroid Build Coastguard Worker     }
721*89c4ff92SAndroid Build Coastguard Worker     // Do the same for the top half.
722*89c4ff92SAndroid Build Coastguard Worker     for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
723*89c4ff92SAndroid Build Coastguard Worker          ++bigit_index) {
724*89c4ff92SAndroid Build Coastguard Worker       for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
725*89c4ff92SAndroid Build Coastguard Worker         sum += static_cast<double_bigit>(n[i++]) * n[j--];
726*89c4ff92SAndroid Build Coastguard Worker       (*this)[bigit_index] = static_cast<bigit>(sum);
727*89c4ff92SAndroid Build Coastguard Worker       sum >>= bits<bigit>::value;
728*89c4ff92SAndroid Build Coastguard Worker     }
729*89c4ff92SAndroid Build Coastguard Worker     --num_result_bigits;
730*89c4ff92SAndroid Build Coastguard Worker     remove_leading_zeros();
731*89c4ff92SAndroid Build Coastguard Worker     exp_ *= 2;
732*89c4ff92SAndroid Build Coastguard Worker   }
733*89c4ff92SAndroid Build Coastguard Worker 
734*89c4ff92SAndroid Build Coastguard Worker   // Divides this bignum by divisor, assigning the remainder to this and
735*89c4ff92SAndroid Build Coastguard Worker   // returning the quotient.
736*89c4ff92SAndroid Build Coastguard Worker   int divmod_assign(const bigint& divisor) {
737*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(this != &divisor, "");
738*89c4ff92SAndroid Build Coastguard Worker     if (compare(*this, divisor) < 0) return 0;
739*89c4ff92SAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size());
740*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
741*89c4ff92SAndroid Build Coastguard Worker     int exp_difference = exp_ - divisor.exp_;
742*89c4ff92SAndroid Build Coastguard Worker     if (exp_difference > 0) {
743*89c4ff92SAndroid Build Coastguard Worker       // Align bigints by adding trailing zeros to simplify subtraction.
744*89c4ff92SAndroid Build Coastguard Worker       bigits_.resize(to_unsigned(num_bigits + exp_difference));
745*89c4ff92SAndroid Build Coastguard Worker       for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
746*89c4ff92SAndroid Build Coastguard Worker         bigits_[j] = bigits_[i];
747*89c4ff92SAndroid Build Coastguard Worker       std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
748*89c4ff92SAndroid Build Coastguard Worker       exp_ -= exp_difference;
749*89c4ff92SAndroid Build Coastguard Worker     }
750*89c4ff92SAndroid Build Coastguard Worker     int quotient = 0;
751*89c4ff92SAndroid Build Coastguard Worker     do {
752*89c4ff92SAndroid Build Coastguard Worker       subtract_aligned(divisor);
753*89c4ff92SAndroid Build Coastguard Worker       ++quotient;
754*89c4ff92SAndroid Build Coastguard Worker     } while (compare(*this, divisor) >= 0);
755*89c4ff92SAndroid Build Coastguard Worker     return quotient;
756*89c4ff92SAndroid Build Coastguard Worker   }
757*89c4ff92SAndroid Build Coastguard Worker };
758*89c4ff92SAndroid Build Coastguard Worker 
759*89c4ff92SAndroid Build Coastguard Worker enum class round_direction { unknown, up, down };
760*89c4ff92SAndroid Build Coastguard Worker 
761*89c4ff92SAndroid Build Coastguard Worker // Given the divisor (normally a power of 10), the remainder = v % divisor for
762*89c4ff92SAndroid Build Coastguard Worker // some number v and the error, returns whether v should be rounded up, down, or
763*89c4ff92SAndroid Build Coastguard Worker // whether the rounding direction can't be determined due to error.
764*89c4ff92SAndroid Build Coastguard Worker // error should be less than divisor / 2.
765*89c4ff92SAndroid Build Coastguard Worker inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder,
766*89c4ff92SAndroid Build Coastguard Worker                                            uint64_t error) {
767*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(remainder < divisor, "");  // divisor - remainder won't overflow.
768*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(error < divisor, "");      // divisor - error won't overflow.
769*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(error < divisor - error, "");  // error * 2 won't overflow.
770*89c4ff92SAndroid Build Coastguard Worker   // Round down if (remainder + error) * 2 <= divisor.
771*89c4ff92SAndroid Build Coastguard Worker   if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
772*89c4ff92SAndroid Build Coastguard Worker     return round_direction::down;
773*89c4ff92SAndroid Build Coastguard Worker   // Round up if (remainder - error) * 2 >= divisor.
774*89c4ff92SAndroid Build Coastguard Worker   if (remainder >= error &&
775*89c4ff92SAndroid Build Coastguard Worker       remainder - error >= divisor - (remainder - error)) {
776*89c4ff92SAndroid Build Coastguard Worker     return round_direction::up;
777*89c4ff92SAndroid Build Coastguard Worker   }
778*89c4ff92SAndroid Build Coastguard Worker   return round_direction::unknown;
779*89c4ff92SAndroid Build Coastguard Worker }
780*89c4ff92SAndroid Build Coastguard Worker 
781*89c4ff92SAndroid Build Coastguard Worker namespace digits {
782*89c4ff92SAndroid Build Coastguard Worker enum result {
783*89c4ff92SAndroid Build Coastguard Worker   more,  // Generate more digits.
784*89c4ff92SAndroid Build Coastguard Worker   done,  // Done generating digits.
785*89c4ff92SAndroid Build Coastguard Worker   error  // Digit generation cancelled due to an error.
786*89c4ff92SAndroid Build Coastguard Worker };
787*89c4ff92SAndroid Build Coastguard Worker }
788*89c4ff92SAndroid Build Coastguard Worker 
789*89c4ff92SAndroid Build Coastguard Worker // A version of count_digits optimized for grisu_gen_digits.
790*89c4ff92SAndroid Build Coastguard Worker inline int grisu_count_digits(uint32_t n) {
791*89c4ff92SAndroid Build Coastguard Worker   if (n < 10) return 1;
792*89c4ff92SAndroid Build Coastguard Worker   if (n < 100) return 2;
793*89c4ff92SAndroid Build Coastguard Worker   if (n < 1000) return 3;
794*89c4ff92SAndroid Build Coastguard Worker   if (n < 10000) return 4;
795*89c4ff92SAndroid Build Coastguard Worker   if (n < 100000) return 5;
796*89c4ff92SAndroid Build Coastguard Worker   if (n < 1000000) return 6;
797*89c4ff92SAndroid Build Coastguard Worker   if (n < 10000000) return 7;
798*89c4ff92SAndroid Build Coastguard Worker   if (n < 100000000) return 8;
799*89c4ff92SAndroid Build Coastguard Worker   if (n < 1000000000) return 9;
800*89c4ff92SAndroid Build Coastguard Worker   return 10;
801*89c4ff92SAndroid Build Coastguard Worker }
802*89c4ff92SAndroid Build Coastguard Worker 
803*89c4ff92SAndroid Build Coastguard Worker // Generates output using the Grisu digit-gen algorithm.
804*89c4ff92SAndroid Build Coastguard Worker // error: the size of the region (lower, upper) outside of which numbers
805*89c4ff92SAndroid Build Coastguard Worker // definitely do not round to value (Delta in Grisu3).
806*89c4ff92SAndroid Build Coastguard Worker template <typename Handler>
807*89c4ff92SAndroid Build Coastguard Worker FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
808*89c4ff92SAndroid Build Coastguard Worker                                                   int& exp, Handler& handler) {
809*89c4ff92SAndroid Build Coastguard Worker   const fp one(1ULL << -value.e, value.e);
810*89c4ff92SAndroid Build Coastguard Worker   // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
811*89c4ff92SAndroid Build Coastguard Worker   // zero because it contains a product of two 64-bit numbers with MSB set (due
812*89c4ff92SAndroid Build Coastguard Worker   // to normalization) - 1, shifted right by at most 60 bits.
813*89c4ff92SAndroid Build Coastguard Worker   auto integral = static_cast<uint32_t>(value.f >> -one.e);
814*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(integral != 0, "");
815*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(integral == value.f >> -one.e, "");
816*89c4ff92SAndroid Build Coastguard Worker   // The fractional part of scaled value (p2 in Grisu) c = value % one.
817*89c4ff92SAndroid Build Coastguard Worker   uint64_t fractional = value.f & (one.f - 1);
818*89c4ff92SAndroid Build Coastguard Worker   exp = grisu_count_digits(integral);  // kappa in Grisu.
819*89c4ff92SAndroid Build Coastguard Worker   // Divide by 10 to prevent overflow.
820*89c4ff92SAndroid Build Coastguard Worker   auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e,
821*89c4ff92SAndroid Build Coastguard Worker                                  value.f / 10, error * 10, exp);
822*89c4ff92SAndroid Build Coastguard Worker   if (result != digits::more) return result;
823*89c4ff92SAndroid Build Coastguard Worker   // Generate digits for the integral part. This can produce up to 10 digits.
824*89c4ff92SAndroid Build Coastguard Worker   do {
825*89c4ff92SAndroid Build Coastguard Worker     uint32_t digit = 0;
826*89c4ff92SAndroid Build Coastguard Worker     auto divmod_integral = [&](uint32_t divisor) {
827*89c4ff92SAndroid Build Coastguard Worker       digit = integral / divisor;
828*89c4ff92SAndroid Build Coastguard Worker       integral %= divisor;
829*89c4ff92SAndroid Build Coastguard Worker     };
830*89c4ff92SAndroid Build Coastguard Worker     // This optimization by Milo Yip reduces the number of integer divisions by
831*89c4ff92SAndroid Build Coastguard Worker     // one per iteration.
832*89c4ff92SAndroid Build Coastguard Worker     switch (exp) {
833*89c4ff92SAndroid Build Coastguard Worker     case 10:
834*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(1000000000);
835*89c4ff92SAndroid Build Coastguard Worker       break;
836*89c4ff92SAndroid Build Coastguard Worker     case 9:
837*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(100000000);
838*89c4ff92SAndroid Build Coastguard Worker       break;
839*89c4ff92SAndroid Build Coastguard Worker     case 8:
840*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(10000000);
841*89c4ff92SAndroid Build Coastguard Worker       break;
842*89c4ff92SAndroid Build Coastguard Worker     case 7:
843*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(1000000);
844*89c4ff92SAndroid Build Coastguard Worker       break;
845*89c4ff92SAndroid Build Coastguard Worker     case 6:
846*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(100000);
847*89c4ff92SAndroid Build Coastguard Worker       break;
848*89c4ff92SAndroid Build Coastguard Worker     case 5:
849*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(10000);
850*89c4ff92SAndroid Build Coastguard Worker       break;
851*89c4ff92SAndroid Build Coastguard Worker     case 4:
852*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(1000);
853*89c4ff92SAndroid Build Coastguard Worker       break;
854*89c4ff92SAndroid Build Coastguard Worker     case 3:
855*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(100);
856*89c4ff92SAndroid Build Coastguard Worker       break;
857*89c4ff92SAndroid Build Coastguard Worker     case 2:
858*89c4ff92SAndroid Build Coastguard Worker       divmod_integral(10);
859*89c4ff92SAndroid Build Coastguard Worker       break;
860*89c4ff92SAndroid Build Coastguard Worker     case 1:
861*89c4ff92SAndroid Build Coastguard Worker       digit = integral;
862*89c4ff92SAndroid Build Coastguard Worker       integral = 0;
863*89c4ff92SAndroid Build Coastguard Worker       break;
864*89c4ff92SAndroid Build Coastguard Worker     default:
865*89c4ff92SAndroid Build Coastguard Worker       FMT_ASSERT(false, "invalid number of digits");
866*89c4ff92SAndroid Build Coastguard Worker     }
867*89c4ff92SAndroid Build Coastguard Worker     --exp;
868*89c4ff92SAndroid Build Coastguard Worker     uint64_t remainder =
869*89c4ff92SAndroid Build Coastguard Worker         (static_cast<uint64_t>(integral) << -one.e) + fractional;
870*89c4ff92SAndroid Build Coastguard Worker     result = handler.on_digit(static_cast<char>('0' + digit),
871*89c4ff92SAndroid Build Coastguard Worker                               data::powers_of_10_64[exp] << -one.e, remainder,
872*89c4ff92SAndroid Build Coastguard Worker                               error, exp, true);
873*89c4ff92SAndroid Build Coastguard Worker     if (result != digits::more) return result;
874*89c4ff92SAndroid Build Coastguard Worker   } while (exp > 0);
875*89c4ff92SAndroid Build Coastguard Worker   // Generate digits for the fractional part.
876*89c4ff92SAndroid Build Coastguard Worker   for (;;) {
877*89c4ff92SAndroid Build Coastguard Worker     fractional *= 10;
878*89c4ff92SAndroid Build Coastguard Worker     error *= 10;
879*89c4ff92SAndroid Build Coastguard Worker     char digit =
880*89c4ff92SAndroid Build Coastguard Worker         static_cast<char>('0' + static_cast<char>(fractional >> -one.e));
881*89c4ff92SAndroid Build Coastguard Worker     fractional &= one.f - 1;
882*89c4ff92SAndroid Build Coastguard Worker     --exp;
883*89c4ff92SAndroid Build Coastguard Worker     result = handler.on_digit(digit, one.f, fractional, error, exp, false);
884*89c4ff92SAndroid Build Coastguard Worker     if (result != digits::more) return result;
885*89c4ff92SAndroid Build Coastguard Worker   }
886*89c4ff92SAndroid Build Coastguard Worker }
887*89c4ff92SAndroid Build Coastguard Worker 
888*89c4ff92SAndroid Build Coastguard Worker // The fixed precision digit handler.
889*89c4ff92SAndroid Build Coastguard Worker struct fixed_handler {
890*89c4ff92SAndroid Build Coastguard Worker   char* buf;
891*89c4ff92SAndroid Build Coastguard Worker   int size;
892*89c4ff92SAndroid Build Coastguard Worker   int precision;
893*89c4ff92SAndroid Build Coastguard Worker   int exp10;
894*89c4ff92SAndroid Build Coastguard Worker   bool fixed;
895*89c4ff92SAndroid Build Coastguard Worker 
896*89c4ff92SAndroid Build Coastguard Worker   digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error,
897*89c4ff92SAndroid Build Coastguard Worker                           int& exp) {
898*89c4ff92SAndroid Build Coastguard Worker     // Non-fixed formats require at least one digit and no precision adjustment.
899*89c4ff92SAndroid Build Coastguard Worker     if (!fixed) return digits::more;
900*89c4ff92SAndroid Build Coastguard Worker     // Adjust fixed precision by exponent because it is relative to decimal
901*89c4ff92SAndroid Build Coastguard Worker     // point.
902*89c4ff92SAndroid Build Coastguard Worker     precision += exp + exp10;
903*89c4ff92SAndroid Build Coastguard Worker     // Check if precision is satisfied just by leading zeros, e.g.
904*89c4ff92SAndroid Build Coastguard Worker     // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
905*89c4ff92SAndroid Build Coastguard Worker     if (precision > 0) return digits::more;
906*89c4ff92SAndroid Build Coastguard Worker     if (precision < 0) return digits::done;
907*89c4ff92SAndroid Build Coastguard Worker     auto dir = get_round_direction(divisor, remainder, error);
908*89c4ff92SAndroid Build Coastguard Worker     if (dir == round_direction::unknown) return digits::error;
909*89c4ff92SAndroid Build Coastguard Worker     buf[size++] = dir == round_direction::up ? '1' : '0';
910*89c4ff92SAndroid Build Coastguard Worker     return digits::done;
911*89c4ff92SAndroid Build Coastguard Worker   }
912*89c4ff92SAndroid Build Coastguard Worker 
913*89c4ff92SAndroid Build Coastguard Worker   digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder,
914*89c4ff92SAndroid Build Coastguard Worker                           uint64_t error, int, bool integral) {
915*89c4ff92SAndroid Build Coastguard Worker     FMT_ASSERT(remainder < divisor, "");
916*89c4ff92SAndroid Build Coastguard Worker     buf[size++] = digit;
917*89c4ff92SAndroid Build Coastguard Worker     if (size < precision) return digits::more;
918*89c4ff92SAndroid Build Coastguard Worker     if (!integral) {
919*89c4ff92SAndroid Build Coastguard Worker       // Check if error * 2 < divisor with overflow prevention.
920*89c4ff92SAndroid Build Coastguard Worker       // The check is not needed for the integral part because error = 1
921*89c4ff92SAndroid Build Coastguard Worker       // and divisor > (1 << 32) there.
922*89c4ff92SAndroid Build Coastguard Worker       if (error >= divisor || error >= divisor - error) return digits::error;
923*89c4ff92SAndroid Build Coastguard Worker     } else {
924*89c4ff92SAndroid Build Coastguard Worker       FMT_ASSERT(error == 1 && divisor > 2, "");
925*89c4ff92SAndroid Build Coastguard Worker     }
926*89c4ff92SAndroid Build Coastguard Worker     auto dir = get_round_direction(divisor, remainder, error);
927*89c4ff92SAndroid Build Coastguard Worker     if (dir != round_direction::up)
928*89c4ff92SAndroid Build Coastguard Worker       return dir == round_direction::down ? digits::done : digits::error;
929*89c4ff92SAndroid Build Coastguard Worker     ++buf[size - 1];
930*89c4ff92SAndroid Build Coastguard Worker     for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
931*89c4ff92SAndroid Build Coastguard Worker       buf[i] = '0';
932*89c4ff92SAndroid Build Coastguard Worker       ++buf[i - 1];
933*89c4ff92SAndroid Build Coastguard Worker     }
934*89c4ff92SAndroid Build Coastguard Worker     if (buf[0] > '9') {
935*89c4ff92SAndroid Build Coastguard Worker       buf[0] = '1';
936*89c4ff92SAndroid Build Coastguard Worker       buf[size++] = '0';
937*89c4ff92SAndroid Build Coastguard Worker     }
938*89c4ff92SAndroid Build Coastguard Worker     return digits::done;
939*89c4ff92SAndroid Build Coastguard Worker   }
940*89c4ff92SAndroid Build Coastguard Worker };
941*89c4ff92SAndroid Build Coastguard Worker 
942*89c4ff92SAndroid Build Coastguard Worker // The shortest representation digit handler.
943*89c4ff92SAndroid Build Coastguard Worker struct grisu_shortest_handler {
944*89c4ff92SAndroid Build Coastguard Worker   char* buf;
945*89c4ff92SAndroid Build Coastguard Worker   int size;
946*89c4ff92SAndroid Build Coastguard Worker   // Distance between scaled value and upper bound (wp_W in Grisu3).
947*89c4ff92SAndroid Build Coastguard Worker   uint64_t diff;
948*89c4ff92SAndroid Build Coastguard Worker 
949*89c4ff92SAndroid Build Coastguard Worker   digits::result on_start(uint64_t, uint64_t, uint64_t, int&) {
950*89c4ff92SAndroid Build Coastguard Worker     return digits::more;
951*89c4ff92SAndroid Build Coastguard Worker   }
952*89c4ff92SAndroid Build Coastguard Worker 
953*89c4ff92SAndroid Build Coastguard Worker   // Decrement the generated number approaching value from above.
954*89c4ff92SAndroid Build Coastguard Worker   void round(uint64_t d, uint64_t divisor, uint64_t& remainder,
955*89c4ff92SAndroid Build Coastguard Worker              uint64_t error) {
956*89c4ff92SAndroid Build Coastguard Worker     while (
957*89c4ff92SAndroid Build Coastguard Worker         remainder < d && error - remainder >= divisor &&
958*89c4ff92SAndroid Build Coastguard Worker         (remainder + divisor < d || d - remainder >= remainder + divisor - d)) {
959*89c4ff92SAndroid Build Coastguard Worker       --buf[size - 1];
960*89c4ff92SAndroid Build Coastguard Worker       remainder += divisor;
961*89c4ff92SAndroid Build Coastguard Worker     }
962*89c4ff92SAndroid Build Coastguard Worker   }
963*89c4ff92SAndroid Build Coastguard Worker 
964*89c4ff92SAndroid Build Coastguard Worker   // Implements Grisu's round_weed.
965*89c4ff92SAndroid Build Coastguard Worker   digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder,
966*89c4ff92SAndroid Build Coastguard Worker                           uint64_t error, int exp, bool integral) {
967*89c4ff92SAndroid Build Coastguard Worker     buf[size++] = digit;
968*89c4ff92SAndroid Build Coastguard Worker     if (remainder >= error) return digits::more;
969*89c4ff92SAndroid Build Coastguard Worker     uint64_t unit = integral ? 1 : data::powers_of_10_64[-exp];
970*89c4ff92SAndroid Build Coastguard Worker     uint64_t up = (diff - 1) * unit;  // wp_Wup
971*89c4ff92SAndroid Build Coastguard Worker     round(up, divisor, remainder, error);
972*89c4ff92SAndroid Build Coastguard Worker     uint64_t down = (diff + 1) * unit;  // wp_Wdown
973*89c4ff92SAndroid Build Coastguard Worker     if (remainder < down && error - remainder >= divisor &&
974*89c4ff92SAndroid Build Coastguard Worker         (remainder + divisor < down ||
975*89c4ff92SAndroid Build Coastguard Worker          down - remainder > remainder + divisor - down)) {
976*89c4ff92SAndroid Build Coastguard Worker       return digits::error;
977*89c4ff92SAndroid Build Coastguard Worker     }
978*89c4ff92SAndroid Build Coastguard Worker     return 2 * unit <= remainder && remainder <= error - 4 * unit
979*89c4ff92SAndroid Build Coastguard Worker                ? digits::done
980*89c4ff92SAndroid Build Coastguard Worker                : digits::error;
981*89c4ff92SAndroid Build Coastguard Worker   }
982*89c4ff92SAndroid Build Coastguard Worker };
983*89c4ff92SAndroid Build Coastguard Worker 
984*89c4ff92SAndroid Build Coastguard Worker // Formats value using a variation of the Fixed-Precision Positive
985*89c4ff92SAndroid Build Coastguard Worker // Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
986*89c4ff92SAndroid Build Coastguard Worker // https://fmt.dev/p372-steele.pdf.
987*89c4ff92SAndroid Build Coastguard Worker template <typename Double>
988*89c4ff92SAndroid Build Coastguard Worker void fallback_format(Double d, buffer<char>& buf, int& exp10) {
989*89c4ff92SAndroid Build Coastguard Worker   bigint numerator;    // 2 * R in (FPP)^2.
990*89c4ff92SAndroid Build Coastguard Worker   bigint denominator;  // 2 * S in (FPP)^2.
991*89c4ff92SAndroid Build Coastguard Worker   // lower and upper are differences between value and corresponding boundaries.
992*89c4ff92SAndroid Build Coastguard Worker   bigint lower;             // (M^- in (FPP)^2).
993*89c4ff92SAndroid Build Coastguard Worker   bigint upper_store;       // upper's value if different from lower.
994*89c4ff92SAndroid Build Coastguard Worker   bigint* upper = nullptr;  // (M^+ in (FPP)^2).
995*89c4ff92SAndroid Build Coastguard Worker   fp value;
996*89c4ff92SAndroid Build Coastguard Worker   // Shift numerator and denominator by an extra bit or two (if lower boundary
997*89c4ff92SAndroid Build Coastguard Worker   // is closer) to make lower and upper integers. This eliminates multiplication
998*89c4ff92SAndroid Build Coastguard Worker   // by 2 during later computations.
999*89c4ff92SAndroid Build Coastguard Worker   // TODO: handle float
1000*89c4ff92SAndroid Build Coastguard Worker   int shift = value.assign(d) ? 2 : 1;
1001*89c4ff92SAndroid Build Coastguard Worker   uint64_t significand = value.f << shift;
1002*89c4ff92SAndroid Build Coastguard Worker   if (value.e >= 0) {
1003*89c4ff92SAndroid Build Coastguard Worker     numerator.assign(significand);
1004*89c4ff92SAndroid Build Coastguard Worker     numerator <<= value.e;
1005*89c4ff92SAndroid Build Coastguard Worker     lower.assign(1);
1006*89c4ff92SAndroid Build Coastguard Worker     lower <<= value.e;
1007*89c4ff92SAndroid Build Coastguard Worker     if (shift != 1) {
1008*89c4ff92SAndroid Build Coastguard Worker       upper_store.assign(1);
1009*89c4ff92SAndroid Build Coastguard Worker       upper_store <<= value.e + 1;
1010*89c4ff92SAndroid Build Coastguard Worker       upper = &upper_store;
1011*89c4ff92SAndroid Build Coastguard Worker     }
1012*89c4ff92SAndroid Build Coastguard Worker     denominator.assign_pow10(exp10);
1013*89c4ff92SAndroid Build Coastguard Worker     denominator <<= 1;
1014*89c4ff92SAndroid Build Coastguard Worker   } else if (exp10 < 0) {
1015*89c4ff92SAndroid Build Coastguard Worker     numerator.assign_pow10(-exp10);
1016*89c4ff92SAndroid Build Coastguard Worker     lower.assign(numerator);
1017*89c4ff92SAndroid Build Coastguard Worker     if (shift != 1) {
1018*89c4ff92SAndroid Build Coastguard Worker       upper_store.assign(numerator);
1019*89c4ff92SAndroid Build Coastguard Worker       upper_store <<= 1;
1020*89c4ff92SAndroid Build Coastguard Worker       upper = &upper_store;
1021*89c4ff92SAndroid Build Coastguard Worker     }
1022*89c4ff92SAndroid Build Coastguard Worker     numerator *= significand;
1023*89c4ff92SAndroid Build Coastguard Worker     denominator.assign(1);
1024*89c4ff92SAndroid Build Coastguard Worker     denominator <<= shift - value.e;
1025*89c4ff92SAndroid Build Coastguard Worker   } else {
1026*89c4ff92SAndroid Build Coastguard Worker     numerator.assign(significand);
1027*89c4ff92SAndroid Build Coastguard Worker     denominator.assign_pow10(exp10);
1028*89c4ff92SAndroid Build Coastguard Worker     denominator <<= shift - value.e;
1029*89c4ff92SAndroid Build Coastguard Worker     lower.assign(1);
1030*89c4ff92SAndroid Build Coastguard Worker     if (shift != 1) {
1031*89c4ff92SAndroid Build Coastguard Worker       upper_store.assign(1ULL << 1);
1032*89c4ff92SAndroid Build Coastguard Worker       upper = &upper_store;
1033*89c4ff92SAndroid Build Coastguard Worker     }
1034*89c4ff92SAndroid Build Coastguard Worker   }
1035*89c4ff92SAndroid Build Coastguard Worker   if (!upper) upper = &lower;
1036*89c4ff92SAndroid Build Coastguard Worker   // Invariant: value == (numerator / denominator) * pow(10, exp10).
1037*89c4ff92SAndroid Build Coastguard Worker   bool even = (value.f & 1) == 0;
1038*89c4ff92SAndroid Build Coastguard Worker   int num_digits = 0;
1039*89c4ff92SAndroid Build Coastguard Worker   char* data = buf.data();
1040*89c4ff92SAndroid Build Coastguard Worker   for (;;) {
1041*89c4ff92SAndroid Build Coastguard Worker     int digit = numerator.divmod_assign(denominator);
1042*89c4ff92SAndroid Build Coastguard Worker     bool low = compare(numerator, lower) - even < 0;  // numerator <[=] lower.
1043*89c4ff92SAndroid Build Coastguard Worker     // numerator + upper >[=] pow10:
1044*89c4ff92SAndroid Build Coastguard Worker     bool high = add_compare(numerator, *upper, denominator) + even > 0;
1045*89c4ff92SAndroid Build Coastguard Worker     data[num_digits++] = static_cast<char>('0' + digit);
1046*89c4ff92SAndroid Build Coastguard Worker     if (low || high) {
1047*89c4ff92SAndroid Build Coastguard Worker       if (!low) {
1048*89c4ff92SAndroid Build Coastguard Worker         ++data[num_digits - 1];
1049*89c4ff92SAndroid Build Coastguard Worker       } else if (high) {
1050*89c4ff92SAndroid Build Coastguard Worker         int result = add_compare(numerator, numerator, denominator);
1051*89c4ff92SAndroid Build Coastguard Worker         // Round half to even.
1052*89c4ff92SAndroid Build Coastguard Worker         if (result > 0 || (result == 0 && (digit % 2) != 0))
1053*89c4ff92SAndroid Build Coastguard Worker           ++data[num_digits - 1];
1054*89c4ff92SAndroid Build Coastguard Worker       }
1055*89c4ff92SAndroid Build Coastguard Worker       buf.try_resize(to_unsigned(num_digits));
1056*89c4ff92SAndroid Build Coastguard Worker       exp10 -= num_digits - 1;
1057*89c4ff92SAndroid Build Coastguard Worker       return;
1058*89c4ff92SAndroid Build Coastguard Worker     }
1059*89c4ff92SAndroid Build Coastguard Worker     numerator *= 10;
1060*89c4ff92SAndroid Build Coastguard Worker     lower *= 10;
1061*89c4ff92SAndroid Build Coastguard Worker     if (upper != &lower) *upper *= 10;
1062*89c4ff92SAndroid Build Coastguard Worker   }
1063*89c4ff92SAndroid Build Coastguard Worker }
1064*89c4ff92SAndroid Build Coastguard Worker 
1065*89c4ff92SAndroid Build Coastguard Worker // Formats value using the Grisu algorithm
1066*89c4ff92SAndroid Build Coastguard Worker // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf)
1067*89c4ff92SAndroid Build Coastguard Worker // if T is a IEEE754 binary32 or binary64 and snprintf otherwise.
1068*89c4ff92SAndroid Build Coastguard Worker template <typename T>
1069*89c4ff92SAndroid Build Coastguard Worker int format_float(T value, int precision, float_specs specs, buffer<char>& buf) {
1070*89c4ff92SAndroid Build Coastguard Worker   static_assert(!std::is_same<T, float>::value, "");
1071*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(value >= 0, "value is negative");
1072*89c4ff92SAndroid Build Coastguard Worker 
1073*89c4ff92SAndroid Build Coastguard Worker   const bool fixed = specs.format == float_format::fixed;
1074*89c4ff92SAndroid Build Coastguard Worker   if (value <= 0) {  // <= instead of == to silence a warning.
1075*89c4ff92SAndroid Build Coastguard Worker     if (precision <= 0 || !fixed) {
1076*89c4ff92SAndroid Build Coastguard Worker       buf.push_back('0');
1077*89c4ff92SAndroid Build Coastguard Worker       return 0;
1078*89c4ff92SAndroid Build Coastguard Worker     }
1079*89c4ff92SAndroid Build Coastguard Worker     buf.try_resize(to_unsigned(precision));
1080*89c4ff92SAndroid Build Coastguard Worker     std::uninitialized_fill_n(buf.data(), precision, '0');
1081*89c4ff92SAndroid Build Coastguard Worker     return -precision;
1082*89c4ff92SAndroid Build Coastguard Worker   }
1083*89c4ff92SAndroid Build Coastguard Worker 
1084*89c4ff92SAndroid Build Coastguard Worker   if (!specs.use_grisu) return snprintf_float(value, precision, specs, buf);
1085*89c4ff92SAndroid Build Coastguard Worker 
1086*89c4ff92SAndroid Build Coastguard Worker   int exp = 0;
1087*89c4ff92SAndroid Build Coastguard Worker   const int min_exp = -60;  // alpha in Grisu.
1088*89c4ff92SAndroid Build Coastguard Worker   int cached_exp10 = 0;     // K in Grisu.
1089*89c4ff92SAndroid Build Coastguard Worker   if (precision < 0) {
1090*89c4ff92SAndroid Build Coastguard Worker     fp fp_value;
1091*89c4ff92SAndroid Build Coastguard Worker     auto boundaries = specs.binary32
1092*89c4ff92SAndroid Build Coastguard Worker                           ? fp_value.assign_float_with_boundaries(value)
1093*89c4ff92SAndroid Build Coastguard Worker                           : fp_value.assign_with_boundaries(value);
1094*89c4ff92SAndroid Build Coastguard Worker     fp_value = normalize(fp_value);
1095*89c4ff92SAndroid Build Coastguard Worker     // Find a cached power of 10 such that multiplying value by it will bring
1096*89c4ff92SAndroid Build Coastguard Worker     // the exponent in the range [min_exp, -32].
1097*89c4ff92SAndroid Build Coastguard Worker     const fp cached_pow = get_cached_power(
1098*89c4ff92SAndroid Build Coastguard Worker         min_exp - (fp_value.e + fp::significand_size), cached_exp10);
1099*89c4ff92SAndroid Build Coastguard Worker     // Multiply value and boundaries by the cached power of 10.
1100*89c4ff92SAndroid Build Coastguard Worker     fp_value = fp_value * cached_pow;
1101*89c4ff92SAndroid Build Coastguard Worker     boundaries.lower = multiply(boundaries.lower, cached_pow.f);
1102*89c4ff92SAndroid Build Coastguard Worker     boundaries.upper = multiply(boundaries.upper, cached_pow.f);
1103*89c4ff92SAndroid Build Coastguard Worker     assert(min_exp <= fp_value.e && fp_value.e <= -32);
1104*89c4ff92SAndroid Build Coastguard Worker     --boundaries.lower;  // \tilde{M}^- - 1 ulp -> M^-_{\downarrow}.
1105*89c4ff92SAndroid Build Coastguard Worker     ++boundaries.upper;  // \tilde{M}^+ + 1 ulp -> M^+_{\uparrow}.
1106*89c4ff92SAndroid Build Coastguard Worker     // Numbers outside of (lower, upper) definitely do not round to value.
1107*89c4ff92SAndroid Build Coastguard Worker     grisu_shortest_handler handler{buf.data(), 0,
1108*89c4ff92SAndroid Build Coastguard Worker                                    boundaries.upper - fp_value.f};
1109*89c4ff92SAndroid Build Coastguard Worker     auto result =
1110*89c4ff92SAndroid Build Coastguard Worker         grisu_gen_digits(fp(boundaries.upper, fp_value.e),
1111*89c4ff92SAndroid Build Coastguard Worker                          boundaries.upper - boundaries.lower, exp, handler);
1112*89c4ff92SAndroid Build Coastguard Worker     if (result == digits::error) {
1113*89c4ff92SAndroid Build Coastguard Worker       exp += handler.size - cached_exp10 - 1;
1114*89c4ff92SAndroid Build Coastguard Worker       fallback_format(value, buf, exp);
1115*89c4ff92SAndroid Build Coastguard Worker       return exp;
1116*89c4ff92SAndroid Build Coastguard Worker     }
1117*89c4ff92SAndroid Build Coastguard Worker     buf.try_resize(to_unsigned(handler.size));
1118*89c4ff92SAndroid Build Coastguard Worker   } else {
1119*89c4ff92SAndroid Build Coastguard Worker     if (precision > 17) return snprintf_float(value, precision, specs, buf);
1120*89c4ff92SAndroid Build Coastguard Worker     fp normalized = normalize(fp(value));
1121*89c4ff92SAndroid Build Coastguard Worker     const auto cached_pow = get_cached_power(
1122*89c4ff92SAndroid Build Coastguard Worker         min_exp - (normalized.e + fp::significand_size), cached_exp10);
1123*89c4ff92SAndroid Build Coastguard Worker     normalized = normalized * cached_pow;
1124*89c4ff92SAndroid Build Coastguard Worker     fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
1125*89c4ff92SAndroid Build Coastguard Worker     if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error)
1126*89c4ff92SAndroid Build Coastguard Worker       return snprintf_float(value, precision, specs, buf);
1127*89c4ff92SAndroid Build Coastguard Worker     int num_digits = handler.size;
1128*89c4ff92SAndroid Build Coastguard Worker     if (!fixed) {
1129*89c4ff92SAndroid Build Coastguard Worker       // Remove trailing zeros.
1130*89c4ff92SAndroid Build Coastguard Worker       while (num_digits > 0 && buf[num_digits - 1] == '0') {
1131*89c4ff92SAndroid Build Coastguard Worker         --num_digits;
1132*89c4ff92SAndroid Build Coastguard Worker         ++exp;
1133*89c4ff92SAndroid Build Coastguard Worker       }
1134*89c4ff92SAndroid Build Coastguard Worker     }
1135*89c4ff92SAndroid Build Coastguard Worker     buf.try_resize(to_unsigned(num_digits));
1136*89c4ff92SAndroid Build Coastguard Worker   }
1137*89c4ff92SAndroid Build Coastguard Worker   return exp - cached_exp10;
1138*89c4ff92SAndroid Build Coastguard Worker }
1139*89c4ff92SAndroid Build Coastguard Worker 
1140*89c4ff92SAndroid Build Coastguard Worker template <typename T>
1141*89c4ff92SAndroid Build Coastguard Worker int snprintf_float(T value, int precision, float_specs specs,
1142*89c4ff92SAndroid Build Coastguard Worker                    buffer<char>& buf) {
1143*89c4ff92SAndroid Build Coastguard Worker   // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
1144*89c4ff92SAndroid Build Coastguard Worker   FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
1145*89c4ff92SAndroid Build Coastguard Worker   static_assert(!std::is_same<T, float>::value, "");
1146*89c4ff92SAndroid Build Coastguard Worker 
1147*89c4ff92SAndroid Build Coastguard Worker   // Subtract 1 to account for the difference in precision since we use %e for
1148*89c4ff92SAndroid Build Coastguard Worker   // both general and exponent format.
1149*89c4ff92SAndroid Build Coastguard Worker   if (specs.format == float_format::general ||
1150*89c4ff92SAndroid Build Coastguard Worker       specs.format == float_format::exp)
1151*89c4ff92SAndroid Build Coastguard Worker     precision = (precision >= 0 ? precision : 6) - 1;
1152*89c4ff92SAndroid Build Coastguard Worker 
1153*89c4ff92SAndroid Build Coastguard Worker   // Build the format string.
1154*89c4ff92SAndroid Build Coastguard Worker   enum { max_format_size = 7 };  // The longest format is "%#.*Le".
1155*89c4ff92SAndroid Build Coastguard Worker   char format[max_format_size];
1156*89c4ff92SAndroid Build Coastguard Worker   char* format_ptr = format;
1157*89c4ff92SAndroid Build Coastguard Worker   *format_ptr++ = '%';
1158*89c4ff92SAndroid Build Coastguard Worker   if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#';
1159*89c4ff92SAndroid Build Coastguard Worker   if (precision >= 0) {
1160*89c4ff92SAndroid Build Coastguard Worker     *format_ptr++ = '.';
1161*89c4ff92SAndroid Build Coastguard Worker     *format_ptr++ = '*';
1162*89c4ff92SAndroid Build Coastguard Worker   }
1163*89c4ff92SAndroid Build Coastguard Worker   if (std::is_same<T, long double>()) *format_ptr++ = 'L';
1164*89c4ff92SAndroid Build Coastguard Worker   *format_ptr++ = specs.format != float_format::hex
1165*89c4ff92SAndroid Build Coastguard Worker                       ? (specs.format == float_format::fixed ? 'f' : 'e')
1166*89c4ff92SAndroid Build Coastguard Worker                       : (specs.upper ? 'A' : 'a');
1167*89c4ff92SAndroid Build Coastguard Worker   *format_ptr = '\0';
1168*89c4ff92SAndroid Build Coastguard Worker 
1169*89c4ff92SAndroid Build Coastguard Worker   // Format using snprintf.
1170*89c4ff92SAndroid Build Coastguard Worker   auto offset = buf.size();
1171*89c4ff92SAndroid Build Coastguard Worker   for (;;) {
1172*89c4ff92SAndroid Build Coastguard Worker     auto begin = buf.data() + offset;
1173*89c4ff92SAndroid Build Coastguard Worker     auto capacity = buf.capacity() - offset;
1174*89c4ff92SAndroid Build Coastguard Worker #ifdef FMT_FUZZ
1175*89c4ff92SAndroid Build Coastguard Worker     if (precision > 100000)
1176*89c4ff92SAndroid Build Coastguard Worker       throw std::runtime_error(
1177*89c4ff92SAndroid Build Coastguard Worker           "fuzz mode - avoid large allocation inside snprintf");
1178*89c4ff92SAndroid Build Coastguard Worker #endif
1179*89c4ff92SAndroid Build Coastguard Worker     // Suppress the warning about a nonliteral format string.
1180*89c4ff92SAndroid Build Coastguard Worker     // Cannot use auto because of a bug in MinGW (#1532).
1181*89c4ff92SAndroid Build Coastguard Worker     int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
1182*89c4ff92SAndroid Build Coastguard Worker     int result = precision >= 0
1183*89c4ff92SAndroid Build Coastguard Worker                      ? snprintf_ptr(begin, capacity, format, precision, value)
1184*89c4ff92SAndroid Build Coastguard Worker                      : snprintf_ptr(begin, capacity, format, value);
1185*89c4ff92SAndroid Build Coastguard Worker     if (result < 0) {
1186*89c4ff92SAndroid Build Coastguard Worker       // The buffer will grow exponentially.
1187*89c4ff92SAndroid Build Coastguard Worker       buf.try_reserve(buf.capacity() + 1);
1188*89c4ff92SAndroid Build Coastguard Worker       continue;
1189*89c4ff92SAndroid Build Coastguard Worker     }
1190*89c4ff92SAndroid Build Coastguard Worker     auto size = to_unsigned(result);
1191*89c4ff92SAndroid Build Coastguard Worker     // Size equal to capacity means that the last character was truncated.
1192*89c4ff92SAndroid Build Coastguard Worker     if (size >= capacity) {
1193*89c4ff92SAndroid Build Coastguard Worker       buf.try_reserve(size + offset + 1);  // Add 1 for the terminating '\0'.
1194*89c4ff92SAndroid Build Coastguard Worker       continue;
1195*89c4ff92SAndroid Build Coastguard Worker     }
1196*89c4ff92SAndroid Build Coastguard Worker     auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
1197*89c4ff92SAndroid Build Coastguard Worker     if (specs.format == float_format::fixed) {
1198*89c4ff92SAndroid Build Coastguard Worker       if (precision == 0) {
1199*89c4ff92SAndroid Build Coastguard Worker         buf.try_resize(size);
1200*89c4ff92SAndroid Build Coastguard Worker         return 0;
1201*89c4ff92SAndroid Build Coastguard Worker       }
1202*89c4ff92SAndroid Build Coastguard Worker       // Find and remove the decimal point.
1203*89c4ff92SAndroid Build Coastguard Worker       auto end = begin + size, p = end;
1204*89c4ff92SAndroid Build Coastguard Worker       do {
1205*89c4ff92SAndroid Build Coastguard Worker         --p;
1206*89c4ff92SAndroid Build Coastguard Worker       } while (is_digit(*p));
1207*89c4ff92SAndroid Build Coastguard Worker       int fraction_size = static_cast<int>(end - p - 1);
1208*89c4ff92SAndroid Build Coastguard Worker       std::memmove(p, p + 1, to_unsigned(fraction_size));
1209*89c4ff92SAndroid Build Coastguard Worker       buf.try_resize(size - 1);
1210*89c4ff92SAndroid Build Coastguard Worker       return -fraction_size;
1211*89c4ff92SAndroid Build Coastguard Worker     }
1212*89c4ff92SAndroid Build Coastguard Worker     if (specs.format == float_format::hex) {
1213*89c4ff92SAndroid Build Coastguard Worker       buf.try_resize(size + offset);
1214*89c4ff92SAndroid Build Coastguard Worker       return 0;
1215*89c4ff92SAndroid Build Coastguard Worker     }
1216*89c4ff92SAndroid Build Coastguard Worker     // Find and parse the exponent.
1217*89c4ff92SAndroid Build Coastguard Worker     auto end = begin + size, exp_pos = end;
1218*89c4ff92SAndroid Build Coastguard Worker     do {
1219*89c4ff92SAndroid Build Coastguard Worker       --exp_pos;
1220*89c4ff92SAndroid Build Coastguard Worker     } while (*exp_pos != 'e');
1221*89c4ff92SAndroid Build Coastguard Worker     char sign = exp_pos[1];
1222*89c4ff92SAndroid Build Coastguard Worker     assert(sign == '+' || sign == '-');
1223*89c4ff92SAndroid Build Coastguard Worker     int exp = 0;
1224*89c4ff92SAndroid Build Coastguard Worker     auto p = exp_pos + 2;  // Skip 'e' and sign.
1225*89c4ff92SAndroid Build Coastguard Worker     do {
1226*89c4ff92SAndroid Build Coastguard Worker       assert(is_digit(*p));
1227*89c4ff92SAndroid Build Coastguard Worker       exp = exp * 10 + (*p++ - '0');
1228*89c4ff92SAndroid Build Coastguard Worker     } while (p != end);
1229*89c4ff92SAndroid Build Coastguard Worker     if (sign == '-') exp = -exp;
1230*89c4ff92SAndroid Build Coastguard Worker     int fraction_size = 0;
1231*89c4ff92SAndroid Build Coastguard Worker     if (exp_pos != begin + 1) {
1232*89c4ff92SAndroid Build Coastguard Worker       // Remove trailing zeros.
1233*89c4ff92SAndroid Build Coastguard Worker       auto fraction_end = exp_pos - 1;
1234*89c4ff92SAndroid Build Coastguard Worker       while (*fraction_end == '0') --fraction_end;
1235*89c4ff92SAndroid Build Coastguard Worker       // Move the fractional part left to get rid of the decimal point.
1236*89c4ff92SAndroid Build Coastguard Worker       fraction_size = static_cast<int>(fraction_end - begin - 1);
1237*89c4ff92SAndroid Build Coastguard Worker       std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size));
1238*89c4ff92SAndroid Build Coastguard Worker     }
1239*89c4ff92SAndroid Build Coastguard Worker     buf.try_resize(to_unsigned(fraction_size) + offset + 1);
1240*89c4ff92SAndroid Build Coastguard Worker     return exp - fraction_size;
1241*89c4ff92SAndroid Build Coastguard Worker   }
1242*89c4ff92SAndroid Build Coastguard Worker }
1243*89c4ff92SAndroid Build Coastguard Worker 
1244*89c4ff92SAndroid Build Coastguard Worker // A public domain branchless UTF-8 decoder by Christopher Wellons:
1245*89c4ff92SAndroid Build Coastguard Worker // https://github.com/skeeto/branchless-utf8
1246*89c4ff92SAndroid Build Coastguard Worker /* Decode the next character, c, from buf, reporting errors in e.
1247*89c4ff92SAndroid Build Coastguard Worker  *
1248*89c4ff92SAndroid Build Coastguard Worker  * Since this is a branchless decoder, four bytes will be read from the
1249*89c4ff92SAndroid Build Coastguard Worker  * buffer regardless of the actual length of the next character. This
1250*89c4ff92SAndroid Build Coastguard Worker  * means the buffer _must_ have at least three bytes of zero padding
1251*89c4ff92SAndroid Build Coastguard Worker  * following the end of the data stream.
1252*89c4ff92SAndroid Build Coastguard Worker  *
1253*89c4ff92SAndroid Build Coastguard Worker  * Errors are reported in e, which will be non-zero if the parsed
1254*89c4ff92SAndroid Build Coastguard Worker  * character was somehow invalid: invalid byte sequence, non-canonical
1255*89c4ff92SAndroid Build Coastguard Worker  * encoding, or a surrogate half.
1256*89c4ff92SAndroid Build Coastguard Worker  *
1257*89c4ff92SAndroid Build Coastguard Worker  * The function returns a pointer to the next character. When an error
1258*89c4ff92SAndroid Build Coastguard Worker  * occurs, this pointer will be a guess that depends on the particular
1259*89c4ff92SAndroid Build Coastguard Worker  * error, but it will always advance at least one byte.
1260*89c4ff92SAndroid Build Coastguard Worker  */
1261*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC const char* utf8_decode(const char* buf, uint32_t* c, int* e) {
1262*89c4ff92SAndroid Build Coastguard Worker   static const char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1263*89c4ff92SAndroid Build Coastguard Worker                                  1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1264*89c4ff92SAndroid Build Coastguard Worker                                  0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
1265*89c4ff92SAndroid Build Coastguard Worker   static const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
1266*89c4ff92SAndroid Build Coastguard Worker   static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
1267*89c4ff92SAndroid Build Coastguard Worker   static const int shiftc[] = {0, 18, 12, 6, 0};
1268*89c4ff92SAndroid Build Coastguard Worker   static const int shifte[] = {0, 6, 4, 2, 0};
1269*89c4ff92SAndroid Build Coastguard Worker 
1270*89c4ff92SAndroid Build Coastguard Worker   auto s = reinterpret_cast<const unsigned char*>(buf);
1271*89c4ff92SAndroid Build Coastguard Worker   int len = lengths[s[0] >> 3];
1272*89c4ff92SAndroid Build Coastguard Worker 
1273*89c4ff92SAndroid Build Coastguard Worker   // Compute the pointer to the next character early so that the next
1274*89c4ff92SAndroid Build Coastguard Worker   // iteration can start working on the next character. Neither Clang
1275*89c4ff92SAndroid Build Coastguard Worker   // nor GCC figure out this reordering on their own.
1276*89c4ff92SAndroid Build Coastguard Worker   const char* next = buf + len + !len;
1277*89c4ff92SAndroid Build Coastguard Worker 
1278*89c4ff92SAndroid Build Coastguard Worker   // Assume a four-byte character and load four bytes. Unused bits are
1279*89c4ff92SAndroid Build Coastguard Worker   // shifted out.
1280*89c4ff92SAndroid Build Coastguard Worker   *c = uint32_t(s[0] & masks[len]) << 18;
1281*89c4ff92SAndroid Build Coastguard Worker   *c |= uint32_t(s[1] & 0x3f) << 12;
1282*89c4ff92SAndroid Build Coastguard Worker   *c |= uint32_t(s[2] & 0x3f) << 6;
1283*89c4ff92SAndroid Build Coastguard Worker   *c |= uint32_t(s[3] & 0x3f) << 0;
1284*89c4ff92SAndroid Build Coastguard Worker   *c >>= shiftc[len];
1285*89c4ff92SAndroid Build Coastguard Worker 
1286*89c4ff92SAndroid Build Coastguard Worker   // Accumulate the various error conditions.
1287*89c4ff92SAndroid Build Coastguard Worker   *e = (*c < mins[len]) << 6;       // non-canonical encoding
1288*89c4ff92SAndroid Build Coastguard Worker   *e |= ((*c >> 11) == 0x1b) << 7;  // surrogate half?
1289*89c4ff92SAndroid Build Coastguard Worker   *e |= (*c > 0x10FFFF) << 8;       // out of range?
1290*89c4ff92SAndroid Build Coastguard Worker   *e |= (s[1] & 0xc0) >> 2;
1291*89c4ff92SAndroid Build Coastguard Worker   *e |= (s[2] & 0xc0) >> 4;
1292*89c4ff92SAndroid Build Coastguard Worker   *e |= (s[3]) >> 6;
1293*89c4ff92SAndroid Build Coastguard Worker   *e ^= 0x2a;  // top two bits of each tail byte correct?
1294*89c4ff92SAndroid Build Coastguard Worker   *e >>= shifte[len];
1295*89c4ff92SAndroid Build Coastguard Worker 
1296*89c4ff92SAndroid Build Coastguard Worker   return next;
1297*89c4ff92SAndroid Build Coastguard Worker }
1298*89c4ff92SAndroid Build Coastguard Worker 
1299*89c4ff92SAndroid Build Coastguard Worker struct stringifier {
1300*89c4ff92SAndroid Build Coastguard Worker   template <typename T> FMT_INLINE std::string operator()(T value) const {
1301*89c4ff92SAndroid Build Coastguard Worker     return to_string(value);
1302*89c4ff92SAndroid Build Coastguard Worker   }
1303*89c4ff92SAndroid Build Coastguard Worker   std::string operator()(basic_format_arg<format_context>::handle h) const {
1304*89c4ff92SAndroid Build Coastguard Worker     memory_buffer buf;
1305*89c4ff92SAndroid Build Coastguard Worker     format_parse_context parse_ctx({});
1306*89c4ff92SAndroid Build Coastguard Worker     format_context format_ctx(buffer_appender<char>(buf), {}, {});
1307*89c4ff92SAndroid Build Coastguard Worker     h.format(parse_ctx, format_ctx);
1308*89c4ff92SAndroid Build Coastguard Worker     return to_string(buf);
1309*89c4ff92SAndroid Build Coastguard Worker   }
1310*89c4ff92SAndroid Build Coastguard Worker };
1311*89c4ff92SAndroid Build Coastguard Worker }  // namespace detail
1312*89c4ff92SAndroid Build Coastguard Worker 
1313*89c4ff92SAndroid Build Coastguard Worker template <> struct formatter<detail::bigint> {
1314*89c4ff92SAndroid Build Coastguard Worker   format_parse_context::iterator parse(format_parse_context& ctx) {
1315*89c4ff92SAndroid Build Coastguard Worker     return ctx.begin();
1316*89c4ff92SAndroid Build Coastguard Worker   }
1317*89c4ff92SAndroid Build Coastguard Worker 
1318*89c4ff92SAndroid Build Coastguard Worker   format_context::iterator format(const detail::bigint& n,
1319*89c4ff92SAndroid Build Coastguard Worker                                   format_context& ctx) {
1320*89c4ff92SAndroid Build Coastguard Worker     auto out = ctx.out();
1321*89c4ff92SAndroid Build Coastguard Worker     bool first = true;
1322*89c4ff92SAndroid Build Coastguard Worker     for (auto i = n.bigits_.size(); i > 0; --i) {
1323*89c4ff92SAndroid Build Coastguard Worker       auto value = n.bigits_[i - 1u];
1324*89c4ff92SAndroid Build Coastguard Worker       if (first) {
1325*89c4ff92SAndroid Build Coastguard Worker         out = format_to(out, "{:x}", value);
1326*89c4ff92SAndroid Build Coastguard Worker         first = false;
1327*89c4ff92SAndroid Build Coastguard Worker         continue;
1328*89c4ff92SAndroid Build Coastguard Worker       }
1329*89c4ff92SAndroid Build Coastguard Worker       out = format_to(out, "{:08x}", value);
1330*89c4ff92SAndroid Build Coastguard Worker     }
1331*89c4ff92SAndroid Build Coastguard Worker     if (n.exp_ > 0)
1332*89c4ff92SAndroid Build Coastguard Worker       out = format_to(out, "p{}", n.exp_ * detail::bigint::bigit_bits);
1333*89c4ff92SAndroid Build Coastguard Worker     return out;
1334*89c4ff92SAndroid Build Coastguard Worker   }
1335*89c4ff92SAndroid Build Coastguard Worker };
1336*89c4ff92SAndroid Build Coastguard Worker 
1337*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
1338*89c4ff92SAndroid Build Coastguard Worker   auto transcode = [this](const char* p) {
1339*89c4ff92SAndroid Build Coastguard Worker     auto cp = uint32_t();
1340*89c4ff92SAndroid Build Coastguard Worker     auto error = 0;
1341*89c4ff92SAndroid Build Coastguard Worker     p = utf8_decode(p, &cp, &error);
1342*89c4ff92SAndroid Build Coastguard Worker     if (error != 0) FMT_THROW(std::runtime_error("invalid utf8"));
1343*89c4ff92SAndroid Build Coastguard Worker     if (cp <= 0xFFFF) {
1344*89c4ff92SAndroid Build Coastguard Worker       buffer_.push_back(static_cast<wchar_t>(cp));
1345*89c4ff92SAndroid Build Coastguard Worker     } else {
1346*89c4ff92SAndroid Build Coastguard Worker       cp -= 0x10000;
1347*89c4ff92SAndroid Build Coastguard Worker       buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10)));
1348*89c4ff92SAndroid Build Coastguard Worker       buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));
1349*89c4ff92SAndroid Build Coastguard Worker     }
1350*89c4ff92SAndroid Build Coastguard Worker     return p;
1351*89c4ff92SAndroid Build Coastguard Worker   };
1352*89c4ff92SAndroid Build Coastguard Worker   auto p = s.data();
1353*89c4ff92SAndroid Build Coastguard Worker   const size_t block_size = 4;  // utf8_decode always reads blocks of 4 chars.
1354*89c4ff92SAndroid Build Coastguard Worker   if (s.size() >= block_size) {
1355*89c4ff92SAndroid Build Coastguard Worker     for (auto end = p + s.size() - block_size + 1; p < end;) p = transcode(p);
1356*89c4ff92SAndroid Build Coastguard Worker   }
1357*89c4ff92SAndroid Build Coastguard Worker   if (auto num_chars_left = s.data() + s.size() - p) {
1358*89c4ff92SAndroid Build Coastguard Worker     char buf[2 * block_size - 1] = {};
1359*89c4ff92SAndroid Build Coastguard Worker     memcpy(buf, p, to_unsigned(num_chars_left));
1360*89c4ff92SAndroid Build Coastguard Worker     p = buf;
1361*89c4ff92SAndroid Build Coastguard Worker     do {
1362*89c4ff92SAndroid Build Coastguard Worker       p = transcode(p);
1363*89c4ff92SAndroid Build Coastguard Worker     } while (p - buf < num_chars_left);
1364*89c4ff92SAndroid Build Coastguard Worker   }
1365*89c4ff92SAndroid Build Coastguard Worker   buffer_.push_back(0);
1366*89c4ff92SAndroid Build Coastguard Worker }
1367*89c4ff92SAndroid Build Coastguard Worker 
1368*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
1369*89c4ff92SAndroid Build Coastguard Worker                                   string_view message) FMT_NOEXCEPT {
1370*89c4ff92SAndroid Build Coastguard Worker   FMT_TRY {
1371*89c4ff92SAndroid Build Coastguard Worker     memory_buffer buf;
1372*89c4ff92SAndroid Build Coastguard Worker     buf.resize(inline_buffer_size);
1373*89c4ff92SAndroid Build Coastguard Worker     for (;;) {
1374*89c4ff92SAndroid Build Coastguard Worker       char* system_message = &buf[0];
1375*89c4ff92SAndroid Build Coastguard Worker       int result =
1376*89c4ff92SAndroid Build Coastguard Worker           detail::safe_strerror(error_code, system_message, buf.size());
1377*89c4ff92SAndroid Build Coastguard Worker       if (result == 0) {
1378*89c4ff92SAndroid Build Coastguard Worker         format_to(detail::buffer_appender<char>(out), "{}: {}", message,
1379*89c4ff92SAndroid Build Coastguard Worker                   system_message);
1380*89c4ff92SAndroid Build Coastguard Worker         return;
1381*89c4ff92SAndroid Build Coastguard Worker       }
1382*89c4ff92SAndroid Build Coastguard Worker       if (result != ERANGE)
1383*89c4ff92SAndroid Build Coastguard Worker         break;  // Can't get error message, report error code instead.
1384*89c4ff92SAndroid Build Coastguard Worker       buf.resize(buf.size() * 2);
1385*89c4ff92SAndroid Build Coastguard Worker     }
1386*89c4ff92SAndroid Build Coastguard Worker   }
1387*89c4ff92SAndroid Build Coastguard Worker   FMT_CATCH(...) {}
1388*89c4ff92SAndroid Build Coastguard Worker   format_error_code(out, error_code, message);
1389*89c4ff92SAndroid Build Coastguard Worker }
1390*89c4ff92SAndroid Build Coastguard Worker 
1391*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void detail::error_handler::on_error(const char* message) {
1392*89c4ff92SAndroid Build Coastguard Worker   FMT_THROW(format_error(message));
1393*89c4ff92SAndroid Build Coastguard Worker }
1394*89c4ff92SAndroid Build Coastguard Worker 
1395*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void report_system_error(int error_code,
1396*89c4ff92SAndroid Build Coastguard Worker                                   fmt::string_view message) FMT_NOEXCEPT {
1397*89c4ff92SAndroid Build Coastguard Worker   report_error(format_system_error, error_code, message);
1398*89c4ff92SAndroid Build Coastguard Worker }
1399*89c4ff92SAndroid Build Coastguard Worker 
1400*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC std::string detail::vformat(string_view format_str, format_args args) {
1401*89c4ff92SAndroid Build Coastguard Worker   if (format_str.size() == 2 && equal2(format_str.data(), "{}")) {
1402*89c4ff92SAndroid Build Coastguard Worker     auto arg = args.get(0);
1403*89c4ff92SAndroid Build Coastguard Worker     if (!arg) error_handler().on_error("argument not found");
1404*89c4ff92SAndroid Build Coastguard Worker     return visit_format_arg(stringifier(), arg);
1405*89c4ff92SAndroid Build Coastguard Worker   }
1406*89c4ff92SAndroid Build Coastguard Worker   memory_buffer buffer;
1407*89c4ff92SAndroid Build Coastguard Worker   detail::vformat_to(buffer, format_str, args);
1408*89c4ff92SAndroid Build Coastguard Worker   return to_string(buffer);
1409*89c4ff92SAndroid Build Coastguard Worker }
1410*89c4ff92SAndroid Build Coastguard Worker 
1411*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
1412*89c4ff92SAndroid Build Coastguard Worker   memory_buffer buffer;
1413*89c4ff92SAndroid Build Coastguard Worker   detail::vformat_to(buffer, format_str,
1414*89c4ff92SAndroid Build Coastguard Worker                      basic_format_args<buffer_context<char>>(args));
1415*89c4ff92SAndroid Build Coastguard Worker #ifdef _WIN32
1416*89c4ff92SAndroid Build Coastguard Worker   auto fd = _fileno(f);
1417*89c4ff92SAndroid Build Coastguard Worker   if (_isatty(fd)) {
1418*89c4ff92SAndroid Build Coastguard Worker     detail::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size()));
1419*89c4ff92SAndroid Build Coastguard Worker     auto written = DWORD();
1420*89c4ff92SAndroid Build Coastguard Worker     if (!WriteConsoleW(reinterpret_cast<HANDLE>(_get_osfhandle(fd)),
1421*89c4ff92SAndroid Build Coastguard Worker                        u16.c_str(), static_cast<DWORD>(u16.size()), &written,
1422*89c4ff92SAndroid Build Coastguard Worker                        nullptr)) {
1423*89c4ff92SAndroid Build Coastguard Worker       FMT_THROW(format_error("failed to write to console"));
1424*89c4ff92SAndroid Build Coastguard Worker     }
1425*89c4ff92SAndroid Build Coastguard Worker     return;
1426*89c4ff92SAndroid Build Coastguard Worker   }
1427*89c4ff92SAndroid Build Coastguard Worker #endif
1428*89c4ff92SAndroid Build Coastguard Worker   detail::fwrite_fully(buffer.data(), 1, buffer.size(), f);
1429*89c4ff92SAndroid Build Coastguard Worker }
1430*89c4ff92SAndroid Build Coastguard Worker 
1431*89c4ff92SAndroid Build Coastguard Worker #ifdef _WIN32
1432*89c4ff92SAndroid Build Coastguard Worker // Print assuming legacy (non-Unicode) encoding.
1433*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
1434*89c4ff92SAndroid Build Coastguard Worker                                       format_args args) {
1435*89c4ff92SAndroid Build Coastguard Worker   memory_buffer buffer;
1436*89c4ff92SAndroid Build Coastguard Worker   detail::vformat_to(buffer, format_str,
1437*89c4ff92SAndroid Build Coastguard Worker                      basic_format_args<buffer_context<char>>(args));
1438*89c4ff92SAndroid Build Coastguard Worker   fwrite_fully(buffer.data(), 1, buffer.size(), f);
1439*89c4ff92SAndroid Build Coastguard Worker }
1440*89c4ff92SAndroid Build Coastguard Worker #endif
1441*89c4ff92SAndroid Build Coastguard Worker 
1442*89c4ff92SAndroid Build Coastguard Worker FMT_FUNC void vprint(string_view format_str, format_args args) {
1443*89c4ff92SAndroid Build Coastguard Worker   vprint(stdout, format_str, args);
1444*89c4ff92SAndroid Build Coastguard Worker }
1445*89c4ff92SAndroid Build Coastguard Worker 
1446*89c4ff92SAndroid Build Coastguard Worker FMT_END_NAMESPACE
1447*89c4ff92SAndroid Build Coastguard Worker 
1448*89c4ff92SAndroid Build Coastguard Worker #ifdef _MSC_VER
1449*89c4ff92SAndroid Build Coastguard Worker #  pragma warning(pop)
1450*89c4ff92SAndroid Build Coastguard Worker #endif
1451*89c4ff92SAndroid Build Coastguard Worker 
1452*89c4ff92SAndroid Build Coastguard Worker #endif  // FMT_FORMAT_INL_H_
1453