xref: /aosp_15_r20/external/fmtlib/include/fmt/format.h (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
1*5c90c05cSAndroid Build Coastguard Worker /*
2*5c90c05cSAndroid Build Coastguard Worker   Formatting library for C++
3*5c90c05cSAndroid Build Coastguard Worker 
4*5c90c05cSAndroid Build Coastguard Worker   Copyright (c) 2012 - present, Victor Zverovich
5*5c90c05cSAndroid Build Coastguard Worker 
6*5c90c05cSAndroid Build Coastguard Worker   Permission is hereby granted, free of charge, to any person obtaining
7*5c90c05cSAndroid Build Coastguard Worker   a copy of this software and associated documentation files (the
8*5c90c05cSAndroid Build Coastguard Worker   "Software"), to deal in the Software without restriction, including
9*5c90c05cSAndroid Build Coastguard Worker   without limitation the rights to use, copy, modify, merge, publish,
10*5c90c05cSAndroid Build Coastguard Worker   distribute, sublicense, and/or sell copies of the Software, and to
11*5c90c05cSAndroid Build Coastguard Worker   permit persons to whom the Software is furnished to do so, subject to
12*5c90c05cSAndroid Build Coastguard Worker   the following conditions:
13*5c90c05cSAndroid Build Coastguard Worker 
14*5c90c05cSAndroid Build Coastguard Worker   The above copyright notice and this permission notice shall be
15*5c90c05cSAndroid Build Coastguard Worker   included in all copies or substantial portions of the Software.
16*5c90c05cSAndroid Build Coastguard Worker 
17*5c90c05cSAndroid Build Coastguard Worker   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18*5c90c05cSAndroid Build Coastguard Worker   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*5c90c05cSAndroid Build Coastguard Worker   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20*5c90c05cSAndroid Build Coastguard Worker   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21*5c90c05cSAndroid Build Coastguard Worker   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22*5c90c05cSAndroid Build Coastguard Worker   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23*5c90c05cSAndroid Build Coastguard Worker   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24*5c90c05cSAndroid Build Coastguard Worker 
25*5c90c05cSAndroid Build Coastguard Worker   --- Optional exception to the license ---
26*5c90c05cSAndroid Build Coastguard Worker 
27*5c90c05cSAndroid Build Coastguard Worker   As an exception, if, as a result of your compiling your source code, portions
28*5c90c05cSAndroid Build Coastguard Worker   of this Software are embedded into a machine-executable object form of such
29*5c90c05cSAndroid Build Coastguard Worker   source code, you may redistribute such embedded portions in such object form
30*5c90c05cSAndroid Build Coastguard Worker   without including the above copyright and permission notices.
31*5c90c05cSAndroid Build Coastguard Worker  */
32*5c90c05cSAndroid Build Coastguard Worker 
33*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_FORMAT_H_
34*5c90c05cSAndroid Build Coastguard Worker #define FMT_FORMAT_H_
35*5c90c05cSAndroid Build Coastguard Worker 
36*5c90c05cSAndroid Build Coastguard Worker #ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
37*5c90c05cSAndroid Build Coastguard Worker #  define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
38*5c90c05cSAndroid Build Coastguard Worker #  define FMT_REMOVE_TRANSITIVE_INCLUDES
39*5c90c05cSAndroid Build Coastguard Worker #endif
40*5c90c05cSAndroid Build Coastguard Worker 
41*5c90c05cSAndroid Build Coastguard Worker #include "base.h"
42*5c90c05cSAndroid Build Coastguard Worker 
43*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_MODULE
44*5c90c05cSAndroid Build Coastguard Worker #  include <cmath>             // std::signbit
45*5c90c05cSAndroid Build Coastguard Worker #  include <cstddef>           // std::byte
46*5c90c05cSAndroid Build Coastguard Worker #  include <cstdint>           // uint32_t
47*5c90c05cSAndroid Build Coastguard Worker #  include <cstring>           // std::memcpy
48*5c90c05cSAndroid Build Coastguard Worker #  include <initializer_list>  // std::initializer_list
49*5c90c05cSAndroid Build Coastguard Worker #  include <limits>            // std::numeric_limits
50*5c90c05cSAndroid Build Coastguard Worker #  include <new>               // std::bad_alloc
51*5c90c05cSAndroid Build Coastguard Worker #  if defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)
52*5c90c05cSAndroid Build Coastguard Worker // Workaround for pre gcc 5 libstdc++.
53*5c90c05cSAndroid Build Coastguard Worker #    include <memory>  // std::allocator_traits
54*5c90c05cSAndroid Build Coastguard Worker #  endif
55*5c90c05cSAndroid Build Coastguard Worker #  include <stdexcept>     // std::runtime_error
56*5c90c05cSAndroid Build Coastguard Worker #  include <string>        // std::string
57*5c90c05cSAndroid Build Coastguard Worker #  include <system_error>  // std::system_error
58*5c90c05cSAndroid Build Coastguard Worker 
59*5c90c05cSAndroid Build Coastguard Worker // Checking FMT_CPLUSPLUS for warning suppression in MSVC.
60*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_INCLUDE(<bit>) && FMT_CPLUSPLUS > 201703L
61*5c90c05cSAndroid Build Coastguard Worker #    include <bit>  // std::bit_cast
62*5c90c05cSAndroid Build Coastguard Worker #  endif
63*5c90c05cSAndroid Build Coastguard Worker 
64*5c90c05cSAndroid Build Coastguard Worker // libc++ supports string_view in pre-c++17.
65*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_INCLUDE(<string_view>) && \
66*5c90c05cSAndroid Build Coastguard Worker       (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
67*5c90c05cSAndroid Build Coastguard Worker #    include <string_view>
68*5c90c05cSAndroid Build Coastguard Worker #    define FMT_USE_STRING_VIEW
69*5c90c05cSAndroid Build Coastguard Worker #  endif
70*5c90c05cSAndroid Build Coastguard Worker 
71*5c90c05cSAndroid Build Coastguard Worker #  if FMT_MSC_VERSION
72*5c90c05cSAndroid Build Coastguard Worker #    include <intrin.h>  // _BitScanReverse[64], _BitScanForward[64], _umul128
73*5c90c05cSAndroid Build Coastguard Worker #  endif
74*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_MODULE
75*5c90c05cSAndroid Build Coastguard Worker 
76*5c90c05cSAndroid Build Coastguard Worker #if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS)
77*5c90c05cSAndroid Build Coastguard Worker // Use the provided definition.
78*5c90c05cSAndroid Build Coastguard Worker #elif defined(__NVCOMPILER)
79*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
80*5c90c05cSAndroid Build Coastguard Worker #elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L
81*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
82*5c90c05cSAndroid Build Coastguard Worker #elif defined(__cpp_nontype_template_args) && \
83*5c90c05cSAndroid Build Coastguard Worker     __cpp_nontype_template_args >= 201911L
84*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
85*5c90c05cSAndroid Build Coastguard Worker #elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L
86*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
87*5c90c05cSAndroid Build Coastguard Worker #else
88*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
89*5c90c05cSAndroid Build Coastguard Worker #endif
90*5c90c05cSAndroid Build Coastguard Worker 
91*5c90c05cSAndroid Build Coastguard Worker #if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L
92*5c90c05cSAndroid Build Coastguard Worker #  define FMT_INLINE_VARIABLE inline
93*5c90c05cSAndroid Build Coastguard Worker #else
94*5c90c05cSAndroid Build Coastguard Worker #  define FMT_INLINE_VARIABLE
95*5c90c05cSAndroid Build Coastguard Worker #endif
96*5c90c05cSAndroid Build Coastguard Worker 
97*5c90c05cSAndroid Build Coastguard Worker // Check if RTTI is disabled.
98*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_USE_RTTI
99*5c90c05cSAndroid Build Coastguard Worker // Use the provided definition.
100*5c90c05cSAndroid Build Coastguard Worker #elif defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \
101*5c90c05cSAndroid Build Coastguard Worker     defined(__INTEL_RTTI__) || defined(__RTTI)
102*5c90c05cSAndroid Build Coastguard Worker // __RTTI is for EDG compilers. _CPPRTTI is for MSVC.
103*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_RTTI 1
104*5c90c05cSAndroid Build Coastguard Worker #else
105*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_RTTI 0
106*5c90c05cSAndroid Build Coastguard Worker #endif
107*5c90c05cSAndroid Build Coastguard Worker 
108*5c90c05cSAndroid Build Coastguard Worker // Visibility when compiled as a shared library/object.
109*5c90c05cSAndroid Build Coastguard Worker #if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
110*5c90c05cSAndroid Build Coastguard Worker #  define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value)
111*5c90c05cSAndroid Build Coastguard Worker #else
112*5c90c05cSAndroid Build Coastguard Worker #  define FMT_SO_VISIBILITY(value)
113*5c90c05cSAndroid Build Coastguard Worker #endif
114*5c90c05cSAndroid Build Coastguard Worker 
115*5c90c05cSAndroid Build Coastguard Worker #if FMT_GCC_VERSION || FMT_CLANG_VERSION
116*5c90c05cSAndroid Build Coastguard Worker #  define FMT_NOINLINE __attribute__((noinline))
117*5c90c05cSAndroid Build Coastguard Worker #else
118*5c90c05cSAndroid Build Coastguard Worker #  define FMT_NOINLINE
119*5c90c05cSAndroid Build Coastguard Worker #endif
120*5c90c05cSAndroid Build Coastguard Worker 
121*5c90c05cSAndroid Build Coastguard Worker namespace std {
122*5c90c05cSAndroid Build Coastguard Worker template <class T> struct iterator_traits<fmt::basic_appender<T>> {
123*5c90c05cSAndroid Build Coastguard Worker   using iterator_category = output_iterator_tag;
124*5c90c05cSAndroid Build Coastguard Worker   using value_type = T;
125*5c90c05cSAndroid Build Coastguard Worker   using difference_type =
126*5c90c05cSAndroid Build Coastguard Worker       decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
127*5c90c05cSAndroid Build Coastguard Worker   using pointer = void;
128*5c90c05cSAndroid Build Coastguard Worker   using reference = void;
129*5c90c05cSAndroid Build Coastguard Worker };
130*5c90c05cSAndroid Build Coastguard Worker }  // namespace std
131*5c90c05cSAndroid Build Coastguard Worker 
132*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_THROW
133*5c90c05cSAndroid Build Coastguard Worker #  if FMT_USE_EXCEPTIONS
134*5c90c05cSAndroid Build Coastguard Worker #    if FMT_MSC_VERSION || defined(__NVCC__)
135*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
136*5c90c05cSAndroid Build Coastguard Worker namespace detail {
137*5c90c05cSAndroid Build Coastguard Worker template <typename Exception> inline void do_throw(const Exception& x) {
138*5c90c05cSAndroid Build Coastguard Worker   // Silence unreachable code warnings in MSVC and NVCC because these
139*5c90c05cSAndroid Build Coastguard Worker   // are nearly impossible to fix in a generic code.
140*5c90c05cSAndroid Build Coastguard Worker   volatile bool b = true;
141*5c90c05cSAndroid Build Coastguard Worker   if (b) throw x;
142*5c90c05cSAndroid Build Coastguard Worker }
143*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
144*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
145*5c90c05cSAndroid Build Coastguard Worker #      define FMT_THROW(x) detail::do_throw(x)
146*5c90c05cSAndroid Build Coastguard Worker #    else
147*5c90c05cSAndroid Build Coastguard Worker #      define FMT_THROW(x) throw x
148*5c90c05cSAndroid Build Coastguard Worker #    endif
149*5c90c05cSAndroid Build Coastguard Worker #  else
150*5c90c05cSAndroid Build Coastguard Worker #    define FMT_THROW(x) \
151*5c90c05cSAndroid Build Coastguard Worker       ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
152*5c90c05cSAndroid Build Coastguard Worker #  endif
153*5c90c05cSAndroid Build Coastguard Worker #endif
154*5c90c05cSAndroid Build Coastguard Worker 
155*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_NO_UNIQUE_ADDRESS
156*5c90c05cSAndroid Build Coastguard Worker // Use the provided definition.
157*5c90c05cSAndroid Build Coastguard Worker #elif FMT_CPLUSPLUS < 202002L
158*5c90c05cSAndroid Build Coastguard Worker // Not supported.
159*5c90c05cSAndroid Build Coastguard Worker #elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
160*5c90c05cSAndroid Build Coastguard Worker #  define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
161*5c90c05cSAndroid Build Coastguard Worker // VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
162*5c90c05cSAndroid Build Coastguard Worker #elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
163*5c90c05cSAndroid Build Coastguard Worker #  define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
164*5c90c05cSAndroid Build Coastguard Worker #endif
165*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_NO_UNIQUE_ADDRESS
166*5c90c05cSAndroid Build Coastguard Worker #  define FMT_NO_UNIQUE_ADDRESS
167*5c90c05cSAndroid Build Coastguard Worker #endif
168*5c90c05cSAndroid Build Coastguard Worker 
169*5c90c05cSAndroid Build Coastguard Worker // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
170*5c90c05cSAndroid Build Coastguard Worker // integer formatter template instantiations to just one by only using the
171*5c90c05cSAndroid Build Coastguard Worker // largest integer type. This results in a reduction in binary size but will
172*5c90c05cSAndroid Build Coastguard Worker // cause a decrease in integer formatting performance.
173*5c90c05cSAndroid Build Coastguard Worker #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
174*5c90c05cSAndroid Build Coastguard Worker #  define FMT_REDUCE_INT_INSTANTIATIONS 0
175*5c90c05cSAndroid Build Coastguard Worker #endif
176*5c90c05cSAndroid Build Coastguard Worker 
177*5c90c05cSAndroid Build Coastguard Worker // __builtin_clz is broken in clang with Microsoft codegen:
178*5c90c05cSAndroid Build Coastguard Worker // https://github.com/fmtlib/fmt/issues/519.
179*5c90c05cSAndroid Build Coastguard Worker #if !FMT_MSC_VERSION
180*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
181*5c90c05cSAndroid Build Coastguard Worker #    define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
182*5c90c05cSAndroid Build Coastguard Worker #  endif
183*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
184*5c90c05cSAndroid Build Coastguard Worker #    define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
185*5c90c05cSAndroid Build Coastguard Worker #  endif
186*5c90c05cSAndroid Build Coastguard Worker #endif
187*5c90c05cSAndroid Build Coastguard Worker 
188*5c90c05cSAndroid Build Coastguard Worker // __builtin_ctz is broken in Intel Compiler Classic on Windows:
189*5c90c05cSAndroid Build Coastguard Worker // https://github.com/fmtlib/fmt/issues/2510.
190*5c90c05cSAndroid Build Coastguard Worker #ifndef __ICL
191*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
192*5c90c05cSAndroid Build Coastguard Worker       defined(__NVCOMPILER)
193*5c90c05cSAndroid Build Coastguard Worker #    define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
194*5c90c05cSAndroid Build Coastguard Worker #  endif
195*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
196*5c90c05cSAndroid Build Coastguard Worker       FMT_ICC_VERSION || defined(__NVCOMPILER)
197*5c90c05cSAndroid Build Coastguard Worker #    define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
198*5c90c05cSAndroid Build Coastguard Worker #  endif
199*5c90c05cSAndroid Build Coastguard Worker #endif
200*5c90c05cSAndroid Build Coastguard Worker 
201*5c90c05cSAndroid Build Coastguard Worker // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
202*5c90c05cSAndroid Build Coastguard Worker // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
203*5c90c05cSAndroid Build Coastguard Worker // MSVC intrinsics if the clz and clzll builtins are not available.
204*5c90c05cSAndroid Build Coastguard Worker #if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
205*5c90c05cSAndroid Build Coastguard Worker     !defined(FMT_BUILTIN_CTZLL)
206*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
207*5c90c05cSAndroid Build Coastguard Worker namespace detail {
208*5c90c05cSAndroid Build Coastguard Worker // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
209*5c90c05cSAndroid Build Coastguard Worker #  if !defined(__clang__)
210*5c90c05cSAndroid Build Coastguard Worker #    pragma intrinsic(_BitScanForward)
211*5c90c05cSAndroid Build Coastguard Worker #    pragma intrinsic(_BitScanReverse)
212*5c90c05cSAndroid Build Coastguard Worker #    if defined(_WIN64)
213*5c90c05cSAndroid Build Coastguard Worker #      pragma intrinsic(_BitScanForward64)
214*5c90c05cSAndroid Build Coastguard Worker #      pragma intrinsic(_BitScanReverse64)
215*5c90c05cSAndroid Build Coastguard Worker #    endif
216*5c90c05cSAndroid Build Coastguard Worker #  endif
217*5c90c05cSAndroid Build Coastguard Worker 
218*5c90c05cSAndroid Build Coastguard Worker inline auto clz(uint32_t x) -> int {
219*5c90c05cSAndroid Build Coastguard Worker   unsigned long r = 0;
220*5c90c05cSAndroid Build Coastguard Worker   _BitScanReverse(&r, x);
221*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(x != 0, "");
222*5c90c05cSAndroid Build Coastguard Worker   // Static analysis complains about using uninitialized data
223*5c90c05cSAndroid Build Coastguard Worker   // "r", but the only way that can happen is if "x" is 0,
224*5c90c05cSAndroid Build Coastguard Worker   // which the callers guarantee to not happen.
225*5c90c05cSAndroid Build Coastguard Worker   FMT_MSC_WARNING(suppress : 6102)
226*5c90c05cSAndroid Build Coastguard Worker   return 31 ^ static_cast<int>(r);
227*5c90c05cSAndroid Build Coastguard Worker }
228*5c90c05cSAndroid Build Coastguard Worker #  define FMT_BUILTIN_CLZ(n) detail::clz(n)
229*5c90c05cSAndroid Build Coastguard Worker 
230*5c90c05cSAndroid Build Coastguard Worker inline auto clzll(uint64_t x) -> int {
231*5c90c05cSAndroid Build Coastguard Worker   unsigned long r = 0;
232*5c90c05cSAndroid Build Coastguard Worker #  ifdef _WIN64
233*5c90c05cSAndroid Build Coastguard Worker   _BitScanReverse64(&r, x);
234*5c90c05cSAndroid Build Coastguard Worker #  else
235*5c90c05cSAndroid Build Coastguard Worker   // Scan the high 32 bits.
236*5c90c05cSAndroid Build Coastguard Worker   if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
237*5c90c05cSAndroid Build Coastguard Worker     return 63 ^ static_cast<int>(r + 32);
238*5c90c05cSAndroid Build Coastguard Worker   // Scan the low 32 bits.
239*5c90c05cSAndroid Build Coastguard Worker   _BitScanReverse(&r, static_cast<uint32_t>(x));
240*5c90c05cSAndroid Build Coastguard Worker #  endif
241*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(x != 0, "");
242*5c90c05cSAndroid Build Coastguard Worker   FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.
243*5c90c05cSAndroid Build Coastguard Worker   return 63 ^ static_cast<int>(r);
244*5c90c05cSAndroid Build Coastguard Worker }
245*5c90c05cSAndroid Build Coastguard Worker #  define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
246*5c90c05cSAndroid Build Coastguard Worker 
247*5c90c05cSAndroid Build Coastguard Worker inline auto ctz(uint32_t x) -> int {
248*5c90c05cSAndroid Build Coastguard Worker   unsigned long r = 0;
249*5c90c05cSAndroid Build Coastguard Worker   _BitScanForward(&r, x);
250*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(x != 0, "");
251*5c90c05cSAndroid Build Coastguard Worker   FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.
252*5c90c05cSAndroid Build Coastguard Worker   return static_cast<int>(r);
253*5c90c05cSAndroid Build Coastguard Worker }
254*5c90c05cSAndroid Build Coastguard Worker #  define FMT_BUILTIN_CTZ(n) detail::ctz(n)
255*5c90c05cSAndroid Build Coastguard Worker 
256*5c90c05cSAndroid Build Coastguard Worker inline auto ctzll(uint64_t x) -> int {
257*5c90c05cSAndroid Build Coastguard Worker   unsigned long r = 0;
258*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(x != 0, "");
259*5c90c05cSAndroid Build Coastguard Worker   FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.
260*5c90c05cSAndroid Build Coastguard Worker #  ifdef _WIN64
261*5c90c05cSAndroid Build Coastguard Worker   _BitScanForward64(&r, x);
262*5c90c05cSAndroid Build Coastguard Worker #  else
263*5c90c05cSAndroid Build Coastguard Worker   // Scan the low 32 bits.
264*5c90c05cSAndroid Build Coastguard Worker   if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
265*5c90c05cSAndroid Build Coastguard Worker   // Scan the high 32 bits.
266*5c90c05cSAndroid Build Coastguard Worker   _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
267*5c90c05cSAndroid Build Coastguard Worker   r += 32;
268*5c90c05cSAndroid Build Coastguard Worker #  endif
269*5c90c05cSAndroid Build Coastguard Worker   return static_cast<int>(r);
270*5c90c05cSAndroid Build Coastguard Worker }
271*5c90c05cSAndroid Build Coastguard Worker #  define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
272*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
273*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
274*5c90c05cSAndroid Build Coastguard Worker #endif
275*5c90c05cSAndroid Build Coastguard Worker 
276*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
277*5c90c05cSAndroid Build Coastguard Worker 
278*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename Traits, typename Allocator>
279*5c90c05cSAndroid Build Coastguard Worker struct is_contiguous<std::basic_string<Char, Traits, Allocator>>
280*5c90c05cSAndroid Build Coastguard Worker     : std::true_type {};
281*5c90c05cSAndroid Build Coastguard Worker 
282*5c90c05cSAndroid Build Coastguard Worker namespace detail {
283*5c90c05cSAndroid Build Coastguard Worker 
284*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
285*5c90c05cSAndroid Build Coastguard Worker   ignore_unused(condition);
286*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_FUZZ
287*5c90c05cSAndroid Build Coastguard Worker   if (condition) throw std::runtime_error("fuzzing limit reached");
288*5c90c05cSAndroid Build Coastguard Worker #endif
289*5c90c05cSAndroid Build Coastguard Worker }
290*5c90c05cSAndroid Build Coastguard Worker 
291*5c90c05cSAndroid Build Coastguard Worker #if defined(FMT_USE_STRING_VIEW)
292*5c90c05cSAndroid Build Coastguard Worker template <typename Char> using std_string_view = std::basic_string_view<Char>;
293*5c90c05cSAndroid Build Coastguard Worker #else
294*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct std_string_view {};
295*5c90c05cSAndroid Build Coastguard Worker #endif
296*5c90c05cSAndroid Build Coastguard Worker 
297*5c90c05cSAndroid Build Coastguard Worker template <typename Char, Char... C> struct string_literal {
298*5c90c05cSAndroid Build Coastguard Worker   static constexpr Char value[sizeof...(C)] = {C...};
299*5c90c05cSAndroid Build Coastguard Worker   constexpr operator basic_string_view<Char>() const {
300*5c90c05cSAndroid Build Coastguard Worker     return {value, sizeof...(C)};
301*5c90c05cSAndroid Build Coastguard Worker   }
302*5c90c05cSAndroid Build Coastguard Worker };
303*5c90c05cSAndroid Build Coastguard Worker #if FMT_CPLUSPLUS < 201703L
304*5c90c05cSAndroid Build Coastguard Worker template <typename Char, Char... C>
305*5c90c05cSAndroid Build Coastguard Worker constexpr Char string_literal<Char, C...>::value[sizeof...(C)];
306*5c90c05cSAndroid Build Coastguard Worker #endif
307*5c90c05cSAndroid Build Coastguard Worker 
308*5c90c05cSAndroid Build Coastguard Worker // Implementation of std::bit_cast for pre-C++20.
309*5c90c05cSAndroid Build Coastguard Worker template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
310*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
311*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_bit_cast
312*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) return std::bit_cast<To>(from);
313*5c90c05cSAndroid Build Coastguard Worker #endif
314*5c90c05cSAndroid Build Coastguard Worker   auto to = To();
315*5c90c05cSAndroid Build Coastguard Worker   // The cast suppresses a bogus -Wclass-memaccess on GCC.
316*5c90c05cSAndroid Build Coastguard Worker   std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
317*5c90c05cSAndroid Build Coastguard Worker   return to;
318*5c90c05cSAndroid Build Coastguard Worker }
319*5c90c05cSAndroid Build Coastguard Worker 
320*5c90c05cSAndroid Build Coastguard Worker inline auto is_big_endian() -> bool {
321*5c90c05cSAndroid Build Coastguard Worker #ifdef _WIN32
322*5c90c05cSAndroid Build Coastguard Worker   return false;
323*5c90c05cSAndroid Build Coastguard Worker #elif defined(__BIG_ENDIAN__)
324*5c90c05cSAndroid Build Coastguard Worker   return true;
325*5c90c05cSAndroid Build Coastguard Worker #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
326*5c90c05cSAndroid Build Coastguard Worker   return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
327*5c90c05cSAndroid Build Coastguard Worker #else
328*5c90c05cSAndroid Build Coastguard Worker   struct bytes {
329*5c90c05cSAndroid Build Coastguard Worker     char data[sizeof(int)];
330*5c90c05cSAndroid Build Coastguard Worker   };
331*5c90c05cSAndroid Build Coastguard Worker   return bit_cast<bytes>(1).data[0] == 0;
332*5c90c05cSAndroid Build Coastguard Worker #endif
333*5c90c05cSAndroid Build Coastguard Worker }
334*5c90c05cSAndroid Build Coastguard Worker 
335*5c90c05cSAndroid Build Coastguard Worker class uint128_fallback {
336*5c90c05cSAndroid Build Coastguard Worker  private:
337*5c90c05cSAndroid Build Coastguard Worker   uint64_t lo_, hi_;
338*5c90c05cSAndroid Build Coastguard Worker 
339*5c90c05cSAndroid Build Coastguard Worker  public:
340*5c90c05cSAndroid Build Coastguard Worker   constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
341*5c90c05cSAndroid Build Coastguard Worker   constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
342*5c90c05cSAndroid Build Coastguard Worker 
343*5c90c05cSAndroid Build Coastguard Worker   constexpr auto high() const noexcept -> uint64_t { return hi_; }
344*5c90c05cSAndroid Build Coastguard Worker   constexpr auto low() const noexcept -> uint64_t { return lo_; }
345*5c90c05cSAndroid Build Coastguard Worker 
346*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
347*5c90c05cSAndroid Build Coastguard Worker   constexpr explicit operator T() const {
348*5c90c05cSAndroid Build Coastguard Worker     return static_cast<T>(lo_);
349*5c90c05cSAndroid Build Coastguard Worker   }
350*5c90c05cSAndroid Build Coastguard Worker 
351*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator==(const uint128_fallback& lhs,
352*5c90c05cSAndroid Build Coastguard Worker                                    const uint128_fallback& rhs) -> bool {
353*5c90c05cSAndroid Build Coastguard Worker     return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
354*5c90c05cSAndroid Build Coastguard Worker   }
355*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator!=(const uint128_fallback& lhs,
356*5c90c05cSAndroid Build Coastguard Worker                                    const uint128_fallback& rhs) -> bool {
357*5c90c05cSAndroid Build Coastguard Worker     return !(lhs == rhs);
358*5c90c05cSAndroid Build Coastguard Worker   }
359*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator>(const uint128_fallback& lhs,
360*5c90c05cSAndroid Build Coastguard Worker                                   const uint128_fallback& rhs) -> bool {
361*5c90c05cSAndroid Build Coastguard Worker     return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
362*5c90c05cSAndroid Build Coastguard Worker   }
363*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator|(const uint128_fallback& lhs,
364*5c90c05cSAndroid Build Coastguard Worker                                   const uint128_fallback& rhs)
365*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
366*5c90c05cSAndroid Build Coastguard Worker     return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
367*5c90c05cSAndroid Build Coastguard Worker   }
368*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator&(const uint128_fallback& lhs,
369*5c90c05cSAndroid Build Coastguard Worker                                   const uint128_fallback& rhs)
370*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
371*5c90c05cSAndroid Build Coastguard Worker     return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
372*5c90c05cSAndroid Build Coastguard Worker   }
373*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator~(const uint128_fallback& n)
374*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
375*5c90c05cSAndroid Build Coastguard Worker     return {~n.hi_, ~n.lo_};
376*5c90c05cSAndroid Build Coastguard Worker   }
377*5c90c05cSAndroid Build Coastguard Worker   friend FMT_CONSTEXPR auto operator+(const uint128_fallback& lhs,
378*5c90c05cSAndroid Build Coastguard Worker                                       const uint128_fallback& rhs)
379*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
380*5c90c05cSAndroid Build Coastguard Worker     auto result = uint128_fallback(lhs);
381*5c90c05cSAndroid Build Coastguard Worker     result += rhs;
382*5c90c05cSAndroid Build Coastguard Worker     return result;
383*5c90c05cSAndroid Build Coastguard Worker   }
384*5c90c05cSAndroid Build Coastguard Worker   friend FMT_CONSTEXPR auto operator*(const uint128_fallback& lhs, uint32_t rhs)
385*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
386*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(lhs.hi_ == 0, "");
387*5c90c05cSAndroid Build Coastguard Worker     uint64_t hi = (lhs.lo_ >> 32) * rhs;
388*5c90c05cSAndroid Build Coastguard Worker     uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
389*5c90c05cSAndroid Build Coastguard Worker     uint64_t new_lo = (hi << 32) + lo;
390*5c90c05cSAndroid Build Coastguard Worker     return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
391*5c90c05cSAndroid Build Coastguard Worker   }
392*5c90c05cSAndroid Build Coastguard Worker   friend constexpr auto operator-(const uint128_fallback& lhs, uint64_t rhs)
393*5c90c05cSAndroid Build Coastguard Worker       -> uint128_fallback {
394*5c90c05cSAndroid Build Coastguard Worker     return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
395*5c90c05cSAndroid Build Coastguard Worker   }
396*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
397*5c90c05cSAndroid Build Coastguard Worker     if (shift == 64) return {0, hi_};
398*5c90c05cSAndroid Build Coastguard Worker     if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);
399*5c90c05cSAndroid Build Coastguard Worker     return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
400*5c90c05cSAndroid Build Coastguard Worker   }
401*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
402*5c90c05cSAndroid Build Coastguard Worker     if (shift == 64) return {lo_, 0};
403*5c90c05cSAndroid Build Coastguard Worker     if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);
404*5c90c05cSAndroid Build Coastguard Worker     return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
405*5c90c05cSAndroid Build Coastguard Worker   }
406*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& {
407*5c90c05cSAndroid Build Coastguard Worker     return *this = *this >> shift;
408*5c90c05cSAndroid Build Coastguard Worker   }
409*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void operator+=(uint128_fallback n) {
410*5c90c05cSAndroid Build Coastguard Worker     uint64_t new_lo = lo_ + n.lo_;
411*5c90c05cSAndroid Build Coastguard Worker     uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
412*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(new_hi >= hi_, "");
413*5c90c05cSAndroid Build Coastguard Worker     lo_ = new_lo;
414*5c90c05cSAndroid Build Coastguard Worker     hi_ = new_hi;
415*5c90c05cSAndroid Build Coastguard Worker   }
416*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void operator&=(uint128_fallback n) {
417*5c90c05cSAndroid Build Coastguard Worker     lo_ &= n.lo_;
418*5c90c05cSAndroid Build Coastguard Worker     hi_ &= n.hi_;
419*5c90c05cSAndroid Build Coastguard Worker   }
420*5c90c05cSAndroid Build Coastguard Worker 
421*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& {
422*5c90c05cSAndroid Build Coastguard Worker     if (is_constant_evaluated()) {
423*5c90c05cSAndroid Build Coastguard Worker       lo_ += n;
424*5c90c05cSAndroid Build Coastguard Worker       hi_ += (lo_ < n ? 1 : 0);
425*5c90c05cSAndroid Build Coastguard Worker       return *this;
426*5c90c05cSAndroid Build Coastguard Worker     }
427*5c90c05cSAndroid Build Coastguard Worker #if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
428*5c90c05cSAndroid Build Coastguard Worker     unsigned long long carry;
429*5c90c05cSAndroid Build Coastguard Worker     lo_ = __builtin_addcll(lo_, n, 0, &carry);
430*5c90c05cSAndroid Build Coastguard Worker     hi_ += carry;
431*5c90c05cSAndroid Build Coastguard Worker #elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
432*5c90c05cSAndroid Build Coastguard Worker     unsigned long long result;
433*5c90c05cSAndroid Build Coastguard Worker     auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);
434*5c90c05cSAndroid Build Coastguard Worker     lo_ = result;
435*5c90c05cSAndroid Build Coastguard Worker     hi_ += carry;
436*5c90c05cSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_X64)
437*5c90c05cSAndroid Build Coastguard Worker     auto carry = _addcarry_u64(0, lo_, n, &lo_);
438*5c90c05cSAndroid Build Coastguard Worker     _addcarry_u64(carry, hi_, 0, &hi_);
439*5c90c05cSAndroid Build Coastguard Worker #else
440*5c90c05cSAndroid Build Coastguard Worker     lo_ += n;
441*5c90c05cSAndroid Build Coastguard Worker     hi_ += (lo_ < n ? 1 : 0);
442*5c90c05cSAndroid Build Coastguard Worker #endif
443*5c90c05cSAndroid Build Coastguard Worker     return *this;
444*5c90c05cSAndroid Build Coastguard Worker   }
445*5c90c05cSAndroid Build Coastguard Worker };
446*5c90c05cSAndroid Build Coastguard Worker 
447*5c90c05cSAndroid Build Coastguard Worker using uint128_t = conditional_t<FMT_USE_INT128, uint128_opt, uint128_fallback>;
448*5c90c05cSAndroid Build Coastguard Worker 
449*5c90c05cSAndroid Build Coastguard Worker #ifdef UINTPTR_MAX
450*5c90c05cSAndroid Build Coastguard Worker using uintptr_t = ::uintptr_t;
451*5c90c05cSAndroid Build Coastguard Worker #else
452*5c90c05cSAndroid Build Coastguard Worker using uintptr_t = uint128_t;
453*5c90c05cSAndroid Build Coastguard Worker #endif
454*5c90c05cSAndroid Build Coastguard Worker 
455*5c90c05cSAndroid Build Coastguard Worker // Returns the largest possible value for type T. Same as
456*5c90c05cSAndroid Build Coastguard Worker // std::numeric_limits<T>::max() but shorter and not affected by the max macro.
457*5c90c05cSAndroid Build Coastguard Worker template <typename T> constexpr auto max_value() -> T {
458*5c90c05cSAndroid Build Coastguard Worker   return (std::numeric_limits<T>::max)();
459*5c90c05cSAndroid Build Coastguard Worker }
460*5c90c05cSAndroid Build Coastguard Worker template <typename T> constexpr auto num_bits() -> int {
461*5c90c05cSAndroid Build Coastguard Worker   return std::numeric_limits<T>::digits;
462*5c90c05cSAndroid Build Coastguard Worker }
463*5c90c05cSAndroid Build Coastguard Worker // std::numeric_limits<T>::digits may return 0 for 128-bit ints.
464*5c90c05cSAndroid Build Coastguard Worker template <> constexpr auto num_bits<int128_opt>() -> int { return 128; }
465*5c90c05cSAndroid Build Coastguard Worker template <> constexpr auto num_bits<uint128_opt>() -> int { return 128; }
466*5c90c05cSAndroid Build Coastguard Worker template <> constexpr auto num_bits<uint128_fallback>() -> int { return 128; }
467*5c90c05cSAndroid Build Coastguard Worker 
468*5c90c05cSAndroid Build Coastguard Worker // A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
469*5c90c05cSAndroid Build Coastguard Worker // and 128-bit pointers to uint128_fallback.
470*5c90c05cSAndroid Build Coastguard Worker template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
471*5c90c05cSAndroid Build Coastguard Worker inline auto bit_cast(const From& from) -> To {
472*5c90c05cSAndroid Build Coastguard Worker   constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned));
473*5c90c05cSAndroid Build Coastguard Worker   struct data_t {
474*5c90c05cSAndroid Build Coastguard Worker     unsigned value[static_cast<unsigned>(size)];
475*5c90c05cSAndroid Build Coastguard Worker   } data = bit_cast<data_t>(from);
476*5c90c05cSAndroid Build Coastguard Worker   auto result = To();
477*5c90c05cSAndroid Build Coastguard Worker   if (const_check(is_big_endian())) {
478*5c90c05cSAndroid Build Coastguard Worker     for (int i = 0; i < size; ++i)
479*5c90c05cSAndroid Build Coastguard Worker       result = (result << num_bits<unsigned>()) | data.value[i];
480*5c90c05cSAndroid Build Coastguard Worker   } else {
481*5c90c05cSAndroid Build Coastguard Worker     for (int i = size - 1; i >= 0; --i)
482*5c90c05cSAndroid Build Coastguard Worker       result = (result << num_bits<unsigned>()) | data.value[i];
483*5c90c05cSAndroid Build Coastguard Worker   }
484*5c90c05cSAndroid Build Coastguard Worker   return result;
485*5c90c05cSAndroid Build Coastguard Worker }
486*5c90c05cSAndroid Build Coastguard Worker 
487*5c90c05cSAndroid Build Coastguard Worker template <typename UInt>
488*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int {
489*5c90c05cSAndroid Build Coastguard Worker   int lz = 0;
490*5c90c05cSAndroid Build Coastguard Worker   constexpr UInt msb_mask = static_cast<UInt>(1) << (num_bits<UInt>() - 1);
491*5c90c05cSAndroid Build Coastguard Worker   for (; (n & msb_mask) == 0; n <<= 1) lz++;
492*5c90c05cSAndroid Build Coastguard Worker   return lz;
493*5c90c05cSAndroid Build Coastguard Worker }
494*5c90c05cSAndroid Build Coastguard Worker 
495*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {
496*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZ
497*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);
498*5c90c05cSAndroid Build Coastguard Worker #endif
499*5c90c05cSAndroid Build Coastguard Worker   return countl_zero_fallback(n);
500*5c90c05cSAndroid Build Coastguard Worker }
501*5c90c05cSAndroid Build Coastguard Worker 
502*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int {
503*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZLL
504*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n);
505*5c90c05cSAndroid Build Coastguard Worker #endif
506*5c90c05cSAndroid Build Coastguard Worker   return countl_zero_fallback(n);
507*5c90c05cSAndroid Build Coastguard Worker }
508*5c90c05cSAndroid Build Coastguard Worker 
509*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE void assume(bool condition) {
510*5c90c05cSAndroid Build Coastguard Worker   (void)condition;
511*5c90c05cSAndroid Build Coastguard Worker #if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
512*5c90c05cSAndroid Build Coastguard Worker   __builtin_assume(condition);
513*5c90c05cSAndroid Build Coastguard Worker #elif FMT_GCC_VERSION
514*5c90c05cSAndroid Build Coastguard Worker   if (!condition) __builtin_unreachable();
515*5c90c05cSAndroid Build Coastguard Worker #endif
516*5c90c05cSAndroid Build Coastguard Worker }
517*5c90c05cSAndroid Build Coastguard Worker 
518*5c90c05cSAndroid Build Coastguard Worker // Attempts to reserve space for n extra characters in the output range.
519*5c90c05cSAndroid Build Coastguard Worker // Returns a pointer to the reserved range or a reference to it.
520*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt,
521*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
522*5c90c05cSAndroid Build Coastguard Worker                             is_contiguous<typename OutputIt::container>::value)>
523*5c90c05cSAndroid Build Coastguard Worker #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
524*5c90c05cSAndroid Build Coastguard Worker __attribute__((no_sanitize("undefined")))
525*5c90c05cSAndroid Build Coastguard Worker #endif
526*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto
527*5c90c05cSAndroid Build Coastguard Worker reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* {
528*5c90c05cSAndroid Build Coastguard Worker   auto& c = get_container(it);
529*5c90c05cSAndroid Build Coastguard Worker   size_t size = c.size();
530*5c90c05cSAndroid Build Coastguard Worker   c.resize(size + n);
531*5c90c05cSAndroid Build Coastguard Worker   return &c[size];
532*5c90c05cSAndroid Build Coastguard Worker }
533*5c90c05cSAndroid Build Coastguard Worker 
534*5c90c05cSAndroid Build Coastguard Worker template <typename T>
535*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto reserve(basic_appender<T> it, size_t n)
536*5c90c05cSAndroid Build Coastguard Worker     -> basic_appender<T> {
537*5c90c05cSAndroid Build Coastguard Worker   buffer<T>& buf = get_container(it);
538*5c90c05cSAndroid Build Coastguard Worker   buf.try_reserve(buf.size() + n);
539*5c90c05cSAndroid Build Coastguard Worker   return it;
540*5c90c05cSAndroid Build Coastguard Worker }
541*5c90c05cSAndroid Build Coastguard Worker 
542*5c90c05cSAndroid Build Coastguard Worker template <typename Iterator>
543*5c90c05cSAndroid Build Coastguard Worker constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
544*5c90c05cSAndroid Build Coastguard Worker   return it;
545*5c90c05cSAndroid Build Coastguard Worker }
546*5c90c05cSAndroid Build Coastguard Worker 
547*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt>
548*5c90c05cSAndroid Build Coastguard Worker using reserve_iterator =
549*5c90c05cSAndroid Build Coastguard Worker     remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
550*5c90c05cSAndroid Build Coastguard Worker 
551*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename OutputIt>
552*5c90c05cSAndroid Build Coastguard Worker constexpr auto to_pointer(OutputIt, size_t) -> T* {
553*5c90c05cSAndroid Build Coastguard Worker   return nullptr;
554*5c90c05cSAndroid Build Coastguard Worker }
555*5c90c05cSAndroid Build Coastguard Worker template <typename T>
556*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto to_pointer(basic_appender<T> it, size_t n) -> T* {
557*5c90c05cSAndroid Build Coastguard Worker   buffer<T>& buf = get_container(it);
558*5c90c05cSAndroid Build Coastguard Worker   auto size = buf.size();
559*5c90c05cSAndroid Build Coastguard Worker   buf.try_reserve(size + n);
560*5c90c05cSAndroid Build Coastguard Worker   if (buf.capacity() < size + n) return nullptr;
561*5c90c05cSAndroid Build Coastguard Worker   buf.try_resize(size + n);
562*5c90c05cSAndroid Build Coastguard Worker   return buf.data() + size;
563*5c90c05cSAndroid Build Coastguard Worker }
564*5c90c05cSAndroid Build Coastguard Worker 
565*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt,
566*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
567*5c90c05cSAndroid Build Coastguard Worker                             is_contiguous<typename OutputIt::container>::value)>
568*5c90c05cSAndroid Build Coastguard Worker inline auto base_iterator(OutputIt it,
569*5c90c05cSAndroid Build Coastguard Worker                           typename OutputIt::container_type::value_type*)
570*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
571*5c90c05cSAndroid Build Coastguard Worker   return it;
572*5c90c05cSAndroid Build Coastguard Worker }
573*5c90c05cSAndroid Build Coastguard Worker 
574*5c90c05cSAndroid Build Coastguard Worker template <typename Iterator>
575*5c90c05cSAndroid Build Coastguard Worker constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
576*5c90c05cSAndroid Build Coastguard Worker   return it;
577*5c90c05cSAndroid Build Coastguard Worker }
578*5c90c05cSAndroid Build Coastguard Worker 
579*5c90c05cSAndroid Build Coastguard Worker // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
580*5c90c05cSAndroid Build Coastguard Worker // instead (#1998).
581*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Size, typename T>
582*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
583*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
584*5c90c05cSAndroid Build Coastguard Worker   for (Size i = 0; i < count; ++i) *out++ = value;
585*5c90c05cSAndroid Build Coastguard Worker   return out;
586*5c90c05cSAndroid Build Coastguard Worker }
587*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Size>
588*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
589*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) return fill_n<T*, Size, T>(out, count, value);
590*5c90c05cSAndroid Build Coastguard Worker   std::memset(out, value, to_unsigned(count));
591*5c90c05cSAndroid Build Coastguard Worker   return out + count;
592*5c90c05cSAndroid Build Coastguard Worker }
593*5c90c05cSAndroid Build Coastguard Worker 
594*5c90c05cSAndroid Build Coastguard Worker template <typename OutChar, typename InputIt, typename OutputIt>
595*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,
596*5c90c05cSAndroid Build Coastguard Worker                                               OutputIt out) -> OutputIt {
597*5c90c05cSAndroid Build Coastguard Worker   return copy<OutChar>(begin, end, out);
598*5c90c05cSAndroid Build Coastguard Worker }
599*5c90c05cSAndroid Build Coastguard Worker 
600*5c90c05cSAndroid Build Coastguard Worker // A public domain branchless UTF-8 decoder by Christopher Wellons:
601*5c90c05cSAndroid Build Coastguard Worker // https://github.com/skeeto/branchless-utf8
602*5c90c05cSAndroid Build Coastguard Worker /* Decode the next character, c, from s, reporting errors in e.
603*5c90c05cSAndroid Build Coastguard Worker  *
604*5c90c05cSAndroid Build Coastguard Worker  * Since this is a branchless decoder, four bytes will be read from the
605*5c90c05cSAndroid Build Coastguard Worker  * buffer regardless of the actual length of the next character. This
606*5c90c05cSAndroid Build Coastguard Worker  * means the buffer _must_ have at least three bytes of zero padding
607*5c90c05cSAndroid Build Coastguard Worker  * following the end of the data stream.
608*5c90c05cSAndroid Build Coastguard Worker  *
609*5c90c05cSAndroid Build Coastguard Worker  * Errors are reported in e, which will be non-zero if the parsed
610*5c90c05cSAndroid Build Coastguard Worker  * character was somehow invalid: invalid byte sequence, non-canonical
611*5c90c05cSAndroid Build Coastguard Worker  * encoding, or a surrogate half.
612*5c90c05cSAndroid Build Coastguard Worker  *
613*5c90c05cSAndroid Build Coastguard Worker  * The function returns a pointer to the next character. When an error
614*5c90c05cSAndroid Build Coastguard Worker  * occurs, this pointer will be a guess that depends on the particular
615*5c90c05cSAndroid Build Coastguard Worker  * error, but it will always advance at least one byte.
616*5c90c05cSAndroid Build Coastguard Worker  */
617*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
618*5c90c05cSAndroid Build Coastguard Worker     -> const char* {
619*5c90c05cSAndroid Build Coastguard Worker   constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
620*5c90c05cSAndroid Build Coastguard Worker   constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
621*5c90c05cSAndroid Build Coastguard Worker   constexpr const int shiftc[] = {0, 18, 12, 6, 0};
622*5c90c05cSAndroid Build Coastguard Worker   constexpr const int shifte[] = {0, 6, 4, 2, 0};
623*5c90c05cSAndroid Build Coastguard Worker 
624*5c90c05cSAndroid Build Coastguard Worker   int len = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"
625*5c90c05cSAndroid Build Coastguard Worker       [static_cast<unsigned char>(*s) >> 3];
626*5c90c05cSAndroid Build Coastguard Worker   // Compute the pointer to the next character early so that the next
627*5c90c05cSAndroid Build Coastguard Worker   // iteration can start working on the next character. Neither Clang
628*5c90c05cSAndroid Build Coastguard Worker   // nor GCC figure out this reordering on their own.
629*5c90c05cSAndroid Build Coastguard Worker   const char* next = s + len + !len;
630*5c90c05cSAndroid Build Coastguard Worker 
631*5c90c05cSAndroid Build Coastguard Worker   using uchar = unsigned char;
632*5c90c05cSAndroid Build Coastguard Worker 
633*5c90c05cSAndroid Build Coastguard Worker   // Assume a four-byte character and load four bytes. Unused bits are
634*5c90c05cSAndroid Build Coastguard Worker   // shifted out.
635*5c90c05cSAndroid Build Coastguard Worker   *c = uint32_t(uchar(s[0]) & masks[len]) << 18;
636*5c90c05cSAndroid Build Coastguard Worker   *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;
637*5c90c05cSAndroid Build Coastguard Worker   *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;
638*5c90c05cSAndroid Build Coastguard Worker   *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;
639*5c90c05cSAndroid Build Coastguard Worker   *c >>= shiftc[len];
640*5c90c05cSAndroid Build Coastguard Worker 
641*5c90c05cSAndroid Build Coastguard Worker   // Accumulate the various error conditions.
642*5c90c05cSAndroid Build Coastguard Worker   *e = (*c < mins[len]) << 6;       // non-canonical encoding
643*5c90c05cSAndroid Build Coastguard Worker   *e |= ((*c >> 11) == 0x1b) << 7;  // surrogate half?
644*5c90c05cSAndroid Build Coastguard Worker   *e |= (*c > 0x10FFFF) << 8;       // out of range?
645*5c90c05cSAndroid Build Coastguard Worker   *e |= (uchar(s[1]) & 0xc0) >> 2;
646*5c90c05cSAndroid Build Coastguard Worker   *e |= (uchar(s[2]) & 0xc0) >> 4;
647*5c90c05cSAndroid Build Coastguard Worker   *e |= uchar(s[3]) >> 6;
648*5c90c05cSAndroid Build Coastguard Worker   *e ^= 0x2a;  // top two bits of each tail byte correct?
649*5c90c05cSAndroid Build Coastguard Worker   *e >>= shifte[len];
650*5c90c05cSAndroid Build Coastguard Worker 
651*5c90c05cSAndroid Build Coastguard Worker   return next;
652*5c90c05cSAndroid Build Coastguard Worker }
653*5c90c05cSAndroid Build Coastguard Worker 
654*5c90c05cSAndroid Build Coastguard Worker constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t();
655*5c90c05cSAndroid Build Coastguard Worker 
656*5c90c05cSAndroid Build Coastguard Worker // Invokes f(cp, sv) for every code point cp in s with sv being the string view
657*5c90c05cSAndroid Build Coastguard Worker // corresponding to the code point. cp is invalid_code_point on error.
658*5c90c05cSAndroid Build Coastguard Worker template <typename F>
659*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
660*5c90c05cSAndroid Build Coastguard Worker   auto decode = [f](const char* buf_ptr, const char* ptr) {
661*5c90c05cSAndroid Build Coastguard Worker     auto cp = uint32_t();
662*5c90c05cSAndroid Build Coastguard Worker     auto error = 0;
663*5c90c05cSAndroid Build Coastguard Worker     auto end = utf8_decode(buf_ptr, &cp, &error);
664*5c90c05cSAndroid Build Coastguard Worker     bool result = f(error ? invalid_code_point : cp,
665*5c90c05cSAndroid Build Coastguard Worker                     string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
666*5c90c05cSAndroid Build Coastguard Worker     return result ? (error ? buf_ptr + 1 : end) : nullptr;
667*5c90c05cSAndroid Build Coastguard Worker   };
668*5c90c05cSAndroid Build Coastguard Worker 
669*5c90c05cSAndroid Build Coastguard Worker   auto p = s.data();
670*5c90c05cSAndroid Build Coastguard Worker   const size_t block_size = 4;  // utf8_decode always reads blocks of 4 chars.
671*5c90c05cSAndroid Build Coastguard Worker   if (s.size() >= block_size) {
672*5c90c05cSAndroid Build Coastguard Worker     for (auto end = p + s.size() - block_size + 1; p < end;) {
673*5c90c05cSAndroid Build Coastguard Worker       p = decode(p, p);
674*5c90c05cSAndroid Build Coastguard Worker       if (!p) return;
675*5c90c05cSAndroid Build Coastguard Worker     }
676*5c90c05cSAndroid Build Coastguard Worker   }
677*5c90c05cSAndroid Build Coastguard Worker   auto num_chars_left = to_unsigned(s.data() + s.size() - p);
678*5c90c05cSAndroid Build Coastguard Worker   if (num_chars_left == 0) return;
679*5c90c05cSAndroid Build Coastguard Worker 
680*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(num_chars_left < block_size, "");
681*5c90c05cSAndroid Build Coastguard Worker   char buf[2 * block_size - 1] = {};
682*5c90c05cSAndroid Build Coastguard Worker   copy<char>(p, p + num_chars_left, buf);
683*5c90c05cSAndroid Build Coastguard Worker   const char* buf_ptr = buf;
684*5c90c05cSAndroid Build Coastguard Worker   do {
685*5c90c05cSAndroid Build Coastguard Worker     auto end = decode(buf_ptr, p);
686*5c90c05cSAndroid Build Coastguard Worker     if (!end) return;
687*5c90c05cSAndroid Build Coastguard Worker     p += end - buf_ptr;
688*5c90c05cSAndroid Build Coastguard Worker     buf_ptr = end;
689*5c90c05cSAndroid Build Coastguard Worker   } while (buf_ptr < buf + num_chars_left);
690*5c90c05cSAndroid Build Coastguard Worker }
691*5c90c05cSAndroid Build Coastguard Worker 
692*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
693*5c90c05cSAndroid Build Coastguard Worker inline auto compute_width(basic_string_view<Char> s) -> size_t {
694*5c90c05cSAndroid Build Coastguard Worker   return s.size();
695*5c90c05cSAndroid Build Coastguard Worker }
696*5c90c05cSAndroid Build Coastguard Worker 
697*5c90c05cSAndroid Build Coastguard Worker // Computes approximate display width of a UTF-8 string.
698*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto compute_width(string_view s) -> size_t {
699*5c90c05cSAndroid Build Coastguard Worker   size_t num_code_points = 0;
700*5c90c05cSAndroid Build Coastguard Worker   // It is not a lambda for compatibility with C++14.
701*5c90c05cSAndroid Build Coastguard Worker   struct count_code_points {
702*5c90c05cSAndroid Build Coastguard Worker     size_t* count;
703*5c90c05cSAndroid Build Coastguard Worker     FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool {
704*5c90c05cSAndroid Build Coastguard Worker       *count += to_unsigned(
705*5c90c05cSAndroid Build Coastguard Worker           1 +
706*5c90c05cSAndroid Build Coastguard Worker           (cp >= 0x1100 &&
707*5c90c05cSAndroid Build Coastguard Worker            (cp <= 0x115f ||  // Hangul Jamo init. consonants
708*5c90c05cSAndroid Build Coastguard Worker             cp == 0x2329 ||  // LEFT-POINTING ANGLE BRACKET
709*5c90c05cSAndroid Build Coastguard Worker             cp == 0x232a ||  // RIGHT-POINTING ANGLE BRACKET
710*5c90c05cSAndroid Build Coastguard Worker             // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
711*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
712*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xac00 && cp <= 0xd7a3) ||    // Hangul Syllables
713*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xf900 && cp <= 0xfaff) ||    // CJK Compatibility Ideographs
714*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xfe10 && cp <= 0xfe19) ||    // Vertical Forms
715*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xfe30 && cp <= 0xfe6f) ||    // CJK Compatibility Forms
716*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xff00 && cp <= 0xff60) ||    // Fullwidth Forms
717*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0xffe0 && cp <= 0xffe6) ||    // Fullwidth Forms
718*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0x20000 && cp <= 0x2fffd) ||  // CJK
719*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0x30000 && cp <= 0x3fffd) ||
720*5c90c05cSAndroid Build Coastguard Worker             // Miscellaneous Symbols and Pictographs + Emoticons:
721*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0x1f300 && cp <= 0x1f64f) ||
722*5c90c05cSAndroid Build Coastguard Worker             // Supplemental Symbols and Pictographs:
723*5c90c05cSAndroid Build Coastguard Worker             (cp >= 0x1f900 && cp <= 0x1f9ff))));
724*5c90c05cSAndroid Build Coastguard Worker       return true;
725*5c90c05cSAndroid Build Coastguard Worker     }
726*5c90c05cSAndroid Build Coastguard Worker   };
727*5c90c05cSAndroid Build Coastguard Worker   // We could avoid branches by using utf8_decode directly.
728*5c90c05cSAndroid Build Coastguard Worker   for_each_codepoint(s, count_code_points{&num_code_points});
729*5c90c05cSAndroid Build Coastguard Worker   return num_code_points;
730*5c90c05cSAndroid Build Coastguard Worker }
731*5c90c05cSAndroid Build Coastguard Worker 
732*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
733*5c90c05cSAndroid Build Coastguard Worker inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
734*5c90c05cSAndroid Build Coastguard Worker   return min_of(n, s.size());
735*5c90c05cSAndroid Build Coastguard Worker }
736*5c90c05cSAndroid Build Coastguard Worker 
737*5c90c05cSAndroid Build Coastguard Worker // Calculates the index of the nth code point in a UTF-8 string.
738*5c90c05cSAndroid Build Coastguard Worker inline auto code_point_index(string_view s, size_t n) -> size_t {
739*5c90c05cSAndroid Build Coastguard Worker   size_t result = s.size();
740*5c90c05cSAndroid Build Coastguard Worker   const char* begin = s.begin();
741*5c90c05cSAndroid Build Coastguard Worker   for_each_codepoint(s, [begin, &n, &result](uint32_t, string_view sv) {
742*5c90c05cSAndroid Build Coastguard Worker     if (n != 0) {
743*5c90c05cSAndroid Build Coastguard Worker       --n;
744*5c90c05cSAndroid Build Coastguard Worker       return true;
745*5c90c05cSAndroid Build Coastguard Worker     }
746*5c90c05cSAndroid Build Coastguard Worker     result = to_unsigned(sv.begin() - begin);
747*5c90c05cSAndroid Build Coastguard Worker     return false;
748*5c90c05cSAndroid Build Coastguard Worker   });
749*5c90c05cSAndroid Build Coastguard Worker   return result;
750*5c90c05cSAndroid Build Coastguard Worker }
751*5c90c05cSAndroid Build Coastguard Worker 
752*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct is_integral : std::is_integral<T> {};
753*5c90c05cSAndroid Build Coastguard Worker template <> struct is_integral<int128_opt> : std::true_type {};
754*5c90c05cSAndroid Build Coastguard Worker template <> struct is_integral<uint128_t> : std::true_type {};
755*5c90c05cSAndroid Build Coastguard Worker 
756*5c90c05cSAndroid Build Coastguard Worker template <typename T>
757*5c90c05cSAndroid Build Coastguard Worker using is_signed =
758*5c90c05cSAndroid Build Coastguard Worker     std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
759*5c90c05cSAndroid Build Coastguard Worker                                      std::is_same<T, int128_opt>::value>;
760*5c90c05cSAndroid Build Coastguard Worker 
761*5c90c05cSAndroid Build Coastguard Worker template <typename T>
762*5c90c05cSAndroid Build Coastguard Worker using is_integer =
763*5c90c05cSAndroid Build Coastguard Worker     bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
764*5c90c05cSAndroid Build Coastguard Worker                   !std::is_same<T, char>::value &&
765*5c90c05cSAndroid Build Coastguard Worker                   !std::is_same<T, wchar_t>::value>;
766*5c90c05cSAndroid Build Coastguard Worker 
767*5c90c05cSAndroid Build Coastguard Worker #if defined(FMT_USE_FLOAT128)
768*5c90c05cSAndroid Build Coastguard Worker // Use the provided definition.
769*5c90c05cSAndroid Build Coastguard Worker #elif FMT_CLANG_VERSION && FMT_HAS_INCLUDE(<quadmath.h>)
770*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_FLOAT128 1
771*5c90c05cSAndroid Build Coastguard Worker #elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \
772*5c90c05cSAndroid Build Coastguard Worker     !defined(__STRICT_ANSI__)
773*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_FLOAT128 1
774*5c90c05cSAndroid Build Coastguard Worker #else
775*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_FLOAT128 0
776*5c90c05cSAndroid Build Coastguard Worker #endif
777*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FLOAT128
778*5c90c05cSAndroid Build Coastguard Worker using float128 = __float128;
779*5c90c05cSAndroid Build Coastguard Worker #else
780*5c90c05cSAndroid Build Coastguard Worker struct float128 {};
781*5c90c05cSAndroid Build Coastguard Worker #endif
782*5c90c05cSAndroid Build Coastguard Worker 
783*5c90c05cSAndroid Build Coastguard Worker template <typename T> using is_float128 = std::is_same<T, float128>;
784*5c90c05cSAndroid Build Coastguard Worker 
785*5c90c05cSAndroid Build Coastguard Worker template <typename T>
786*5c90c05cSAndroid Build Coastguard Worker using is_floating_point =
787*5c90c05cSAndroid Build Coastguard Worker     bool_constant<std::is_floating_point<T>::value || is_float128<T>::value>;
788*5c90c05cSAndroid Build Coastguard Worker 
789*5c90c05cSAndroid Build Coastguard Worker template <typename T, bool = std::is_floating_point<T>::value>
790*5c90c05cSAndroid Build Coastguard Worker struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
791*5c90c05cSAndroid Build Coastguard Worker                                      sizeof(T) <= sizeof(double)> {};
792*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct is_fast_float<T, false> : std::false_type {};
793*5c90c05cSAndroid Build Coastguard Worker 
794*5c90c05cSAndroid Build Coastguard Worker template <typename T>
795*5c90c05cSAndroid Build Coastguard Worker using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
796*5c90c05cSAndroid Build Coastguard Worker 
797*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
798*5c90c05cSAndroid Build Coastguard Worker #  define FMT_USE_FULL_CACHE_DRAGONBOX 0
799*5c90c05cSAndroid Build Coastguard Worker #endif
800*5c90c05cSAndroid Build Coastguard Worker 
801*5c90c05cSAndroid Build Coastguard Worker // An allocator that uses malloc/free to allow removing dependency on the C++
802*5c90c05cSAndroid Build Coastguard Worker // standard libary runtime.
803*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct allocator {
804*5c90c05cSAndroid Build Coastguard Worker   using value_type = T;
805*5c90c05cSAndroid Build Coastguard Worker 
806*5c90c05cSAndroid Build Coastguard Worker   T* allocate(size_t n) {
807*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(n <= max_value<size_t>() / sizeof(T), "");
808*5c90c05cSAndroid Build Coastguard Worker     T* p = static_cast<T*>(malloc(n * sizeof(T)));
809*5c90c05cSAndroid Build Coastguard Worker     if (!p) FMT_THROW(std::bad_alloc());
810*5c90c05cSAndroid Build Coastguard Worker     return p;
811*5c90c05cSAndroid Build Coastguard Worker   }
812*5c90c05cSAndroid Build Coastguard Worker 
813*5c90c05cSAndroid Build Coastguard Worker   void deallocate(T* p, size_t) { free(p); }
814*5c90c05cSAndroid Build Coastguard Worker };
815*5c90c05cSAndroid Build Coastguard Worker 
816*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
817*5c90c05cSAndroid Build Coastguard Worker 
818*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
819*5c90c05cSAndroid Build Coastguard Worker 
820*5c90c05cSAndroid Build Coastguard Worker // The number of characters to store in the basic_memory_buffer object itself
821*5c90c05cSAndroid Build Coastguard Worker // to avoid dynamic memory allocation.
822*5c90c05cSAndroid Build Coastguard Worker enum { inline_buffer_size = 500 };
823*5c90c05cSAndroid Build Coastguard Worker 
824*5c90c05cSAndroid Build Coastguard Worker /**
825*5c90c05cSAndroid Build Coastguard Worker  * A dynamically growing memory buffer for trivially copyable/constructible
826*5c90c05cSAndroid Build Coastguard Worker  * types with the first `SIZE` elements stored in the object itself. Most
827*5c90c05cSAndroid Build Coastguard Worker  * commonly used via the `memory_buffer` alias for `char`.
828*5c90c05cSAndroid Build Coastguard Worker  *
829*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
830*5c90c05cSAndroid Build Coastguard Worker  *
831*5c90c05cSAndroid Build Coastguard Worker  *     auto out = fmt::memory_buffer();
832*5c90c05cSAndroid Build Coastguard Worker  *     fmt::format_to(std::back_inserter(out), "The answer is {}.", 42);
833*5c90c05cSAndroid Build Coastguard Worker  *
834*5c90c05cSAndroid Build Coastguard Worker  * This will append "The answer is 42." to `out`. The buffer content can be
835*5c90c05cSAndroid Build Coastguard Worker  * converted to `std::string` with `to_string(out)`.
836*5c90c05cSAndroid Build Coastguard Worker  */
837*5c90c05cSAndroid Build Coastguard Worker template <typename T, size_t SIZE = inline_buffer_size,
838*5c90c05cSAndroid Build Coastguard Worker           typename Allocator = detail::allocator<T>>
839*5c90c05cSAndroid Build Coastguard Worker class basic_memory_buffer : public detail::buffer<T> {
840*5c90c05cSAndroid Build Coastguard Worker  private:
841*5c90c05cSAndroid Build Coastguard Worker   T store_[SIZE];
842*5c90c05cSAndroid Build Coastguard Worker 
843*5c90c05cSAndroid Build Coastguard Worker   // Don't inherit from Allocator to avoid generating type_info for it.
844*5c90c05cSAndroid Build Coastguard Worker   FMT_NO_UNIQUE_ADDRESS Allocator alloc_;
845*5c90c05cSAndroid Build Coastguard Worker 
846*5c90c05cSAndroid Build Coastguard Worker   // Deallocate memory allocated by the buffer.
847*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 void deallocate() {
848*5c90c05cSAndroid Build Coastguard Worker     T* data = this->data();
849*5c90c05cSAndroid Build Coastguard Worker     if (data != store_) alloc_.deallocate(data, this->capacity());
850*5c90c05cSAndroid Build Coastguard Worker   }
851*5c90c05cSAndroid Build Coastguard Worker 
852*5c90c05cSAndroid Build Coastguard Worker   static FMT_CONSTEXPR20 void grow(detail::buffer<T>& buf, size_t size) {
853*5c90c05cSAndroid Build Coastguard Worker     detail::abort_fuzzing_if(size > 5000);
854*5c90c05cSAndroid Build Coastguard Worker     auto& self = static_cast<basic_memory_buffer&>(buf);
855*5c90c05cSAndroid Build Coastguard Worker     const size_t max_size =
856*5c90c05cSAndroid Build Coastguard Worker         std::allocator_traits<Allocator>::max_size(self.alloc_);
857*5c90c05cSAndroid Build Coastguard Worker     size_t old_capacity = buf.capacity();
858*5c90c05cSAndroid Build Coastguard Worker     size_t new_capacity = old_capacity + old_capacity / 2;
859*5c90c05cSAndroid Build Coastguard Worker     if (size > new_capacity)
860*5c90c05cSAndroid Build Coastguard Worker       new_capacity = size;
861*5c90c05cSAndroid Build Coastguard Worker     else if (new_capacity > max_size)
862*5c90c05cSAndroid Build Coastguard Worker       new_capacity = max_of(size, max_size);
863*5c90c05cSAndroid Build Coastguard Worker     T* old_data = buf.data();
864*5c90c05cSAndroid Build Coastguard Worker     T* new_data = self.alloc_.allocate(new_capacity);
865*5c90c05cSAndroid Build Coastguard Worker     // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
866*5c90c05cSAndroid Build Coastguard Worker     detail::assume(buf.size() <= new_capacity);
867*5c90c05cSAndroid Build Coastguard Worker     // The following code doesn't throw, so the raw pointer above doesn't leak.
868*5c90c05cSAndroid Build Coastguard Worker     memcpy(new_data, old_data, buf.size() * sizeof(T));
869*5c90c05cSAndroid Build Coastguard Worker     self.set(new_data, new_capacity);
870*5c90c05cSAndroid Build Coastguard Worker     // deallocate must not throw according to the standard, but even if it does,
871*5c90c05cSAndroid Build Coastguard Worker     // the buffer already uses the new storage and will deallocate it in
872*5c90c05cSAndroid Build Coastguard Worker     // destructor.
873*5c90c05cSAndroid Build Coastguard Worker     if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity);
874*5c90c05cSAndroid Build Coastguard Worker   }
875*5c90c05cSAndroid Build Coastguard Worker 
876*5c90c05cSAndroid Build Coastguard Worker  public:
877*5c90c05cSAndroid Build Coastguard Worker   using value_type = T;
878*5c90c05cSAndroid Build Coastguard Worker   using const_reference = const T&;
879*5c90c05cSAndroid Build Coastguard Worker 
880*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR explicit basic_memory_buffer(
881*5c90c05cSAndroid Build Coastguard Worker       const Allocator& alloc = Allocator())
882*5c90c05cSAndroid Build Coastguard Worker       : detail::buffer<T>(grow), alloc_(alloc) {
883*5c90c05cSAndroid Build Coastguard Worker     this->set(store_, SIZE);
884*5c90c05cSAndroid Build Coastguard Worker     if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
885*5c90c05cSAndroid Build Coastguard Worker   }
886*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
887*5c90c05cSAndroid Build Coastguard Worker 
888*5c90c05cSAndroid Build Coastguard Worker  private:
889*5c90c05cSAndroid Build Coastguard Worker   // Move data from other to this buffer.
890*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
891*5c90c05cSAndroid Build Coastguard Worker     alloc_ = std::move(other.alloc_);
892*5c90c05cSAndroid Build Coastguard Worker     T* data = other.data();
893*5c90c05cSAndroid Build Coastguard Worker     size_t size = other.size(), capacity = other.capacity();
894*5c90c05cSAndroid Build Coastguard Worker     if (data == other.store_) {
895*5c90c05cSAndroid Build Coastguard Worker       this->set(store_, capacity);
896*5c90c05cSAndroid Build Coastguard Worker       detail::copy<T>(other.store_, other.store_ + size, store_);
897*5c90c05cSAndroid Build Coastguard Worker     } else {
898*5c90c05cSAndroid Build Coastguard Worker       this->set(data, capacity);
899*5c90c05cSAndroid Build Coastguard Worker       // Set pointer to the inline array so that delete is not called
900*5c90c05cSAndroid Build Coastguard Worker       // when deallocating.
901*5c90c05cSAndroid Build Coastguard Worker       other.set(other.store_, 0);
902*5c90c05cSAndroid Build Coastguard Worker       other.clear();
903*5c90c05cSAndroid Build Coastguard Worker     }
904*5c90c05cSAndroid Build Coastguard Worker     this->resize(size);
905*5c90c05cSAndroid Build Coastguard Worker   }
906*5c90c05cSAndroid Build Coastguard Worker 
907*5c90c05cSAndroid Build Coastguard Worker  public:
908*5c90c05cSAndroid Build Coastguard Worker   /// Constructs a `basic_memory_buffer` object moving the content of the other
909*5c90c05cSAndroid Build Coastguard Worker   /// object to it.
910*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept
911*5c90c05cSAndroid Build Coastguard Worker       : detail::buffer<T>(grow) {
912*5c90c05cSAndroid Build Coastguard Worker     move(other);
913*5c90c05cSAndroid Build Coastguard Worker   }
914*5c90c05cSAndroid Build Coastguard Worker 
915*5c90c05cSAndroid Build Coastguard Worker   /// Moves the content of the other `basic_memory_buffer` object to this one.
916*5c90c05cSAndroid Build Coastguard Worker   auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& {
917*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(this != &other, "");
918*5c90c05cSAndroid Build Coastguard Worker     deallocate();
919*5c90c05cSAndroid Build Coastguard Worker     move(other);
920*5c90c05cSAndroid Build Coastguard Worker     return *this;
921*5c90c05cSAndroid Build Coastguard Worker   }
922*5c90c05cSAndroid Build Coastguard Worker 
923*5c90c05cSAndroid Build Coastguard Worker   // Returns a copy of the allocator associated with this buffer.
924*5c90c05cSAndroid Build Coastguard Worker   auto get_allocator() const -> Allocator { return alloc_; }
925*5c90c05cSAndroid Build Coastguard Worker 
926*5c90c05cSAndroid Build Coastguard Worker   /// Resizes the buffer to contain `count` elements. If T is a POD type new
927*5c90c05cSAndroid Build Coastguard Worker   /// elements may not be initialized.
928*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); }
929*5c90c05cSAndroid Build Coastguard Worker 
930*5c90c05cSAndroid Build Coastguard Worker   /// Increases the buffer capacity to `new_capacity`.
931*5c90c05cSAndroid Build Coastguard Worker   void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
932*5c90c05cSAndroid Build Coastguard Worker 
933*5c90c05cSAndroid Build Coastguard Worker   using detail::buffer<T>::append;
934*5c90c05cSAndroid Build Coastguard Worker   template <typename ContiguousRange>
935*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 void append(const ContiguousRange& range) {
936*5c90c05cSAndroid Build Coastguard Worker     append(range.data(), range.data() + range.size());
937*5c90c05cSAndroid Build Coastguard Worker   }
938*5c90c05cSAndroid Build Coastguard Worker };
939*5c90c05cSAndroid Build Coastguard Worker 
940*5c90c05cSAndroid Build Coastguard Worker using memory_buffer = basic_memory_buffer<char>;
941*5c90c05cSAndroid Build Coastguard Worker 
942*5c90c05cSAndroid Build Coastguard Worker template <size_t SIZE>
943*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD auto to_string(basic_memory_buffer<char, SIZE>& buf)
944*5c90c05cSAndroid Build Coastguard Worker     -> std::string {
945*5c90c05cSAndroid Build Coastguard Worker   auto size = buf.size();
946*5c90c05cSAndroid Build Coastguard Worker   detail::assume(size < std::string().max_size());
947*5c90c05cSAndroid Build Coastguard Worker   return {buf.data(), size};
948*5c90c05cSAndroid Build Coastguard Worker }
949*5c90c05cSAndroid Build Coastguard Worker 
950*5c90c05cSAndroid Build Coastguard Worker // A writer to a buffered stream. It doesn't own the underlying stream.
951*5c90c05cSAndroid Build Coastguard Worker class writer {
952*5c90c05cSAndroid Build Coastguard Worker  private:
953*5c90c05cSAndroid Build Coastguard Worker   detail::buffer<char>* buf_;
954*5c90c05cSAndroid Build Coastguard Worker 
955*5c90c05cSAndroid Build Coastguard Worker   // We cannot create a file buffer in advance because any write to a FILE may
956*5c90c05cSAndroid Build Coastguard Worker   // invalidate it.
957*5c90c05cSAndroid Build Coastguard Worker   FILE* file_;
958*5c90c05cSAndroid Build Coastguard Worker 
959*5c90c05cSAndroid Build Coastguard Worker  public:
960*5c90c05cSAndroid Build Coastguard Worker   inline writer(FILE* f) : buf_(nullptr), file_(f) {}
961*5c90c05cSAndroid Build Coastguard Worker   inline writer(detail::buffer<char>& buf) : buf_(&buf) {}
962*5c90c05cSAndroid Build Coastguard Worker 
963*5c90c05cSAndroid Build Coastguard Worker   /// Formats `args` according to specifications in `fmt` and writes the
964*5c90c05cSAndroid Build Coastguard Worker   /// output to the file.
965*5c90c05cSAndroid Build Coastguard Worker   template <typename... T> void print(format_string<T...> fmt, T&&... args) {
966*5c90c05cSAndroid Build Coastguard Worker     if (buf_)
967*5c90c05cSAndroid Build Coastguard Worker       fmt::format_to(appender(*buf_), fmt, std::forward<T>(args)...);
968*5c90c05cSAndroid Build Coastguard Worker     else
969*5c90c05cSAndroid Build Coastguard Worker       fmt::print(file_, fmt, std::forward<T>(args)...);
970*5c90c05cSAndroid Build Coastguard Worker   }
971*5c90c05cSAndroid Build Coastguard Worker };
972*5c90c05cSAndroid Build Coastguard Worker 
973*5c90c05cSAndroid Build Coastguard Worker class string_buffer {
974*5c90c05cSAndroid Build Coastguard Worker  private:
975*5c90c05cSAndroid Build Coastguard Worker   std::string str_;
976*5c90c05cSAndroid Build Coastguard Worker   detail::container_buffer<std::string> buf_;
977*5c90c05cSAndroid Build Coastguard Worker 
978*5c90c05cSAndroid Build Coastguard Worker  public:
979*5c90c05cSAndroid Build Coastguard Worker   inline string_buffer() : buf_(str_) {}
980*5c90c05cSAndroid Build Coastguard Worker 
981*5c90c05cSAndroid Build Coastguard Worker   inline operator writer() { return buf_; }
982*5c90c05cSAndroid Build Coastguard Worker   inline std::string& str() { return str_; }
983*5c90c05cSAndroid Build Coastguard Worker };
984*5c90c05cSAndroid Build Coastguard Worker 
985*5c90c05cSAndroid Build Coastguard Worker template <typename T, size_t SIZE, typename Allocator>
986*5c90c05cSAndroid Build Coastguard Worker struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
987*5c90c05cSAndroid Build Coastguard Worker };
988*5c90c05cSAndroid Build Coastguard Worker 
989*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
990*5c90c05cSAndroid Build Coastguard Worker namespace detail {
991*5c90c05cSAndroid Build Coastguard Worker FMT_API auto write_console(int fd, string_view text) -> bool;
992*5c90c05cSAndroid Build Coastguard Worker FMT_API void print(FILE*, string_view);
993*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
994*5c90c05cSAndroid Build Coastguard Worker 
995*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
996*5c90c05cSAndroid Build Coastguard Worker 
997*5c90c05cSAndroid Build Coastguard Worker // Suppress a misleading warning in older versions of clang.
998*5c90c05cSAndroid Build Coastguard Worker FMT_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables")
999*5c90c05cSAndroid Build Coastguard Worker 
1000*5c90c05cSAndroid Build Coastguard Worker /// An error reported from a formatting function.
1001*5c90c05cSAndroid Build Coastguard Worker class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error {
1002*5c90c05cSAndroid Build Coastguard Worker  public:
1003*5c90c05cSAndroid Build Coastguard Worker   using std::runtime_error::runtime_error;
1004*5c90c05cSAndroid Build Coastguard Worker };
1005*5c90c05cSAndroid Build Coastguard Worker 
1006*5c90c05cSAndroid Build Coastguard Worker namespace detail {
1007*5c90c05cSAndroid Build Coastguard Worker template <typename Char, size_t N> struct fixed_string {
1008*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 fixed_string(const Char (&s)[N]) {
1009*5c90c05cSAndroid Build Coastguard Worker     detail::copy<Char, const Char*, Char*>(static_cast<const Char*>(s), s + N,
1010*5c90c05cSAndroid Build Coastguard Worker                                            data);
1011*5c90c05cSAndroid Build Coastguard Worker   }
1012*5c90c05cSAndroid Build Coastguard Worker   Char data[N] = {};
1013*5c90c05cSAndroid Build Coastguard Worker };
1014*5c90c05cSAndroid Build Coastguard Worker 
1015*5c90c05cSAndroid Build Coastguard Worker // Converts a compile-time string to basic_string_view.
1016*5c90c05cSAndroid Build Coastguard Worker template <typename Char, size_t N>
1017*5c90c05cSAndroid Build Coastguard Worker constexpr auto compile_string_to_view(const Char (&s)[N])
1018*5c90c05cSAndroid Build Coastguard Worker     -> basic_string_view<Char> {
1019*5c90c05cSAndroid Build Coastguard Worker   // Remove trailing NUL character if needed. Won't be present if this is used
1020*5c90c05cSAndroid Build Coastguard Worker   // with a raw character array (i.e. not defined as a string).
1021*5c90c05cSAndroid Build Coastguard Worker   return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
1022*5c90c05cSAndroid Build Coastguard Worker }
1023*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1024*5c90c05cSAndroid Build Coastguard Worker constexpr auto compile_string_to_view(basic_string_view<Char> s)
1025*5c90c05cSAndroid Build Coastguard Worker     -> basic_string_view<Char> {
1026*5c90c05cSAndroid Build Coastguard Worker   return s;
1027*5c90c05cSAndroid Build Coastguard Worker }
1028*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
1029*5c90c05cSAndroid Build Coastguard Worker 
1030*5c90c05cSAndroid Build Coastguard Worker // A generic formatting context with custom output iterator and character
1031*5c90c05cSAndroid Build Coastguard Worker // (code unit) support. Char is the format string code unit type which can be
1032*5c90c05cSAndroid Build Coastguard Worker // different from OutputIt::value_type.
1033*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Char> class generic_context {
1034*5c90c05cSAndroid Build Coastguard Worker  private:
1035*5c90c05cSAndroid Build Coastguard Worker   OutputIt out_;
1036*5c90c05cSAndroid Build Coastguard Worker   basic_format_args<generic_context> args_;
1037*5c90c05cSAndroid Build Coastguard Worker   detail::locale_ref loc_;
1038*5c90c05cSAndroid Build Coastguard Worker 
1039*5c90c05cSAndroid Build Coastguard Worker  public:
1040*5c90c05cSAndroid Build Coastguard Worker   using char_type = Char;
1041*5c90c05cSAndroid Build Coastguard Worker   using iterator = OutputIt;
1042*5c90c05cSAndroid Build Coastguard Worker   using parse_context_type FMT_DEPRECATED = parse_context<Char>;
1043*5c90c05cSAndroid Build Coastguard Worker   template <typename T>
1044*5c90c05cSAndroid Build Coastguard Worker   using formatter_type FMT_DEPRECATED = formatter<T, Char>;
1045*5c90c05cSAndroid Build Coastguard Worker   enum { builtin_types = FMT_BUILTIN_TYPES };
1046*5c90c05cSAndroid Build Coastguard Worker 
1047*5c90c05cSAndroid Build Coastguard Worker   constexpr generic_context(OutputIt out,
1048*5c90c05cSAndroid Build Coastguard Worker                             basic_format_args<generic_context> args,
1049*5c90c05cSAndroid Build Coastguard Worker                             detail::locale_ref loc = {})
1050*5c90c05cSAndroid Build Coastguard Worker       : out_(out), args_(args), loc_(loc) {}
1051*5c90c05cSAndroid Build Coastguard Worker   generic_context(generic_context&&) = default;
1052*5c90c05cSAndroid Build Coastguard Worker   generic_context(const generic_context&) = delete;
1053*5c90c05cSAndroid Build Coastguard Worker   void operator=(const generic_context&) = delete;
1054*5c90c05cSAndroid Build Coastguard Worker 
1055*5c90c05cSAndroid Build Coastguard Worker   constexpr auto arg(int id) const -> basic_format_arg<generic_context> {
1056*5c90c05cSAndroid Build Coastguard Worker     return args_.get(id);
1057*5c90c05cSAndroid Build Coastguard Worker   }
1058*5c90c05cSAndroid Build Coastguard Worker   auto arg(basic_string_view<Char> name) -> basic_format_arg<generic_context> {
1059*5c90c05cSAndroid Build Coastguard Worker     return args_.get(name);
1060*5c90c05cSAndroid Build Coastguard Worker   }
1061*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto arg_id(basic_string_view<Char> name) -> int {
1062*5c90c05cSAndroid Build Coastguard Worker     return args_.get_id(name);
1063*5c90c05cSAndroid Build Coastguard Worker   }
1064*5c90c05cSAndroid Build Coastguard Worker 
1065*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto out() -> iterator { return out_; }
1066*5c90c05cSAndroid Build Coastguard Worker 
1067*5c90c05cSAndroid Build Coastguard Worker   void advance_to(iterator it) {
1068*5c90c05cSAndroid Build Coastguard Worker     if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
1069*5c90c05cSAndroid Build Coastguard Worker   }
1070*5c90c05cSAndroid Build Coastguard Worker 
1071*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
1072*5c90c05cSAndroid Build Coastguard Worker };
1073*5c90c05cSAndroid Build Coastguard Worker 
1074*5c90c05cSAndroid Build Coastguard Worker class loc_value {
1075*5c90c05cSAndroid Build Coastguard Worker  private:
1076*5c90c05cSAndroid Build Coastguard Worker   basic_format_arg<context> value_;
1077*5c90c05cSAndroid Build Coastguard Worker 
1078*5c90c05cSAndroid Build Coastguard Worker  public:
1079*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
1080*5c90c05cSAndroid Build Coastguard Worker   loc_value(T value) : value_(value) {}
1081*5c90c05cSAndroid Build Coastguard Worker 
1082*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
1083*5c90c05cSAndroid Build Coastguard Worker   loc_value(T) {}
1084*5c90c05cSAndroid Build Coastguard Worker 
1085*5c90c05cSAndroid Build Coastguard Worker   template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {
1086*5c90c05cSAndroid Build Coastguard Worker     return value_.visit(vis);
1087*5c90c05cSAndroid Build Coastguard Worker   }
1088*5c90c05cSAndroid Build Coastguard Worker };
1089*5c90c05cSAndroid Build Coastguard Worker 
1090*5c90c05cSAndroid Build Coastguard Worker // A locale facet that formats values in UTF-8.
1091*5c90c05cSAndroid Build Coastguard Worker // It is parameterized on the locale to avoid the heavy <locale> include.
1092*5c90c05cSAndroid Build Coastguard Worker template <typename Locale> class format_facet : public Locale::facet {
1093*5c90c05cSAndroid Build Coastguard Worker  private:
1094*5c90c05cSAndroid Build Coastguard Worker   std::string separator_;
1095*5c90c05cSAndroid Build Coastguard Worker   std::string grouping_;
1096*5c90c05cSAndroid Build Coastguard Worker   std::string decimal_point_;
1097*5c90c05cSAndroid Build Coastguard Worker 
1098*5c90c05cSAndroid Build Coastguard Worker  protected:
1099*5c90c05cSAndroid Build Coastguard Worker   virtual auto do_put(appender out, loc_value val,
1100*5c90c05cSAndroid Build Coastguard Worker                       const format_specs& specs) const -> bool;
1101*5c90c05cSAndroid Build Coastguard Worker 
1102*5c90c05cSAndroid Build Coastguard Worker  public:
1103*5c90c05cSAndroid Build Coastguard Worker   static FMT_API typename Locale::id id;
1104*5c90c05cSAndroid Build Coastguard Worker 
1105*5c90c05cSAndroid Build Coastguard Worker   explicit format_facet(Locale& loc);
1106*5c90c05cSAndroid Build Coastguard Worker   explicit format_facet(string_view sep = "",
1107*5c90c05cSAndroid Build Coastguard Worker                         std::initializer_list<unsigned char> g = {3},
1108*5c90c05cSAndroid Build Coastguard Worker                         std::string decimal_point = ".")
1109*5c90c05cSAndroid Build Coastguard Worker       : separator_(sep.data(), sep.size()),
1110*5c90c05cSAndroid Build Coastguard Worker         grouping_(g.begin(), g.end()),
1111*5c90c05cSAndroid Build Coastguard Worker         decimal_point_(decimal_point) {}
1112*5c90c05cSAndroid Build Coastguard Worker 
1113*5c90c05cSAndroid Build Coastguard Worker   auto put(appender out, loc_value val, const format_specs& specs) const
1114*5c90c05cSAndroid Build Coastguard Worker       -> bool {
1115*5c90c05cSAndroid Build Coastguard Worker     return do_put(out, val, specs);
1116*5c90c05cSAndroid Build Coastguard Worker   }
1117*5c90c05cSAndroid Build Coastguard Worker };
1118*5c90c05cSAndroid Build Coastguard Worker 
1119*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
1120*5c90c05cSAndroid Build Coastguard Worker 
1121*5c90c05cSAndroid Build Coastguard Worker namespace detail {
1122*5c90c05cSAndroid Build Coastguard Worker 
1123*5c90c05cSAndroid Build Coastguard Worker // Returns true if value is negative, false otherwise.
1124*5c90c05cSAndroid Build Coastguard Worker // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1125*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1126*5c90c05cSAndroid Build Coastguard Worker constexpr auto is_negative(T value) -> bool {
1127*5c90c05cSAndroid Build Coastguard Worker   return value < 0;
1128*5c90c05cSAndroid Build Coastguard Worker }
1129*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1130*5c90c05cSAndroid Build Coastguard Worker constexpr auto is_negative(T) -> bool {
1131*5c90c05cSAndroid Build Coastguard Worker   return false;
1132*5c90c05cSAndroid Build Coastguard Worker }
1133*5c90c05cSAndroid Build Coastguard Worker 
1134*5c90c05cSAndroid Build Coastguard Worker // Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1135*5c90c05cSAndroid Build Coastguard Worker // represent all values of an integral type T.
1136*5c90c05cSAndroid Build Coastguard Worker template <typename T>
1137*5c90c05cSAndroid Build Coastguard Worker using uint32_or_64_or_128_t =
1138*5c90c05cSAndroid Build Coastguard Worker     conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,
1139*5c90c05cSAndroid Build Coastguard Worker                   uint32_t,
1140*5c90c05cSAndroid Build Coastguard Worker                   conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
1141*5c90c05cSAndroid Build Coastguard Worker template <typename T>
1142*5c90c05cSAndroid Build Coastguard Worker using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
1143*5c90c05cSAndroid Build Coastguard Worker 
1144*5c90c05cSAndroid Build Coastguard Worker #define FMT_POWERS_OF_10(factor)                                  \
1145*5c90c05cSAndroid Build Coastguard Worker   factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \
1146*5c90c05cSAndroid Build Coastguard Worker       (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \
1147*5c90c05cSAndroid Build Coastguard Worker       (factor) * 100000000, (factor) * 1000000000
1148*5c90c05cSAndroid Build Coastguard Worker 
1149*5c90c05cSAndroid Build Coastguard Worker // Converts value in the range [0, 100) to a string.
1150*5c90c05cSAndroid Build Coastguard Worker // GCC generates slightly better code when value is pointer-size.
1151*5c90c05cSAndroid Build Coastguard Worker inline auto digits2(size_t value) -> const char* {
1152*5c90c05cSAndroid Build Coastguard Worker   // Align data since unaligned access may be slower when crossing a
1153*5c90c05cSAndroid Build Coastguard Worker   // hardware-specific boundary.
1154*5c90c05cSAndroid Build Coastguard Worker   alignas(2) static const char data[] =
1155*5c90c05cSAndroid Build Coastguard Worker       "0001020304050607080910111213141516171819"
1156*5c90c05cSAndroid Build Coastguard Worker       "2021222324252627282930313233343536373839"
1157*5c90c05cSAndroid Build Coastguard Worker       "4041424344454647484950515253545556575859"
1158*5c90c05cSAndroid Build Coastguard Worker       "6061626364656667686970717273747576777879"
1159*5c90c05cSAndroid Build Coastguard Worker       "8081828384858687888990919293949596979899";
1160*5c90c05cSAndroid Build Coastguard Worker   return &data[value * 2];
1161*5c90c05cSAndroid Build Coastguard Worker }
1162*5c90c05cSAndroid Build Coastguard Worker 
1163*5c90c05cSAndroid Build Coastguard Worker template <typename Char> constexpr auto getsign(sign s) -> Char {
1164*5c90c05cSAndroid Build Coastguard Worker   return static_cast<char>(((' ' << 24) | ('+' << 16) | ('-' << 8)) >>
1165*5c90c05cSAndroid Build Coastguard Worker                            (static_cast<int>(s) * 8));
1166*5c90c05cSAndroid Build Coastguard Worker }
1167*5c90c05cSAndroid Build Coastguard Worker 
1168*5c90c05cSAndroid Build Coastguard Worker template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1169*5c90c05cSAndroid Build Coastguard Worker   int count = 1;
1170*5c90c05cSAndroid Build Coastguard Worker   for (;;) {
1171*5c90c05cSAndroid Build Coastguard Worker     // Integer division is slow so do it for a group of four digits instead
1172*5c90c05cSAndroid Build Coastguard Worker     // of for every digit. The idea comes from the talk by Alexandrescu
1173*5c90c05cSAndroid Build Coastguard Worker     // "Three Optimization Tips for C++". See speed-test for a comparison.
1174*5c90c05cSAndroid Build Coastguard Worker     if (n < 10) return count;
1175*5c90c05cSAndroid Build Coastguard Worker     if (n < 100) return count + 1;
1176*5c90c05cSAndroid Build Coastguard Worker     if (n < 1000) return count + 2;
1177*5c90c05cSAndroid Build Coastguard Worker     if (n < 10000) return count + 3;
1178*5c90c05cSAndroid Build Coastguard Worker     n /= 10000u;
1179*5c90c05cSAndroid Build Coastguard Worker     count += 4;
1180*5c90c05cSAndroid Build Coastguard Worker   }
1181*5c90c05cSAndroid Build Coastguard Worker }
1182*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_INT128
1183*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1184*5c90c05cSAndroid Build Coastguard Worker   return count_digits_fallback(n);
1185*5c90c05cSAndroid Build Coastguard Worker }
1186*5c90c05cSAndroid Build Coastguard Worker #endif
1187*5c90c05cSAndroid Build Coastguard Worker 
1188*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZLL
1189*5c90c05cSAndroid Build Coastguard Worker // It is a separate function rather than a part of count_digits to workaround
1190*5c90c05cSAndroid Build Coastguard Worker // the lack of static constexpr in constexpr functions.
1191*5c90c05cSAndroid Build Coastguard Worker inline auto do_count_digits(uint64_t n) -> int {
1192*5c90c05cSAndroid Build Coastguard Worker   // This has comparable performance to the version by Kendall Willets
1193*5c90c05cSAndroid Build Coastguard Worker   // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1194*5c90c05cSAndroid Build Coastguard Worker   // but uses smaller tables.
1195*5c90c05cSAndroid Build Coastguard Worker   // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1196*5c90c05cSAndroid Build Coastguard Worker   static constexpr uint8_t bsr2log10[] = {
1197*5c90c05cSAndroid Build Coastguard Worker       1,  1,  1,  2,  2,  2,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,
1198*5c90c05cSAndroid Build Coastguard Worker       6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9,  10, 10, 10,
1199*5c90c05cSAndroid Build Coastguard Worker       10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1200*5c90c05cSAndroid Build Coastguard Worker       15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1201*5c90c05cSAndroid Build Coastguard Worker   auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1202*5c90c05cSAndroid Build Coastguard Worker   static constexpr const uint64_t zero_or_powers_of_10[] = {
1203*5c90c05cSAndroid Build Coastguard Worker       0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1204*5c90c05cSAndroid Build Coastguard Worker       10000000000000000000ULL};
1205*5c90c05cSAndroid Build Coastguard Worker   return t - (n < zero_or_powers_of_10[t]);
1206*5c90c05cSAndroid Build Coastguard Worker }
1207*5c90c05cSAndroid Build Coastguard Worker #endif
1208*5c90c05cSAndroid Build Coastguard Worker 
1209*5c90c05cSAndroid Build Coastguard Worker // Returns the number of decimal digits in n. Leading zeros are not counted
1210*5c90c05cSAndroid Build Coastguard Worker // except for n == 0 in which case count_digits returns 1.
1211*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
1212*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZLL
1213*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);
1214*5c90c05cSAndroid Build Coastguard Worker #endif
1215*5c90c05cSAndroid Build Coastguard Worker   return count_digits_fallback(n);
1216*5c90c05cSAndroid Build Coastguard Worker }
1217*5c90c05cSAndroid Build Coastguard Worker 
1218*5c90c05cSAndroid Build Coastguard Worker // Counts the number of digits in n. BITS = log2(radix).
1219*5c90c05cSAndroid Build Coastguard Worker template <int BITS, typename UInt>
1220*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1221*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZ
1222*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1223*5c90c05cSAndroid Build Coastguard Worker     return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1224*5c90c05cSAndroid Build Coastguard Worker #endif
1225*5c90c05cSAndroid Build Coastguard Worker   // Lambda avoids unreachable code warnings from NVHPC.
1226*5c90c05cSAndroid Build Coastguard Worker   return [](UInt m) {
1227*5c90c05cSAndroid Build Coastguard Worker     int num_digits = 0;
1228*5c90c05cSAndroid Build Coastguard Worker     do {
1229*5c90c05cSAndroid Build Coastguard Worker       ++num_digits;
1230*5c90c05cSAndroid Build Coastguard Worker     } while ((m >>= BITS) != 0);
1231*5c90c05cSAndroid Build Coastguard Worker     return num_digits;
1232*5c90c05cSAndroid Build Coastguard Worker   }(n);
1233*5c90c05cSAndroid Build Coastguard Worker }
1234*5c90c05cSAndroid Build Coastguard Worker 
1235*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZ
1236*5c90c05cSAndroid Build Coastguard Worker // It is a separate function rather than a part of count_digits to workaround
1237*5c90c05cSAndroid Build Coastguard Worker // the lack of static constexpr in constexpr functions.
1238*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1239*5c90c05cSAndroid Build Coastguard Worker // An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1240*5c90c05cSAndroid Build Coastguard Worker // This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1241*5c90c05cSAndroid Build Coastguard Worker #  define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
1242*5c90c05cSAndroid Build Coastguard Worker   static constexpr uint64_t table[] = {
1243*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(0),          FMT_INC(0),          FMT_INC(0),           // 8
1244*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(10),         FMT_INC(10),         FMT_INC(10),          // 64
1245*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(100),        FMT_INC(100),        FMT_INC(100),         // 512
1246*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(1000),       FMT_INC(1000),       FMT_INC(1000),        // 4096
1247*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(10000),      FMT_INC(10000),      FMT_INC(10000),       // 32k
1248*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(100000),     FMT_INC(100000),     FMT_INC(100000),      // 256k
1249*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(1000000),    FMT_INC(1000000),    FMT_INC(1000000),     // 2048k
1250*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(10000000),   FMT_INC(10000000),   FMT_INC(10000000),    // 16M
1251*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(100000000),  FMT_INC(100000000),  FMT_INC(100000000),   // 128M
1252*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000),  // 1024M
1253*5c90c05cSAndroid Build Coastguard Worker       FMT_INC(1000000000), FMT_INC(1000000000)                        // 4B
1254*5c90c05cSAndroid Build Coastguard Worker   };
1255*5c90c05cSAndroid Build Coastguard Worker   auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1256*5c90c05cSAndroid Build Coastguard Worker   return static_cast<int>((n + inc) >> 32);
1257*5c90c05cSAndroid Build Coastguard Worker }
1258*5c90c05cSAndroid Build Coastguard Worker #endif
1259*5c90c05cSAndroid Build Coastguard Worker 
1260*5c90c05cSAndroid Build Coastguard Worker // Optional version of count_digits for better performance on 32-bit platforms.
1261*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
1262*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_BUILTIN_CLZ
1263*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);
1264*5c90c05cSAndroid Build Coastguard Worker #endif
1265*5c90c05cSAndroid Build Coastguard Worker   return count_digits_fallback(n);
1266*5c90c05cSAndroid Build Coastguard Worker }
1267*5c90c05cSAndroid Build Coastguard Worker 
1268*5c90c05cSAndroid Build Coastguard Worker template <typename Int> constexpr auto digits10() noexcept -> int {
1269*5c90c05cSAndroid Build Coastguard Worker   return std::numeric_limits<Int>::digits10;
1270*5c90c05cSAndroid Build Coastguard Worker }
1271*5c90c05cSAndroid Build Coastguard Worker template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1272*5c90c05cSAndroid Build Coastguard Worker template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1273*5c90c05cSAndroid Build Coastguard Worker 
1274*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct thousands_sep_result {
1275*5c90c05cSAndroid Build Coastguard Worker   std::string grouping;
1276*5c90c05cSAndroid Build Coastguard Worker   Char thousands_sep;
1277*5c90c05cSAndroid Build Coastguard Worker };
1278*5c90c05cSAndroid Build Coastguard Worker 
1279*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1280*5c90c05cSAndroid Build Coastguard Worker FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
1281*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1282*5c90c05cSAndroid Build Coastguard Worker inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
1283*5c90c05cSAndroid Build Coastguard Worker   auto result = thousands_sep_impl<char>(loc);
1284*5c90c05cSAndroid Build Coastguard Worker   return {result.grouping, Char(result.thousands_sep)};
1285*5c90c05cSAndroid Build Coastguard Worker }
1286*5c90c05cSAndroid Build Coastguard Worker template <>
1287*5c90c05cSAndroid Build Coastguard Worker inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {
1288*5c90c05cSAndroid Build Coastguard Worker   return thousands_sep_impl<wchar_t>(loc);
1289*5c90c05cSAndroid Build Coastguard Worker }
1290*5c90c05cSAndroid Build Coastguard Worker 
1291*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1292*5c90c05cSAndroid Build Coastguard Worker FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1293*5c90c05cSAndroid Build Coastguard Worker template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1294*5c90c05cSAndroid Build Coastguard Worker   return Char(decimal_point_impl<char>(loc));
1295*5c90c05cSAndroid Build Coastguard Worker }
1296*5c90c05cSAndroid Build Coastguard Worker template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1297*5c90c05cSAndroid Build Coastguard Worker   return decimal_point_impl<wchar_t>(loc);
1298*5c90c05cSAndroid Build Coastguard Worker }
1299*5c90c05cSAndroid Build Coastguard Worker 
1300*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_HEADER_ONLY
1301*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
1302*5c90c05cSAndroid Build Coastguard Worker extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
1303*5c90c05cSAndroid Build Coastguard Worker     -> thousands_sep_result<char>;
1304*5c90c05cSAndroid Build Coastguard Worker extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
1305*5c90c05cSAndroid Build Coastguard Worker     -> thousands_sep_result<wchar_t>;
1306*5c90c05cSAndroid Build Coastguard Worker extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
1307*5c90c05cSAndroid Build Coastguard Worker extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
1308*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
1309*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_HEADER_ONLY
1310*5c90c05cSAndroid Build Coastguard Worker 
1311*5c90c05cSAndroid Build Coastguard Worker // Compares two characters for equality.
1312*5c90c05cSAndroid Build Coastguard Worker template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1313*5c90c05cSAndroid Build Coastguard Worker   return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1314*5c90c05cSAndroid Build Coastguard Worker }
1315*5c90c05cSAndroid Build Coastguard Worker inline auto equal2(const char* lhs, const char* rhs) -> bool {
1316*5c90c05cSAndroid Build Coastguard Worker   return memcmp(lhs, rhs, 2) == 0;
1317*5c90c05cSAndroid Build Coastguard Worker }
1318*5c90c05cSAndroid Build Coastguard Worker 
1319*5c90c05cSAndroid Build Coastguard Worker // Writes a two-digit value to out.
1320*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1321*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 FMT_INLINE void write2digits(Char* out, size_t value) {
1322*5c90c05cSAndroid Build Coastguard Worker   if (!is_constant_evaluated() && std::is_same<Char, char>::value &&
1323*5c90c05cSAndroid Build Coastguard Worker       !FMT_OPTIMIZE_SIZE) {
1324*5c90c05cSAndroid Build Coastguard Worker     memcpy(out, digits2(value), 2);
1325*5c90c05cSAndroid Build Coastguard Worker     return;
1326*5c90c05cSAndroid Build Coastguard Worker   }
1327*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('0' + value / 10);
1328*5c90c05cSAndroid Build Coastguard Worker   *out = static_cast<Char>('0' + value % 10);
1329*5c90c05cSAndroid Build Coastguard Worker }
1330*5c90c05cSAndroid Build Coastguard Worker 
1331*5c90c05cSAndroid Build Coastguard Worker // Formats a decimal unsigned integer value writing to out pointing to a buffer
1332*5c90c05cSAndroid Build Coastguard Worker // of specified size. The caller must ensure that the buffer is large enough.
1333*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt>
1334*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size)
1335*5c90c05cSAndroid Build Coastguard Worker     -> Char* {
1336*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1337*5c90c05cSAndroid Build Coastguard Worker   unsigned n = to_unsigned(size);
1338*5c90c05cSAndroid Build Coastguard Worker   while (value >= 100) {
1339*5c90c05cSAndroid Build Coastguard Worker     // Integer division is slow so do it for a group of two digits instead
1340*5c90c05cSAndroid Build Coastguard Worker     // of for every digit. The idea comes from the talk by Alexandrescu
1341*5c90c05cSAndroid Build Coastguard Worker     // "Three Optimization Tips for C++". See speed-test for a comparison.
1342*5c90c05cSAndroid Build Coastguard Worker     n -= 2;
1343*5c90c05cSAndroid Build Coastguard Worker     write2digits(out + n, static_cast<unsigned>(value % 100));
1344*5c90c05cSAndroid Build Coastguard Worker     value /= 100;
1345*5c90c05cSAndroid Build Coastguard Worker   }
1346*5c90c05cSAndroid Build Coastguard Worker   if (value >= 10) {
1347*5c90c05cSAndroid Build Coastguard Worker     n -= 2;
1348*5c90c05cSAndroid Build Coastguard Worker     write2digits(out + n, static_cast<unsigned>(value));
1349*5c90c05cSAndroid Build Coastguard Worker   } else {
1350*5c90c05cSAndroid Build Coastguard Worker     out[--n] = static_cast<Char>('0' + value);
1351*5c90c05cSAndroid Build Coastguard Worker   }
1352*5c90c05cSAndroid Build Coastguard Worker   return out + n;
1353*5c90c05cSAndroid Build Coastguard Worker }
1354*5c90c05cSAndroid Build Coastguard Worker 
1355*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt>
1356*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value,
1357*5c90c05cSAndroid Build Coastguard Worker                                              int num_digits) -> Char* {
1358*5c90c05cSAndroid Build Coastguard Worker   do_format_decimal(out, value, num_digits);
1359*5c90c05cSAndroid Build Coastguard Worker   return out + num_digits;
1360*5c90c05cSAndroid Build Coastguard Worker }
1361*5c90c05cSAndroid Build Coastguard Worker 
1362*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt, typename OutputIt,
1363*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
1364*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)
1365*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
1366*5c90c05cSAndroid Build Coastguard Worker   if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1367*5c90c05cSAndroid Build Coastguard Worker     do_format_decimal(ptr, value, num_digits);
1368*5c90c05cSAndroid Build Coastguard Worker     return out;
1369*5c90c05cSAndroid Build Coastguard Worker   }
1370*5c90c05cSAndroid Build Coastguard Worker   // Buffer is large enough to hold all digits (digits10 + 1).
1371*5c90c05cSAndroid Build Coastguard Worker   char buffer[digits10<UInt>() + 1];
1372*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1373*5c90c05cSAndroid Build Coastguard Worker   do_format_decimal(buffer, value, num_digits);
1374*5c90c05cSAndroid Build Coastguard Worker   return copy_noinline<Char>(buffer, buffer + num_digits, out);
1375*5c90c05cSAndroid Build Coastguard Worker }
1376*5c90c05cSAndroid Build Coastguard Worker 
1377*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt>
1378*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto do_format_base2e(int base_bits, Char* out, UInt value,
1379*5c90c05cSAndroid Build Coastguard Worker                                     int size, bool upper = false) -> Char* {
1380*5c90c05cSAndroid Build Coastguard Worker   out += size;
1381*5c90c05cSAndroid Build Coastguard Worker   do {
1382*5c90c05cSAndroid Build Coastguard Worker     const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1383*5c90c05cSAndroid Build Coastguard Worker     unsigned digit = static_cast<unsigned>(value & ((1 << base_bits) - 1));
1384*5c90c05cSAndroid Build Coastguard Worker     *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)
1385*5c90c05cSAndroid Build Coastguard Worker                                              : digits[digit]);
1386*5c90c05cSAndroid Build Coastguard Worker   } while ((value >>= base_bits) != 0);
1387*5c90c05cSAndroid Build Coastguard Worker   return out;
1388*5c90c05cSAndroid Build Coastguard Worker }
1389*5c90c05cSAndroid Build Coastguard Worker 
1390*5c90c05cSAndroid Build Coastguard Worker // Formats an unsigned integer in the power of two base (binary, octal, hex).
1391*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt>
1392*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto format_base2e(int base_bits, Char* out, UInt value,
1393*5c90c05cSAndroid Build Coastguard Worker                                  int num_digits, bool upper = false) -> Char* {
1394*5c90c05cSAndroid Build Coastguard Worker   do_format_base2e(base_bits, out, value, num_digits, upper);
1395*5c90c05cSAndroid Build Coastguard Worker   return out + num_digits;
1396*5c90c05cSAndroid Build Coastguard Worker }
1397*5c90c05cSAndroid Build Coastguard Worker 
1398*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename UInt,
1399*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
1400*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto format_base2e(int base_bits, OutputIt out, UInt value,
1401*5c90c05cSAndroid Build Coastguard Worker                                         int num_digits, bool upper = false)
1402*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
1403*5c90c05cSAndroid Build Coastguard Worker   if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1404*5c90c05cSAndroid Build Coastguard Worker     format_base2e(base_bits, ptr, value, num_digits, upper);
1405*5c90c05cSAndroid Build Coastguard Worker     return out;
1406*5c90c05cSAndroid Build Coastguard Worker   }
1407*5c90c05cSAndroid Build Coastguard Worker   // Make buffer large enough for any base.
1408*5c90c05cSAndroid Build Coastguard Worker   char buffer[num_bits<UInt>()];
1409*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1410*5c90c05cSAndroid Build Coastguard Worker   format_base2e(base_bits, buffer, value, num_digits, upper);
1411*5c90c05cSAndroid Build Coastguard Worker   return detail::copy_noinline<Char>(buffer, buffer + num_digits, out);
1412*5c90c05cSAndroid Build Coastguard Worker }
1413*5c90c05cSAndroid Build Coastguard Worker 
1414*5c90c05cSAndroid Build Coastguard Worker // A converter from UTF-8 to UTF-16.
1415*5c90c05cSAndroid Build Coastguard Worker class utf8_to_utf16 {
1416*5c90c05cSAndroid Build Coastguard Worker  private:
1417*5c90c05cSAndroid Build Coastguard Worker   basic_memory_buffer<wchar_t> buffer_;
1418*5c90c05cSAndroid Build Coastguard Worker 
1419*5c90c05cSAndroid Build Coastguard Worker  public:
1420*5c90c05cSAndroid Build Coastguard Worker   FMT_API explicit utf8_to_utf16(string_view s);
1421*5c90c05cSAndroid Build Coastguard Worker   inline operator basic_string_view<wchar_t>() const {
1422*5c90c05cSAndroid Build Coastguard Worker     return {&buffer_[0], size()};
1423*5c90c05cSAndroid Build Coastguard Worker   }
1424*5c90c05cSAndroid Build Coastguard Worker   inline auto size() const -> size_t { return buffer_.size() - 1; }
1425*5c90c05cSAndroid Build Coastguard Worker   inline auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1426*5c90c05cSAndroid Build Coastguard Worker   inline auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1427*5c90c05cSAndroid Build Coastguard Worker };
1428*5c90c05cSAndroid Build Coastguard Worker 
1429*5c90c05cSAndroid Build Coastguard Worker enum class to_utf8_error_policy { abort, replace };
1430*5c90c05cSAndroid Build Coastguard Worker 
1431*5c90c05cSAndroid Build Coastguard Worker // A converter from UTF-16/UTF-32 (host endian) to UTF-8.
1432*5c90c05cSAndroid Build Coastguard Worker template <typename WChar, typename Buffer = memory_buffer> class to_utf8 {
1433*5c90c05cSAndroid Build Coastguard Worker  private:
1434*5c90c05cSAndroid Build Coastguard Worker   Buffer buffer_;
1435*5c90c05cSAndroid Build Coastguard Worker 
1436*5c90c05cSAndroid Build Coastguard Worker  public:
1437*5c90c05cSAndroid Build Coastguard Worker   to_utf8() {}
1438*5c90c05cSAndroid Build Coastguard Worker   explicit to_utf8(basic_string_view<WChar> s,
1439*5c90c05cSAndroid Build Coastguard Worker                    to_utf8_error_policy policy = to_utf8_error_policy::abort) {
1440*5c90c05cSAndroid Build Coastguard Worker     static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4,
1441*5c90c05cSAndroid Build Coastguard Worker                   "Expect utf16 or utf32");
1442*5c90c05cSAndroid Build Coastguard Worker     if (!convert(s, policy))
1443*5c90c05cSAndroid Build Coastguard Worker       FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16"
1444*5c90c05cSAndroid Build Coastguard Worker                                                       : "invalid utf32"));
1445*5c90c05cSAndroid Build Coastguard Worker   }
1446*5c90c05cSAndroid Build Coastguard Worker   operator string_view() const { return string_view(&buffer_[0], size()); }
1447*5c90c05cSAndroid Build Coastguard Worker   auto size() const -> size_t { return buffer_.size() - 1; }
1448*5c90c05cSAndroid Build Coastguard Worker   auto c_str() const -> const char* { return &buffer_[0]; }
1449*5c90c05cSAndroid Build Coastguard Worker   auto str() const -> std::string { return std::string(&buffer_[0], size()); }
1450*5c90c05cSAndroid Build Coastguard Worker 
1451*5c90c05cSAndroid Build Coastguard Worker   // Performs conversion returning a bool instead of throwing exception on
1452*5c90c05cSAndroid Build Coastguard Worker   // conversion error. This method may still throw in case of memory allocation
1453*5c90c05cSAndroid Build Coastguard Worker   // error.
1454*5c90c05cSAndroid Build Coastguard Worker   auto convert(basic_string_view<WChar> s,
1455*5c90c05cSAndroid Build Coastguard Worker                to_utf8_error_policy policy = to_utf8_error_policy::abort)
1456*5c90c05cSAndroid Build Coastguard Worker       -> bool {
1457*5c90c05cSAndroid Build Coastguard Worker     if (!convert(buffer_, s, policy)) return false;
1458*5c90c05cSAndroid Build Coastguard Worker     buffer_.push_back(0);
1459*5c90c05cSAndroid Build Coastguard Worker     return true;
1460*5c90c05cSAndroid Build Coastguard Worker   }
1461*5c90c05cSAndroid Build Coastguard Worker   static auto convert(Buffer& buf, basic_string_view<WChar> s,
1462*5c90c05cSAndroid Build Coastguard Worker                       to_utf8_error_policy policy = to_utf8_error_policy::abort)
1463*5c90c05cSAndroid Build Coastguard Worker       -> bool {
1464*5c90c05cSAndroid Build Coastguard Worker     for (auto p = s.begin(); p != s.end(); ++p) {
1465*5c90c05cSAndroid Build Coastguard Worker       uint32_t c = static_cast<uint32_t>(*p);
1466*5c90c05cSAndroid Build Coastguard Worker       if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {
1467*5c90c05cSAndroid Build Coastguard Worker         // Handle a surrogate pair.
1468*5c90c05cSAndroid Build Coastguard Worker         ++p;
1469*5c90c05cSAndroid Build Coastguard Worker         if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
1470*5c90c05cSAndroid Build Coastguard Worker           if (policy == to_utf8_error_policy::abort) return false;
1471*5c90c05cSAndroid Build Coastguard Worker           buf.append(string_view("\xEF\xBF\xBD"));
1472*5c90c05cSAndroid Build Coastguard Worker           --p;
1473*5c90c05cSAndroid Build Coastguard Worker           continue;
1474*5c90c05cSAndroid Build Coastguard Worker         } else {
1475*5c90c05cSAndroid Build Coastguard Worker           c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
1476*5c90c05cSAndroid Build Coastguard Worker         }
1477*5c90c05cSAndroid Build Coastguard Worker       }
1478*5c90c05cSAndroid Build Coastguard Worker       if (c < 0x80) {
1479*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(c));
1480*5c90c05cSAndroid Build Coastguard Worker       } else if (c < 0x800) {
1481*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0xc0 | (c >> 6)));
1482*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1483*5c90c05cSAndroid Build Coastguard Worker       } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {
1484*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0xe0 | (c >> 12)));
1485*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1486*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1487*5c90c05cSAndroid Build Coastguard Worker       } else if (c >= 0x10000 && c <= 0x10ffff) {
1488*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0xf0 | (c >> 18)));
1489*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));
1490*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1491*5c90c05cSAndroid Build Coastguard Worker         buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1492*5c90c05cSAndroid Build Coastguard Worker       } else {
1493*5c90c05cSAndroid Build Coastguard Worker         return false;
1494*5c90c05cSAndroid Build Coastguard Worker       }
1495*5c90c05cSAndroid Build Coastguard Worker     }
1496*5c90c05cSAndroid Build Coastguard Worker     return true;
1497*5c90c05cSAndroid Build Coastguard Worker   }
1498*5c90c05cSAndroid Build Coastguard Worker };
1499*5c90c05cSAndroid Build Coastguard Worker 
1500*5c90c05cSAndroid Build Coastguard Worker // Computes 128-bit result of multiplication of two 64-bit unsigned integers.
1501*5c90c05cSAndroid Build Coastguard Worker inline auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback {
1502*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_INT128
1503*5c90c05cSAndroid Build Coastguard Worker   auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1504*5c90c05cSAndroid Build Coastguard Worker   return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};
1505*5c90c05cSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_X64)
1506*5c90c05cSAndroid Build Coastguard Worker   auto hi = uint64_t();
1507*5c90c05cSAndroid Build Coastguard Worker   auto lo = _umul128(x, y, &hi);
1508*5c90c05cSAndroid Build Coastguard Worker   return {hi, lo};
1509*5c90c05cSAndroid Build Coastguard Worker #else
1510*5c90c05cSAndroid Build Coastguard Worker   const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());
1511*5c90c05cSAndroid Build Coastguard Worker 
1512*5c90c05cSAndroid Build Coastguard Worker   uint64_t a = x >> 32;
1513*5c90c05cSAndroid Build Coastguard Worker   uint64_t b = x & mask;
1514*5c90c05cSAndroid Build Coastguard Worker   uint64_t c = y >> 32;
1515*5c90c05cSAndroid Build Coastguard Worker   uint64_t d = y & mask;
1516*5c90c05cSAndroid Build Coastguard Worker 
1517*5c90c05cSAndroid Build Coastguard Worker   uint64_t ac = a * c;
1518*5c90c05cSAndroid Build Coastguard Worker   uint64_t bc = b * c;
1519*5c90c05cSAndroid Build Coastguard Worker   uint64_t ad = a * d;
1520*5c90c05cSAndroid Build Coastguard Worker   uint64_t bd = b * d;
1521*5c90c05cSAndroid Build Coastguard Worker 
1522*5c90c05cSAndroid Build Coastguard Worker   uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
1523*5c90c05cSAndroid Build Coastguard Worker 
1524*5c90c05cSAndroid Build Coastguard Worker   return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1525*5c90c05cSAndroid Build Coastguard Worker           (intermediate << 32) + (bd & mask)};
1526*5c90c05cSAndroid Build Coastguard Worker #endif
1527*5c90c05cSAndroid Build Coastguard Worker }
1528*5c90c05cSAndroid Build Coastguard Worker 
1529*5c90c05cSAndroid Build Coastguard Worker namespace dragonbox {
1530*5c90c05cSAndroid Build Coastguard Worker // Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from
1531*5c90c05cSAndroid Build Coastguard Worker // https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1.
1532*5c90c05cSAndroid Build Coastguard Worker inline auto floor_log10_pow2(int e) noexcept -> int {
1533*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent");
1534*5c90c05cSAndroid Build Coastguard Worker   static_assert((-1 >> 1) == -1, "right shift is not arithmetic");
1535*5c90c05cSAndroid Build Coastguard Worker   return (e * 315653) >> 20;
1536*5c90c05cSAndroid Build Coastguard Worker }
1537*5c90c05cSAndroid Build Coastguard Worker 
1538*5c90c05cSAndroid Build Coastguard Worker inline auto floor_log2_pow10(int e) noexcept -> int {
1539*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
1540*5c90c05cSAndroid Build Coastguard Worker   return (e * 1741647) >> 19;
1541*5c90c05cSAndroid Build Coastguard Worker }
1542*5c90c05cSAndroid Build Coastguard Worker 
1543*5c90c05cSAndroid Build Coastguard Worker // Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
1544*5c90c05cSAndroid Build Coastguard Worker inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t {
1545*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_INT128
1546*5c90c05cSAndroid Build Coastguard Worker   auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1547*5c90c05cSAndroid Build Coastguard Worker   return static_cast<uint64_t>(p >> 64);
1548*5c90c05cSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_X64)
1549*5c90c05cSAndroid Build Coastguard Worker   return __umulh(x, y);
1550*5c90c05cSAndroid Build Coastguard Worker #else
1551*5c90c05cSAndroid Build Coastguard Worker   return umul128(x, y).high();
1552*5c90c05cSAndroid Build Coastguard Worker #endif
1553*5c90c05cSAndroid Build Coastguard Worker }
1554*5c90c05cSAndroid Build Coastguard Worker 
1555*5c90c05cSAndroid Build Coastguard Worker // Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a
1556*5c90c05cSAndroid Build Coastguard Worker // 128-bit unsigned integer.
1557*5c90c05cSAndroid Build Coastguard Worker inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept
1558*5c90c05cSAndroid Build Coastguard Worker     -> uint128_fallback {
1559*5c90c05cSAndroid Build Coastguard Worker   uint128_fallback r = umul128(x, y.high());
1560*5c90c05cSAndroid Build Coastguard Worker   r += umul128_upper64(x, y.low());
1561*5c90c05cSAndroid Build Coastguard Worker   return r;
1562*5c90c05cSAndroid Build Coastguard Worker }
1563*5c90c05cSAndroid Build Coastguard Worker 
1564*5c90c05cSAndroid Build Coastguard Worker FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback;
1565*5c90c05cSAndroid Build Coastguard Worker 
1566*5c90c05cSAndroid Build Coastguard Worker // Type-specific information that Dragonbox uses.
1567*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Enable = void> struct float_info;
1568*5c90c05cSAndroid Build Coastguard Worker 
1569*5c90c05cSAndroid Build Coastguard Worker template <> struct float_info<float> {
1570*5c90c05cSAndroid Build Coastguard Worker   using carrier_uint = uint32_t;
1571*5c90c05cSAndroid Build Coastguard Worker   static const int exponent_bits = 8;
1572*5c90c05cSAndroid Build Coastguard Worker   static const int kappa = 1;
1573*5c90c05cSAndroid Build Coastguard Worker   static const int big_divisor = 100;
1574*5c90c05cSAndroid Build Coastguard Worker   static const int small_divisor = 10;
1575*5c90c05cSAndroid Build Coastguard Worker   static const int min_k = -31;
1576*5c90c05cSAndroid Build Coastguard Worker   static const int max_k = 46;
1577*5c90c05cSAndroid Build Coastguard Worker   static const int shorter_interval_tie_lower_threshold = -35;
1578*5c90c05cSAndroid Build Coastguard Worker   static const int shorter_interval_tie_upper_threshold = -35;
1579*5c90c05cSAndroid Build Coastguard Worker };
1580*5c90c05cSAndroid Build Coastguard Worker 
1581*5c90c05cSAndroid Build Coastguard Worker template <> struct float_info<double> {
1582*5c90c05cSAndroid Build Coastguard Worker   using carrier_uint = uint64_t;
1583*5c90c05cSAndroid Build Coastguard Worker   static const int exponent_bits = 11;
1584*5c90c05cSAndroid Build Coastguard Worker   static const int kappa = 2;
1585*5c90c05cSAndroid Build Coastguard Worker   static const int big_divisor = 1000;
1586*5c90c05cSAndroid Build Coastguard Worker   static const int small_divisor = 100;
1587*5c90c05cSAndroid Build Coastguard Worker   static const int min_k = -292;
1588*5c90c05cSAndroid Build Coastguard Worker   static const int max_k = 341;
1589*5c90c05cSAndroid Build Coastguard Worker   static const int shorter_interval_tie_lower_threshold = -77;
1590*5c90c05cSAndroid Build Coastguard Worker   static const int shorter_interval_tie_upper_threshold = -77;
1591*5c90c05cSAndroid Build Coastguard Worker };
1592*5c90c05cSAndroid Build Coastguard Worker 
1593*5c90c05cSAndroid Build Coastguard Worker // An 80- or 128-bit floating point number.
1594*5c90c05cSAndroid Build Coastguard Worker template <typename T>
1595*5c90c05cSAndroid Build Coastguard Worker struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1596*5c90c05cSAndroid Build Coastguard Worker                                  std::numeric_limits<T>::digits == 113 ||
1597*5c90c05cSAndroid Build Coastguard Worker                                  is_float128<T>::value>> {
1598*5c90c05cSAndroid Build Coastguard Worker   using carrier_uint = detail::uint128_t;
1599*5c90c05cSAndroid Build Coastguard Worker   static const int exponent_bits = 15;
1600*5c90c05cSAndroid Build Coastguard Worker };
1601*5c90c05cSAndroid Build Coastguard Worker 
1602*5c90c05cSAndroid Build Coastguard Worker // A double-double floating point number.
1603*5c90c05cSAndroid Build Coastguard Worker template <typename T>
1604*5c90c05cSAndroid Build Coastguard Worker struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1605*5c90c05cSAndroid Build Coastguard Worker   using carrier_uint = detail::uint128_t;
1606*5c90c05cSAndroid Build Coastguard Worker };
1607*5c90c05cSAndroid Build Coastguard Worker 
1608*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct decimal_fp {
1609*5c90c05cSAndroid Build Coastguard Worker   using significand_type = typename float_info<T>::carrier_uint;
1610*5c90c05cSAndroid Build Coastguard Worker   significand_type significand;
1611*5c90c05cSAndroid Build Coastguard Worker   int exponent;
1612*5c90c05cSAndroid Build Coastguard Worker };
1613*5c90c05cSAndroid Build Coastguard Worker 
1614*5c90c05cSAndroid Build Coastguard Worker template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1615*5c90c05cSAndroid Build Coastguard Worker }  // namespace dragonbox
1616*5c90c05cSAndroid Build Coastguard Worker 
1617*5c90c05cSAndroid Build Coastguard Worker // Returns true iff Float has the implicit bit which is not stored.
1618*5c90c05cSAndroid Build Coastguard Worker template <typename Float> constexpr auto has_implicit_bit() -> bool {
1619*5c90c05cSAndroid Build Coastguard Worker   // An 80-bit FP number has a 64-bit significand an no implicit bit.
1620*5c90c05cSAndroid Build Coastguard Worker   return std::numeric_limits<Float>::digits != 64;
1621*5c90c05cSAndroid Build Coastguard Worker }
1622*5c90c05cSAndroid Build Coastguard Worker 
1623*5c90c05cSAndroid Build Coastguard Worker // Returns the number of significand bits stored in Float. The implicit bit is
1624*5c90c05cSAndroid Build Coastguard Worker // not counted since it is not stored.
1625*5c90c05cSAndroid Build Coastguard Worker template <typename Float> constexpr auto num_significand_bits() -> int {
1626*5c90c05cSAndroid Build Coastguard Worker   // std::numeric_limits may not support __float128.
1627*5c90c05cSAndroid Build Coastguard Worker   return is_float128<Float>() ? 112
1628*5c90c05cSAndroid Build Coastguard Worker                               : (std::numeric_limits<Float>::digits -
1629*5c90c05cSAndroid Build Coastguard Worker                                  (has_implicit_bit<Float>() ? 1 : 0));
1630*5c90c05cSAndroid Build Coastguard Worker }
1631*5c90c05cSAndroid Build Coastguard Worker 
1632*5c90c05cSAndroid Build Coastguard Worker template <typename Float>
1633*5c90c05cSAndroid Build Coastguard Worker constexpr auto exponent_mask() ->
1634*5c90c05cSAndroid Build Coastguard Worker     typename dragonbox::float_info<Float>::carrier_uint {
1635*5c90c05cSAndroid Build Coastguard Worker   using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1636*5c90c05cSAndroid Build Coastguard Worker   return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1637*5c90c05cSAndroid Build Coastguard Worker          << num_significand_bits<Float>();
1638*5c90c05cSAndroid Build Coastguard Worker }
1639*5c90c05cSAndroid Build Coastguard Worker template <typename Float> constexpr auto exponent_bias() -> int {
1640*5c90c05cSAndroid Build Coastguard Worker   // std::numeric_limits may not support __float128.
1641*5c90c05cSAndroid Build Coastguard Worker   return is_float128<Float>() ? 16383
1642*5c90c05cSAndroid Build Coastguard Worker                               : std::numeric_limits<Float>::max_exponent - 1;
1643*5c90c05cSAndroid Build Coastguard Worker }
1644*5c90c05cSAndroid Build Coastguard Worker 
1645*5c90c05cSAndroid Build Coastguard Worker // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1646*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1647*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write_exponent(int exp, OutputIt out) -> OutputIt {
1648*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1649*5c90c05cSAndroid Build Coastguard Worker   if (exp < 0) {
1650*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>('-');
1651*5c90c05cSAndroid Build Coastguard Worker     exp = -exp;
1652*5c90c05cSAndroid Build Coastguard Worker   } else {
1653*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>('+');
1654*5c90c05cSAndroid Build Coastguard Worker   }
1655*5c90c05cSAndroid Build Coastguard Worker   auto uexp = static_cast<uint32_t>(exp);
1656*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) {
1657*5c90c05cSAndroid Build Coastguard Worker     if (uexp < 10) *out++ = '0';
1658*5c90c05cSAndroid Build Coastguard Worker     return format_decimal<Char>(out, uexp, count_digits(uexp));
1659*5c90c05cSAndroid Build Coastguard Worker   }
1660*5c90c05cSAndroid Build Coastguard Worker   if (uexp >= 100u) {
1661*5c90c05cSAndroid Build Coastguard Worker     const char* top = digits2(uexp / 100);
1662*5c90c05cSAndroid Build Coastguard Worker     if (uexp >= 1000u) *out++ = static_cast<Char>(top[0]);
1663*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>(top[1]);
1664*5c90c05cSAndroid Build Coastguard Worker     uexp %= 100;
1665*5c90c05cSAndroid Build Coastguard Worker   }
1666*5c90c05cSAndroid Build Coastguard Worker   const char* d = digits2(uexp);
1667*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>(d[0]);
1668*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>(d[1]);
1669*5c90c05cSAndroid Build Coastguard Worker   return out;
1670*5c90c05cSAndroid Build Coastguard Worker }
1671*5c90c05cSAndroid Build Coastguard Worker 
1672*5c90c05cSAndroid Build Coastguard Worker // A floating-point number f * pow(2, e) where F is an unsigned type.
1673*5c90c05cSAndroid Build Coastguard Worker template <typename F> struct basic_fp {
1674*5c90c05cSAndroid Build Coastguard Worker   F f;
1675*5c90c05cSAndroid Build Coastguard Worker   int e;
1676*5c90c05cSAndroid Build Coastguard Worker 
1677*5c90c05cSAndroid Build Coastguard Worker   static constexpr const int num_significand_bits =
1678*5c90c05cSAndroid Build Coastguard Worker       static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1679*5c90c05cSAndroid Build Coastguard Worker 
1680*5c90c05cSAndroid Build Coastguard Worker   constexpr basic_fp() : f(0), e(0) {}
1681*5c90c05cSAndroid Build Coastguard Worker   constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1682*5c90c05cSAndroid Build Coastguard Worker 
1683*5c90c05cSAndroid Build Coastguard Worker   // Constructs fp from an IEEE754 floating-point number.
1684*5c90c05cSAndroid Build Coastguard Worker   template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1685*5c90c05cSAndroid Build Coastguard Worker 
1686*5c90c05cSAndroid Build Coastguard Worker   // Assigns n to this and return true iff predecessor is closer than successor.
1687*5c90c05cSAndroid Build Coastguard Worker   template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1688*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto assign(Float n) -> bool {
1689*5c90c05cSAndroid Build Coastguard Worker     static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1690*5c90c05cSAndroid Build Coastguard Worker     // Assume Float is in the format [sign][exponent][significand].
1691*5c90c05cSAndroid Build Coastguard Worker     using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1692*5c90c05cSAndroid Build Coastguard Worker     const auto num_float_significand_bits =
1693*5c90c05cSAndroid Build Coastguard Worker         detail::num_significand_bits<Float>();
1694*5c90c05cSAndroid Build Coastguard Worker     const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1695*5c90c05cSAndroid Build Coastguard Worker     const auto significand_mask = implicit_bit - 1;
1696*5c90c05cSAndroid Build Coastguard Worker     auto u = bit_cast<carrier_uint>(n);
1697*5c90c05cSAndroid Build Coastguard Worker     f = static_cast<F>(u & significand_mask);
1698*5c90c05cSAndroid Build Coastguard Worker     auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1699*5c90c05cSAndroid Build Coastguard Worker                                      num_float_significand_bits);
1700*5c90c05cSAndroid Build Coastguard Worker     // The predecessor is closer if n is a normalized power of 2 (f == 0)
1701*5c90c05cSAndroid Build Coastguard Worker     // other than the smallest normalized number (biased_e > 1).
1702*5c90c05cSAndroid Build Coastguard Worker     auto is_predecessor_closer = f == 0 && biased_e > 1;
1703*5c90c05cSAndroid Build Coastguard Worker     if (biased_e == 0)
1704*5c90c05cSAndroid Build Coastguard Worker       biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1705*5c90c05cSAndroid Build Coastguard Worker     else if (has_implicit_bit<Float>())
1706*5c90c05cSAndroid Build Coastguard Worker       f += static_cast<F>(implicit_bit);
1707*5c90c05cSAndroid Build Coastguard Worker     e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1708*5c90c05cSAndroid Build Coastguard Worker     if (!has_implicit_bit<Float>()) ++e;
1709*5c90c05cSAndroid Build Coastguard Worker     return is_predecessor_closer;
1710*5c90c05cSAndroid Build Coastguard Worker   }
1711*5c90c05cSAndroid Build Coastguard Worker 
1712*5c90c05cSAndroid Build Coastguard Worker   template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1713*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto assign(Float n) -> bool {
1714*5c90c05cSAndroid Build Coastguard Worker     static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1715*5c90c05cSAndroid Build Coastguard Worker     return assign(static_cast<double>(n));
1716*5c90c05cSAndroid Build Coastguard Worker   }
1717*5c90c05cSAndroid Build Coastguard Worker };
1718*5c90c05cSAndroid Build Coastguard Worker 
1719*5c90c05cSAndroid Build Coastguard Worker using fp = basic_fp<unsigned long long>;
1720*5c90c05cSAndroid Build Coastguard Worker 
1721*5c90c05cSAndroid Build Coastguard Worker // Normalizes the value converted from double and multiplied by (1 << SHIFT).
1722*5c90c05cSAndroid Build Coastguard Worker template <int SHIFT = 0, typename F>
1723*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto normalize(basic_fp<F> value) -> basic_fp<F> {
1724*5c90c05cSAndroid Build Coastguard Worker   // Handle subnormals.
1725*5c90c05cSAndroid Build Coastguard Worker   const auto implicit_bit = F(1) << num_significand_bits<double>();
1726*5c90c05cSAndroid Build Coastguard Worker   const auto shifted_implicit_bit = implicit_bit << SHIFT;
1727*5c90c05cSAndroid Build Coastguard Worker   while ((value.f & shifted_implicit_bit) == 0) {
1728*5c90c05cSAndroid Build Coastguard Worker     value.f <<= 1;
1729*5c90c05cSAndroid Build Coastguard Worker     --value.e;
1730*5c90c05cSAndroid Build Coastguard Worker   }
1731*5c90c05cSAndroid Build Coastguard Worker   // Subtract 1 to account for hidden bit.
1732*5c90c05cSAndroid Build Coastguard Worker   const auto offset = basic_fp<F>::num_significand_bits -
1733*5c90c05cSAndroid Build Coastguard Worker                       num_significand_bits<double>() - SHIFT - 1;
1734*5c90c05cSAndroid Build Coastguard Worker   value.f <<= offset;
1735*5c90c05cSAndroid Build Coastguard Worker   value.e -= offset;
1736*5c90c05cSAndroid Build Coastguard Worker   return value;
1737*5c90c05cSAndroid Build Coastguard Worker }
1738*5c90c05cSAndroid Build Coastguard Worker 
1739*5c90c05cSAndroid Build Coastguard Worker // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1740*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t {
1741*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_INT128
1742*5c90c05cSAndroid Build Coastguard Worker   auto product = static_cast<__uint128_t>(lhs) * rhs;
1743*5c90c05cSAndroid Build Coastguard Worker   auto f = static_cast<uint64_t>(product >> 64);
1744*5c90c05cSAndroid Build Coastguard Worker   return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1745*5c90c05cSAndroid Build Coastguard Worker #else
1746*5c90c05cSAndroid Build Coastguard Worker   // Multiply 32-bit parts of significands.
1747*5c90c05cSAndroid Build Coastguard Worker   uint64_t mask = (1ULL << 32) - 1;
1748*5c90c05cSAndroid Build Coastguard Worker   uint64_t a = lhs >> 32, b = lhs & mask;
1749*5c90c05cSAndroid Build Coastguard Worker   uint64_t c = rhs >> 32, d = rhs & mask;
1750*5c90c05cSAndroid Build Coastguard Worker   uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1751*5c90c05cSAndroid Build Coastguard Worker   // Compute mid 64-bit of result and round.
1752*5c90c05cSAndroid Build Coastguard Worker   uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1753*5c90c05cSAndroid Build Coastguard Worker   return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1754*5c90c05cSAndroid Build Coastguard Worker #endif
1755*5c90c05cSAndroid Build Coastguard Worker }
1756*5c90c05cSAndroid Build Coastguard Worker 
1757*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp {
1758*5c90c05cSAndroid Build Coastguard Worker   return {multiply(x.f, y.f), x.e + y.e + 64};
1759*5c90c05cSAndroid Build Coastguard Worker }
1760*5c90c05cSAndroid Build Coastguard Worker 
1761*5c90c05cSAndroid Build Coastguard Worker template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
1762*5c90c05cSAndroid Build Coastguard Worker using convert_float_result =
1763*5c90c05cSAndroid Build Coastguard Worker     conditional_t<std::is_same<T, float>::value || doublish, double, T>;
1764*5c90c05cSAndroid Build Coastguard Worker 
1765*5c90c05cSAndroid Build Coastguard Worker template <typename T>
1766*5c90c05cSAndroid Build Coastguard Worker constexpr auto convert_float(T value) -> convert_float_result<T> {
1767*5c90c05cSAndroid Build Coastguard Worker   return static_cast<convert_float_result<T>>(value);
1768*5c90c05cSAndroid Build Coastguard Worker }
1769*5c90c05cSAndroid Build Coastguard Worker 
1770*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1771*5c90c05cSAndroid Build Coastguard Worker FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1772*5c90c05cSAndroid Build Coastguard Worker                                      const basic_specs& specs) -> OutputIt {
1773*5c90c05cSAndroid Build Coastguard Worker   auto fill_size = specs.fill_size();
1774*5c90c05cSAndroid Build Coastguard Worker   if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit<Char>());
1775*5c90c05cSAndroid Build Coastguard Worker   if (const Char* data = specs.fill<Char>()) {
1776*5c90c05cSAndroid Build Coastguard Worker     for (size_t i = 0; i < n; ++i) it = copy<Char>(data, data + fill_size, it);
1777*5c90c05cSAndroid Build Coastguard Worker   }
1778*5c90c05cSAndroid Build Coastguard Worker   return it;
1779*5c90c05cSAndroid Build Coastguard Worker }
1780*5c90c05cSAndroid Build Coastguard Worker 
1781*5c90c05cSAndroid Build Coastguard Worker // Writes the output of f, padded according to format specifications in specs.
1782*5c90c05cSAndroid Build Coastguard Worker // size: output size in code units.
1783*5c90c05cSAndroid Build Coastguard Worker // width: output display width in (terminal) column positions.
1784*5c90c05cSAndroid Build Coastguard Worker template <typename Char, align default_align = align::left, typename OutputIt,
1785*5c90c05cSAndroid Build Coastguard Worker           typename F>
1786*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs,
1787*5c90c05cSAndroid Build Coastguard Worker                                 size_t size, size_t width, F&& f) -> OutputIt {
1788*5c90c05cSAndroid Build Coastguard Worker   static_assert(default_align == align::left || default_align == align::right,
1789*5c90c05cSAndroid Build Coastguard Worker                 "");
1790*5c90c05cSAndroid Build Coastguard Worker   unsigned spec_width = to_unsigned(specs.width);
1791*5c90c05cSAndroid Build Coastguard Worker   size_t padding = spec_width > width ? spec_width - width : 0;
1792*5c90c05cSAndroid Build Coastguard Worker   // Shifts are encoded as string literals because static constexpr is not
1793*5c90c05cSAndroid Build Coastguard Worker   // supported in constexpr functions.
1794*5c90c05cSAndroid Build Coastguard Worker   auto* shifts =
1795*5c90c05cSAndroid Build Coastguard Worker       default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1796*5c90c05cSAndroid Build Coastguard Worker   size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1797*5c90c05cSAndroid Build Coastguard Worker   size_t right_padding = padding - left_padding;
1798*5c90c05cSAndroid Build Coastguard Worker   auto it = reserve(out, size + padding * specs.fill_size());
1799*5c90c05cSAndroid Build Coastguard Worker   if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1800*5c90c05cSAndroid Build Coastguard Worker   it = f(it);
1801*5c90c05cSAndroid Build Coastguard Worker   if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1802*5c90c05cSAndroid Build Coastguard Worker   return base_iterator(out, it);
1803*5c90c05cSAndroid Build Coastguard Worker }
1804*5c90c05cSAndroid Build Coastguard Worker 
1805*5c90c05cSAndroid Build Coastguard Worker template <typename Char, align default_align = align::left, typename OutputIt,
1806*5c90c05cSAndroid Build Coastguard Worker           typename F>
1807*5c90c05cSAndroid Build Coastguard Worker constexpr auto write_padded(OutputIt out, const format_specs& specs,
1808*5c90c05cSAndroid Build Coastguard Worker                             size_t size, F&& f) -> OutputIt {
1809*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char, default_align>(out, specs, size, size, f);
1810*5c90c05cSAndroid Build Coastguard Worker }
1811*5c90c05cSAndroid Build Coastguard Worker 
1812*5c90c05cSAndroid Build Coastguard Worker template <typename Char, align default_align = align::left, typename OutputIt>
1813*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
1814*5c90c05cSAndroid Build Coastguard Worker                                const format_specs& specs = {}) -> OutputIt {
1815*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char, default_align>(
1816*5c90c05cSAndroid Build Coastguard Worker       out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1817*5c90c05cSAndroid Build Coastguard Worker         const char* data = bytes.data();
1818*5c90c05cSAndroid Build Coastguard Worker         return copy<Char>(data, data + bytes.size(), it);
1819*5c90c05cSAndroid Build Coastguard Worker       });
1820*5c90c05cSAndroid Build Coastguard Worker }
1821*5c90c05cSAndroid Build Coastguard Worker 
1822*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename UIntPtr>
1823*5c90c05cSAndroid Build Coastguard Worker auto write_ptr(OutputIt out, UIntPtr value, const format_specs* specs)
1824*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
1825*5c90c05cSAndroid Build Coastguard Worker   int num_digits = count_digits<4>(value);
1826*5c90c05cSAndroid Build Coastguard Worker   auto size = to_unsigned(num_digits) + size_t(2);
1827*5c90c05cSAndroid Build Coastguard Worker   auto write = [=](reserve_iterator<OutputIt> it) {
1828*5c90c05cSAndroid Build Coastguard Worker     *it++ = static_cast<Char>('0');
1829*5c90c05cSAndroid Build Coastguard Worker     *it++ = static_cast<Char>('x');
1830*5c90c05cSAndroid Build Coastguard Worker     return format_base2e<Char>(4, it, value, num_digits);
1831*5c90c05cSAndroid Build Coastguard Worker   };
1832*5c90c05cSAndroid Build Coastguard Worker   return specs ? write_padded<Char, align::right>(out, *specs, size, write)
1833*5c90c05cSAndroid Build Coastguard Worker                : base_iterator(out, write(reserve(out, size)));
1834*5c90c05cSAndroid Build Coastguard Worker }
1835*5c90c05cSAndroid Build Coastguard Worker 
1836*5c90c05cSAndroid Build Coastguard Worker // Returns true iff the code point cp is printable.
1837*5c90c05cSAndroid Build Coastguard Worker FMT_API auto is_printable(uint32_t cp) -> bool;
1838*5c90c05cSAndroid Build Coastguard Worker 
1839*5c90c05cSAndroid Build Coastguard Worker inline auto needs_escape(uint32_t cp) -> bool {
1840*5c90c05cSAndroid Build Coastguard Worker   if (cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\') return true;
1841*5c90c05cSAndroid Build Coastguard Worker   if (FMT_OPTIMIZE_SIZE > 1) return false;
1842*5c90c05cSAndroid Build Coastguard Worker   return !is_printable(cp);
1843*5c90c05cSAndroid Build Coastguard Worker }
1844*5c90c05cSAndroid Build Coastguard Worker 
1845*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct find_escape_result {
1846*5c90c05cSAndroid Build Coastguard Worker   const Char* begin;
1847*5c90c05cSAndroid Build Coastguard Worker   const Char* end;
1848*5c90c05cSAndroid Build Coastguard Worker   uint32_t cp;
1849*5c90c05cSAndroid Build Coastguard Worker };
1850*5c90c05cSAndroid Build Coastguard Worker 
1851*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
1852*5c90c05cSAndroid Build Coastguard Worker auto find_escape(const Char* begin, const Char* end)
1853*5c90c05cSAndroid Build Coastguard Worker     -> find_escape_result<Char> {
1854*5c90c05cSAndroid Build Coastguard Worker   for (; begin != end; ++begin) {
1855*5c90c05cSAndroid Build Coastguard Worker     uint32_t cp = static_cast<unsigned_char<Char>>(*begin);
1856*5c90c05cSAndroid Build Coastguard Worker     if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1857*5c90c05cSAndroid Build Coastguard Worker     if (needs_escape(cp)) return {begin, begin + 1, cp};
1858*5c90c05cSAndroid Build Coastguard Worker   }
1859*5c90c05cSAndroid Build Coastguard Worker   return {begin, nullptr, 0};
1860*5c90c05cSAndroid Build Coastguard Worker }
1861*5c90c05cSAndroid Build Coastguard Worker 
1862*5c90c05cSAndroid Build Coastguard Worker inline auto find_escape(const char* begin, const char* end)
1863*5c90c05cSAndroid Build Coastguard Worker     -> find_escape_result<char> {
1864*5c90c05cSAndroid Build Coastguard Worker   if (!detail::use_utf8) return find_escape<char>(begin, end);
1865*5c90c05cSAndroid Build Coastguard Worker   auto result = find_escape_result<char>{end, nullptr, 0};
1866*5c90c05cSAndroid Build Coastguard Worker   for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
1867*5c90c05cSAndroid Build Coastguard Worker                      [&](uint32_t cp, string_view sv) {
1868*5c90c05cSAndroid Build Coastguard Worker                        if (needs_escape(cp)) {
1869*5c90c05cSAndroid Build Coastguard Worker                          result = {sv.begin(), sv.end(), cp};
1870*5c90c05cSAndroid Build Coastguard Worker                          return false;
1871*5c90c05cSAndroid Build Coastguard Worker                        }
1872*5c90c05cSAndroid Build Coastguard Worker                        return true;
1873*5c90c05cSAndroid Build Coastguard Worker                      });
1874*5c90c05cSAndroid Build Coastguard Worker   return result;
1875*5c90c05cSAndroid Build Coastguard Worker }
1876*5c90c05cSAndroid Build Coastguard Worker 
1877*5c90c05cSAndroid Build Coastguard Worker template <size_t width, typename Char, typename OutputIt>
1878*5c90c05cSAndroid Build Coastguard Worker auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1879*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('\\');
1880*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>(prefix);
1881*5c90c05cSAndroid Build Coastguard Worker   Char buf[width];
1882*5c90c05cSAndroid Build Coastguard Worker   fill_n(buf, width, static_cast<Char>('0'));
1883*5c90c05cSAndroid Build Coastguard Worker   format_base2e(4, buf, cp, width);
1884*5c90c05cSAndroid Build Coastguard Worker   return copy<Char>(buf, buf + width, out);
1885*5c90c05cSAndroid Build Coastguard Worker }
1886*5c90c05cSAndroid Build Coastguard Worker 
1887*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Char>
1888*5c90c05cSAndroid Build Coastguard Worker auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
1889*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
1890*5c90c05cSAndroid Build Coastguard Worker   auto c = static_cast<Char>(escape.cp);
1891*5c90c05cSAndroid Build Coastguard Worker   switch (escape.cp) {
1892*5c90c05cSAndroid Build Coastguard Worker   case '\n':
1893*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>('\\');
1894*5c90c05cSAndroid Build Coastguard Worker     c = static_cast<Char>('n');
1895*5c90c05cSAndroid Build Coastguard Worker     break;
1896*5c90c05cSAndroid Build Coastguard Worker   case '\r':
1897*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>('\\');
1898*5c90c05cSAndroid Build Coastguard Worker     c = static_cast<Char>('r');
1899*5c90c05cSAndroid Build Coastguard Worker     break;
1900*5c90c05cSAndroid Build Coastguard Worker   case '\t':
1901*5c90c05cSAndroid Build Coastguard Worker     *out++ = static_cast<Char>('\\');
1902*5c90c05cSAndroid Build Coastguard Worker     c = static_cast<Char>('t');
1903*5c90c05cSAndroid Build Coastguard Worker     break;
1904*5c90c05cSAndroid Build Coastguard Worker   case '"':  FMT_FALLTHROUGH;
1905*5c90c05cSAndroid Build Coastguard Worker   case '\'': FMT_FALLTHROUGH;
1906*5c90c05cSAndroid Build Coastguard Worker   case '\\': *out++ = static_cast<Char>('\\'); break;
1907*5c90c05cSAndroid Build Coastguard Worker   default:
1908*5c90c05cSAndroid Build Coastguard Worker     if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp);
1909*5c90c05cSAndroid Build Coastguard Worker     if (escape.cp < 0x10000)
1910*5c90c05cSAndroid Build Coastguard Worker       return write_codepoint<4, Char>(out, 'u', escape.cp);
1911*5c90c05cSAndroid Build Coastguard Worker     if (escape.cp < 0x110000)
1912*5c90c05cSAndroid Build Coastguard Worker       return write_codepoint<8, Char>(out, 'U', escape.cp);
1913*5c90c05cSAndroid Build Coastguard Worker     for (Char escape_char : basic_string_view<Char>(
1914*5c90c05cSAndroid Build Coastguard Worker              escape.begin, to_unsigned(escape.end - escape.begin))) {
1915*5c90c05cSAndroid Build Coastguard Worker       out = write_codepoint<2, Char>(out, 'x',
1916*5c90c05cSAndroid Build Coastguard Worker                                      static_cast<uint32_t>(escape_char) & 0xFF);
1917*5c90c05cSAndroid Build Coastguard Worker     }
1918*5c90c05cSAndroid Build Coastguard Worker     return out;
1919*5c90c05cSAndroid Build Coastguard Worker   }
1920*5c90c05cSAndroid Build Coastguard Worker   *out++ = c;
1921*5c90c05cSAndroid Build Coastguard Worker   return out;
1922*5c90c05cSAndroid Build Coastguard Worker }
1923*5c90c05cSAndroid Build Coastguard Worker 
1924*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1925*5c90c05cSAndroid Build Coastguard Worker auto write_escaped_string(OutputIt out, basic_string_view<Char> str)
1926*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
1927*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('"');
1928*5c90c05cSAndroid Build Coastguard Worker   auto begin = str.begin(), end = str.end();
1929*5c90c05cSAndroid Build Coastguard Worker   do {
1930*5c90c05cSAndroid Build Coastguard Worker     auto escape = find_escape(begin, end);
1931*5c90c05cSAndroid Build Coastguard Worker     out = copy<Char>(begin, escape.begin, out);
1932*5c90c05cSAndroid Build Coastguard Worker     begin = escape.end;
1933*5c90c05cSAndroid Build Coastguard Worker     if (!begin) break;
1934*5c90c05cSAndroid Build Coastguard Worker     out = write_escaped_cp<OutputIt, Char>(out, escape);
1935*5c90c05cSAndroid Build Coastguard Worker   } while (begin != end);
1936*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('"');
1937*5c90c05cSAndroid Build Coastguard Worker   return out;
1938*5c90c05cSAndroid Build Coastguard Worker }
1939*5c90c05cSAndroid Build Coastguard Worker 
1940*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1941*5c90c05cSAndroid Build Coastguard Worker auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1942*5c90c05cSAndroid Build Coastguard Worker   Char v_array[1] = {v};
1943*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('\'');
1944*5c90c05cSAndroid Build Coastguard Worker   if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1945*5c90c05cSAndroid Build Coastguard Worker       v == static_cast<Char>('\'')) {
1946*5c90c05cSAndroid Build Coastguard Worker     out = write_escaped_cp(out,
1947*5c90c05cSAndroid Build Coastguard Worker                            find_escape_result<Char>{v_array, v_array + 1,
1948*5c90c05cSAndroid Build Coastguard Worker                                                     static_cast<uint32_t>(v)});
1949*5c90c05cSAndroid Build Coastguard Worker   } else {
1950*5c90c05cSAndroid Build Coastguard Worker     *out++ = v;
1951*5c90c05cSAndroid Build Coastguard Worker   }
1952*5c90c05cSAndroid Build Coastguard Worker   *out++ = static_cast<Char>('\'');
1953*5c90c05cSAndroid Build Coastguard Worker   return out;
1954*5c90c05cSAndroid Build Coastguard Worker }
1955*5c90c05cSAndroid Build Coastguard Worker 
1956*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1957*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1958*5c90c05cSAndroid Build Coastguard Worker                               const format_specs& specs) -> OutputIt {
1959*5c90c05cSAndroid Build Coastguard Worker   bool is_debug = specs.type() == presentation_type::debug;
1960*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char>(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1961*5c90c05cSAndroid Build Coastguard Worker     if (is_debug) return write_escaped_char(it, value);
1962*5c90c05cSAndroid Build Coastguard Worker     *it++ = value;
1963*5c90c05cSAndroid Build Coastguard Worker     return it;
1964*5c90c05cSAndroid Build Coastguard Worker   });
1965*5c90c05cSAndroid Build Coastguard Worker }
1966*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
1967*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs& specs,
1968*5c90c05cSAndroid Build Coastguard Worker                          locale_ref loc = {}) -> OutputIt {
1969*5c90c05cSAndroid Build Coastguard Worker   // char is formatted as unsigned char for consistency across platforms.
1970*5c90c05cSAndroid Build Coastguard Worker   using unsigned_type =
1971*5c90c05cSAndroid Build Coastguard Worker       conditional_t<std::is_same<Char, char>::value, unsigned char, unsigned>;
1972*5c90c05cSAndroid Build Coastguard Worker   return check_char_specs(specs)
1973*5c90c05cSAndroid Build Coastguard Worker              ? write_char<Char>(out, value, specs)
1974*5c90c05cSAndroid Build Coastguard Worker              : write<Char>(out, static_cast<unsigned_type>(value), specs, loc);
1975*5c90c05cSAndroid Build Coastguard Worker }
1976*5c90c05cSAndroid Build Coastguard Worker 
1977*5c90c05cSAndroid Build Coastguard Worker template <typename Char> class digit_grouping {
1978*5c90c05cSAndroid Build Coastguard Worker  private:
1979*5c90c05cSAndroid Build Coastguard Worker   std::string grouping_;
1980*5c90c05cSAndroid Build Coastguard Worker   std::basic_string<Char> thousands_sep_;
1981*5c90c05cSAndroid Build Coastguard Worker 
1982*5c90c05cSAndroid Build Coastguard Worker   struct next_state {
1983*5c90c05cSAndroid Build Coastguard Worker     std::string::const_iterator group;
1984*5c90c05cSAndroid Build Coastguard Worker     int pos;
1985*5c90c05cSAndroid Build Coastguard Worker   };
1986*5c90c05cSAndroid Build Coastguard Worker   auto initial_state() const -> next_state { return {grouping_.begin(), 0}; }
1987*5c90c05cSAndroid Build Coastguard Worker 
1988*5c90c05cSAndroid Build Coastguard Worker   // Returns the next digit group separator position.
1989*5c90c05cSAndroid Build Coastguard Worker   auto next(next_state& state) const -> int {
1990*5c90c05cSAndroid Build Coastguard Worker     if (thousands_sep_.empty()) return max_value<int>();
1991*5c90c05cSAndroid Build Coastguard Worker     if (state.group == grouping_.end()) return state.pos += grouping_.back();
1992*5c90c05cSAndroid Build Coastguard Worker     if (*state.group <= 0 || *state.group == max_value<char>())
1993*5c90c05cSAndroid Build Coastguard Worker       return max_value<int>();
1994*5c90c05cSAndroid Build Coastguard Worker     state.pos += *state.group++;
1995*5c90c05cSAndroid Build Coastguard Worker     return state.pos;
1996*5c90c05cSAndroid Build Coastguard Worker   }
1997*5c90c05cSAndroid Build Coastguard Worker 
1998*5c90c05cSAndroid Build Coastguard Worker  public:
1999*5c90c05cSAndroid Build Coastguard Worker   explicit digit_grouping(locale_ref loc, bool localized = true) {
2000*5c90c05cSAndroid Build Coastguard Worker     if (!localized) return;
2001*5c90c05cSAndroid Build Coastguard Worker     auto sep = thousands_sep<Char>(loc);
2002*5c90c05cSAndroid Build Coastguard Worker     grouping_ = sep.grouping;
2003*5c90c05cSAndroid Build Coastguard Worker     if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);
2004*5c90c05cSAndroid Build Coastguard Worker   }
2005*5c90c05cSAndroid Build Coastguard Worker   digit_grouping(std::string grouping, std::basic_string<Char> sep)
2006*5c90c05cSAndroid Build Coastguard Worker       : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}
2007*5c90c05cSAndroid Build Coastguard Worker 
2008*5c90c05cSAndroid Build Coastguard Worker   auto has_separator() const -> bool { return !thousands_sep_.empty(); }
2009*5c90c05cSAndroid Build Coastguard Worker 
2010*5c90c05cSAndroid Build Coastguard Worker   auto count_separators(int num_digits) const -> int {
2011*5c90c05cSAndroid Build Coastguard Worker     int count = 0;
2012*5c90c05cSAndroid Build Coastguard Worker     auto state = initial_state();
2013*5c90c05cSAndroid Build Coastguard Worker     while (num_digits > next(state)) ++count;
2014*5c90c05cSAndroid Build Coastguard Worker     return count;
2015*5c90c05cSAndroid Build Coastguard Worker   }
2016*5c90c05cSAndroid Build Coastguard Worker 
2017*5c90c05cSAndroid Build Coastguard Worker   // Applies grouping to digits and write the output to out.
2018*5c90c05cSAndroid Build Coastguard Worker   template <typename Out, typename C>
2019*5c90c05cSAndroid Build Coastguard Worker   auto apply(Out out, basic_string_view<C> digits) const -> Out {
2020*5c90c05cSAndroid Build Coastguard Worker     auto num_digits = static_cast<int>(digits.size());
2021*5c90c05cSAndroid Build Coastguard Worker     auto separators = basic_memory_buffer<int>();
2022*5c90c05cSAndroid Build Coastguard Worker     separators.push_back(0);
2023*5c90c05cSAndroid Build Coastguard Worker     auto state = initial_state();
2024*5c90c05cSAndroid Build Coastguard Worker     while (int i = next(state)) {
2025*5c90c05cSAndroid Build Coastguard Worker       if (i >= num_digits) break;
2026*5c90c05cSAndroid Build Coastguard Worker       separators.push_back(i);
2027*5c90c05cSAndroid Build Coastguard Worker     }
2028*5c90c05cSAndroid Build Coastguard Worker     for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
2029*5c90c05cSAndroid Build Coastguard Worker          i < num_digits; ++i) {
2030*5c90c05cSAndroid Build Coastguard Worker       if (num_digits - i == separators[sep_index]) {
2031*5c90c05cSAndroid Build Coastguard Worker         out = copy<Char>(thousands_sep_.data(),
2032*5c90c05cSAndroid Build Coastguard Worker                          thousands_sep_.data() + thousands_sep_.size(), out);
2033*5c90c05cSAndroid Build Coastguard Worker         --sep_index;
2034*5c90c05cSAndroid Build Coastguard Worker       }
2035*5c90c05cSAndroid Build Coastguard Worker       *out++ = static_cast<Char>(digits[to_unsigned(i)]);
2036*5c90c05cSAndroid Build Coastguard Worker     }
2037*5c90c05cSAndroid Build Coastguard Worker     return out;
2038*5c90c05cSAndroid Build Coastguard Worker   }
2039*5c90c05cSAndroid Build Coastguard Worker };
2040*5c90c05cSAndroid Build Coastguard Worker 
2041*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
2042*5c90c05cSAndroid Build Coastguard Worker   prefix |= prefix != 0 ? value << 8 : value;
2043*5c90c05cSAndroid Build Coastguard Worker   prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2044*5c90c05cSAndroid Build Coastguard Worker }
2045*5c90c05cSAndroid Build Coastguard Worker 
2046*5c90c05cSAndroid Build Coastguard Worker // Writes a decimal integer with digit grouping.
2047*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename UInt, typename Char>
2048*5c90c05cSAndroid Build Coastguard Worker auto write_int(OutputIt out, UInt value, unsigned prefix,
2049*5c90c05cSAndroid Build Coastguard Worker                const format_specs& specs, const digit_grouping<Char>& grouping)
2050*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
2051*5c90c05cSAndroid Build Coastguard Worker   static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
2052*5c90c05cSAndroid Build Coastguard Worker   int num_digits = 0;
2053*5c90c05cSAndroid Build Coastguard Worker   auto buffer = memory_buffer();
2054*5c90c05cSAndroid Build Coastguard Worker   switch (specs.type()) {
2055*5c90c05cSAndroid Build Coastguard Worker   default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
2056*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::none:
2057*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::dec:
2058*5c90c05cSAndroid Build Coastguard Worker     num_digits = count_digits(value);
2059*5c90c05cSAndroid Build Coastguard Worker     format_decimal<char>(appender(buffer), value, num_digits);
2060*5c90c05cSAndroid Build Coastguard Worker     break;
2061*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::hex:
2062*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt())
2063*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
2064*5c90c05cSAndroid Build Coastguard Worker     num_digits = count_digits<4>(value);
2065*5c90c05cSAndroid Build Coastguard Worker     format_base2e<char>(4, appender(buffer), value, num_digits, specs.upper());
2066*5c90c05cSAndroid Build Coastguard Worker     break;
2067*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::oct:
2068*5c90c05cSAndroid Build Coastguard Worker     num_digits = count_digits<3>(value);
2069*5c90c05cSAndroid Build Coastguard Worker     // Octal prefix '0' is counted as a digit, so only add it if precision
2070*5c90c05cSAndroid Build Coastguard Worker     // is not greater than the number of digits.
2071*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt() && specs.precision <= num_digits && value != 0)
2072*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, '0');
2073*5c90c05cSAndroid Build Coastguard Worker     format_base2e<char>(3, appender(buffer), value, num_digits);
2074*5c90c05cSAndroid Build Coastguard Worker     break;
2075*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::bin:
2076*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt())
2077*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
2078*5c90c05cSAndroid Build Coastguard Worker     num_digits = count_digits<1>(value);
2079*5c90c05cSAndroid Build Coastguard Worker     format_base2e<char>(1, appender(buffer), value, num_digits);
2080*5c90c05cSAndroid Build Coastguard Worker     break;
2081*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::chr:
2082*5c90c05cSAndroid Build Coastguard Worker     return write_char<Char>(out, static_cast<Char>(value), specs);
2083*5c90c05cSAndroid Build Coastguard Worker   }
2084*5c90c05cSAndroid Build Coastguard Worker 
2085*5c90c05cSAndroid Build Coastguard Worker   unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +
2086*5c90c05cSAndroid Build Coastguard Worker                   to_unsigned(grouping.count_separators(num_digits));
2087*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char, align::right>(
2088*5c90c05cSAndroid Build Coastguard Worker       out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2089*5c90c05cSAndroid Build Coastguard Worker         for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2090*5c90c05cSAndroid Build Coastguard Worker           *it++ = static_cast<Char>(p & 0xff);
2091*5c90c05cSAndroid Build Coastguard Worker         return grouping.apply(it, string_view(buffer.data(), buffer.size()));
2092*5c90c05cSAndroid Build Coastguard Worker       });
2093*5c90c05cSAndroid Build Coastguard Worker }
2094*5c90c05cSAndroid Build Coastguard Worker 
2095*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_LOCALE
2096*5c90c05cSAndroid Build Coastguard Worker // Writes a localized value.
2097*5c90c05cSAndroid Build Coastguard Worker FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs,
2098*5c90c05cSAndroid Build Coastguard Worker                        locale_ref loc) -> bool;
2099*5c90c05cSAndroid Build Coastguard Worker #endif
2100*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt>
2101*5c90c05cSAndroid Build Coastguard Worker inline auto write_loc(OutputIt, loc_value, const format_specs&, locale_ref)
2102*5c90c05cSAndroid Build Coastguard Worker     -> bool {
2103*5c90c05cSAndroid Build Coastguard Worker   return false;
2104*5c90c05cSAndroid Build Coastguard Worker }
2105*5c90c05cSAndroid Build Coastguard Worker 
2106*5c90c05cSAndroid Build Coastguard Worker template <typename UInt> struct write_int_arg {
2107*5c90c05cSAndroid Build Coastguard Worker   UInt abs_value;
2108*5c90c05cSAndroid Build Coastguard Worker   unsigned prefix;
2109*5c90c05cSAndroid Build Coastguard Worker };
2110*5c90c05cSAndroid Build Coastguard Worker 
2111*5c90c05cSAndroid Build Coastguard Worker template <typename T>
2112*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto make_write_int_arg(T value, sign s)
2113*5c90c05cSAndroid Build Coastguard Worker     -> write_int_arg<uint32_or_64_or_128_t<T>> {
2114*5c90c05cSAndroid Build Coastguard Worker   auto prefix = 0u;
2115*5c90c05cSAndroid Build Coastguard Worker   auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2116*5c90c05cSAndroid Build Coastguard Worker   if (is_negative(value)) {
2117*5c90c05cSAndroid Build Coastguard Worker     prefix = 0x01000000 | '-';
2118*5c90c05cSAndroid Build Coastguard Worker     abs_value = 0 - abs_value;
2119*5c90c05cSAndroid Build Coastguard Worker   } else {
2120*5c90c05cSAndroid Build Coastguard Worker     constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
2121*5c90c05cSAndroid Build Coastguard Worker                                             0x1000000u | ' '};
2122*5c90c05cSAndroid Build Coastguard Worker     prefix = prefixes[static_cast<int>(s)];
2123*5c90c05cSAndroid Build Coastguard Worker   }
2124*5c90c05cSAndroid Build Coastguard Worker   return {abs_value, prefix};
2125*5c90c05cSAndroid Build Coastguard Worker }
2126*5c90c05cSAndroid Build Coastguard Worker 
2127*5c90c05cSAndroid Build Coastguard Worker template <typename Char = char> struct loc_writer {
2128*5c90c05cSAndroid Build Coastguard Worker   basic_appender<Char> out;
2129*5c90c05cSAndroid Build Coastguard Worker   const format_specs& specs;
2130*5c90c05cSAndroid Build Coastguard Worker   std::basic_string<Char> sep;
2131*5c90c05cSAndroid Build Coastguard Worker   std::string grouping;
2132*5c90c05cSAndroid Build Coastguard Worker   std::basic_string<Char> decimal_point;
2133*5c90c05cSAndroid Build Coastguard Worker 
2134*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2135*5c90c05cSAndroid Build Coastguard Worker   auto operator()(T value) -> bool {
2136*5c90c05cSAndroid Build Coastguard Worker     auto arg = make_write_int_arg(value, specs.sign());
2137*5c90c05cSAndroid Build Coastguard Worker     write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2138*5c90c05cSAndroid Build Coastguard Worker               specs, digit_grouping<Char>(grouping, sep));
2139*5c90c05cSAndroid Build Coastguard Worker     return true;
2140*5c90c05cSAndroid Build Coastguard Worker   }
2141*5c90c05cSAndroid Build Coastguard Worker 
2142*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2143*5c90c05cSAndroid Build Coastguard Worker   auto operator()(T) -> bool {
2144*5c90c05cSAndroid Build Coastguard Worker     return false;
2145*5c90c05cSAndroid Build Coastguard Worker   }
2146*5c90c05cSAndroid Build Coastguard Worker };
2147*5c90c05cSAndroid Build Coastguard Worker 
2148*5c90c05cSAndroid Build Coastguard Worker // Size and padding computation separate from write_int to avoid template bloat.
2149*5c90c05cSAndroid Build Coastguard Worker struct size_padding {
2150*5c90c05cSAndroid Build Coastguard Worker   unsigned size;
2151*5c90c05cSAndroid Build Coastguard Worker   unsigned padding;
2152*5c90c05cSAndroid Build Coastguard Worker 
2153*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix,
2154*5c90c05cSAndroid Build Coastguard Worker                              const format_specs& specs)
2155*5c90c05cSAndroid Build Coastguard Worker       : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
2156*5c90c05cSAndroid Build Coastguard Worker     if (specs.align() == align::numeric) {
2157*5c90c05cSAndroid Build Coastguard Worker       auto width = to_unsigned(specs.width);
2158*5c90c05cSAndroid Build Coastguard Worker       if (width > size) {
2159*5c90c05cSAndroid Build Coastguard Worker         padding = width - size;
2160*5c90c05cSAndroid Build Coastguard Worker         size = width;
2161*5c90c05cSAndroid Build Coastguard Worker       }
2162*5c90c05cSAndroid Build Coastguard Worker     } else if (specs.precision > num_digits) {
2163*5c90c05cSAndroid Build Coastguard Worker       size = (prefix >> 24) + to_unsigned(specs.precision);
2164*5c90c05cSAndroid Build Coastguard Worker       padding = to_unsigned(specs.precision - num_digits);
2165*5c90c05cSAndroid Build Coastguard Worker     }
2166*5c90c05cSAndroid Build Coastguard Worker   }
2167*5c90c05cSAndroid Build Coastguard Worker };
2168*5c90c05cSAndroid Build Coastguard Worker 
2169*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T>
2170*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
2171*5c90c05cSAndroid Build Coastguard Worker                                         const format_specs& specs) -> OutputIt {
2172*5c90c05cSAndroid Build Coastguard Worker   static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2173*5c90c05cSAndroid Build Coastguard Worker 
2174*5c90c05cSAndroid Build Coastguard Worker   constexpr int buffer_size = num_bits<T>();
2175*5c90c05cSAndroid Build Coastguard Worker   char buffer[buffer_size];
2176*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0');
2177*5c90c05cSAndroid Build Coastguard Worker   const char* begin = nullptr;
2178*5c90c05cSAndroid Build Coastguard Worker   const char* end = buffer + buffer_size;
2179*5c90c05cSAndroid Build Coastguard Worker 
2180*5c90c05cSAndroid Build Coastguard Worker   auto abs_value = arg.abs_value;
2181*5c90c05cSAndroid Build Coastguard Worker   auto prefix = arg.prefix;
2182*5c90c05cSAndroid Build Coastguard Worker   switch (specs.type()) {
2183*5c90c05cSAndroid Build Coastguard Worker   default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
2184*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::none:
2185*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::dec:
2186*5c90c05cSAndroid Build Coastguard Worker     begin = do_format_decimal(buffer, abs_value, buffer_size);
2187*5c90c05cSAndroid Build Coastguard Worker     break;
2188*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::hex:
2189*5c90c05cSAndroid Build Coastguard Worker     begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper());
2190*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt())
2191*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
2192*5c90c05cSAndroid Build Coastguard Worker     break;
2193*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::oct: {
2194*5c90c05cSAndroid Build Coastguard Worker     begin = do_format_base2e(3, buffer, abs_value, buffer_size);
2195*5c90c05cSAndroid Build Coastguard Worker     // Octal prefix '0' is counted as a digit, so only add it if precision
2196*5c90c05cSAndroid Build Coastguard Worker     // is not greater than the number of digits.
2197*5c90c05cSAndroid Build Coastguard Worker     auto num_digits = end - begin;
2198*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt() && specs.precision <= num_digits && abs_value != 0)
2199*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, '0');
2200*5c90c05cSAndroid Build Coastguard Worker     break;
2201*5c90c05cSAndroid Build Coastguard Worker   }
2202*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::bin:
2203*5c90c05cSAndroid Build Coastguard Worker     begin = do_format_base2e(1, buffer, abs_value, buffer_size);
2204*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt())
2205*5c90c05cSAndroid Build Coastguard Worker       prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
2206*5c90c05cSAndroid Build Coastguard Worker     break;
2207*5c90c05cSAndroid Build Coastguard Worker   case presentation_type::chr:
2208*5c90c05cSAndroid Build Coastguard Worker     return write_char<Char>(out, static_cast<Char>(abs_value), specs);
2209*5c90c05cSAndroid Build Coastguard Worker   }
2210*5c90c05cSAndroid Build Coastguard Worker 
2211*5c90c05cSAndroid Build Coastguard Worker   // Write an integer in the format
2212*5c90c05cSAndroid Build Coastguard Worker   //   <left-padding><prefix><numeric-padding><digits><right-padding>
2213*5c90c05cSAndroid Build Coastguard Worker   // prefix contains chars in three lower bytes and the size in the fourth byte.
2214*5c90c05cSAndroid Build Coastguard Worker   int num_digits = static_cast<int>(end - begin);
2215*5c90c05cSAndroid Build Coastguard Worker   // Slightly faster check for specs.width == 0 && specs.precision == -1.
2216*5c90c05cSAndroid Build Coastguard Worker   if ((specs.width | (specs.precision + 1)) == 0) {
2217*5c90c05cSAndroid Build Coastguard Worker     auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
2218*5c90c05cSAndroid Build Coastguard Worker     for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2219*5c90c05cSAndroid Build Coastguard Worker       *it++ = static_cast<Char>(p & 0xff);
2220*5c90c05cSAndroid Build Coastguard Worker     return base_iterator(out, copy<Char>(begin, end, it));
2221*5c90c05cSAndroid Build Coastguard Worker   }
2222*5c90c05cSAndroid Build Coastguard Worker   auto sp = size_padding(num_digits, prefix, specs);
2223*5c90c05cSAndroid Build Coastguard Worker   unsigned padding = sp.padding;
2224*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char, align::right>(
2225*5c90c05cSAndroid Build Coastguard Worker       out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2226*5c90c05cSAndroid Build Coastguard Worker         for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2227*5c90c05cSAndroid Build Coastguard Worker           *it++ = static_cast<Char>(p & 0xff);
2228*5c90c05cSAndroid Build Coastguard Worker         it = detail::fill_n(it, padding, static_cast<Char>('0'));
2229*5c90c05cSAndroid Build Coastguard Worker         return copy<Char>(begin, end, it);
2230*5c90c05cSAndroid Build Coastguard Worker       });
2231*5c90c05cSAndroid Build Coastguard Worker }
2232*5c90c05cSAndroid Build Coastguard Worker 
2233*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T>
2234*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out,
2235*5c90c05cSAndroid Build Coastguard Worker                                                    write_int_arg<T> arg,
2236*5c90c05cSAndroid Build Coastguard Worker                                                    const format_specs& specs)
2237*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
2238*5c90c05cSAndroid Build Coastguard Worker   return write_int<Char>(out, arg, specs);
2239*5c90c05cSAndroid Build Coastguard Worker }
2240*5c90c05cSAndroid Build Coastguard Worker 
2241*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename T,
2242*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_integral<T>::value &&
2243*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, bool>::value &&
2244*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, Char>::value)>
2245*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_INLINE auto write(basic_appender<Char> out, T value,
2246*5c90c05cSAndroid Build Coastguard Worker                                     const format_specs& specs, locale_ref loc)
2247*5c90c05cSAndroid Build Coastguard Worker     -> basic_appender<Char> {
2248*5c90c05cSAndroid Build Coastguard Worker   if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2249*5c90c05cSAndroid Build Coastguard Worker   return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2250*5c90c05cSAndroid Build Coastguard Worker                                   specs);
2251*5c90c05cSAndroid Build Coastguard Worker }
2252*5c90c05cSAndroid Build Coastguard Worker 
2253*5c90c05cSAndroid Build Coastguard Worker // An inlined version of write used in format string compilation.
2254*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
2255*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_integral<T>::value &&
2256*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, bool>::value &&
2257*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, Char>::value &&
2258*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<OutputIt, basic_appender<Char>>::value)>
2259*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2260*5c90c05cSAndroid Build Coastguard Worker                                     const format_specs& specs, locale_ref loc)
2261*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
2262*5c90c05cSAndroid Build Coastguard Worker   if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2263*5c90c05cSAndroid Build Coastguard Worker   return write_int<Char>(out, make_write_int_arg(value, specs.sign()), specs);
2264*5c90c05cSAndroid Build Coastguard Worker }
2265*5c90c05cSAndroid Build Coastguard Worker 
2266*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
2267*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2268*5c90c05cSAndroid Build Coastguard Worker                          const format_specs& specs) -> OutputIt {
2269*5c90c05cSAndroid Build Coastguard Worker   auto data = s.data();
2270*5c90c05cSAndroid Build Coastguard Worker   auto size = s.size();
2271*5c90c05cSAndroid Build Coastguard Worker   if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2272*5c90c05cSAndroid Build Coastguard Worker     size = code_point_index(s, to_unsigned(specs.precision));
2273*5c90c05cSAndroid Build Coastguard Worker 
2274*5c90c05cSAndroid Build Coastguard Worker   bool is_debug = specs.type() == presentation_type::debug;
2275*5c90c05cSAndroid Build Coastguard Worker   if (is_debug) {
2276*5c90c05cSAndroid Build Coastguard Worker     auto buf = counting_buffer<Char>();
2277*5c90c05cSAndroid Build Coastguard Worker     write_escaped_string(basic_appender<Char>(buf), s);
2278*5c90c05cSAndroid Build Coastguard Worker     size = buf.count();
2279*5c90c05cSAndroid Build Coastguard Worker   }
2280*5c90c05cSAndroid Build Coastguard Worker 
2281*5c90c05cSAndroid Build Coastguard Worker   size_t width = 0;
2282*5c90c05cSAndroid Build Coastguard Worker   if (specs.width != 0) {
2283*5c90c05cSAndroid Build Coastguard Worker     width =
2284*5c90c05cSAndroid Build Coastguard Worker         is_debug ? size : compute_width(basic_string_view<Char>(data, size));
2285*5c90c05cSAndroid Build Coastguard Worker   }
2286*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char>(
2287*5c90c05cSAndroid Build Coastguard Worker       out, specs, size, width, [=](reserve_iterator<OutputIt> it) {
2288*5c90c05cSAndroid Build Coastguard Worker         return is_debug ? write_escaped_string(it, s)
2289*5c90c05cSAndroid Build Coastguard Worker                         : copy<Char>(data, data + size, it);
2290*5c90c05cSAndroid Build Coastguard Worker       });
2291*5c90c05cSAndroid Build Coastguard Worker }
2292*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
2293*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2294*5c90c05cSAndroid Build Coastguard Worker                          const format_specs& specs, locale_ref) -> OutputIt {
2295*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(out, s, specs);
2296*5c90c05cSAndroid Build Coastguard Worker }
2297*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
2298*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, const Char* s, const format_specs& specs,
2299*5c90c05cSAndroid Build Coastguard Worker                          locale_ref) -> OutputIt {
2300*5c90c05cSAndroid Build Coastguard Worker   if (specs.type() == presentation_type::pointer)
2301*5c90c05cSAndroid Build Coastguard Worker     return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2302*5c90c05cSAndroid Build Coastguard Worker   if (!s) report_error("string pointer is null");
2303*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(out, basic_string_view<Char>(s), specs, {});
2304*5c90c05cSAndroid Build Coastguard Worker }
2305*5c90c05cSAndroid Build Coastguard Worker 
2306*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
2307*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_integral<T>::value &&
2308*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, bool>::value &&
2309*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<T, Char>::value)>
2310*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2311*5c90c05cSAndroid Build Coastguard Worker   auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2312*5c90c05cSAndroid Build Coastguard Worker   bool negative = is_negative(value);
2313*5c90c05cSAndroid Build Coastguard Worker   // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2314*5c90c05cSAndroid Build Coastguard Worker   if (negative) abs_value = ~abs_value + 1;
2315*5c90c05cSAndroid Build Coastguard Worker   int num_digits = count_digits(abs_value);
2316*5c90c05cSAndroid Build Coastguard Worker   auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2317*5c90c05cSAndroid Build Coastguard Worker   if (auto ptr = to_pointer<Char>(out, size)) {
2318*5c90c05cSAndroid Build Coastguard Worker     if (negative) *ptr++ = static_cast<Char>('-');
2319*5c90c05cSAndroid Build Coastguard Worker     format_decimal<Char>(ptr, abs_value, num_digits);
2320*5c90c05cSAndroid Build Coastguard Worker     return out;
2321*5c90c05cSAndroid Build Coastguard Worker   }
2322*5c90c05cSAndroid Build Coastguard Worker   if (negative) *out++ = static_cast<Char>('-');
2323*5c90c05cSAndroid Build Coastguard Worker   return format_decimal<Char>(out, abs_value, num_digits);
2324*5c90c05cSAndroid Build Coastguard Worker }
2325*5c90c05cSAndroid Build Coastguard Worker 
2326*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
2327*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2328*5c90c05cSAndroid Build Coastguard Worker                                format_specs& specs) -> const Char* {
2329*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(begin != end, "");
2330*5c90c05cSAndroid Build Coastguard Worker   auto alignment = align::none;
2331*5c90c05cSAndroid Build Coastguard Worker   auto p = begin + code_point_length(begin);
2332*5c90c05cSAndroid Build Coastguard Worker   if (end - p <= 0) p = begin;
2333*5c90c05cSAndroid Build Coastguard Worker   for (;;) {
2334*5c90c05cSAndroid Build Coastguard Worker     switch (to_ascii(*p)) {
2335*5c90c05cSAndroid Build Coastguard Worker     case '<': alignment = align::left; break;
2336*5c90c05cSAndroid Build Coastguard Worker     case '>': alignment = align::right; break;
2337*5c90c05cSAndroid Build Coastguard Worker     case '^': alignment = align::center; break;
2338*5c90c05cSAndroid Build Coastguard Worker     }
2339*5c90c05cSAndroid Build Coastguard Worker     if (alignment != align::none) {
2340*5c90c05cSAndroid Build Coastguard Worker       if (p != begin) {
2341*5c90c05cSAndroid Build Coastguard Worker         auto c = *begin;
2342*5c90c05cSAndroid Build Coastguard Worker         if (c == '}') return begin;
2343*5c90c05cSAndroid Build Coastguard Worker         if (c == '{') {
2344*5c90c05cSAndroid Build Coastguard Worker           report_error("invalid fill character '{'");
2345*5c90c05cSAndroid Build Coastguard Worker           return begin;
2346*5c90c05cSAndroid Build Coastguard Worker         }
2347*5c90c05cSAndroid Build Coastguard Worker         specs.set_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));
2348*5c90c05cSAndroid Build Coastguard Worker         begin = p + 1;
2349*5c90c05cSAndroid Build Coastguard Worker       } else {
2350*5c90c05cSAndroid Build Coastguard Worker         ++begin;
2351*5c90c05cSAndroid Build Coastguard Worker       }
2352*5c90c05cSAndroid Build Coastguard Worker       break;
2353*5c90c05cSAndroid Build Coastguard Worker     } else if (p == begin) {
2354*5c90c05cSAndroid Build Coastguard Worker       break;
2355*5c90c05cSAndroid Build Coastguard Worker     }
2356*5c90c05cSAndroid Build Coastguard Worker     p = begin;
2357*5c90c05cSAndroid Build Coastguard Worker   }
2358*5c90c05cSAndroid Build Coastguard Worker   specs.set_align(alignment);
2359*5c90c05cSAndroid Build Coastguard Worker   return begin;
2360*5c90c05cSAndroid Build Coastguard Worker }
2361*5c90c05cSAndroid Build Coastguard Worker 
2362*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
2363*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2364*5c90c05cSAndroid Build Coastguard Worker                                      format_specs specs, sign s) -> OutputIt {
2365*5c90c05cSAndroid Build Coastguard Worker   auto str =
2366*5c90c05cSAndroid Build Coastguard Worker       isnan ? (specs.upper() ? "NAN" : "nan") : (specs.upper() ? "INF" : "inf");
2367*5c90c05cSAndroid Build Coastguard Worker   constexpr size_t str_size = 3;
2368*5c90c05cSAndroid Build Coastguard Worker   auto size = str_size + (s != sign::none ? 1 : 0);
2369*5c90c05cSAndroid Build Coastguard Worker   // Replace '0'-padding with space for non-finite values.
2370*5c90c05cSAndroid Build Coastguard Worker   const bool is_zero_fill =
2371*5c90c05cSAndroid Build Coastguard Worker       specs.fill_size() == 1 && specs.fill_unit<Char>() == '0';
2372*5c90c05cSAndroid Build Coastguard Worker   if (is_zero_fill) specs.set_fill(' ');
2373*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char>(out, specs, size,
2374*5c90c05cSAndroid Build Coastguard Worker                             [=](reserve_iterator<OutputIt> it) {
2375*5c90c05cSAndroid Build Coastguard Worker                               if (s != sign::none)
2376*5c90c05cSAndroid Build Coastguard Worker                                 *it++ = detail::getsign<Char>(s);
2377*5c90c05cSAndroid Build Coastguard Worker                               return copy<Char>(str, str + str_size, it);
2378*5c90c05cSAndroid Build Coastguard Worker                             });
2379*5c90c05cSAndroid Build Coastguard Worker }
2380*5c90c05cSAndroid Build Coastguard Worker 
2381*5c90c05cSAndroid Build Coastguard Worker // A decimal floating-point number significand * pow(10, exp).
2382*5c90c05cSAndroid Build Coastguard Worker struct big_decimal_fp {
2383*5c90c05cSAndroid Build Coastguard Worker   const char* significand;
2384*5c90c05cSAndroid Build Coastguard Worker   int significand_size;
2385*5c90c05cSAndroid Build Coastguard Worker   int exponent;
2386*5c90c05cSAndroid Build Coastguard Worker };
2387*5c90c05cSAndroid Build Coastguard Worker 
2388*5c90c05cSAndroid Build Coastguard Worker constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2389*5c90c05cSAndroid Build Coastguard Worker   return f.significand_size;
2390*5c90c05cSAndroid Build Coastguard Worker }
2391*5c90c05cSAndroid Build Coastguard Worker template <typename T>
2392*5c90c05cSAndroid Build Coastguard Worker inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2393*5c90c05cSAndroid Build Coastguard Worker   return count_digits(f.significand);
2394*5c90c05cSAndroid Build Coastguard Worker }
2395*5c90c05cSAndroid Build Coastguard Worker 
2396*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
2397*5c90c05cSAndroid Build Coastguard Worker constexpr auto write_significand(OutputIt out, const char* significand,
2398*5c90c05cSAndroid Build Coastguard Worker                                  int significand_size) -> OutputIt {
2399*5c90c05cSAndroid Build Coastguard Worker   return copy<Char>(significand, significand + significand_size, out);
2400*5c90c05cSAndroid Build Coastguard Worker }
2401*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename UInt>
2402*5c90c05cSAndroid Build Coastguard Worker inline auto write_significand(OutputIt out, UInt significand,
2403*5c90c05cSAndroid Build Coastguard Worker                               int significand_size) -> OutputIt {
2404*5c90c05cSAndroid Build Coastguard Worker   return format_decimal<Char>(out, significand, significand_size);
2405*5c90c05cSAndroid Build Coastguard Worker }
2406*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T, typename Grouping>
2407*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2408*5c90c05cSAndroid Build Coastguard Worker                                        int significand_size, int exponent,
2409*5c90c05cSAndroid Build Coastguard Worker                                        const Grouping& grouping) -> OutputIt {
2410*5c90c05cSAndroid Build Coastguard Worker   if (!grouping.has_separator()) {
2411*5c90c05cSAndroid Build Coastguard Worker     out = write_significand<Char>(out, significand, significand_size);
2412*5c90c05cSAndroid Build Coastguard Worker     return detail::fill_n(out, exponent, static_cast<Char>('0'));
2413*5c90c05cSAndroid Build Coastguard Worker   }
2414*5c90c05cSAndroid Build Coastguard Worker   auto buffer = memory_buffer();
2415*5c90c05cSAndroid Build Coastguard Worker   write_significand<char>(appender(buffer), significand, significand_size);
2416*5c90c05cSAndroid Build Coastguard Worker   detail::fill_n(appender(buffer), exponent, '0');
2417*5c90c05cSAndroid Build Coastguard Worker   return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2418*5c90c05cSAndroid Build Coastguard Worker }
2419*5c90c05cSAndroid Build Coastguard Worker 
2420*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename UInt,
2421*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2422*5c90c05cSAndroid Build Coastguard Worker inline auto write_significand(Char* out, UInt significand, int significand_size,
2423*5c90c05cSAndroid Build Coastguard Worker                               int integral_size, Char decimal_point) -> Char* {
2424*5c90c05cSAndroid Build Coastguard Worker   if (!decimal_point) return format_decimal(out, significand, significand_size);
2425*5c90c05cSAndroid Build Coastguard Worker   out += significand_size + 1;
2426*5c90c05cSAndroid Build Coastguard Worker   Char* end = out;
2427*5c90c05cSAndroid Build Coastguard Worker   int floating_size = significand_size - integral_size;
2428*5c90c05cSAndroid Build Coastguard Worker   for (int i = floating_size / 2; i > 0; --i) {
2429*5c90c05cSAndroid Build Coastguard Worker     out -= 2;
2430*5c90c05cSAndroid Build Coastguard Worker     write2digits(out, static_cast<std::size_t>(significand % 100));
2431*5c90c05cSAndroid Build Coastguard Worker     significand /= 100;
2432*5c90c05cSAndroid Build Coastguard Worker   }
2433*5c90c05cSAndroid Build Coastguard Worker   if (floating_size % 2 != 0) {
2434*5c90c05cSAndroid Build Coastguard Worker     *--out = static_cast<Char>('0' + significand % 10);
2435*5c90c05cSAndroid Build Coastguard Worker     significand /= 10;
2436*5c90c05cSAndroid Build Coastguard Worker   }
2437*5c90c05cSAndroid Build Coastguard Worker   *--out = decimal_point;
2438*5c90c05cSAndroid Build Coastguard Worker   format_decimal(out - integral_size, significand, integral_size);
2439*5c90c05cSAndroid Build Coastguard Worker   return end;
2440*5c90c05cSAndroid Build Coastguard Worker }
2441*5c90c05cSAndroid Build Coastguard Worker 
2442*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename UInt, typename Char,
2443*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
2444*5c90c05cSAndroid Build Coastguard Worker inline auto write_significand(OutputIt out, UInt significand,
2445*5c90c05cSAndroid Build Coastguard Worker                               int significand_size, int integral_size,
2446*5c90c05cSAndroid Build Coastguard Worker                               Char decimal_point) -> OutputIt {
2447*5c90c05cSAndroid Build Coastguard Worker   // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2448*5c90c05cSAndroid Build Coastguard Worker   Char buffer[digits10<UInt>() + 2];
2449*5c90c05cSAndroid Build Coastguard Worker   auto end = write_significand(buffer, significand, significand_size,
2450*5c90c05cSAndroid Build Coastguard Worker                                integral_size, decimal_point);
2451*5c90c05cSAndroid Build Coastguard Worker   return detail::copy_noinline<Char>(buffer, end, out);
2452*5c90c05cSAndroid Build Coastguard Worker }
2453*5c90c05cSAndroid Build Coastguard Worker 
2454*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Char>
2455*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2456*5c90c05cSAndroid Build Coastguard Worker                                      int significand_size, int integral_size,
2457*5c90c05cSAndroid Build Coastguard Worker                                      Char decimal_point) -> OutputIt {
2458*5c90c05cSAndroid Build Coastguard Worker   out = detail::copy_noinline<Char>(significand, significand + integral_size,
2459*5c90c05cSAndroid Build Coastguard Worker                                     out);
2460*5c90c05cSAndroid Build Coastguard Worker   if (!decimal_point) return out;
2461*5c90c05cSAndroid Build Coastguard Worker   *out++ = decimal_point;
2462*5c90c05cSAndroid Build Coastguard Worker   return detail::copy_noinline<Char>(significand + integral_size,
2463*5c90c05cSAndroid Build Coastguard Worker                                      significand + significand_size, out);
2464*5c90c05cSAndroid Build Coastguard Worker }
2465*5c90c05cSAndroid Build Coastguard Worker 
2466*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Char, typename T, typename Grouping>
2467*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2468*5c90c05cSAndroid Build Coastguard Worker                                        int significand_size, int integral_size,
2469*5c90c05cSAndroid Build Coastguard Worker                                        Char decimal_point,
2470*5c90c05cSAndroid Build Coastguard Worker                                        const Grouping& grouping) -> OutputIt {
2471*5c90c05cSAndroid Build Coastguard Worker   if (!grouping.has_separator()) {
2472*5c90c05cSAndroid Build Coastguard Worker     return write_significand(out, significand, significand_size, integral_size,
2473*5c90c05cSAndroid Build Coastguard Worker                              decimal_point);
2474*5c90c05cSAndroid Build Coastguard Worker   }
2475*5c90c05cSAndroid Build Coastguard Worker   auto buffer = basic_memory_buffer<Char>();
2476*5c90c05cSAndroid Build Coastguard Worker   write_significand(basic_appender<Char>(buffer), significand, significand_size,
2477*5c90c05cSAndroid Build Coastguard Worker                     integral_size, decimal_point);
2478*5c90c05cSAndroid Build Coastguard Worker   grouping.apply(
2479*5c90c05cSAndroid Build Coastguard Worker       out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2480*5c90c05cSAndroid Build Coastguard Worker   return detail::copy_noinline<Char>(buffer.data() + integral_size,
2481*5c90c05cSAndroid Build Coastguard Worker                                      buffer.end(), out);
2482*5c90c05cSAndroid Build Coastguard Worker }
2483*5c90c05cSAndroid Build Coastguard Worker 
2484*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename DecimalFP,
2485*5c90c05cSAndroid Build Coastguard Worker           typename Grouping = digit_grouping<Char>>
2486*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2487*5c90c05cSAndroid Build Coastguard Worker                                     const format_specs& specs, sign s,
2488*5c90c05cSAndroid Build Coastguard Worker                                     locale_ref loc) -> OutputIt {
2489*5c90c05cSAndroid Build Coastguard Worker   auto significand = f.significand;
2490*5c90c05cSAndroid Build Coastguard Worker   int significand_size = get_significand_size(f);
2491*5c90c05cSAndroid Build Coastguard Worker   const Char zero = static_cast<Char>('0');
2492*5c90c05cSAndroid Build Coastguard Worker   size_t size = to_unsigned(significand_size) + (s != sign::none ? 1 : 0);
2493*5c90c05cSAndroid Build Coastguard Worker   using iterator = reserve_iterator<OutputIt>;
2494*5c90c05cSAndroid Build Coastguard Worker 
2495*5c90c05cSAndroid Build Coastguard Worker   Char decimal_point = specs.localized() ? detail::decimal_point<Char>(loc)
2496*5c90c05cSAndroid Build Coastguard Worker                                          : static_cast<Char>('.');
2497*5c90c05cSAndroid Build Coastguard Worker 
2498*5c90c05cSAndroid Build Coastguard Worker   int output_exp = f.exponent + significand_size - 1;
2499*5c90c05cSAndroid Build Coastguard Worker   auto use_exp_format = [=]() {
2500*5c90c05cSAndroid Build Coastguard Worker     if (specs.type() == presentation_type::exp) return true;
2501*5c90c05cSAndroid Build Coastguard Worker     if (specs.type() == presentation_type::fixed) return false;
2502*5c90c05cSAndroid Build Coastguard Worker     // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2503*5c90c05cSAndroid Build Coastguard Worker     // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2504*5c90c05cSAndroid Build Coastguard Worker     const int exp_lower = -4, exp_upper = 16;
2505*5c90c05cSAndroid Build Coastguard Worker     return output_exp < exp_lower ||
2506*5c90c05cSAndroid Build Coastguard Worker            output_exp >= (specs.precision > 0 ? specs.precision : exp_upper);
2507*5c90c05cSAndroid Build Coastguard Worker   };
2508*5c90c05cSAndroid Build Coastguard Worker   if (use_exp_format()) {
2509*5c90c05cSAndroid Build Coastguard Worker     int num_zeros = 0;
2510*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt()) {
2511*5c90c05cSAndroid Build Coastguard Worker       num_zeros = specs.precision - significand_size;
2512*5c90c05cSAndroid Build Coastguard Worker       if (num_zeros < 0) num_zeros = 0;
2513*5c90c05cSAndroid Build Coastguard Worker       size += to_unsigned(num_zeros);
2514*5c90c05cSAndroid Build Coastguard Worker     } else if (significand_size == 1) {
2515*5c90c05cSAndroid Build Coastguard Worker       decimal_point = Char();
2516*5c90c05cSAndroid Build Coastguard Worker     }
2517*5c90c05cSAndroid Build Coastguard Worker     auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2518*5c90c05cSAndroid Build Coastguard Worker     int exp_digits = 2;
2519*5c90c05cSAndroid Build Coastguard Worker     if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2520*5c90c05cSAndroid Build Coastguard Worker 
2521*5c90c05cSAndroid Build Coastguard Worker     size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2522*5c90c05cSAndroid Build Coastguard Worker     char exp_char = specs.upper() ? 'E' : 'e';
2523*5c90c05cSAndroid Build Coastguard Worker     auto write = [=](iterator it) {
2524*5c90c05cSAndroid Build Coastguard Worker       if (s != sign::none) *it++ = detail::getsign<Char>(s);
2525*5c90c05cSAndroid Build Coastguard Worker       // Insert a decimal point after the first digit and add an exponent.
2526*5c90c05cSAndroid Build Coastguard Worker       it = write_significand(it, significand, significand_size, 1,
2527*5c90c05cSAndroid Build Coastguard Worker                              decimal_point);
2528*5c90c05cSAndroid Build Coastguard Worker       if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2529*5c90c05cSAndroid Build Coastguard Worker       *it++ = static_cast<Char>(exp_char);
2530*5c90c05cSAndroid Build Coastguard Worker       return write_exponent<Char>(output_exp, it);
2531*5c90c05cSAndroid Build Coastguard Worker     };
2532*5c90c05cSAndroid Build Coastguard Worker     return specs.width > 0
2533*5c90c05cSAndroid Build Coastguard Worker                ? write_padded<Char, align::right>(out, specs, size, write)
2534*5c90c05cSAndroid Build Coastguard Worker                : base_iterator(out, write(reserve(out, size)));
2535*5c90c05cSAndroid Build Coastguard Worker   }
2536*5c90c05cSAndroid Build Coastguard Worker 
2537*5c90c05cSAndroid Build Coastguard Worker   int exp = f.exponent + significand_size;
2538*5c90c05cSAndroid Build Coastguard Worker   if (f.exponent >= 0) {
2539*5c90c05cSAndroid Build Coastguard Worker     // 1234e5 -> 123400000[.0+]
2540*5c90c05cSAndroid Build Coastguard Worker     size += to_unsigned(f.exponent);
2541*5c90c05cSAndroid Build Coastguard Worker     int num_zeros = specs.precision - exp;
2542*5c90c05cSAndroid Build Coastguard Worker     abort_fuzzing_if(num_zeros > 5000);
2543*5c90c05cSAndroid Build Coastguard Worker     if (specs.alt()) {
2544*5c90c05cSAndroid Build Coastguard Worker       ++size;
2545*5c90c05cSAndroid Build Coastguard Worker       if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2546*5c90c05cSAndroid Build Coastguard Worker         num_zeros = 0;
2547*5c90c05cSAndroid Build Coastguard Worker       if (num_zeros > 0) size += to_unsigned(num_zeros);
2548*5c90c05cSAndroid Build Coastguard Worker     }
2549*5c90c05cSAndroid Build Coastguard Worker     auto grouping = Grouping(loc, specs.localized());
2550*5c90c05cSAndroid Build Coastguard Worker     size += to_unsigned(grouping.count_separators(exp));
2551*5c90c05cSAndroid Build Coastguard Worker     return write_padded<Char, align::right>(out, specs, size, [&](iterator it) {
2552*5c90c05cSAndroid Build Coastguard Worker       if (s != sign::none) *it++ = detail::getsign<Char>(s);
2553*5c90c05cSAndroid Build Coastguard Worker       it = write_significand<Char>(it, significand, significand_size,
2554*5c90c05cSAndroid Build Coastguard Worker                                    f.exponent, grouping);
2555*5c90c05cSAndroid Build Coastguard Worker       if (!specs.alt()) return it;
2556*5c90c05cSAndroid Build Coastguard Worker       *it++ = decimal_point;
2557*5c90c05cSAndroid Build Coastguard Worker       return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2558*5c90c05cSAndroid Build Coastguard Worker     });
2559*5c90c05cSAndroid Build Coastguard Worker   } else if (exp > 0) {
2560*5c90c05cSAndroid Build Coastguard Worker     // 1234e-2 -> 12.34[0+]
2561*5c90c05cSAndroid Build Coastguard Worker     int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2562*5c90c05cSAndroid Build Coastguard Worker     size += 1 + static_cast<unsigned>(max_of(num_zeros, 0));
2563*5c90c05cSAndroid Build Coastguard Worker     auto grouping = Grouping(loc, specs.localized());
2564*5c90c05cSAndroid Build Coastguard Worker     size += to_unsigned(grouping.count_separators(exp));
2565*5c90c05cSAndroid Build Coastguard Worker     return write_padded<Char, align::right>(out, specs, size, [&](iterator it) {
2566*5c90c05cSAndroid Build Coastguard Worker       if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567*5c90c05cSAndroid Build Coastguard Worker       it = write_significand(it, significand, significand_size, exp,
2568*5c90c05cSAndroid Build Coastguard Worker                              decimal_point, grouping);
2569*5c90c05cSAndroid Build Coastguard Worker       return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2570*5c90c05cSAndroid Build Coastguard Worker     });
2571*5c90c05cSAndroid Build Coastguard Worker   }
2572*5c90c05cSAndroid Build Coastguard Worker   // 1234e-6 -> 0.001234
2573*5c90c05cSAndroid Build Coastguard Worker   int num_zeros = -exp;
2574*5c90c05cSAndroid Build Coastguard Worker   if (significand_size == 0 && specs.precision >= 0 &&
2575*5c90c05cSAndroid Build Coastguard Worker       specs.precision < num_zeros) {
2576*5c90c05cSAndroid Build Coastguard Worker     num_zeros = specs.precision;
2577*5c90c05cSAndroid Build Coastguard Worker   }
2578*5c90c05cSAndroid Build Coastguard Worker   bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2579*5c90c05cSAndroid Build Coastguard Worker   size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
2580*5c90c05cSAndroid Build Coastguard Worker   return write_padded<Char, align::right>(out, specs, size, [&](iterator it) {
2581*5c90c05cSAndroid Build Coastguard Worker     if (s != sign::none) *it++ = detail::getsign<Char>(s);
2582*5c90c05cSAndroid Build Coastguard Worker     *it++ = zero;
2583*5c90c05cSAndroid Build Coastguard Worker     if (!pointy) return it;
2584*5c90c05cSAndroid Build Coastguard Worker     *it++ = decimal_point;
2585*5c90c05cSAndroid Build Coastguard Worker     it = detail::fill_n(it, num_zeros, zero);
2586*5c90c05cSAndroid Build Coastguard Worker     return write_significand<Char>(it, significand, significand_size);
2587*5c90c05cSAndroid Build Coastguard Worker   });
2588*5c90c05cSAndroid Build Coastguard Worker }
2589*5c90c05cSAndroid Build Coastguard Worker 
2590*5c90c05cSAndroid Build Coastguard Worker template <typename Char> class fallback_digit_grouping {
2591*5c90c05cSAndroid Build Coastguard Worker  public:
2592*5c90c05cSAndroid Build Coastguard Worker   constexpr fallback_digit_grouping(locale_ref, bool) {}
2593*5c90c05cSAndroid Build Coastguard Worker 
2594*5c90c05cSAndroid Build Coastguard Worker   constexpr auto has_separator() const -> bool { return false; }
2595*5c90c05cSAndroid Build Coastguard Worker 
2596*5c90c05cSAndroid Build Coastguard Worker   constexpr auto count_separators(int) const -> int { return 0; }
2597*5c90c05cSAndroid Build Coastguard Worker 
2598*5c90c05cSAndroid Build Coastguard Worker   template <typename Out, typename C>
2599*5c90c05cSAndroid Build Coastguard Worker   constexpr auto apply(Out out, basic_string_view<C>) const -> Out {
2600*5c90c05cSAndroid Build Coastguard Worker     return out;
2601*5c90c05cSAndroid Build Coastguard Worker   }
2602*5c90c05cSAndroid Build Coastguard Worker };
2603*5c90c05cSAndroid Build Coastguard Worker 
2604*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename DecimalFP>
2605*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2606*5c90c05cSAndroid Build Coastguard Worker                                  const format_specs& specs, sign s,
2607*5c90c05cSAndroid Build Coastguard Worker                                  locale_ref loc) -> OutputIt {
2608*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) {
2609*5c90c05cSAndroid Build Coastguard Worker     return do_write_float<Char, OutputIt, DecimalFP,
2610*5c90c05cSAndroid Build Coastguard Worker                           fallback_digit_grouping<Char>>(out, f, specs, s, loc);
2611*5c90c05cSAndroid Build Coastguard Worker   } else {
2612*5c90c05cSAndroid Build Coastguard Worker     return do_write_float<Char>(out, f, specs, s, loc);
2613*5c90c05cSAndroid Build Coastguard Worker   }
2614*5c90c05cSAndroid Build Coastguard Worker }
2615*5c90c05cSAndroid Build Coastguard Worker 
2616*5c90c05cSAndroid Build Coastguard Worker template <typename T> constexpr auto isnan(T value) -> bool {
2617*5c90c05cSAndroid Build Coastguard Worker   return value != value;  // std::isnan doesn't support __float128.
2618*5c90c05cSAndroid Build Coastguard Worker }
2619*5c90c05cSAndroid Build Coastguard Worker 
2620*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Enable = void>
2621*5c90c05cSAndroid Build Coastguard Worker struct has_isfinite : std::false_type {};
2622*5c90c05cSAndroid Build Coastguard Worker 
2623*5c90c05cSAndroid Build Coastguard Worker template <typename T>
2624*5c90c05cSAndroid Build Coastguard Worker struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2625*5c90c05cSAndroid Build Coastguard Worker     : std::true_type {};
2626*5c90c05cSAndroid Build Coastguard Worker 
2627*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
2628*5c90c05cSAndroid Build Coastguard Worker                                         has_isfinite<T>::value)>
2629*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2630*5c90c05cSAndroid Build Coastguard Worker   constexpr T inf = T(std::numeric_limits<double>::infinity());
2631*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated(true))
2632*5c90c05cSAndroid Build Coastguard Worker     return !detail::isnan(value) && value < inf && value > -inf;
2633*5c90c05cSAndroid Build Coastguard Worker   return std::isfinite(value);
2634*5c90c05cSAndroid Build Coastguard Worker }
2635*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2636*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto isfinite(T value) -> bool {
2637*5c90c05cSAndroid Build Coastguard Worker   T inf = T(std::numeric_limits<double>::infinity());
2638*5c90c05cSAndroid Build Coastguard Worker   // std::isfinite doesn't support __float128.
2639*5c90c05cSAndroid Build Coastguard Worker   return !detail::isnan(value) && value < inf && value > -inf;
2640*5c90c05cSAndroid Build Coastguard Worker }
2641*5c90c05cSAndroid Build Coastguard Worker 
2642*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2643*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE FMT_CONSTEXPR bool signbit(T value) {
2644*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) {
2645*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_if_constexpr
2646*5c90c05cSAndroid Build Coastguard Worker     if constexpr (std::numeric_limits<double>::is_iec559) {
2647*5c90c05cSAndroid Build Coastguard Worker       auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2648*5c90c05cSAndroid Build Coastguard Worker       return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2649*5c90c05cSAndroid Build Coastguard Worker     }
2650*5c90c05cSAndroid Build Coastguard Worker #endif
2651*5c90c05cSAndroid Build Coastguard Worker   }
2652*5c90c05cSAndroid Build Coastguard Worker   return std::signbit(static_cast<double>(value));
2653*5c90c05cSAndroid Build Coastguard Worker }
2654*5c90c05cSAndroid Build Coastguard Worker 
2655*5c90c05cSAndroid Build Coastguard Worker inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2656*5c90c05cSAndroid Build Coastguard Worker   // Adjust fixed precision by exponent because it is relative to decimal
2657*5c90c05cSAndroid Build Coastguard Worker   // point.
2658*5c90c05cSAndroid Build Coastguard Worker   if (exp10 > 0 && precision > max_value<int>() - exp10)
2659*5c90c05cSAndroid Build Coastguard Worker     FMT_THROW(format_error("number is too big"));
2660*5c90c05cSAndroid Build Coastguard Worker   precision += exp10;
2661*5c90c05cSAndroid Build Coastguard Worker }
2662*5c90c05cSAndroid Build Coastguard Worker 
2663*5c90c05cSAndroid Build Coastguard Worker class bigint {
2664*5c90c05cSAndroid Build Coastguard Worker  private:
2665*5c90c05cSAndroid Build Coastguard Worker   // A bigint is a number in the form bigit_[N - 1] ... bigit_[0] * 32^exp_.
2666*5c90c05cSAndroid Build Coastguard Worker   using bigit = uint32_t;  // A big digit.
2667*5c90c05cSAndroid Build Coastguard Worker   using double_bigit = uint64_t;
2668*5c90c05cSAndroid Build Coastguard Worker   enum { bigit_bits = num_bits<bigit>() };
2669*5c90c05cSAndroid Build Coastguard Worker   enum { bigits_capacity = 32 };
2670*5c90c05cSAndroid Build Coastguard Worker   basic_memory_buffer<bigit, bigits_capacity> bigits_;
2671*5c90c05cSAndroid Build Coastguard Worker   int exp_;
2672*5c90c05cSAndroid Build Coastguard Worker 
2673*5c90c05cSAndroid Build Coastguard Worker   friend struct formatter<bigint>;
2674*5c90c05cSAndroid Build Coastguard Worker 
2675*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto get_bigit(int i) const -> bigit {
2676*5c90c05cSAndroid Build Coastguard Worker     return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0;
2677*5c90c05cSAndroid Build Coastguard Worker   }
2678*5c90c05cSAndroid Build Coastguard Worker 
2679*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) {
2680*5c90c05cSAndroid Build Coastguard Worker     auto result = double_bigit(bigits_[index]) - other - borrow;
2681*5c90c05cSAndroid Build Coastguard Worker     bigits_[index] = static_cast<bigit>(result);
2682*5c90c05cSAndroid Build Coastguard Worker     borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2683*5c90c05cSAndroid Build Coastguard Worker   }
2684*5c90c05cSAndroid Build Coastguard Worker 
2685*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void remove_leading_zeros() {
2686*5c90c05cSAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size()) - 1;
2687*5c90c05cSAndroid Build Coastguard Worker     while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits;
2688*5c90c05cSAndroid Build Coastguard Worker     bigits_.resize(to_unsigned(num_bigits + 1));
2689*5c90c05cSAndroid Build Coastguard Worker   }
2690*5c90c05cSAndroid Build Coastguard Worker 
2691*5c90c05cSAndroid Build Coastguard Worker   // Computes *this -= other assuming aligned bigints and *this >= other.
2692*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void subtract_aligned(const bigint& other) {
2693*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2694*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(compare(*this, other) >= 0, "");
2695*5c90c05cSAndroid Build Coastguard Worker     bigit borrow = 0;
2696*5c90c05cSAndroid Build Coastguard Worker     int i = other.exp_ - exp_;
2697*5c90c05cSAndroid Build Coastguard Worker     for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2698*5c90c05cSAndroid Build Coastguard Worker       subtract_bigits(i, other.bigits_[j], borrow);
2699*5c90c05cSAndroid Build Coastguard Worker     if (borrow != 0) subtract_bigits(i, 0, borrow);
2700*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(borrow == 0, "");
2701*5c90c05cSAndroid Build Coastguard Worker     remove_leading_zeros();
2702*5c90c05cSAndroid Build Coastguard Worker   }
2703*5c90c05cSAndroid Build Coastguard Worker 
2704*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void multiply(uint32_t value) {
2705*5c90c05cSAndroid Build Coastguard Worker     bigit carry = 0;
2706*5c90c05cSAndroid Build Coastguard Worker     const double_bigit wide_value = value;
2707*5c90c05cSAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2708*5c90c05cSAndroid Build Coastguard Worker       double_bigit result = bigits_[i] * wide_value + carry;
2709*5c90c05cSAndroid Build Coastguard Worker       bigits_[i] = static_cast<bigit>(result);
2710*5c90c05cSAndroid Build Coastguard Worker       carry = static_cast<bigit>(result >> bigit_bits);
2711*5c90c05cSAndroid Build Coastguard Worker     }
2712*5c90c05cSAndroid Build Coastguard Worker     if (carry != 0) bigits_.push_back(carry);
2713*5c90c05cSAndroid Build Coastguard Worker   }
2714*5c90c05cSAndroid Build Coastguard Worker 
2715*5c90c05cSAndroid Build Coastguard Worker   template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2716*5c90c05cSAndroid Build Coastguard Worker                                          std::is_same<UInt, uint128_t>::value)>
2717*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void multiply(UInt value) {
2718*5c90c05cSAndroid Build Coastguard Worker     using half_uint =
2719*5c90c05cSAndroid Build Coastguard Worker         conditional_t<std::is_same<UInt, uint128_t>::value, uint64_t, uint32_t>;
2720*5c90c05cSAndroid Build Coastguard Worker     const int shift = num_bits<half_uint>() - bigit_bits;
2721*5c90c05cSAndroid Build Coastguard Worker     const UInt lower = static_cast<half_uint>(value);
2722*5c90c05cSAndroid Build Coastguard Worker     const UInt upper = value >> num_bits<half_uint>();
2723*5c90c05cSAndroid Build Coastguard Worker     UInt carry = 0;
2724*5c90c05cSAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2725*5c90c05cSAndroid Build Coastguard Worker       UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2726*5c90c05cSAndroid Build Coastguard Worker       carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2727*5c90c05cSAndroid Build Coastguard Worker               (carry >> bigit_bits);
2728*5c90c05cSAndroid Build Coastguard Worker       bigits_[i] = static_cast<bigit>(result);
2729*5c90c05cSAndroid Build Coastguard Worker     }
2730*5c90c05cSAndroid Build Coastguard Worker     while (carry != 0) {
2731*5c90c05cSAndroid Build Coastguard Worker       bigits_.push_back(static_cast<bigit>(carry));
2732*5c90c05cSAndroid Build Coastguard Worker       carry >>= bigit_bits;
2733*5c90c05cSAndroid Build Coastguard Worker     }
2734*5c90c05cSAndroid Build Coastguard Worker   }
2735*5c90c05cSAndroid Build Coastguard Worker 
2736*5c90c05cSAndroid Build Coastguard Worker   template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2737*5c90c05cSAndroid Build Coastguard Worker                                          std::is_same<UInt, uint128_t>::value)>
2738*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void assign(UInt n) {
2739*5c90c05cSAndroid Build Coastguard Worker     size_t num_bigits = 0;
2740*5c90c05cSAndroid Build Coastguard Worker     do {
2741*5c90c05cSAndroid Build Coastguard Worker       bigits_[num_bigits++] = static_cast<bigit>(n);
2742*5c90c05cSAndroid Build Coastguard Worker       n >>= bigit_bits;
2743*5c90c05cSAndroid Build Coastguard Worker     } while (n != 0);
2744*5c90c05cSAndroid Build Coastguard Worker     bigits_.resize(num_bigits);
2745*5c90c05cSAndroid Build Coastguard Worker     exp_ = 0;
2746*5c90c05cSAndroid Build Coastguard Worker   }
2747*5c90c05cSAndroid Build Coastguard Worker 
2748*5c90c05cSAndroid Build Coastguard Worker  public:
2749*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR bigint() : exp_(0) {}
2750*5c90c05cSAndroid Build Coastguard Worker   explicit bigint(uint64_t n) { assign(n); }
2751*5c90c05cSAndroid Build Coastguard Worker 
2752*5c90c05cSAndroid Build Coastguard Worker   bigint(const bigint&) = delete;
2753*5c90c05cSAndroid Build Coastguard Worker   void operator=(const bigint&) = delete;
2754*5c90c05cSAndroid Build Coastguard Worker 
2755*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void assign(const bigint& other) {
2756*5c90c05cSAndroid Build Coastguard Worker     auto size = other.bigits_.size();
2757*5c90c05cSAndroid Build Coastguard Worker     bigits_.resize(size);
2758*5c90c05cSAndroid Build Coastguard Worker     auto data = other.bigits_.data();
2759*5c90c05cSAndroid Build Coastguard Worker     copy<bigit>(data, data + size, bigits_.data());
2760*5c90c05cSAndroid Build Coastguard Worker     exp_ = other.exp_;
2761*5c90c05cSAndroid Build Coastguard Worker   }
2762*5c90c05cSAndroid Build Coastguard Worker 
2763*5c90c05cSAndroid Build Coastguard Worker   template <typename Int> FMT_CONSTEXPR void operator=(Int n) {
2764*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(n > 0, "");
2765*5c90c05cSAndroid Build Coastguard Worker     assign(uint64_or_128_t<Int>(n));
2766*5c90c05cSAndroid Build Coastguard Worker   }
2767*5c90c05cSAndroid Build Coastguard Worker 
2768*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto num_bigits() const -> int {
2769*5c90c05cSAndroid Build Coastguard Worker     return static_cast<int>(bigits_.size()) + exp_;
2770*5c90c05cSAndroid Build Coastguard Worker   }
2771*5c90c05cSAndroid Build Coastguard Worker 
2772*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator<<=(int shift) -> bigint& {
2773*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(shift >= 0, "");
2774*5c90c05cSAndroid Build Coastguard Worker     exp_ += shift / bigit_bits;
2775*5c90c05cSAndroid Build Coastguard Worker     shift %= bigit_bits;
2776*5c90c05cSAndroid Build Coastguard Worker     if (shift == 0) return *this;
2777*5c90c05cSAndroid Build Coastguard Worker     bigit carry = 0;
2778*5c90c05cSAndroid Build Coastguard Worker     for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2779*5c90c05cSAndroid Build Coastguard Worker       bigit c = bigits_[i] >> (bigit_bits - shift);
2780*5c90c05cSAndroid Build Coastguard Worker       bigits_[i] = (bigits_[i] << shift) + carry;
2781*5c90c05cSAndroid Build Coastguard Worker       carry = c;
2782*5c90c05cSAndroid Build Coastguard Worker     }
2783*5c90c05cSAndroid Build Coastguard Worker     if (carry != 0) bigits_.push_back(carry);
2784*5c90c05cSAndroid Build Coastguard Worker     return *this;
2785*5c90c05cSAndroid Build Coastguard Worker   }
2786*5c90c05cSAndroid Build Coastguard Worker 
2787*5c90c05cSAndroid Build Coastguard Worker   template <typename Int> FMT_CONSTEXPR auto operator*=(Int value) -> bigint& {
2788*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(value > 0, "");
2789*5c90c05cSAndroid Build Coastguard Worker     multiply(uint32_or_64_or_128_t<Int>(value));
2790*5c90c05cSAndroid Build Coastguard Worker     return *this;
2791*5c90c05cSAndroid Build Coastguard Worker   }
2792*5c90c05cSAndroid Build Coastguard Worker 
2793*5c90c05cSAndroid Build Coastguard Worker   friend FMT_CONSTEXPR auto compare(const bigint& b1, const bigint& b2) -> int {
2794*5c90c05cSAndroid Build Coastguard Worker     int num_bigits1 = b1.num_bigits(), num_bigits2 = b2.num_bigits();
2795*5c90c05cSAndroid Build Coastguard Worker     if (num_bigits1 != num_bigits2) return num_bigits1 > num_bigits2 ? 1 : -1;
2796*5c90c05cSAndroid Build Coastguard Worker     int i = static_cast<int>(b1.bigits_.size()) - 1;
2797*5c90c05cSAndroid Build Coastguard Worker     int j = static_cast<int>(b2.bigits_.size()) - 1;
2798*5c90c05cSAndroid Build Coastguard Worker     int end = i - j;
2799*5c90c05cSAndroid Build Coastguard Worker     if (end < 0) end = 0;
2800*5c90c05cSAndroid Build Coastguard Worker     for (; i >= end; --i, --j) {
2801*5c90c05cSAndroid Build Coastguard Worker       bigit b1_bigit = b1.bigits_[i], b2_bigit = b2.bigits_[j];
2802*5c90c05cSAndroid Build Coastguard Worker       if (b1_bigit != b2_bigit) return b1_bigit > b2_bigit ? 1 : -1;
2803*5c90c05cSAndroid Build Coastguard Worker     }
2804*5c90c05cSAndroid Build Coastguard Worker     if (i != j) return i > j ? 1 : -1;
2805*5c90c05cSAndroid Build Coastguard Worker     return 0;
2806*5c90c05cSAndroid Build Coastguard Worker   }
2807*5c90c05cSAndroid Build Coastguard Worker 
2808*5c90c05cSAndroid Build Coastguard Worker   // Returns compare(lhs1 + lhs2, rhs).
2809*5c90c05cSAndroid Build Coastguard Worker   friend FMT_CONSTEXPR auto add_compare(const bigint& lhs1, const bigint& lhs2,
2810*5c90c05cSAndroid Build Coastguard Worker                                         const bigint& rhs) -> int {
2811*5c90c05cSAndroid Build Coastguard Worker     int max_lhs_bigits = max_of(lhs1.num_bigits(), lhs2.num_bigits());
2812*5c90c05cSAndroid Build Coastguard Worker     int num_rhs_bigits = rhs.num_bigits();
2813*5c90c05cSAndroid Build Coastguard Worker     if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2814*5c90c05cSAndroid Build Coastguard Worker     if (max_lhs_bigits > num_rhs_bigits) return 1;
2815*5c90c05cSAndroid Build Coastguard Worker     double_bigit borrow = 0;
2816*5c90c05cSAndroid Build Coastguard Worker     int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_);
2817*5c90c05cSAndroid Build Coastguard Worker     for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2818*5c90c05cSAndroid Build Coastguard Worker       double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i);
2819*5c90c05cSAndroid Build Coastguard Worker       bigit rhs_bigit = rhs.get_bigit(i);
2820*5c90c05cSAndroid Build Coastguard Worker       if (sum > rhs_bigit + borrow) return 1;
2821*5c90c05cSAndroid Build Coastguard Worker       borrow = rhs_bigit + borrow - sum;
2822*5c90c05cSAndroid Build Coastguard Worker       if (borrow > 1) return -1;
2823*5c90c05cSAndroid Build Coastguard Worker       borrow <<= bigit_bits;
2824*5c90c05cSAndroid Build Coastguard Worker     }
2825*5c90c05cSAndroid Build Coastguard Worker     return borrow != 0 ? -1 : 0;
2826*5c90c05cSAndroid Build Coastguard Worker   }
2827*5c90c05cSAndroid Build Coastguard Worker 
2828*5c90c05cSAndroid Build Coastguard Worker   // Assigns pow(10, exp) to this bigint.
2829*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 void assign_pow10(int exp) {
2830*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(exp >= 0, "");
2831*5c90c05cSAndroid Build Coastguard Worker     if (exp == 0) return *this = 1;
2832*5c90c05cSAndroid Build Coastguard Worker     int bitmask = 1 << (num_bits<unsigned>() -
2833*5c90c05cSAndroid Build Coastguard Worker                         countl_zero(static_cast<uint32_t>(exp)) - 1);
2834*5c90c05cSAndroid Build Coastguard Worker     // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2835*5c90c05cSAndroid Build Coastguard Worker     // repeated squaring and multiplication.
2836*5c90c05cSAndroid Build Coastguard Worker     *this = 5;
2837*5c90c05cSAndroid Build Coastguard Worker     bitmask >>= 1;
2838*5c90c05cSAndroid Build Coastguard Worker     while (bitmask != 0) {
2839*5c90c05cSAndroid Build Coastguard Worker       square();
2840*5c90c05cSAndroid Build Coastguard Worker       if ((exp & bitmask) != 0) *this *= 5;
2841*5c90c05cSAndroid Build Coastguard Worker       bitmask >>= 1;
2842*5c90c05cSAndroid Build Coastguard Worker     }
2843*5c90c05cSAndroid Build Coastguard Worker     *this <<= exp;  // Multiply by pow(2, exp) by shifting.
2844*5c90c05cSAndroid Build Coastguard Worker   }
2845*5c90c05cSAndroid Build Coastguard Worker 
2846*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 void square() {
2847*5c90c05cSAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size());
2848*5c90c05cSAndroid Build Coastguard Worker     int num_result_bigits = 2 * num_bigits;
2849*5c90c05cSAndroid Build Coastguard Worker     basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
2850*5c90c05cSAndroid Build Coastguard Worker     bigits_.resize(to_unsigned(num_result_bigits));
2851*5c90c05cSAndroid Build Coastguard Worker     auto sum = uint128_t();
2852*5c90c05cSAndroid Build Coastguard Worker     for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2853*5c90c05cSAndroid Build Coastguard Worker       // Compute bigit at position bigit_index of the result by adding
2854*5c90c05cSAndroid Build Coastguard Worker       // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2855*5c90c05cSAndroid Build Coastguard Worker       for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2856*5c90c05cSAndroid Build Coastguard Worker         // Most terms are multiplied twice which can be optimized in the future.
2857*5c90c05cSAndroid Build Coastguard Worker         sum += double_bigit(n[i]) * n[j];
2858*5c90c05cSAndroid Build Coastguard Worker       }
2859*5c90c05cSAndroid Build Coastguard Worker       bigits_[bigit_index] = static_cast<bigit>(sum);
2860*5c90c05cSAndroid Build Coastguard Worker       sum >>= num_bits<bigit>();  // Compute the carry.
2861*5c90c05cSAndroid Build Coastguard Worker     }
2862*5c90c05cSAndroid Build Coastguard Worker     // Do the same for the top half.
2863*5c90c05cSAndroid Build Coastguard Worker     for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2864*5c90c05cSAndroid Build Coastguard Worker          ++bigit_index) {
2865*5c90c05cSAndroid Build Coastguard Worker       for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
2866*5c90c05cSAndroid Build Coastguard Worker         sum += double_bigit(n[i++]) * n[j--];
2867*5c90c05cSAndroid Build Coastguard Worker       bigits_[bigit_index] = static_cast<bigit>(sum);
2868*5c90c05cSAndroid Build Coastguard Worker       sum >>= num_bits<bigit>();
2869*5c90c05cSAndroid Build Coastguard Worker     }
2870*5c90c05cSAndroid Build Coastguard Worker     remove_leading_zeros();
2871*5c90c05cSAndroid Build Coastguard Worker     exp_ *= 2;
2872*5c90c05cSAndroid Build Coastguard Worker   }
2873*5c90c05cSAndroid Build Coastguard Worker 
2874*5c90c05cSAndroid Build Coastguard Worker   // If this bigint has a bigger exponent than other, adds trailing zero to make
2875*5c90c05cSAndroid Build Coastguard Worker   // exponents equal. This simplifies some operations such as subtraction.
2876*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR void align(const bigint& other) {
2877*5c90c05cSAndroid Build Coastguard Worker     int exp_difference = exp_ - other.exp_;
2878*5c90c05cSAndroid Build Coastguard Worker     if (exp_difference <= 0) return;
2879*5c90c05cSAndroid Build Coastguard Worker     int num_bigits = static_cast<int>(bigits_.size());
2880*5c90c05cSAndroid Build Coastguard Worker     bigits_.resize(to_unsigned(num_bigits + exp_difference));
2881*5c90c05cSAndroid Build Coastguard Worker     for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
2882*5c90c05cSAndroid Build Coastguard Worker       bigits_[j] = bigits_[i];
2883*5c90c05cSAndroid Build Coastguard Worker     memset(bigits_.data(), 0, to_unsigned(exp_difference) * sizeof(bigit));
2884*5c90c05cSAndroid Build Coastguard Worker     exp_ -= exp_difference;
2885*5c90c05cSAndroid Build Coastguard Worker   }
2886*5c90c05cSAndroid Build Coastguard Worker 
2887*5c90c05cSAndroid Build Coastguard Worker   // Divides this bignum by divisor, assigning the remainder to this and
2888*5c90c05cSAndroid Build Coastguard Worker   // returning the quotient.
2889*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto divmod_assign(const bigint& divisor) -> int {
2890*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(this != &divisor, "");
2891*5c90c05cSAndroid Build Coastguard Worker     if (compare(*this, divisor) < 0) return 0;
2892*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
2893*5c90c05cSAndroid Build Coastguard Worker     align(divisor);
2894*5c90c05cSAndroid Build Coastguard Worker     int quotient = 0;
2895*5c90c05cSAndroid Build Coastguard Worker     do {
2896*5c90c05cSAndroid Build Coastguard Worker       subtract_aligned(divisor);
2897*5c90c05cSAndroid Build Coastguard Worker       ++quotient;
2898*5c90c05cSAndroid Build Coastguard Worker     } while (compare(*this, divisor) >= 0);
2899*5c90c05cSAndroid Build Coastguard Worker     return quotient;
2900*5c90c05cSAndroid Build Coastguard Worker   }
2901*5c90c05cSAndroid Build Coastguard Worker };
2902*5c90c05cSAndroid Build Coastguard Worker 
2903*5c90c05cSAndroid Build Coastguard Worker // format_dragon flags.
2904*5c90c05cSAndroid Build Coastguard Worker enum dragon {
2905*5c90c05cSAndroid Build Coastguard Worker   predecessor_closer = 1,
2906*5c90c05cSAndroid Build Coastguard Worker   fixup = 2,  // Run fixup to correct exp10 which can be off by one.
2907*5c90c05cSAndroid Build Coastguard Worker   fixed = 4,
2908*5c90c05cSAndroid Build Coastguard Worker };
2909*5c90c05cSAndroid Build Coastguard Worker 
2910*5c90c05cSAndroid Build Coastguard Worker // Formats a floating-point number using a variation of the Fixed-Precision
2911*5c90c05cSAndroid Build Coastguard Worker // Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
2912*5c90c05cSAndroid Build Coastguard Worker // https://fmt.dev/papers/p372-steele.pdf.
2913*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value,
2914*5c90c05cSAndroid Build Coastguard Worker                                           unsigned flags, int num_digits,
2915*5c90c05cSAndroid Build Coastguard Worker                                           buffer<char>& buf, int& exp10) {
2916*5c90c05cSAndroid Build Coastguard Worker   bigint numerator;    // 2 * R in (FPP)^2.
2917*5c90c05cSAndroid Build Coastguard Worker   bigint denominator;  // 2 * S in (FPP)^2.
2918*5c90c05cSAndroid Build Coastguard Worker   // lower and upper are differences between value and corresponding boundaries.
2919*5c90c05cSAndroid Build Coastguard Worker   bigint lower;             // (M^- in (FPP)^2).
2920*5c90c05cSAndroid Build Coastguard Worker   bigint upper_store;       // upper's value if different from lower.
2921*5c90c05cSAndroid Build Coastguard Worker   bigint* upper = nullptr;  // (M^+ in (FPP)^2).
2922*5c90c05cSAndroid Build Coastguard Worker   // Shift numerator and denominator by an extra bit or two (if lower boundary
2923*5c90c05cSAndroid Build Coastguard Worker   // is closer) to make lower and upper integers. This eliminates multiplication
2924*5c90c05cSAndroid Build Coastguard Worker   // by 2 during later computations.
2925*5c90c05cSAndroid Build Coastguard Worker   bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
2926*5c90c05cSAndroid Build Coastguard Worker   int shift = is_predecessor_closer ? 2 : 1;
2927*5c90c05cSAndroid Build Coastguard Worker   if (value.e >= 0) {
2928*5c90c05cSAndroid Build Coastguard Worker     numerator = value.f;
2929*5c90c05cSAndroid Build Coastguard Worker     numerator <<= value.e + shift;
2930*5c90c05cSAndroid Build Coastguard Worker     lower = 1;
2931*5c90c05cSAndroid Build Coastguard Worker     lower <<= value.e;
2932*5c90c05cSAndroid Build Coastguard Worker     if (is_predecessor_closer) {
2933*5c90c05cSAndroid Build Coastguard Worker       upper_store = 1;
2934*5c90c05cSAndroid Build Coastguard Worker       upper_store <<= value.e + 1;
2935*5c90c05cSAndroid Build Coastguard Worker       upper = &upper_store;
2936*5c90c05cSAndroid Build Coastguard Worker     }
2937*5c90c05cSAndroid Build Coastguard Worker     denominator.assign_pow10(exp10);
2938*5c90c05cSAndroid Build Coastguard Worker     denominator <<= shift;
2939*5c90c05cSAndroid Build Coastguard Worker   } else if (exp10 < 0) {
2940*5c90c05cSAndroid Build Coastguard Worker     numerator.assign_pow10(-exp10);
2941*5c90c05cSAndroid Build Coastguard Worker     lower.assign(numerator);
2942*5c90c05cSAndroid Build Coastguard Worker     if (is_predecessor_closer) {
2943*5c90c05cSAndroid Build Coastguard Worker       upper_store.assign(numerator);
2944*5c90c05cSAndroid Build Coastguard Worker       upper_store <<= 1;
2945*5c90c05cSAndroid Build Coastguard Worker       upper = &upper_store;
2946*5c90c05cSAndroid Build Coastguard Worker     }
2947*5c90c05cSAndroid Build Coastguard Worker     numerator *= value.f;
2948*5c90c05cSAndroid Build Coastguard Worker     numerator <<= shift;
2949*5c90c05cSAndroid Build Coastguard Worker     denominator = 1;
2950*5c90c05cSAndroid Build Coastguard Worker     denominator <<= shift - value.e;
2951*5c90c05cSAndroid Build Coastguard Worker   } else {
2952*5c90c05cSAndroid Build Coastguard Worker     numerator = value.f;
2953*5c90c05cSAndroid Build Coastguard Worker     numerator <<= shift;
2954*5c90c05cSAndroid Build Coastguard Worker     denominator.assign_pow10(exp10);
2955*5c90c05cSAndroid Build Coastguard Worker     denominator <<= shift - value.e;
2956*5c90c05cSAndroid Build Coastguard Worker     lower = 1;
2957*5c90c05cSAndroid Build Coastguard Worker     if (is_predecessor_closer) {
2958*5c90c05cSAndroid Build Coastguard Worker       upper_store = 1ULL << 1;
2959*5c90c05cSAndroid Build Coastguard Worker       upper = &upper_store;
2960*5c90c05cSAndroid Build Coastguard Worker     }
2961*5c90c05cSAndroid Build Coastguard Worker   }
2962*5c90c05cSAndroid Build Coastguard Worker   int even = static_cast<int>((value.f & 1) == 0);
2963*5c90c05cSAndroid Build Coastguard Worker   if (!upper) upper = &lower;
2964*5c90c05cSAndroid Build Coastguard Worker   bool shortest = num_digits < 0;
2965*5c90c05cSAndroid Build Coastguard Worker   if ((flags & dragon::fixup) != 0) {
2966*5c90c05cSAndroid Build Coastguard Worker     if (add_compare(numerator, *upper, denominator) + even <= 0) {
2967*5c90c05cSAndroid Build Coastguard Worker       --exp10;
2968*5c90c05cSAndroid Build Coastguard Worker       numerator *= 10;
2969*5c90c05cSAndroid Build Coastguard Worker       if (num_digits < 0) {
2970*5c90c05cSAndroid Build Coastguard Worker         lower *= 10;
2971*5c90c05cSAndroid Build Coastguard Worker         if (upper != &lower) *upper *= 10;
2972*5c90c05cSAndroid Build Coastguard Worker       }
2973*5c90c05cSAndroid Build Coastguard Worker     }
2974*5c90c05cSAndroid Build Coastguard Worker     if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
2975*5c90c05cSAndroid Build Coastguard Worker   }
2976*5c90c05cSAndroid Build Coastguard Worker   // Invariant: value == (numerator / denominator) * pow(10, exp10).
2977*5c90c05cSAndroid Build Coastguard Worker   if (shortest) {
2978*5c90c05cSAndroid Build Coastguard Worker     // Generate the shortest representation.
2979*5c90c05cSAndroid Build Coastguard Worker     num_digits = 0;
2980*5c90c05cSAndroid Build Coastguard Worker     char* data = buf.data();
2981*5c90c05cSAndroid Build Coastguard Worker     for (;;) {
2982*5c90c05cSAndroid Build Coastguard Worker       int digit = numerator.divmod_assign(denominator);
2983*5c90c05cSAndroid Build Coastguard Worker       bool low = compare(numerator, lower) - even < 0;  // numerator <[=] lower.
2984*5c90c05cSAndroid Build Coastguard Worker       // numerator + upper >[=] pow10:
2985*5c90c05cSAndroid Build Coastguard Worker       bool high = add_compare(numerator, *upper, denominator) + even > 0;
2986*5c90c05cSAndroid Build Coastguard Worker       data[num_digits++] = static_cast<char>('0' + digit);
2987*5c90c05cSAndroid Build Coastguard Worker       if (low || high) {
2988*5c90c05cSAndroid Build Coastguard Worker         if (!low) {
2989*5c90c05cSAndroid Build Coastguard Worker           ++data[num_digits - 1];
2990*5c90c05cSAndroid Build Coastguard Worker         } else if (high) {
2991*5c90c05cSAndroid Build Coastguard Worker           int result = add_compare(numerator, numerator, denominator);
2992*5c90c05cSAndroid Build Coastguard Worker           // Round half to even.
2993*5c90c05cSAndroid Build Coastguard Worker           if (result > 0 || (result == 0 && (digit % 2) != 0))
2994*5c90c05cSAndroid Build Coastguard Worker             ++data[num_digits - 1];
2995*5c90c05cSAndroid Build Coastguard Worker         }
2996*5c90c05cSAndroid Build Coastguard Worker         buf.try_resize(to_unsigned(num_digits));
2997*5c90c05cSAndroid Build Coastguard Worker         exp10 -= num_digits - 1;
2998*5c90c05cSAndroid Build Coastguard Worker         return;
2999*5c90c05cSAndroid Build Coastguard Worker       }
3000*5c90c05cSAndroid Build Coastguard Worker       numerator *= 10;
3001*5c90c05cSAndroid Build Coastguard Worker       lower *= 10;
3002*5c90c05cSAndroid Build Coastguard Worker       if (upper != &lower) *upper *= 10;
3003*5c90c05cSAndroid Build Coastguard Worker     }
3004*5c90c05cSAndroid Build Coastguard Worker   }
3005*5c90c05cSAndroid Build Coastguard Worker   // Generate the given number of digits.
3006*5c90c05cSAndroid Build Coastguard Worker   exp10 -= num_digits - 1;
3007*5c90c05cSAndroid Build Coastguard Worker   if (num_digits <= 0) {
3008*5c90c05cSAndroid Build Coastguard Worker     auto digit = '0';
3009*5c90c05cSAndroid Build Coastguard Worker     if (num_digits == 0) {
3010*5c90c05cSAndroid Build Coastguard Worker       denominator *= 10;
3011*5c90c05cSAndroid Build Coastguard Worker       digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3012*5c90c05cSAndroid Build Coastguard Worker     }
3013*5c90c05cSAndroid Build Coastguard Worker     buf.push_back(digit);
3014*5c90c05cSAndroid Build Coastguard Worker     return;
3015*5c90c05cSAndroid Build Coastguard Worker   }
3016*5c90c05cSAndroid Build Coastguard Worker   buf.try_resize(to_unsigned(num_digits));
3017*5c90c05cSAndroid Build Coastguard Worker   for (int i = 0; i < num_digits - 1; ++i) {
3018*5c90c05cSAndroid Build Coastguard Worker     int digit = numerator.divmod_assign(denominator);
3019*5c90c05cSAndroid Build Coastguard Worker     buf[i] = static_cast<char>('0' + digit);
3020*5c90c05cSAndroid Build Coastguard Worker     numerator *= 10;
3021*5c90c05cSAndroid Build Coastguard Worker   }
3022*5c90c05cSAndroid Build Coastguard Worker   int digit = numerator.divmod_assign(denominator);
3023*5c90c05cSAndroid Build Coastguard Worker   auto result = add_compare(numerator, numerator, denominator);
3024*5c90c05cSAndroid Build Coastguard Worker   if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3025*5c90c05cSAndroid Build Coastguard Worker     if (digit == 9) {
3026*5c90c05cSAndroid Build Coastguard Worker       const auto overflow = '0' + 10;
3027*5c90c05cSAndroid Build Coastguard Worker       buf[num_digits - 1] = overflow;
3028*5c90c05cSAndroid Build Coastguard Worker       // Propagate the carry.
3029*5c90c05cSAndroid Build Coastguard Worker       for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3030*5c90c05cSAndroid Build Coastguard Worker         buf[i] = '0';
3031*5c90c05cSAndroid Build Coastguard Worker         ++buf[i - 1];
3032*5c90c05cSAndroid Build Coastguard Worker       }
3033*5c90c05cSAndroid Build Coastguard Worker       if (buf[0] == overflow) {
3034*5c90c05cSAndroid Build Coastguard Worker         buf[0] = '1';
3035*5c90c05cSAndroid Build Coastguard Worker         if ((flags & dragon::fixed) != 0)
3036*5c90c05cSAndroid Build Coastguard Worker           buf.push_back('0');
3037*5c90c05cSAndroid Build Coastguard Worker         else
3038*5c90c05cSAndroid Build Coastguard Worker           ++exp10;
3039*5c90c05cSAndroid Build Coastguard Worker       }
3040*5c90c05cSAndroid Build Coastguard Worker       return;
3041*5c90c05cSAndroid Build Coastguard Worker     }
3042*5c90c05cSAndroid Build Coastguard Worker     ++digit;
3043*5c90c05cSAndroid Build Coastguard Worker   }
3044*5c90c05cSAndroid Build Coastguard Worker   buf[num_digits - 1] = static_cast<char>('0' + digit);
3045*5c90c05cSAndroid Build Coastguard Worker }
3046*5c90c05cSAndroid Build Coastguard Worker 
3047*5c90c05cSAndroid Build Coastguard Worker // Formats a floating-point number using the hexfloat format.
3048*5c90c05cSAndroid Build Coastguard Worker template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
3049*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,
3050*5c90c05cSAndroid Build Coastguard Worker                                      buffer<char>& buf) {
3051*5c90c05cSAndroid Build Coastguard Worker   // float is passed as double to reduce the number of instantiations and to
3052*5c90c05cSAndroid Build Coastguard Worker   // simplify implementation.
3053*5c90c05cSAndroid Build Coastguard Worker   static_assert(!std::is_same<Float, float>::value, "");
3054*5c90c05cSAndroid Build Coastguard Worker 
3055*5c90c05cSAndroid Build Coastguard Worker   using info = dragonbox::float_info<Float>;
3056*5c90c05cSAndroid Build Coastguard Worker 
3057*5c90c05cSAndroid Build Coastguard Worker   // Assume Float is in the format [sign][exponent][significand].
3058*5c90c05cSAndroid Build Coastguard Worker   using carrier_uint = typename info::carrier_uint;
3059*5c90c05cSAndroid Build Coastguard Worker 
3060*5c90c05cSAndroid Build Coastguard Worker   const auto num_float_significand_bits = detail::num_significand_bits<Float>();
3061*5c90c05cSAndroid Build Coastguard Worker 
3062*5c90c05cSAndroid Build Coastguard Worker   basic_fp<carrier_uint> f(value);
3063*5c90c05cSAndroid Build Coastguard Worker   f.e += num_float_significand_bits;
3064*5c90c05cSAndroid Build Coastguard Worker   if (!has_implicit_bit<Float>()) --f.e;
3065*5c90c05cSAndroid Build Coastguard Worker 
3066*5c90c05cSAndroid Build Coastguard Worker   const auto num_fraction_bits =
3067*5c90c05cSAndroid Build Coastguard Worker       num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3068*5c90c05cSAndroid Build Coastguard Worker   const auto num_xdigits = (num_fraction_bits + 3) / 4;
3069*5c90c05cSAndroid Build Coastguard Worker 
3070*5c90c05cSAndroid Build Coastguard Worker   const auto leading_shift = ((num_xdigits - 1) * 4);
3071*5c90c05cSAndroid Build Coastguard Worker   const auto leading_mask = carrier_uint(0xF) << leading_shift;
3072*5c90c05cSAndroid Build Coastguard Worker   const auto leading_xdigit =
3073*5c90c05cSAndroid Build Coastguard Worker       static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3074*5c90c05cSAndroid Build Coastguard Worker   if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3075*5c90c05cSAndroid Build Coastguard Worker 
3076*5c90c05cSAndroid Build Coastguard Worker   int print_xdigits = num_xdigits - 1;
3077*5c90c05cSAndroid Build Coastguard Worker   if (specs.precision >= 0 && print_xdigits > specs.precision) {
3078*5c90c05cSAndroid Build Coastguard Worker     const int shift = ((print_xdigits - specs.precision - 1) * 4);
3079*5c90c05cSAndroid Build Coastguard Worker     const auto mask = carrier_uint(0xF) << shift;
3080*5c90c05cSAndroid Build Coastguard Worker     const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3081*5c90c05cSAndroid Build Coastguard Worker 
3082*5c90c05cSAndroid Build Coastguard Worker     if (v >= 8) {
3083*5c90c05cSAndroid Build Coastguard Worker       const auto inc = carrier_uint(1) << (shift + 4);
3084*5c90c05cSAndroid Build Coastguard Worker       f.f += inc;
3085*5c90c05cSAndroid Build Coastguard Worker       f.f &= ~(inc - 1);
3086*5c90c05cSAndroid Build Coastguard Worker     }
3087*5c90c05cSAndroid Build Coastguard Worker 
3088*5c90c05cSAndroid Build Coastguard Worker     // Check long double overflow
3089*5c90c05cSAndroid Build Coastguard Worker     if (!has_implicit_bit<Float>()) {
3090*5c90c05cSAndroid Build Coastguard Worker       const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3091*5c90c05cSAndroid Build Coastguard Worker       if ((f.f & implicit_bit) == implicit_bit) {
3092*5c90c05cSAndroid Build Coastguard Worker         f.f >>= 4;
3093*5c90c05cSAndroid Build Coastguard Worker         f.e += 4;
3094*5c90c05cSAndroid Build Coastguard Worker       }
3095*5c90c05cSAndroid Build Coastguard Worker     }
3096*5c90c05cSAndroid Build Coastguard Worker 
3097*5c90c05cSAndroid Build Coastguard Worker     print_xdigits = specs.precision;
3098*5c90c05cSAndroid Build Coastguard Worker   }
3099*5c90c05cSAndroid Build Coastguard Worker 
3100*5c90c05cSAndroid Build Coastguard Worker   char xdigits[num_bits<carrier_uint>() / 4];
3101*5c90c05cSAndroid Build Coastguard Worker   detail::fill_n(xdigits, sizeof(xdigits), '0');
3102*5c90c05cSAndroid Build Coastguard Worker   format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());
3103*5c90c05cSAndroid Build Coastguard Worker 
3104*5c90c05cSAndroid Build Coastguard Worker   // Remove zero tail
3105*5c90c05cSAndroid Build Coastguard Worker   while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3106*5c90c05cSAndroid Build Coastguard Worker 
3107*5c90c05cSAndroid Build Coastguard Worker   buf.push_back('0');
3108*5c90c05cSAndroid Build Coastguard Worker   buf.push_back(specs.upper() ? 'X' : 'x');
3109*5c90c05cSAndroid Build Coastguard Worker   buf.push_back(xdigits[0]);
3110*5c90c05cSAndroid Build Coastguard Worker   if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision)
3111*5c90c05cSAndroid Build Coastguard Worker     buf.push_back('.');
3112*5c90c05cSAndroid Build Coastguard Worker   buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3113*5c90c05cSAndroid Build Coastguard Worker   for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0');
3114*5c90c05cSAndroid Build Coastguard Worker 
3115*5c90c05cSAndroid Build Coastguard Worker   buf.push_back(specs.upper() ? 'P' : 'p');
3116*5c90c05cSAndroid Build Coastguard Worker 
3117*5c90c05cSAndroid Build Coastguard Worker   uint32_t abs_e;
3118*5c90c05cSAndroid Build Coastguard Worker   if (f.e < 0) {
3119*5c90c05cSAndroid Build Coastguard Worker     buf.push_back('-');
3120*5c90c05cSAndroid Build Coastguard Worker     abs_e = static_cast<uint32_t>(-f.e);
3121*5c90c05cSAndroid Build Coastguard Worker   } else {
3122*5c90c05cSAndroid Build Coastguard Worker     buf.push_back('+');
3123*5c90c05cSAndroid Build Coastguard Worker     abs_e = static_cast<uint32_t>(f.e);
3124*5c90c05cSAndroid Build Coastguard Worker   }
3125*5c90c05cSAndroid Build Coastguard Worker   format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3126*5c90c05cSAndroid Build Coastguard Worker }
3127*5c90c05cSAndroid Build Coastguard Worker 
3128*5c90c05cSAndroid Build Coastguard Worker template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
3129*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,
3130*5c90c05cSAndroid Build Coastguard Worker                                      buffer<char>& buf) {
3131*5c90c05cSAndroid Build Coastguard Worker   format_hexfloat(static_cast<double>(value), specs, buf);
3132*5c90c05cSAndroid Build Coastguard Worker }
3133*5c90c05cSAndroid Build Coastguard Worker 
3134*5c90c05cSAndroid Build Coastguard Worker constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t {
3135*5c90c05cSAndroid Build Coastguard Worker   // For checking rounding thresholds.
3136*5c90c05cSAndroid Build Coastguard Worker   // The kth entry is chosen to be the smallest integer such that the
3137*5c90c05cSAndroid Build Coastguard Worker   // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
3138*5c90c05cSAndroid Build Coastguard Worker   // It is equal to ceil(2^31 + 2^32/10^(k + 1)).
3139*5c90c05cSAndroid Build Coastguard Worker   // These are stored in a string literal because we cannot have static arrays
3140*5c90c05cSAndroid Build Coastguard Worker   // in constexpr functions and non-static ones are poorly optimized.
3141*5c90c05cSAndroid Build Coastguard Worker   return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7"
3142*5c90c05cSAndroid Build Coastguard Worker          U"\x800001ae\x8000002b"[index];
3143*5c90c05cSAndroid Build Coastguard Worker }
3144*5c90c05cSAndroid Build Coastguard Worker 
3145*5c90c05cSAndroid Build Coastguard Worker template <typename Float>
3146*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto format_float(Float value, int precision,
3147*5c90c05cSAndroid Build Coastguard Worker                                   const format_specs& specs, bool binary32,
3148*5c90c05cSAndroid Build Coastguard Worker                                   buffer<char>& buf) -> int {
3149*5c90c05cSAndroid Build Coastguard Worker   // float is passed as double to reduce the number of instantiations.
3150*5c90c05cSAndroid Build Coastguard Worker   static_assert(!std::is_same<Float, float>::value, "");
3151*5c90c05cSAndroid Build Coastguard Worker   auto converted_value = convert_float(value);
3152*5c90c05cSAndroid Build Coastguard Worker 
3153*5c90c05cSAndroid Build Coastguard Worker   const bool fixed = specs.type() == presentation_type::fixed;
3154*5c90c05cSAndroid Build Coastguard Worker   if (value == 0) {
3155*5c90c05cSAndroid Build Coastguard Worker     if (precision <= 0 || !fixed) {
3156*5c90c05cSAndroid Build Coastguard Worker       buf.push_back('0');
3157*5c90c05cSAndroid Build Coastguard Worker       return 0;
3158*5c90c05cSAndroid Build Coastguard Worker     }
3159*5c90c05cSAndroid Build Coastguard Worker     buf.try_resize(to_unsigned(precision));
3160*5c90c05cSAndroid Build Coastguard Worker     fill_n(buf.data(), precision, '0');
3161*5c90c05cSAndroid Build Coastguard Worker     return -precision;
3162*5c90c05cSAndroid Build Coastguard Worker   }
3163*5c90c05cSAndroid Build Coastguard Worker 
3164*5c90c05cSAndroid Build Coastguard Worker   int exp = 0;
3165*5c90c05cSAndroid Build Coastguard Worker   bool use_dragon = true;
3166*5c90c05cSAndroid Build Coastguard Worker   unsigned dragon_flags = 0;
3167*5c90c05cSAndroid Build Coastguard Worker   if (!is_fast_float<Float>() || is_constant_evaluated()) {
3168*5c90c05cSAndroid Build Coastguard Worker     const auto inv_log2_10 = 0.3010299956639812;  // 1 / log2(10)
3169*5c90c05cSAndroid Build Coastguard Worker     using info = dragonbox::float_info<decltype(converted_value)>;
3170*5c90c05cSAndroid Build Coastguard Worker     const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3171*5c90c05cSAndroid Build Coastguard Worker     // Compute exp, an approximate power of 10, such that
3172*5c90c05cSAndroid Build Coastguard Worker     //   10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3173*5c90c05cSAndroid Build Coastguard Worker     // This is based on log10(value) == log2(value) / log2(10) and approximation
3174*5c90c05cSAndroid Build Coastguard Worker     // of log2(value) by e + num_fraction_bits idea from double-conversion.
3175*5c90c05cSAndroid Build Coastguard Worker     auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3176*5c90c05cSAndroid Build Coastguard Worker     exp = static_cast<int>(e);
3177*5c90c05cSAndroid Build Coastguard Worker     if (e > exp) ++exp;  // Compute ceil.
3178*5c90c05cSAndroid Build Coastguard Worker     dragon_flags = dragon::fixup;
3179*5c90c05cSAndroid Build Coastguard Worker   } else {
3180*5c90c05cSAndroid Build Coastguard Worker     // Extract significand bits and exponent bits.
3181*5c90c05cSAndroid Build Coastguard Worker     using info = dragonbox::float_info<double>;
3182*5c90c05cSAndroid Build Coastguard Worker     auto br = bit_cast<uint64_t>(static_cast<double>(value));
3183*5c90c05cSAndroid Build Coastguard Worker 
3184*5c90c05cSAndroid Build Coastguard Worker     const uint64_t significand_mask =
3185*5c90c05cSAndroid Build Coastguard Worker         (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3186*5c90c05cSAndroid Build Coastguard Worker     uint64_t significand = (br & significand_mask);
3187*5c90c05cSAndroid Build Coastguard Worker     int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3188*5c90c05cSAndroid Build Coastguard Worker                                     num_significand_bits<double>());
3189*5c90c05cSAndroid Build Coastguard Worker 
3190*5c90c05cSAndroid Build Coastguard Worker     if (exponent != 0) {  // Check if normal.
3191*5c90c05cSAndroid Build Coastguard Worker       exponent -= exponent_bias<double>() + num_significand_bits<double>();
3192*5c90c05cSAndroid Build Coastguard Worker       significand |=
3193*5c90c05cSAndroid Build Coastguard Worker           (static_cast<uint64_t>(1) << num_significand_bits<double>());
3194*5c90c05cSAndroid Build Coastguard Worker       significand <<= 1;
3195*5c90c05cSAndroid Build Coastguard Worker     } else {
3196*5c90c05cSAndroid Build Coastguard Worker       // Normalize subnormal inputs.
3197*5c90c05cSAndroid Build Coastguard Worker       FMT_ASSERT(significand != 0, "zeros should not appear here");
3198*5c90c05cSAndroid Build Coastguard Worker       int shift = countl_zero(significand);
3199*5c90c05cSAndroid Build Coastguard Worker       FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3200*5c90c05cSAndroid Build Coastguard Worker                  "");
3201*5c90c05cSAndroid Build Coastguard Worker       shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3202*5c90c05cSAndroid Build Coastguard Worker       exponent = (std::numeric_limits<double>::min_exponent -
3203*5c90c05cSAndroid Build Coastguard Worker                   num_significand_bits<double>()) -
3204*5c90c05cSAndroid Build Coastguard Worker                  shift;
3205*5c90c05cSAndroid Build Coastguard Worker       significand <<= shift;
3206*5c90c05cSAndroid Build Coastguard Worker     }
3207*5c90c05cSAndroid Build Coastguard Worker 
3208*5c90c05cSAndroid Build Coastguard Worker     // Compute the first several nonzero decimal significand digits.
3209*5c90c05cSAndroid Build Coastguard Worker     // We call the number we get the first segment.
3210*5c90c05cSAndroid Build Coastguard Worker     const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3211*5c90c05cSAndroid Build Coastguard Worker     exp = -k;
3212*5c90c05cSAndroid Build Coastguard Worker     const int beta = exponent + dragonbox::floor_log2_pow10(k);
3213*5c90c05cSAndroid Build Coastguard Worker     uint64_t first_segment;
3214*5c90c05cSAndroid Build Coastguard Worker     bool has_more_segments;
3215*5c90c05cSAndroid Build Coastguard Worker     int digits_in_the_first_segment;
3216*5c90c05cSAndroid Build Coastguard Worker     {
3217*5c90c05cSAndroid Build Coastguard Worker       const auto r = dragonbox::umul192_upper128(
3218*5c90c05cSAndroid Build Coastguard Worker           significand << beta, dragonbox::get_cached_power(k));
3219*5c90c05cSAndroid Build Coastguard Worker       first_segment = r.high();
3220*5c90c05cSAndroid Build Coastguard Worker       has_more_segments = r.low() != 0;
3221*5c90c05cSAndroid Build Coastguard Worker 
3222*5c90c05cSAndroid Build Coastguard Worker       // The first segment can have 18 ~ 19 digits.
3223*5c90c05cSAndroid Build Coastguard Worker       if (first_segment >= 1000000000000000000ULL) {
3224*5c90c05cSAndroid Build Coastguard Worker         digits_in_the_first_segment = 19;
3225*5c90c05cSAndroid Build Coastguard Worker       } else {
3226*5c90c05cSAndroid Build Coastguard Worker         // When it is of 18-digits, we align it to 19-digits by adding a bogus
3227*5c90c05cSAndroid Build Coastguard Worker         // zero at the end.
3228*5c90c05cSAndroid Build Coastguard Worker         digits_in_the_first_segment = 18;
3229*5c90c05cSAndroid Build Coastguard Worker         first_segment *= 10;
3230*5c90c05cSAndroid Build Coastguard Worker       }
3231*5c90c05cSAndroid Build Coastguard Worker     }
3232*5c90c05cSAndroid Build Coastguard Worker 
3233*5c90c05cSAndroid Build Coastguard Worker     // Compute the actual number of decimal digits to print.
3234*5c90c05cSAndroid Build Coastguard Worker     if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3235*5c90c05cSAndroid Build Coastguard Worker 
3236*5c90c05cSAndroid Build Coastguard Worker     // Use Dragon4 only when there might be not enough digits in the first
3237*5c90c05cSAndroid Build Coastguard Worker     // segment.
3238*5c90c05cSAndroid Build Coastguard Worker     if (digits_in_the_first_segment > precision) {
3239*5c90c05cSAndroid Build Coastguard Worker       use_dragon = false;
3240*5c90c05cSAndroid Build Coastguard Worker 
3241*5c90c05cSAndroid Build Coastguard Worker       if (precision <= 0) {
3242*5c90c05cSAndroid Build Coastguard Worker         exp += digits_in_the_first_segment;
3243*5c90c05cSAndroid Build Coastguard Worker 
3244*5c90c05cSAndroid Build Coastguard Worker         if (precision < 0) {
3245*5c90c05cSAndroid Build Coastguard Worker           // Nothing to do, since all we have are just leading zeros.
3246*5c90c05cSAndroid Build Coastguard Worker           buf.try_resize(0);
3247*5c90c05cSAndroid Build Coastguard Worker         } else {
3248*5c90c05cSAndroid Build Coastguard Worker           // We may need to round-up.
3249*5c90c05cSAndroid Build Coastguard Worker           buf.try_resize(1);
3250*5c90c05cSAndroid Build Coastguard Worker           if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3251*5c90c05cSAndroid Build Coastguard Worker               5000000000000000000ULL) {
3252*5c90c05cSAndroid Build Coastguard Worker             buf[0] = '1';
3253*5c90c05cSAndroid Build Coastguard Worker           } else {
3254*5c90c05cSAndroid Build Coastguard Worker             buf[0] = '0';
3255*5c90c05cSAndroid Build Coastguard Worker           }
3256*5c90c05cSAndroid Build Coastguard Worker         }
3257*5c90c05cSAndroid Build Coastguard Worker       }  // precision <= 0
3258*5c90c05cSAndroid Build Coastguard Worker       else {
3259*5c90c05cSAndroid Build Coastguard Worker         exp += digits_in_the_first_segment - precision;
3260*5c90c05cSAndroid Build Coastguard Worker 
3261*5c90c05cSAndroid Build Coastguard Worker         // When precision > 0, we divide the first segment into three
3262*5c90c05cSAndroid Build Coastguard Worker         // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3263*5c90c05cSAndroid Build Coastguard Worker         // in 32-bits which usually allows faster calculation than in
3264*5c90c05cSAndroid Build Coastguard Worker         // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3265*5c90c05cSAndroid Build Coastguard Worker         // division-by-constant for large 64-bit divisors, we do it here
3266*5c90c05cSAndroid Build Coastguard Worker         // manually. The magic number 7922816251426433760 below is equal to
3267*5c90c05cSAndroid Build Coastguard Worker         // ceil(2^(64+32) / 10^10).
3268*5c90c05cSAndroid Build Coastguard Worker         const uint32_t first_subsegment = static_cast<uint32_t>(
3269*5c90c05cSAndroid Build Coastguard Worker             dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3270*5c90c05cSAndroid Build Coastguard Worker             32);
3271*5c90c05cSAndroid Build Coastguard Worker         const uint64_t second_third_subsegments =
3272*5c90c05cSAndroid Build Coastguard Worker             first_segment - first_subsegment * 10000000000ULL;
3273*5c90c05cSAndroid Build Coastguard Worker 
3274*5c90c05cSAndroid Build Coastguard Worker         uint64_t prod;
3275*5c90c05cSAndroid Build Coastguard Worker         uint32_t digits;
3276*5c90c05cSAndroid Build Coastguard Worker         bool should_round_up;
3277*5c90c05cSAndroid Build Coastguard Worker         int number_of_digits_to_print = min_of(precision, 9);
3278*5c90c05cSAndroid Build Coastguard Worker 
3279*5c90c05cSAndroid Build Coastguard Worker         // Print a 9-digits subsegment, either the first or the second.
3280*5c90c05cSAndroid Build Coastguard Worker         auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3281*5c90c05cSAndroid Build Coastguard Worker           int number_of_digits_printed = 0;
3282*5c90c05cSAndroid Build Coastguard Worker 
3283*5c90c05cSAndroid Build Coastguard Worker           // If we want to print an odd number of digits from the subsegment,
3284*5c90c05cSAndroid Build Coastguard Worker           if ((number_of_digits_to_print & 1) != 0) {
3285*5c90c05cSAndroid Build Coastguard Worker             // Convert to 64-bit fixed-point fractional form with 1-digit
3286*5c90c05cSAndroid Build Coastguard Worker             // integer part. The magic number 720575941 is a good enough
3287*5c90c05cSAndroid Build Coastguard Worker             // approximation of 2^(32 + 24) / 10^8; see
3288*5c90c05cSAndroid Build Coastguard Worker             // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3289*5c90c05cSAndroid Build Coastguard Worker             // for details.
3290*5c90c05cSAndroid Build Coastguard Worker             prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3291*5c90c05cSAndroid Build Coastguard Worker             digits = static_cast<uint32_t>(prod >> 32);
3292*5c90c05cSAndroid Build Coastguard Worker             *buffer = static_cast<char>('0' + digits);
3293*5c90c05cSAndroid Build Coastguard Worker             number_of_digits_printed++;
3294*5c90c05cSAndroid Build Coastguard Worker           }
3295*5c90c05cSAndroid Build Coastguard Worker           // If we want to print an even number of digits from the
3296*5c90c05cSAndroid Build Coastguard Worker           // first_subsegment,
3297*5c90c05cSAndroid Build Coastguard Worker           else {
3298*5c90c05cSAndroid Build Coastguard Worker             // Convert to 64-bit fixed-point fractional form with 2-digits
3299*5c90c05cSAndroid Build Coastguard Worker             // integer part. The magic number 450359963 is a good enough
3300*5c90c05cSAndroid Build Coastguard Worker             // approximation of 2^(32 + 20) / 10^7; see
3301*5c90c05cSAndroid Build Coastguard Worker             // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3302*5c90c05cSAndroid Build Coastguard Worker             // for details.
3303*5c90c05cSAndroid Build Coastguard Worker             prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3304*5c90c05cSAndroid Build Coastguard Worker             digits = static_cast<uint32_t>(prod >> 32);
3305*5c90c05cSAndroid Build Coastguard Worker             write2digits(buffer, digits);
3306*5c90c05cSAndroid Build Coastguard Worker             number_of_digits_printed += 2;
3307*5c90c05cSAndroid Build Coastguard Worker           }
3308*5c90c05cSAndroid Build Coastguard Worker 
3309*5c90c05cSAndroid Build Coastguard Worker           // Print all digit pairs.
3310*5c90c05cSAndroid Build Coastguard Worker           while (number_of_digits_printed < number_of_digits_to_print) {
3311*5c90c05cSAndroid Build Coastguard Worker             prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3312*5c90c05cSAndroid Build Coastguard Worker             digits = static_cast<uint32_t>(prod >> 32);
3313*5c90c05cSAndroid Build Coastguard Worker             write2digits(buffer + number_of_digits_printed, digits);
3314*5c90c05cSAndroid Build Coastguard Worker             number_of_digits_printed += 2;
3315*5c90c05cSAndroid Build Coastguard Worker           }
3316*5c90c05cSAndroid Build Coastguard Worker         };
3317*5c90c05cSAndroid Build Coastguard Worker 
3318*5c90c05cSAndroid Build Coastguard Worker         // Print first subsegment.
3319*5c90c05cSAndroid Build Coastguard Worker         print_subsegment(first_subsegment, buf.data());
3320*5c90c05cSAndroid Build Coastguard Worker 
3321*5c90c05cSAndroid Build Coastguard Worker         // Perform rounding if the first subsegment is the last subsegment to
3322*5c90c05cSAndroid Build Coastguard Worker         // print.
3323*5c90c05cSAndroid Build Coastguard Worker         if (precision <= 9) {
3324*5c90c05cSAndroid Build Coastguard Worker           // Rounding inside the subsegment.
3325*5c90c05cSAndroid Build Coastguard Worker           // We round-up if:
3326*5c90c05cSAndroid Build Coastguard Worker           //  - either the fractional part is strictly larger than 1/2, or
3327*5c90c05cSAndroid Build Coastguard Worker           //  - the fractional part is exactly 1/2 and the last digit is odd.
3328*5c90c05cSAndroid Build Coastguard Worker           // We rely on the following observations:
3329*5c90c05cSAndroid Build Coastguard Worker           //  - If fractional_part >= threshold, then the fractional part is
3330*5c90c05cSAndroid Build Coastguard Worker           //    strictly larger than 1/2.
3331*5c90c05cSAndroid Build Coastguard Worker           //  - If the MSB of fractional_part is set, then the fractional part
3332*5c90c05cSAndroid Build Coastguard Worker           //    must be at least 1/2.
3333*5c90c05cSAndroid Build Coastguard Worker           //  - When the MSB of fractional_part is set, either
3334*5c90c05cSAndroid Build Coastguard Worker           //    second_third_subsegments being nonzero or has_more_segments
3335*5c90c05cSAndroid Build Coastguard Worker           //    being true means there are further digits not printed, so the
3336*5c90c05cSAndroid Build Coastguard Worker           //    fractional part is strictly larger than 1/2.
3337*5c90c05cSAndroid Build Coastguard Worker           if (precision < 9) {
3338*5c90c05cSAndroid Build Coastguard Worker             uint32_t fractional_part = static_cast<uint32_t>(prod);
3339*5c90c05cSAndroid Build Coastguard Worker             should_round_up =
3340*5c90c05cSAndroid Build Coastguard Worker                 fractional_part >= fractional_part_rounding_thresholds(
3341*5c90c05cSAndroid Build Coastguard Worker                                        8 - number_of_digits_to_print) ||
3342*5c90c05cSAndroid Build Coastguard Worker                 ((fractional_part >> 31) &
3343*5c90c05cSAndroid Build Coastguard Worker                  ((digits & 1) | (second_third_subsegments != 0) |
3344*5c90c05cSAndroid Build Coastguard Worker                   has_more_segments)) != 0;
3345*5c90c05cSAndroid Build Coastguard Worker           }
3346*5c90c05cSAndroid Build Coastguard Worker           // Rounding at the subsegment boundary.
3347*5c90c05cSAndroid Build Coastguard Worker           // In this case, the fractional part is at least 1/2 if and only if
3348*5c90c05cSAndroid Build Coastguard Worker           // second_third_subsegments >= 5000000000ULL, and is strictly larger
3349*5c90c05cSAndroid Build Coastguard Worker           // than 1/2 if we further have either second_third_subsegments >
3350*5c90c05cSAndroid Build Coastguard Worker           // 5000000000ULL or has_more_segments == true.
3351*5c90c05cSAndroid Build Coastguard Worker           else {
3352*5c90c05cSAndroid Build Coastguard Worker             should_round_up = second_third_subsegments > 5000000000ULL ||
3353*5c90c05cSAndroid Build Coastguard Worker                               (second_third_subsegments == 5000000000ULL &&
3354*5c90c05cSAndroid Build Coastguard Worker                                ((digits & 1) != 0 || has_more_segments));
3355*5c90c05cSAndroid Build Coastguard Worker           }
3356*5c90c05cSAndroid Build Coastguard Worker         }
3357*5c90c05cSAndroid Build Coastguard Worker         // Otherwise, print the second subsegment.
3358*5c90c05cSAndroid Build Coastguard Worker         else {
3359*5c90c05cSAndroid Build Coastguard Worker           // Compilers are not aware of how to leverage the maximum value of
3360*5c90c05cSAndroid Build Coastguard Worker           // second_third_subsegments to find out a better magic number which
3361*5c90c05cSAndroid Build Coastguard Worker           // allows us to eliminate an additional shift. 1844674407370955162 =
3362*5c90c05cSAndroid Build Coastguard Worker           // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3363*5c90c05cSAndroid Build Coastguard Worker           const uint32_t second_subsegment =
3364*5c90c05cSAndroid Build Coastguard Worker               static_cast<uint32_t>(dragonbox::umul128_upper64(
3365*5c90c05cSAndroid Build Coastguard Worker                   second_third_subsegments, 1844674407370955162ULL));
3366*5c90c05cSAndroid Build Coastguard Worker           const uint32_t third_subsegment =
3367*5c90c05cSAndroid Build Coastguard Worker               static_cast<uint32_t>(second_third_subsegments) -
3368*5c90c05cSAndroid Build Coastguard Worker               second_subsegment * 10;
3369*5c90c05cSAndroid Build Coastguard Worker 
3370*5c90c05cSAndroid Build Coastguard Worker           number_of_digits_to_print = precision - 9;
3371*5c90c05cSAndroid Build Coastguard Worker           print_subsegment(second_subsegment, buf.data() + 9);
3372*5c90c05cSAndroid Build Coastguard Worker 
3373*5c90c05cSAndroid Build Coastguard Worker           // Rounding inside the subsegment.
3374*5c90c05cSAndroid Build Coastguard Worker           if (precision < 18) {
3375*5c90c05cSAndroid Build Coastguard Worker             // The condition third_subsegment != 0 implies that the segment was
3376*5c90c05cSAndroid Build Coastguard Worker             // of 19 digits, so in this case the third segment should be
3377*5c90c05cSAndroid Build Coastguard Worker             // consisting of a genuine digit from the input.
3378*5c90c05cSAndroid Build Coastguard Worker             uint32_t fractional_part = static_cast<uint32_t>(prod);
3379*5c90c05cSAndroid Build Coastguard Worker             should_round_up =
3380*5c90c05cSAndroid Build Coastguard Worker                 fractional_part >= fractional_part_rounding_thresholds(
3381*5c90c05cSAndroid Build Coastguard Worker                                        8 - number_of_digits_to_print) ||
3382*5c90c05cSAndroid Build Coastguard Worker                 ((fractional_part >> 31) &
3383*5c90c05cSAndroid Build Coastguard Worker                  ((digits & 1) | (third_subsegment != 0) |
3384*5c90c05cSAndroid Build Coastguard Worker                   has_more_segments)) != 0;
3385*5c90c05cSAndroid Build Coastguard Worker           }
3386*5c90c05cSAndroid Build Coastguard Worker           // Rounding at the subsegment boundary.
3387*5c90c05cSAndroid Build Coastguard Worker           else {
3388*5c90c05cSAndroid Build Coastguard Worker             // In this case, the segment must be of 19 digits, thus
3389*5c90c05cSAndroid Build Coastguard Worker             // the third subsegment should be consisting of a genuine digit from
3390*5c90c05cSAndroid Build Coastguard Worker             // the input.
3391*5c90c05cSAndroid Build Coastguard Worker             should_round_up = third_subsegment > 5 ||
3392*5c90c05cSAndroid Build Coastguard Worker                               (third_subsegment == 5 &&
3393*5c90c05cSAndroid Build Coastguard Worker                                ((digits & 1) != 0 || has_more_segments));
3394*5c90c05cSAndroid Build Coastguard Worker           }
3395*5c90c05cSAndroid Build Coastguard Worker         }
3396*5c90c05cSAndroid Build Coastguard Worker 
3397*5c90c05cSAndroid Build Coastguard Worker         // Round-up if necessary.
3398*5c90c05cSAndroid Build Coastguard Worker         if (should_round_up) {
3399*5c90c05cSAndroid Build Coastguard Worker           ++buf[precision - 1];
3400*5c90c05cSAndroid Build Coastguard Worker           for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3401*5c90c05cSAndroid Build Coastguard Worker             buf[i] = '0';
3402*5c90c05cSAndroid Build Coastguard Worker             ++buf[i - 1];
3403*5c90c05cSAndroid Build Coastguard Worker           }
3404*5c90c05cSAndroid Build Coastguard Worker           if (buf[0] > '9') {
3405*5c90c05cSAndroid Build Coastguard Worker             buf[0] = '1';
3406*5c90c05cSAndroid Build Coastguard Worker             if (fixed)
3407*5c90c05cSAndroid Build Coastguard Worker               buf[precision++] = '0';
3408*5c90c05cSAndroid Build Coastguard Worker             else
3409*5c90c05cSAndroid Build Coastguard Worker               ++exp;
3410*5c90c05cSAndroid Build Coastguard Worker           }
3411*5c90c05cSAndroid Build Coastguard Worker         }
3412*5c90c05cSAndroid Build Coastguard Worker         buf.try_resize(to_unsigned(precision));
3413*5c90c05cSAndroid Build Coastguard Worker       }
3414*5c90c05cSAndroid Build Coastguard Worker     }  // if (digits_in_the_first_segment > precision)
3415*5c90c05cSAndroid Build Coastguard Worker     else {
3416*5c90c05cSAndroid Build Coastguard Worker       // Adjust the exponent for its use in Dragon4.
3417*5c90c05cSAndroid Build Coastguard Worker       exp += digits_in_the_first_segment - 1;
3418*5c90c05cSAndroid Build Coastguard Worker     }
3419*5c90c05cSAndroid Build Coastguard Worker   }
3420*5c90c05cSAndroid Build Coastguard Worker   if (use_dragon) {
3421*5c90c05cSAndroid Build Coastguard Worker     auto f = basic_fp<uint128_t>();
3422*5c90c05cSAndroid Build Coastguard Worker     bool is_predecessor_closer = binary32 ? f.assign(static_cast<float>(value))
3423*5c90c05cSAndroid Build Coastguard Worker                                           : f.assign(converted_value);
3424*5c90c05cSAndroid Build Coastguard Worker     if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3425*5c90c05cSAndroid Build Coastguard Worker     if (fixed) dragon_flags |= dragon::fixed;
3426*5c90c05cSAndroid Build Coastguard Worker     // Limit precision to the maximum possible number of significant digits in
3427*5c90c05cSAndroid Build Coastguard Worker     // an IEEE754 double because we don't need to generate zeros.
3428*5c90c05cSAndroid Build Coastguard Worker     const int max_double_digits = 767;
3429*5c90c05cSAndroid Build Coastguard Worker     if (precision > max_double_digits) precision = max_double_digits;
3430*5c90c05cSAndroid Build Coastguard Worker     format_dragon(f, dragon_flags, precision, buf, exp);
3431*5c90c05cSAndroid Build Coastguard Worker   }
3432*5c90c05cSAndroid Build Coastguard Worker   if (!fixed && !specs.alt()) {
3433*5c90c05cSAndroid Build Coastguard Worker     // Remove trailing zeros.
3434*5c90c05cSAndroid Build Coastguard Worker     auto num_digits = buf.size();
3435*5c90c05cSAndroid Build Coastguard Worker     while (num_digits > 0 && buf[num_digits - 1] == '0') {
3436*5c90c05cSAndroid Build Coastguard Worker       --num_digits;
3437*5c90c05cSAndroid Build Coastguard Worker       ++exp;
3438*5c90c05cSAndroid Build Coastguard Worker     }
3439*5c90c05cSAndroid Build Coastguard Worker     buf.try_resize(num_digits);
3440*5c90c05cSAndroid Build Coastguard Worker   }
3441*5c90c05cSAndroid Build Coastguard Worker   return exp;
3442*5c90c05cSAndroid Build Coastguard Worker }
3443*5c90c05cSAndroid Build Coastguard Worker 
3444*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T>
3445*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write_float(OutputIt out, T value, format_specs specs,
3446*5c90c05cSAndroid Build Coastguard Worker                                  locale_ref loc) -> OutputIt {
3447*5c90c05cSAndroid Build Coastguard Worker   // Use signbit because value < 0 is false for NaN.
3448*5c90c05cSAndroid Build Coastguard Worker   sign s = detail::signbit(value) ? sign::minus : specs.sign();
3449*5c90c05cSAndroid Build Coastguard Worker 
3450*5c90c05cSAndroid Build Coastguard Worker   if (!detail::isfinite(value))
3451*5c90c05cSAndroid Build Coastguard Worker     return write_nonfinite<Char>(out, detail::isnan(value), specs, s);
3452*5c90c05cSAndroid Build Coastguard Worker 
3453*5c90c05cSAndroid Build Coastguard Worker   if (specs.align() == align::numeric && s != sign::none) {
3454*5c90c05cSAndroid Build Coastguard Worker     *out++ = detail::getsign<Char>(s);
3455*5c90c05cSAndroid Build Coastguard Worker     s = sign::none;
3456*5c90c05cSAndroid Build Coastguard Worker     if (specs.width != 0) --specs.width;
3457*5c90c05cSAndroid Build Coastguard Worker   }
3458*5c90c05cSAndroid Build Coastguard Worker 
3459*5c90c05cSAndroid Build Coastguard Worker   int precision = specs.precision;
3460*5c90c05cSAndroid Build Coastguard Worker   if (precision < 0) {
3461*5c90c05cSAndroid Build Coastguard Worker     if (specs.type() != presentation_type::none) {
3462*5c90c05cSAndroid Build Coastguard Worker       precision = 6;
3463*5c90c05cSAndroid Build Coastguard Worker     } else if (is_fast_float<T>::value && !is_constant_evaluated()) {
3464*5c90c05cSAndroid Build Coastguard Worker       // Use Dragonbox for the shortest format.
3465*5c90c05cSAndroid Build Coastguard Worker       using floaty = conditional_t<sizeof(T) >= sizeof(double), double, float>;
3466*5c90c05cSAndroid Build Coastguard Worker       auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3467*5c90c05cSAndroid Build Coastguard Worker       return write_float<Char>(out, dec, specs, s, loc);
3468*5c90c05cSAndroid Build Coastguard Worker     }
3469*5c90c05cSAndroid Build Coastguard Worker   }
3470*5c90c05cSAndroid Build Coastguard Worker 
3471*5c90c05cSAndroid Build Coastguard Worker   memory_buffer buffer;
3472*5c90c05cSAndroid Build Coastguard Worker   if (specs.type() == presentation_type::hexfloat) {
3473*5c90c05cSAndroid Build Coastguard Worker     if (s != sign::none) buffer.push_back(detail::getsign<char>(s));
3474*5c90c05cSAndroid Build Coastguard Worker     format_hexfloat(convert_float(value), specs, buffer);
3475*5c90c05cSAndroid Build Coastguard Worker     return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},
3476*5c90c05cSAndroid Build Coastguard Worker                                            specs);
3477*5c90c05cSAndroid Build Coastguard Worker   }
3478*5c90c05cSAndroid Build Coastguard Worker 
3479*5c90c05cSAndroid Build Coastguard Worker   if (specs.type() == presentation_type::exp) {
3480*5c90c05cSAndroid Build Coastguard Worker     if (precision == max_value<int>())
3481*5c90c05cSAndroid Build Coastguard Worker       report_error("number is too big");
3482*5c90c05cSAndroid Build Coastguard Worker     else
3483*5c90c05cSAndroid Build Coastguard Worker       ++precision;
3484*5c90c05cSAndroid Build Coastguard Worker     if (specs.precision != 0) specs.set_alt();
3485*5c90c05cSAndroid Build Coastguard Worker   } else if (specs.type() == presentation_type::fixed) {
3486*5c90c05cSAndroid Build Coastguard Worker     if (specs.precision != 0) specs.set_alt();
3487*5c90c05cSAndroid Build Coastguard Worker   } else if (precision == 0) {
3488*5c90c05cSAndroid Build Coastguard Worker     precision = 1;
3489*5c90c05cSAndroid Build Coastguard Worker   }
3490*5c90c05cSAndroid Build Coastguard Worker   int exp = format_float(convert_float(value), precision, specs,
3491*5c90c05cSAndroid Build Coastguard Worker                          std::is_same<T, float>(), buffer);
3492*5c90c05cSAndroid Build Coastguard Worker 
3493*5c90c05cSAndroid Build Coastguard Worker   specs.precision = precision;
3494*5c90c05cSAndroid Build Coastguard Worker   auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3495*5c90c05cSAndroid Build Coastguard Worker   return write_float<Char>(out, f, specs, s, loc);
3496*5c90c05cSAndroid Build Coastguard Worker }
3497*5c90c05cSAndroid Build Coastguard Worker 
3498*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3499*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_floating_point<T>::value)>
3500*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs,
3501*5c90c05cSAndroid Build Coastguard Worker                            locale_ref loc = {}) -> OutputIt {
3502*5c90c05cSAndroid Build Coastguard Worker   return specs.localized() && write_loc(out, value, specs, loc)
3503*5c90c05cSAndroid Build Coastguard Worker              ? out
3504*5c90c05cSAndroid Build Coastguard Worker              : write_float<Char>(out, value, specs, loc);
3505*5c90c05cSAndroid Build Coastguard Worker }
3506*5c90c05cSAndroid Build Coastguard Worker 
3507*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3508*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_fast_float<T>::value)>
3509*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3510*5c90c05cSAndroid Build Coastguard Worker   if (is_constant_evaluated()) return write<Char>(out, value, format_specs());
3511*5c90c05cSAndroid Build Coastguard Worker 
3512*5c90c05cSAndroid Build Coastguard Worker   auto s = detail::signbit(value) ? sign::minus : sign::none;
3513*5c90c05cSAndroid Build Coastguard Worker 
3514*5c90c05cSAndroid Build Coastguard Worker   constexpr auto specs = format_specs();
3515*5c90c05cSAndroid Build Coastguard Worker   using floaty = conditional_t<sizeof(T) >= sizeof(double), double, float>;
3516*5c90c05cSAndroid Build Coastguard Worker   using floaty_uint = typename dragonbox::float_info<floaty>::carrier_uint;
3517*5c90c05cSAndroid Build Coastguard Worker   floaty_uint mask = exponent_mask<floaty>();
3518*5c90c05cSAndroid Build Coastguard Worker   if ((bit_cast<floaty_uint>(value) & mask) == mask)
3519*5c90c05cSAndroid Build Coastguard Worker     return write_nonfinite<Char>(out, std::isnan(value), specs, s);
3520*5c90c05cSAndroid Build Coastguard Worker 
3521*5c90c05cSAndroid Build Coastguard Worker   auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3522*5c90c05cSAndroid Build Coastguard Worker   return write_float<Char>(out, dec, specs, s, {});
3523*5c90c05cSAndroid Build Coastguard Worker }
3524*5c90c05cSAndroid Build Coastguard Worker 
3525*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3526*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(is_floating_point<T>::value &&
3527*5c90c05cSAndroid Build Coastguard Worker                         !is_fast_float<T>::value)>
3528*5c90c05cSAndroid Build Coastguard Worker inline auto write(OutputIt out, T value) -> OutputIt {
3529*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(out, value, format_specs());
3530*5c90c05cSAndroid Build Coastguard Worker }
3531*5c90c05cSAndroid Build Coastguard Worker 
3532*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
3533*5c90c05cSAndroid Build Coastguard Worker auto write(OutputIt out, monostate, format_specs = {}, locale_ref = {})
3534*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
3535*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(false, "");
3536*5c90c05cSAndroid Build Coastguard Worker   return out;
3537*5c90c05cSAndroid Build Coastguard Worker }
3538*5c90c05cSAndroid Build Coastguard Worker 
3539*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
3540*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
3541*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
3542*5c90c05cSAndroid Build Coastguard Worker   return copy_noinline<Char>(value.begin(), value.end(), out);
3543*5c90c05cSAndroid Build Coastguard Worker }
3544*5c90c05cSAndroid Build Coastguard Worker 
3545*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3546*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(has_to_string_view<T>::value)>
3547*5c90c05cSAndroid Build Coastguard Worker constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3548*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(out, to_string_view(value));
3549*5c90c05cSAndroid Build Coastguard Worker }
3550*5c90c05cSAndroid Build Coastguard Worker 
3551*5c90c05cSAndroid Build Coastguard Worker // FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3552*5c90c05cSAndroid Build Coastguard Worker template <
3553*5c90c05cSAndroid Build Coastguard Worker     typename Char, typename OutputIt, typename T,
3554*5c90c05cSAndroid Build Coastguard Worker     bool check = std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3555*5c90c05cSAndroid Build Coastguard Worker                  mapped_type_constant<T, Char>::value != type::custom_type,
3556*5c90c05cSAndroid Build Coastguard Worker     FMT_ENABLE_IF(check)>
3557*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3558*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(out, static_cast<underlying_t<T>>(value));
3559*5c90c05cSAndroid Build Coastguard Worker }
3560*5c90c05cSAndroid Build Coastguard Worker 
3561*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3562*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3563*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, T value, const format_specs& specs = {},
3564*5c90c05cSAndroid Build Coastguard Worker                          locale_ref = {}) -> OutputIt {
3565*5c90c05cSAndroid Build Coastguard Worker   return specs.type() != presentation_type::none &&
3566*5c90c05cSAndroid Build Coastguard Worker                  specs.type() != presentation_type::string
3567*5c90c05cSAndroid Build Coastguard Worker              ? write<Char>(out, value ? 1 : 0, specs, {})
3568*5c90c05cSAndroid Build Coastguard Worker              : write_bytes<Char>(out, value ? "true" : "false", specs);
3569*5c90c05cSAndroid Build Coastguard Worker }
3570*5c90c05cSAndroid Build Coastguard Worker 
3571*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
3572*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3573*5c90c05cSAndroid Build Coastguard Worker   auto it = reserve(out, 1);
3574*5c90c05cSAndroid Build Coastguard Worker   *it++ = value;
3575*5c90c05cSAndroid Build Coastguard Worker   return base_iterator(out, it);
3576*5c90c05cSAndroid Build Coastguard Worker }
3577*5c90c05cSAndroid Build Coastguard Worker 
3578*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
3579*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt {
3580*5c90c05cSAndroid Build Coastguard Worker   if (value) return write(out, basic_string_view<Char>(value));
3581*5c90c05cSAndroid Build Coastguard Worker   report_error("string pointer is null");
3582*5c90c05cSAndroid Build Coastguard Worker   return out;
3583*5c90c05cSAndroid Build Coastguard Worker }
3584*5c90c05cSAndroid Build Coastguard Worker 
3585*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3586*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(std::is_same<T, void>::value)>
3587*5c90c05cSAndroid Build Coastguard Worker auto write(OutputIt out, const T* value, const format_specs& specs = {},
3588*5c90c05cSAndroid Build Coastguard Worker            locale_ref = {}) -> OutputIt {
3589*5c90c05cSAndroid Build Coastguard Worker   return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3590*5c90c05cSAndroid Build Coastguard Worker }
3591*5c90c05cSAndroid Build Coastguard Worker 
3592*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T,
3593*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(mapped_type_constant<T, Char>::value ==
3594*5c90c05cSAndroid Build Coastguard Worker                             type::custom_type &&
3595*5c90c05cSAndroid Build Coastguard Worker                         !std::is_fundamental<T>::value)>
3596*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> OutputIt {
3597*5c90c05cSAndroid Build Coastguard Worker   auto f = formatter<T, Char>();
3598*5c90c05cSAndroid Build Coastguard Worker   auto parse_ctx = parse_context<Char>({});
3599*5c90c05cSAndroid Build Coastguard Worker   f.parse(parse_ctx);
3600*5c90c05cSAndroid Build Coastguard Worker   auto ctx = basic_format_context<OutputIt, Char>(out, {}, {});
3601*5c90c05cSAndroid Build Coastguard Worker   return f.format(value, ctx);
3602*5c90c05cSAndroid Build Coastguard Worker }
3603*5c90c05cSAndroid Build Coastguard Worker 
3604*5c90c05cSAndroid Build Coastguard Worker template <typename T>
3605*5c90c05cSAndroid Build Coastguard Worker using is_builtin =
3606*5c90c05cSAndroid Build Coastguard Worker     bool_constant<std::is_same<T, int>::value || FMT_BUILTIN_TYPES>;
3607*5c90c05cSAndroid Build Coastguard Worker 
3608*5c90c05cSAndroid Build Coastguard Worker // An argument visitor that formats the argument and writes it via the output
3609*5c90c05cSAndroid Build Coastguard Worker // iterator. It's a class and not a generic lambda for compatibility with C++11.
3610*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct default_arg_formatter {
3611*5c90c05cSAndroid Build Coastguard Worker   using context = buffered_context<Char>;
3612*5c90c05cSAndroid Build Coastguard Worker 
3613*5c90c05cSAndroid Build Coastguard Worker   basic_appender<Char> out;
3614*5c90c05cSAndroid Build Coastguard Worker 
3615*5c90c05cSAndroid Build Coastguard Worker   void operator()(monostate) { report_error("argument not found"); }
3616*5c90c05cSAndroid Build Coastguard Worker 
3617*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>
3618*5c90c05cSAndroid Build Coastguard Worker   void operator()(T value) {
3619*5c90c05cSAndroid Build Coastguard Worker     write<Char>(out, value);
3620*5c90c05cSAndroid Build Coastguard Worker   }
3621*5c90c05cSAndroid Build Coastguard Worker 
3622*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>
3623*5c90c05cSAndroid Build Coastguard Worker   void operator()(T) {
3624*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(false, "");
3625*5c90c05cSAndroid Build Coastguard Worker   }
3626*5c90c05cSAndroid Build Coastguard Worker 
3627*5c90c05cSAndroid Build Coastguard Worker   void operator()(typename basic_format_arg<context>::handle h) {
3628*5c90c05cSAndroid Build Coastguard Worker     // Use a null locale since the default format must be unlocalized.
3629*5c90c05cSAndroid Build Coastguard Worker     auto parse_ctx = parse_context<Char>({});
3630*5c90c05cSAndroid Build Coastguard Worker     auto format_ctx = context(out, {}, {});
3631*5c90c05cSAndroid Build Coastguard Worker     h.format(parse_ctx, format_ctx);
3632*5c90c05cSAndroid Build Coastguard Worker   }
3633*5c90c05cSAndroid Build Coastguard Worker };
3634*5c90c05cSAndroid Build Coastguard Worker 
3635*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct arg_formatter {
3636*5c90c05cSAndroid Build Coastguard Worker   basic_appender<Char> out;
3637*5c90c05cSAndroid Build Coastguard Worker   const format_specs& specs;
3638*5c90c05cSAndroid Build Coastguard Worker   FMT_NO_UNIQUE_ADDRESS locale_ref locale;
3639*5c90c05cSAndroid Build Coastguard Worker 
3640*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>
3641*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3642*5c90c05cSAndroid Build Coastguard Worker     detail::write<Char>(out, value, specs, locale);
3643*5c90c05cSAndroid Build Coastguard Worker   }
3644*5c90c05cSAndroid Build Coastguard Worker 
3645*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>
3646*5c90c05cSAndroid Build Coastguard Worker   void operator()(T) {
3647*5c90c05cSAndroid Build Coastguard Worker     FMT_ASSERT(false, "");
3648*5c90c05cSAndroid Build Coastguard Worker   }
3649*5c90c05cSAndroid Build Coastguard Worker 
3650*5c90c05cSAndroid Build Coastguard Worker   void operator()(typename basic_format_arg<buffered_context<Char>>::handle) {
3651*5c90c05cSAndroid Build Coastguard Worker     // User-defined types are handled separately because they require access
3652*5c90c05cSAndroid Build Coastguard Worker     // to the parse context.
3653*5c90c05cSAndroid Build Coastguard Worker   }
3654*5c90c05cSAndroid Build Coastguard Worker };
3655*5c90c05cSAndroid Build Coastguard Worker 
3656*5c90c05cSAndroid Build Coastguard Worker struct dynamic_spec_getter {
3657*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3658*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3659*5c90c05cSAndroid Build Coastguard Worker     return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3660*5c90c05cSAndroid Build Coastguard Worker   }
3661*5c90c05cSAndroid Build Coastguard Worker 
3662*5c90c05cSAndroid Build Coastguard Worker   template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3663*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3664*5c90c05cSAndroid Build Coastguard Worker     report_error("width/precision is not integer");
3665*5c90c05cSAndroid Build Coastguard Worker     return 0;
3666*5c90c05cSAndroid Build Coastguard Worker   }
3667*5c90c05cSAndroid Build Coastguard Worker };
3668*5c90c05cSAndroid Build Coastguard Worker 
3669*5c90c05cSAndroid Build Coastguard Worker template <typename Context, typename ID>
3670*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> basic_format_arg<Context> {
3671*5c90c05cSAndroid Build Coastguard Worker   auto arg = ctx.arg(id);
3672*5c90c05cSAndroid Build Coastguard Worker   if (!arg) report_error("argument not found");
3673*5c90c05cSAndroid Build Coastguard Worker   return arg;
3674*5c90c05cSAndroid Build Coastguard Worker }
3675*5c90c05cSAndroid Build Coastguard Worker 
3676*5c90c05cSAndroid Build Coastguard Worker template <typename Context>
3677*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR int get_dynamic_spec(
3678*5c90c05cSAndroid Build Coastguard Worker     arg_id_kind kind, const arg_ref<typename Context::char_type>& ref,
3679*5c90c05cSAndroid Build Coastguard Worker     Context& ctx) {
3680*5c90c05cSAndroid Build Coastguard Worker   FMT_ASSERT(kind != arg_id_kind::none, "");
3681*5c90c05cSAndroid Build Coastguard Worker   auto arg =
3682*5c90c05cSAndroid Build Coastguard Worker       kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name);
3683*5c90c05cSAndroid Build Coastguard Worker   if (!arg) report_error("argument not found");
3684*5c90c05cSAndroid Build Coastguard Worker   unsigned long long value = arg.visit(dynamic_spec_getter());
3685*5c90c05cSAndroid Build Coastguard Worker   if (value > to_unsigned(max_value<int>()))
3686*5c90c05cSAndroid Build Coastguard Worker     report_error("width/precision is out of range");
3687*5c90c05cSAndroid Build Coastguard Worker   return static_cast<int>(value);
3688*5c90c05cSAndroid Build Coastguard Worker }
3689*5c90c05cSAndroid Build Coastguard Worker 
3690*5c90c05cSAndroid Build Coastguard Worker template <typename Context>
3691*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR void handle_dynamic_spec(
3692*5c90c05cSAndroid Build Coastguard Worker     arg_id_kind kind, int& value,
3693*5c90c05cSAndroid Build Coastguard Worker     const arg_ref<typename Context::char_type>& ref, Context& ctx) {
3694*5c90c05cSAndroid Build Coastguard Worker   if (kind != arg_id_kind::none) value = get_dynamic_spec(kind, ref, ctx);
3695*5c90c05cSAndroid Build Coastguard Worker }
3696*5c90c05cSAndroid Build Coastguard Worker 
3697*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_NONTYPE_TEMPLATE_ARGS
3698*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char, size_t N,
3699*5c90c05cSAndroid Build Coastguard Worker           fmt::detail::fixed_string<Char, N> Str>
3700*5c90c05cSAndroid Build Coastguard Worker struct static_named_arg : view {
3701*5c90c05cSAndroid Build Coastguard Worker   static constexpr auto name = Str.data;
3702*5c90c05cSAndroid Build Coastguard Worker 
3703*5c90c05cSAndroid Build Coastguard Worker   const T& value;
3704*5c90c05cSAndroid Build Coastguard Worker   static_named_arg(const T& v) : value(v) {}
3705*5c90c05cSAndroid Build Coastguard Worker };
3706*5c90c05cSAndroid Build Coastguard Worker 
3707*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char, size_t N,
3708*5c90c05cSAndroid Build Coastguard Worker           fmt::detail::fixed_string<Char, N> Str>
3709*5c90c05cSAndroid Build Coastguard Worker struct is_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {};
3710*5c90c05cSAndroid Build Coastguard Worker 
3711*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char, size_t N,
3712*5c90c05cSAndroid Build Coastguard Worker           fmt::detail::fixed_string<Char, N> Str>
3713*5c90c05cSAndroid Build Coastguard Worker struct is_static_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {
3714*5c90c05cSAndroid Build Coastguard Worker };
3715*5c90c05cSAndroid Build Coastguard Worker 
3716*5c90c05cSAndroid Build Coastguard Worker template <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>
3717*5c90c05cSAndroid Build Coastguard Worker struct udl_arg {
3718*5c90c05cSAndroid Build Coastguard Worker   template <typename T> auto operator=(T&& value) const {
3719*5c90c05cSAndroid Build Coastguard Worker     return static_named_arg<T, Char, N, Str>(std::forward<T>(value));
3720*5c90c05cSAndroid Build Coastguard Worker   }
3721*5c90c05cSAndroid Build Coastguard Worker };
3722*5c90c05cSAndroid Build Coastguard Worker #else
3723*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct udl_arg {
3724*5c90c05cSAndroid Build Coastguard Worker   const Char* str;
3725*5c90c05cSAndroid Build Coastguard Worker 
3726*5c90c05cSAndroid Build Coastguard Worker   template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3727*5c90c05cSAndroid Build Coastguard Worker     return {str, std::forward<T>(value)};
3728*5c90c05cSAndroid Build Coastguard Worker   }
3729*5c90c05cSAndroid Build Coastguard Worker };
3730*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS
3731*5c90c05cSAndroid Build Coastguard Worker 
3732*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct format_handler {
3733*5c90c05cSAndroid Build Coastguard Worker   parse_context<Char> parse_ctx;
3734*5c90c05cSAndroid Build Coastguard Worker   buffered_context<Char> ctx;
3735*5c90c05cSAndroid Build Coastguard Worker 
3736*5c90c05cSAndroid Build Coastguard Worker   void on_text(const Char* begin, const Char* end) {
3737*5c90c05cSAndroid Build Coastguard Worker     copy_noinline<Char>(begin, end, ctx.out());
3738*5c90c05cSAndroid Build Coastguard Worker   }
3739*5c90c05cSAndroid Build Coastguard Worker 
3740*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }
3741*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto on_arg_id(int id) -> int {
3742*5c90c05cSAndroid Build Coastguard Worker     parse_ctx.check_arg_id(id);
3743*5c90c05cSAndroid Build Coastguard Worker     return id;
3744*5c90c05cSAndroid Build Coastguard Worker   }
3745*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
3746*5c90c05cSAndroid Build Coastguard Worker     parse_ctx.check_arg_id(id);
3747*5c90c05cSAndroid Build Coastguard Worker     int arg_id = ctx.arg_id(id);
3748*5c90c05cSAndroid Build Coastguard Worker     if (arg_id < 0) report_error("argument not found");
3749*5c90c05cSAndroid Build Coastguard Worker     return arg_id;
3750*5c90c05cSAndroid Build Coastguard Worker   }
3751*5c90c05cSAndroid Build Coastguard Worker 
3752*5c90c05cSAndroid Build Coastguard Worker   FMT_INLINE void on_replacement_field(int id, const Char*) {
3753*5c90c05cSAndroid Build Coastguard Worker     ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});
3754*5c90c05cSAndroid Build Coastguard Worker   }
3755*5c90c05cSAndroid Build Coastguard Worker 
3756*5c90c05cSAndroid Build Coastguard Worker   auto on_format_specs(int id, const Char* begin, const Char* end)
3757*5c90c05cSAndroid Build Coastguard Worker       -> const Char* {
3758*5c90c05cSAndroid Build Coastguard Worker     auto arg = get_arg(ctx, id);
3759*5c90c05cSAndroid Build Coastguard Worker     // Not using a visitor for custom types gives better codegen.
3760*5c90c05cSAndroid Build Coastguard Worker     if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();
3761*5c90c05cSAndroid Build Coastguard Worker 
3762*5c90c05cSAndroid Build Coastguard Worker     auto specs = dynamic_format_specs<Char>();
3763*5c90c05cSAndroid Build Coastguard Worker     begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());
3764*5c90c05cSAndroid Build Coastguard Worker     if (specs.dynamic()) {
3765*5c90c05cSAndroid Build Coastguard Worker       handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
3766*5c90c05cSAndroid Build Coastguard Worker                           ctx);
3767*5c90c05cSAndroid Build Coastguard Worker       handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3768*5c90c05cSAndroid Build Coastguard Worker                           specs.precision_ref, ctx);
3769*5c90c05cSAndroid Build Coastguard Worker     }
3770*5c90c05cSAndroid Build Coastguard Worker 
3771*5c90c05cSAndroid Build Coastguard Worker     arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});
3772*5c90c05cSAndroid Build Coastguard Worker     return begin;
3773*5c90c05cSAndroid Build Coastguard Worker   }
3774*5c90c05cSAndroid Build Coastguard Worker 
3775*5c90c05cSAndroid Build Coastguard Worker   FMT_NORETURN void on_error(const char* message) { report_error(message); }
3776*5c90c05cSAndroid Build Coastguard Worker };
3777*5c90c05cSAndroid Build Coastguard Worker 
3778*5c90c05cSAndroid Build Coastguard Worker using format_func = void (*)(detail::buffer<char>&, int, const char*);
3779*5c90c05cSAndroid Build Coastguard Worker FMT_API void do_report_error(format_func func, int error_code,
3780*5c90c05cSAndroid Build Coastguard Worker                              const char* message) noexcept;
3781*5c90c05cSAndroid Build Coastguard Worker 
3782*5c90c05cSAndroid Build Coastguard Worker FMT_API void format_error_code(buffer<char>& out, int error_code,
3783*5c90c05cSAndroid Build Coastguard Worker                                string_view message) noexcept;
3784*5c90c05cSAndroid Build Coastguard Worker 
3785*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char, type TYPE>
3786*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
3787*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto native_formatter<T, Char, TYPE>::format(
3788*5c90c05cSAndroid Build Coastguard Worker     const T& val, FormatContext& ctx) const -> decltype(ctx.out()) {
3789*5c90c05cSAndroid Build Coastguard Worker   if (!specs_.dynamic())
3790*5c90c05cSAndroid Build Coastguard Worker     return write<Char>(ctx.out(), val, specs_, ctx.locale());
3791*5c90c05cSAndroid Build Coastguard Worker   auto specs = format_specs(specs_);
3792*5c90c05cSAndroid Build Coastguard Worker   handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref,
3793*5c90c05cSAndroid Build Coastguard Worker                       ctx);
3794*5c90c05cSAndroid Build Coastguard Worker   handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3795*5c90c05cSAndroid Build Coastguard Worker                       specs_.precision_ref, ctx);
3796*5c90c05cSAndroid Build Coastguard Worker   return write<Char>(ctx.out(), val, specs, ctx.locale());
3797*5c90c05cSAndroid Build Coastguard Worker }
3798*5c90c05cSAndroid Build Coastguard Worker 
3799*5c90c05cSAndroid Build Coastguard Worker // DEPRECATED!
3800*5c90c05cSAndroid Build Coastguard Worker template <typename Char = char> struct vformat_args {
3801*5c90c05cSAndroid Build Coastguard Worker   using type = basic_format_args<buffered_context<Char>>;
3802*5c90c05cSAndroid Build Coastguard Worker };
3803*5c90c05cSAndroid Build Coastguard Worker template <> struct vformat_args<char> {
3804*5c90c05cSAndroid Build Coastguard Worker   using type = format_args;
3805*5c90c05cSAndroid Build Coastguard Worker };
3806*5c90c05cSAndroid Build Coastguard Worker 
3807*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
3808*5c90c05cSAndroid Build Coastguard Worker void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
3809*5c90c05cSAndroid Build Coastguard Worker                 typename vformat_args<Char>::type args, locale_ref loc = {}) {
3810*5c90c05cSAndroid Build Coastguard Worker   auto out = basic_appender<Char>(buf);
3811*5c90c05cSAndroid Build Coastguard Worker   parse_format_string(
3812*5c90c05cSAndroid Build Coastguard Worker       fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
3813*5c90c05cSAndroid Build Coastguard Worker }
3814*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
3815*5c90c05cSAndroid Build Coastguard Worker 
3816*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
3817*5c90c05cSAndroid Build Coastguard Worker 
3818*5c90c05cSAndroid Build Coastguard Worker #define FMT_FORMAT_AS(Type, Base)                                   \
3819*5c90c05cSAndroid Build Coastguard Worker   template <typename Char>                                          \
3820*5c90c05cSAndroid Build Coastguard Worker   struct formatter<Type, Char> : formatter<Base, Char> {            \
3821*5c90c05cSAndroid Build Coastguard Worker     template <typename FormatContext>                               \
3822*5c90c05cSAndroid Build Coastguard Worker     FMT_CONSTEXPR auto format(Type value, FormatContext& ctx) const \
3823*5c90c05cSAndroid Build Coastguard Worker         -> decltype(ctx.out()) {                                    \
3824*5c90c05cSAndroid Build Coastguard Worker       return formatter<Base, Char>::format(value, ctx);             \
3825*5c90c05cSAndroid Build Coastguard Worker     }                                                               \
3826*5c90c05cSAndroid Build Coastguard Worker   }
3827*5c90c05cSAndroid Build Coastguard Worker 
3828*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(signed char, int);
3829*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(unsigned char, unsigned);
3830*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(short, int);
3831*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(unsigned short, unsigned);
3832*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(long, detail::long_type);
3833*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(unsigned long, detail::ulong_type);
3834*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(Char*, const Char*);
3835*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
3836*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(std::nullptr_t, const void*);
3837*5c90c05cSAndroid Build Coastguard Worker FMT_FORMAT_AS(void*, const void*);
3838*5c90c05cSAndroid Build Coastguard Worker 
3839*5c90c05cSAndroid Build Coastguard Worker template <typename Char, size_t N>
3840*5c90c05cSAndroid Build Coastguard Worker struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {};
3841*5c90c05cSAndroid Build Coastguard Worker 
3842*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename Traits, typename Allocator>
3843*5c90c05cSAndroid Build Coastguard Worker class formatter<std::basic_string<Char, Traits, Allocator>, Char>
3844*5c90c05cSAndroid Build Coastguard Worker     : public formatter<basic_string_view<Char>, Char> {};
3845*5c90c05cSAndroid Build Coastguard Worker 
3846*5c90c05cSAndroid Build Coastguard Worker template <int N, typename Char>
3847*5c90c05cSAndroid Build Coastguard Worker struct formatter<detail::bitint<N>, Char> : formatter<long long, Char> {};
3848*5c90c05cSAndroid Build Coastguard Worker template <int N, typename Char>
3849*5c90c05cSAndroid Build Coastguard Worker struct formatter<detail::ubitint<N>, Char>
3850*5c90c05cSAndroid Build Coastguard Worker     : formatter<unsigned long long, Char> {};
3851*5c90c05cSAndroid Build Coastguard Worker 
3852*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
3853*5c90c05cSAndroid Build Coastguard Worker struct formatter<detail::float128, Char>
3854*5c90c05cSAndroid Build Coastguard Worker     : detail::native_formatter<detail::float128, Char,
3855*5c90c05cSAndroid Build Coastguard Worker                                detail::type::float_type> {};
3856*5c90c05cSAndroid Build Coastguard Worker 
3857*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
3858*5c90c05cSAndroid Build Coastguard Worker struct formatter<T, Char, void_t<detail::format_as_result<T>>>
3859*5c90c05cSAndroid Build Coastguard Worker     : formatter<detail::format_as_result<T>, Char> {
3860*5c90c05cSAndroid Build Coastguard Worker   template <typename FormatContext>
3861*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const
3862*5c90c05cSAndroid Build Coastguard Worker       -> decltype(ctx.out()) {
3863*5c90c05cSAndroid Build Coastguard Worker     auto&& val = format_as(value);  // Make an lvalue reference for format.
3864*5c90c05cSAndroid Build Coastguard Worker     return formatter<detail::format_as_result<T>, Char>::format(val, ctx);
3865*5c90c05cSAndroid Build Coastguard Worker   }
3866*5c90c05cSAndroid Build Coastguard Worker };
3867*5c90c05cSAndroid Build Coastguard Worker 
3868*5c90c05cSAndroid Build Coastguard Worker /**
3869*5c90c05cSAndroid Build Coastguard Worker  * Converts `p` to `const void*` for pointer formatting.
3870*5c90c05cSAndroid Build Coastguard Worker  *
3871*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
3872*5c90c05cSAndroid Build Coastguard Worker  *
3873*5c90c05cSAndroid Build Coastguard Worker  *     auto s = fmt::format("{}", fmt::ptr(p));
3874*5c90c05cSAndroid Build Coastguard Worker  */
3875*5c90c05cSAndroid Build Coastguard Worker template <typename T> auto ptr(T p) -> const void* {
3876*5c90c05cSAndroid Build Coastguard Worker   static_assert(std::is_pointer<T>::value, "");
3877*5c90c05cSAndroid Build Coastguard Worker   return detail::bit_cast<const void*>(p);
3878*5c90c05cSAndroid Build Coastguard Worker }
3879*5c90c05cSAndroid Build Coastguard Worker 
3880*5c90c05cSAndroid Build Coastguard Worker /**
3881*5c90c05cSAndroid Build Coastguard Worker  * Converts `e` to the underlying type.
3882*5c90c05cSAndroid Build Coastguard Worker  *
3883*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
3884*5c90c05cSAndroid Build Coastguard Worker  *
3885*5c90c05cSAndroid Build Coastguard Worker  *     enum class color { red, green, blue };
3886*5c90c05cSAndroid Build Coastguard Worker  *     auto s = fmt::format("{}", fmt::underlying(color::red));
3887*5c90c05cSAndroid Build Coastguard Worker  */
3888*5c90c05cSAndroid Build Coastguard Worker template <typename Enum>
3889*5c90c05cSAndroid Build Coastguard Worker constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
3890*5c90c05cSAndroid Build Coastguard Worker   return static_cast<underlying_t<Enum>>(e);
3891*5c90c05cSAndroid Build Coastguard Worker }
3892*5c90c05cSAndroid Build Coastguard Worker 
3893*5c90c05cSAndroid Build Coastguard Worker namespace enums {
3894*5c90c05cSAndroid Build Coastguard Worker template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
3895*5c90c05cSAndroid Build Coastguard Worker constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
3896*5c90c05cSAndroid Build Coastguard Worker   return static_cast<underlying_t<Enum>>(e);
3897*5c90c05cSAndroid Build Coastguard Worker }
3898*5c90c05cSAndroid Build Coastguard Worker }  // namespace enums
3899*5c90c05cSAndroid Build Coastguard Worker 
3900*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_byte
3901*5c90c05cSAndroid Build Coastguard Worker template <> struct formatter<std::byte> : formatter<unsigned> {
3902*5c90c05cSAndroid Build Coastguard Worker   static auto format_as(std::byte b) -> unsigned char {
3903*5c90c05cSAndroid Build Coastguard Worker     return static_cast<unsigned char>(b);
3904*5c90c05cSAndroid Build Coastguard Worker   }
3905*5c90c05cSAndroid Build Coastguard Worker   template <typename Context>
3906*5c90c05cSAndroid Build Coastguard Worker   auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) {
3907*5c90c05cSAndroid Build Coastguard Worker     return formatter<unsigned>::format(format_as(b), ctx);
3908*5c90c05cSAndroid Build Coastguard Worker   }
3909*5c90c05cSAndroid Build Coastguard Worker };
3910*5c90c05cSAndroid Build Coastguard Worker #endif
3911*5c90c05cSAndroid Build Coastguard Worker 
3912*5c90c05cSAndroid Build Coastguard Worker struct bytes {
3913*5c90c05cSAndroid Build Coastguard Worker   string_view data;
3914*5c90c05cSAndroid Build Coastguard Worker 
3915*5c90c05cSAndroid Build Coastguard Worker   inline explicit bytes(string_view s) : data(s) {}
3916*5c90c05cSAndroid Build Coastguard Worker };
3917*5c90c05cSAndroid Build Coastguard Worker 
3918*5c90c05cSAndroid Build Coastguard Worker template <> struct formatter<bytes> {
3919*5c90c05cSAndroid Build Coastguard Worker  private:
3920*5c90c05cSAndroid Build Coastguard Worker   detail::dynamic_format_specs<> specs_;
3921*5c90c05cSAndroid Build Coastguard Worker 
3922*5c90c05cSAndroid Build Coastguard Worker  public:
3923*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
3924*5c90c05cSAndroid Build Coastguard Worker     return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
3925*5c90c05cSAndroid Build Coastguard Worker                               detail::type::string_type);
3926*5c90c05cSAndroid Build Coastguard Worker   }
3927*5c90c05cSAndroid Build Coastguard Worker 
3928*5c90c05cSAndroid Build Coastguard Worker   template <typename FormatContext>
3929*5c90c05cSAndroid Build Coastguard Worker   auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {
3930*5c90c05cSAndroid Build Coastguard Worker     auto specs = specs_;
3931*5c90c05cSAndroid Build Coastguard Worker     detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
3932*5c90c05cSAndroid Build Coastguard Worker                                 specs.width_ref, ctx);
3933*5c90c05cSAndroid Build Coastguard Worker     detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3934*5c90c05cSAndroid Build Coastguard Worker                                 specs.precision_ref, ctx);
3935*5c90c05cSAndroid Build Coastguard Worker     return detail::write_bytes<char>(ctx.out(), b.data, specs);
3936*5c90c05cSAndroid Build Coastguard Worker   }
3937*5c90c05cSAndroid Build Coastguard Worker };
3938*5c90c05cSAndroid Build Coastguard Worker 
3939*5c90c05cSAndroid Build Coastguard Worker // group_digits_view is not derived from view because it copies the argument.
3940*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct group_digits_view {
3941*5c90c05cSAndroid Build Coastguard Worker   T value;
3942*5c90c05cSAndroid Build Coastguard Worker };
3943*5c90c05cSAndroid Build Coastguard Worker 
3944*5c90c05cSAndroid Build Coastguard Worker /**
3945*5c90c05cSAndroid Build Coastguard Worker  * Returns a view that formats an integer value using ',' as a
3946*5c90c05cSAndroid Build Coastguard Worker  * locale-independent thousands separator.
3947*5c90c05cSAndroid Build Coastguard Worker  *
3948*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
3949*5c90c05cSAndroid Build Coastguard Worker  *
3950*5c90c05cSAndroid Build Coastguard Worker  *     fmt::print("{}", fmt::group_digits(12345));
3951*5c90c05cSAndroid Build Coastguard Worker  *     // Output: "12,345"
3952*5c90c05cSAndroid Build Coastguard Worker  */
3953*5c90c05cSAndroid Build Coastguard Worker template <typename T> auto group_digits(T value) -> group_digits_view<T> {
3954*5c90c05cSAndroid Build Coastguard Worker   return {value};
3955*5c90c05cSAndroid Build Coastguard Worker }
3956*5c90c05cSAndroid Build Coastguard Worker 
3957*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
3958*5c90c05cSAndroid Build Coastguard Worker  private:
3959*5c90c05cSAndroid Build Coastguard Worker   detail::dynamic_format_specs<> specs_;
3960*5c90c05cSAndroid Build Coastguard Worker 
3961*5c90c05cSAndroid Build Coastguard Worker  public:
3962*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
3963*5c90c05cSAndroid Build Coastguard Worker     return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
3964*5c90c05cSAndroid Build Coastguard Worker                               detail::type::int_type);
3965*5c90c05cSAndroid Build Coastguard Worker   }
3966*5c90c05cSAndroid Build Coastguard Worker 
3967*5c90c05cSAndroid Build Coastguard Worker   template <typename FormatContext>
3968*5c90c05cSAndroid Build Coastguard Worker   auto format(group_digits_view<T> t, FormatContext& ctx) const
3969*5c90c05cSAndroid Build Coastguard Worker       -> decltype(ctx.out()) {
3970*5c90c05cSAndroid Build Coastguard Worker     auto specs = specs_;
3971*5c90c05cSAndroid Build Coastguard Worker     detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
3972*5c90c05cSAndroid Build Coastguard Worker                                 specs.width_ref, ctx);
3973*5c90c05cSAndroid Build Coastguard Worker     detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3974*5c90c05cSAndroid Build Coastguard Worker                                 specs.precision_ref, ctx);
3975*5c90c05cSAndroid Build Coastguard Worker     auto arg = detail::make_write_int_arg(t.value, specs.sign());
3976*5c90c05cSAndroid Build Coastguard Worker     return detail::write_int(
3977*5c90c05cSAndroid Build Coastguard Worker         ctx.out(), static_cast<detail::uint64_or_128_t<T>>(arg.abs_value),
3978*5c90c05cSAndroid Build Coastguard Worker         arg.prefix, specs, detail::digit_grouping<char>("\3", ","));
3979*5c90c05cSAndroid Build Coastguard Worker   }
3980*5c90c05cSAndroid Build Coastguard Worker };
3981*5c90c05cSAndroid Build Coastguard Worker 
3982*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char> struct nested_view {
3983*5c90c05cSAndroid Build Coastguard Worker   const formatter<T, Char>* fmt;
3984*5c90c05cSAndroid Build Coastguard Worker   const T* value;
3985*5c90c05cSAndroid Build Coastguard Worker };
3986*5c90c05cSAndroid Build Coastguard Worker 
3987*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
3988*5c90c05cSAndroid Build Coastguard Worker struct formatter<nested_view<T, Char>, Char> {
3989*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
3990*5c90c05cSAndroid Build Coastguard Worker     return ctx.begin();
3991*5c90c05cSAndroid Build Coastguard Worker   }
3992*5c90c05cSAndroid Build Coastguard Worker   template <typename FormatContext>
3993*5c90c05cSAndroid Build Coastguard Worker   auto format(nested_view<T, Char> view, FormatContext& ctx) const
3994*5c90c05cSAndroid Build Coastguard Worker       -> decltype(ctx.out()) {
3995*5c90c05cSAndroid Build Coastguard Worker     return view.fmt->format(*view.value, ctx);
3996*5c90c05cSAndroid Build Coastguard Worker   }
3997*5c90c05cSAndroid Build Coastguard Worker };
3998*5c90c05cSAndroid Build Coastguard Worker 
3999*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char = char> struct nested_formatter {
4000*5c90c05cSAndroid Build Coastguard Worker  private:
4001*5c90c05cSAndroid Build Coastguard Worker   basic_specs specs_;
4002*5c90c05cSAndroid Build Coastguard Worker   int width_;
4003*5c90c05cSAndroid Build Coastguard Worker   formatter<T, Char> formatter_;
4004*5c90c05cSAndroid Build Coastguard Worker 
4005*5c90c05cSAndroid Build Coastguard Worker  public:
4006*5c90c05cSAndroid Build Coastguard Worker   constexpr nested_formatter() : width_(0) {}
4007*5c90c05cSAndroid Build Coastguard Worker 
4008*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
4009*5c90c05cSAndroid Build Coastguard Worker     auto it = ctx.begin(), end = ctx.end();
4010*5c90c05cSAndroid Build Coastguard Worker     if (it == end) return it;
4011*5c90c05cSAndroid Build Coastguard Worker     auto specs = format_specs();
4012*5c90c05cSAndroid Build Coastguard Worker     it = detail::parse_align(it, end, specs);
4013*5c90c05cSAndroid Build Coastguard Worker     specs_ = specs;
4014*5c90c05cSAndroid Build Coastguard Worker     Char c = *it;
4015*5c90c05cSAndroid Build Coastguard Worker     auto width_ref = detail::arg_ref<Char>();
4016*5c90c05cSAndroid Build Coastguard Worker     if ((c >= '0' && c <= '9') || c == '{') {
4017*5c90c05cSAndroid Build Coastguard Worker       it = detail::parse_width(it, end, specs, width_ref, ctx);
4018*5c90c05cSAndroid Build Coastguard Worker       width_ = specs.width;
4019*5c90c05cSAndroid Build Coastguard Worker     }
4020*5c90c05cSAndroid Build Coastguard Worker     ctx.advance_to(it);
4021*5c90c05cSAndroid Build Coastguard Worker     return formatter_.parse(ctx);
4022*5c90c05cSAndroid Build Coastguard Worker   }
4023*5c90c05cSAndroid Build Coastguard Worker 
4024*5c90c05cSAndroid Build Coastguard Worker   template <typename FormatContext, typename F>
4025*5c90c05cSAndroid Build Coastguard Worker   auto write_padded(FormatContext& ctx, F write) const -> decltype(ctx.out()) {
4026*5c90c05cSAndroid Build Coastguard Worker     if (width_ == 0) return write(ctx.out());
4027*5c90c05cSAndroid Build Coastguard Worker     auto buf = basic_memory_buffer<Char>();
4028*5c90c05cSAndroid Build Coastguard Worker     write(basic_appender<Char>(buf));
4029*5c90c05cSAndroid Build Coastguard Worker     auto specs = format_specs();
4030*5c90c05cSAndroid Build Coastguard Worker     specs.width = width_;
4031*5c90c05cSAndroid Build Coastguard Worker     specs.set_fill(
4032*5c90c05cSAndroid Build Coastguard Worker         basic_string_view<Char>(specs_.fill<Char>(), specs_.fill_size()));
4033*5c90c05cSAndroid Build Coastguard Worker     specs.set_align(specs_.align());
4034*5c90c05cSAndroid Build Coastguard Worker     return detail::write<Char>(
4035*5c90c05cSAndroid Build Coastguard Worker         ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
4036*5c90c05cSAndroid Build Coastguard Worker   }
4037*5c90c05cSAndroid Build Coastguard Worker 
4038*5c90c05cSAndroid Build Coastguard Worker   auto nested(const T& value) const -> nested_view<T, Char> {
4039*5c90c05cSAndroid Build Coastguard Worker     return nested_view<T, Char>{&formatter_, &value};
4040*5c90c05cSAndroid Build Coastguard Worker   }
4041*5c90c05cSAndroid Build Coastguard Worker };
4042*5c90c05cSAndroid Build Coastguard Worker 
4043*5c90c05cSAndroid Build Coastguard Worker inline namespace literals {
4044*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_NONTYPE_TEMPLATE_ARGS
4045*5c90c05cSAndroid Build Coastguard Worker template <detail::fixed_string Str> constexpr auto operator""_a() {
4046*5c90c05cSAndroid Build Coastguard Worker   using char_t = remove_cvref_t<decltype(Str.data[0])>;
4047*5c90c05cSAndroid Build Coastguard Worker   return detail::udl_arg<char_t, sizeof(Str.data) / sizeof(char_t), Str>();
4048*5c90c05cSAndroid Build Coastguard Worker }
4049*5c90c05cSAndroid Build Coastguard Worker #else
4050*5c90c05cSAndroid Build Coastguard Worker /**
4051*5c90c05cSAndroid Build Coastguard Worker  * User-defined literal equivalent of `fmt::arg`.
4052*5c90c05cSAndroid Build Coastguard Worker  *
4053*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
4054*5c90c05cSAndroid Build Coastguard Worker  *
4055*5c90c05cSAndroid Build Coastguard Worker  *     using namespace fmt::literals;
4056*5c90c05cSAndroid Build Coastguard Worker  *     fmt::print("The answer is {answer}.", "answer"_a=42);
4057*5c90c05cSAndroid Build Coastguard Worker  */
4058*5c90c05cSAndroid Build Coastguard Worker constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg<char> {
4059*5c90c05cSAndroid Build Coastguard Worker   return {s};
4060*5c90c05cSAndroid Build Coastguard Worker }
4061*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS
4062*5c90c05cSAndroid Build Coastguard Worker }  // namespace literals
4063*5c90c05cSAndroid Build Coastguard Worker 
4064*5c90c05cSAndroid Build Coastguard Worker /// A fast integer formatter.
4065*5c90c05cSAndroid Build Coastguard Worker class format_int {
4066*5c90c05cSAndroid Build Coastguard Worker  private:
4067*5c90c05cSAndroid Build Coastguard Worker   // Buffer should be large enough to hold all digits (digits10 + 1),
4068*5c90c05cSAndroid Build Coastguard Worker   // a sign and a null character.
4069*5c90c05cSAndroid Build Coastguard Worker   enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
4070*5c90c05cSAndroid Build Coastguard Worker   mutable char buffer_[buffer_size];
4071*5c90c05cSAndroid Build Coastguard Worker   char* str_;
4072*5c90c05cSAndroid Build Coastguard Worker 
4073*5c90c05cSAndroid Build Coastguard Worker   template <typename UInt>
4074*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* {
4075*5c90c05cSAndroid Build Coastguard Worker     auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
4076*5c90c05cSAndroid Build Coastguard Worker     return detail::do_format_decimal(buffer_, n, buffer_size - 1);
4077*5c90c05cSAndroid Build Coastguard Worker   }
4078*5c90c05cSAndroid Build Coastguard Worker 
4079*5c90c05cSAndroid Build Coastguard Worker   template <typename Int>
4080*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto format_signed(Int value) -> char* {
4081*5c90c05cSAndroid Build Coastguard Worker     auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
4082*5c90c05cSAndroid Build Coastguard Worker     bool negative = value < 0;
4083*5c90c05cSAndroid Build Coastguard Worker     if (negative) abs_value = 0 - abs_value;
4084*5c90c05cSAndroid Build Coastguard Worker     auto begin = format_unsigned(abs_value);
4085*5c90c05cSAndroid Build Coastguard Worker     if (negative) *--begin = '-';
4086*5c90c05cSAndroid Build Coastguard Worker     return begin;
4087*5c90c05cSAndroid Build Coastguard Worker   }
4088*5c90c05cSAndroid Build Coastguard Worker 
4089*5c90c05cSAndroid Build Coastguard Worker  public:
4090*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(int value) : str_(format_signed(value)) {}
4091*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(long value)
4092*5c90c05cSAndroid Build Coastguard Worker       : str_(format_signed(value)) {}
4093*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(long long value)
4094*5c90c05cSAndroid Build Coastguard Worker       : str_(format_signed(value)) {}
4095*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(unsigned value)
4096*5c90c05cSAndroid Build Coastguard Worker       : str_(format_unsigned(value)) {}
4097*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(unsigned long value)
4098*5c90c05cSAndroid Build Coastguard Worker       : str_(format_unsigned(value)) {}
4099*5c90c05cSAndroid Build Coastguard Worker   explicit FMT_CONSTEXPR20 format_int(unsigned long long value)
4100*5c90c05cSAndroid Build Coastguard Worker       : str_(format_unsigned(value)) {}
4101*5c90c05cSAndroid Build Coastguard Worker 
4102*5c90c05cSAndroid Build Coastguard Worker   /// Returns the number of characters written to the output buffer.
4103*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto size() const -> size_t {
4104*5c90c05cSAndroid Build Coastguard Worker     return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
4105*5c90c05cSAndroid Build Coastguard Worker   }
4106*5c90c05cSAndroid Build Coastguard Worker 
4107*5c90c05cSAndroid Build Coastguard Worker   /// Returns a pointer to the output buffer content. No terminating null
4108*5c90c05cSAndroid Build Coastguard Worker   /// character is appended.
4109*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto data() const -> const char* { return str_; }
4110*5c90c05cSAndroid Build Coastguard Worker 
4111*5c90c05cSAndroid Build Coastguard Worker   /// Returns a pointer to the output buffer content with terminating null
4112*5c90c05cSAndroid Build Coastguard Worker   /// character appended.
4113*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR20 auto c_str() const -> const char* {
4114*5c90c05cSAndroid Build Coastguard Worker     buffer_[buffer_size - 1] = '\0';
4115*5c90c05cSAndroid Build Coastguard Worker     return str_;
4116*5c90c05cSAndroid Build Coastguard Worker   }
4117*5c90c05cSAndroid Build Coastguard Worker 
4118*5c90c05cSAndroid Build Coastguard Worker   /// Returns the content of the output buffer as an `std::string`.
4119*5c90c05cSAndroid Build Coastguard Worker   inline auto str() const -> std::string { return {str_, size()}; }
4120*5c90c05cSAndroid Build Coastguard Worker };
4121*5c90c05cSAndroid Build Coastguard Worker 
4122*5c90c05cSAndroid Build Coastguard Worker #define FMT_STRING_IMPL(s, base)                                           \
4123*5c90c05cSAndroid Build Coastguard Worker   [] {                                                                     \
4124*5c90c05cSAndroid Build Coastguard Worker     /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
4125*5c90c05cSAndroid Build Coastguard Worker     /* Use a macro-like name to avoid shadowing warnings. */               \
4126*5c90c05cSAndroid Build Coastguard Worker     struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base {            \
4127*5c90c05cSAndroid Build Coastguard Worker       using char_type = fmt::remove_cvref_t<decltype(s[0])>;               \
4128*5c90c05cSAndroid Build Coastguard Worker       FMT_CONSTEXPR explicit operator fmt::basic_string_view<char_type>()  \
4129*5c90c05cSAndroid Build Coastguard Worker           const {                                                          \
4130*5c90c05cSAndroid Build Coastguard Worker         return fmt::detail::compile_string_to_view<char_type>(s);          \
4131*5c90c05cSAndroid Build Coastguard Worker       }                                                                    \
4132*5c90c05cSAndroid Build Coastguard Worker     };                                                                     \
4133*5c90c05cSAndroid Build Coastguard Worker     using FMT_STRING_VIEW =                                                \
4134*5c90c05cSAndroid Build Coastguard Worker         fmt::basic_string_view<typename FMT_COMPILE_STRING::char_type>;    \
4135*5c90c05cSAndroid Build Coastguard Worker     fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING()));     \
4136*5c90c05cSAndroid Build Coastguard Worker     return FMT_COMPILE_STRING();                                           \
4137*5c90c05cSAndroid Build Coastguard Worker   }()
4138*5c90c05cSAndroid Build Coastguard Worker 
4139*5c90c05cSAndroid Build Coastguard Worker /**
4140*5c90c05cSAndroid Build Coastguard Worker  * Constructs a compile-time format string from a string literal `s`.
4141*5c90c05cSAndroid Build Coastguard Worker  *
4142*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
4143*5c90c05cSAndroid Build Coastguard Worker  *
4144*5c90c05cSAndroid Build Coastguard Worker  *     // A compile-time error because 'd' is an invalid specifier for strings.
4145*5c90c05cSAndroid Build Coastguard Worker  *     std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
4146*5c90c05cSAndroid Build Coastguard Worker  */
4147*5c90c05cSAndroid Build Coastguard Worker #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string)
4148*5c90c05cSAndroid Build Coastguard Worker 
4149*5c90c05cSAndroid Build Coastguard Worker FMT_API auto vsystem_error(int error_code, string_view fmt, format_args args)
4150*5c90c05cSAndroid Build Coastguard Worker     -> std::system_error;
4151*5c90c05cSAndroid Build Coastguard Worker 
4152*5c90c05cSAndroid Build Coastguard Worker /**
4153*5c90c05cSAndroid Build Coastguard Worker  * Constructs `std::system_error` with a message formatted with
4154*5c90c05cSAndroid Build Coastguard Worker  * `fmt::format(fmt, args...)`.
4155*5c90c05cSAndroid Build Coastguard Worker  * `error_code` is a system error code as given by `errno`.
4156*5c90c05cSAndroid Build Coastguard Worker  *
4157*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
4158*5c90c05cSAndroid Build Coastguard Worker  *
4159*5c90c05cSAndroid Build Coastguard Worker  *     // This throws std::system_error with the description
4160*5c90c05cSAndroid Build Coastguard Worker  *     //   cannot open file 'madeup': No such file or directory
4161*5c90c05cSAndroid Build Coastguard Worker  *     // or similar (system message may vary).
4162*5c90c05cSAndroid Build Coastguard Worker  *     const char* filename = "madeup";
4163*5c90c05cSAndroid Build Coastguard Worker  *     FILE* file = fopen(filename, "r");
4164*5c90c05cSAndroid Build Coastguard Worker  *     if (!file)
4165*5c90c05cSAndroid Build Coastguard Worker  *       throw fmt::system_error(errno, "cannot open file '{}'", filename);
4166*5c90c05cSAndroid Build Coastguard Worker  */
4167*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
4168*5c90c05cSAndroid Build Coastguard Worker auto system_error(int error_code, format_string<T...> fmt, T&&... args)
4169*5c90c05cSAndroid Build Coastguard Worker     -> std::system_error {
4170*5c90c05cSAndroid Build Coastguard Worker   return vsystem_error(error_code, fmt.str, vargs<T...>{{args...}});
4171*5c90c05cSAndroid Build Coastguard Worker }
4172*5c90c05cSAndroid Build Coastguard Worker 
4173*5c90c05cSAndroid Build Coastguard Worker /**
4174*5c90c05cSAndroid Build Coastguard Worker  * Formats an error message for an error returned by an operating system or a
4175*5c90c05cSAndroid Build Coastguard Worker  * language runtime, for example a file opening error, and writes it to `out`.
4176*5c90c05cSAndroid Build Coastguard Worker  * The format is the same as the one used by `std::system_error(ec, message)`
4177*5c90c05cSAndroid Build Coastguard Worker  * where `ec` is `std::error_code(error_code, std::generic_category())`.
4178*5c90c05cSAndroid Build Coastguard Worker  * It is implementation-defined but normally looks like:
4179*5c90c05cSAndroid Build Coastguard Worker  *
4180*5c90c05cSAndroid Build Coastguard Worker  *     <message>: <system-message>
4181*5c90c05cSAndroid Build Coastguard Worker  *
4182*5c90c05cSAndroid Build Coastguard Worker  * where `<message>` is the passed message and `<system-message>` is the system
4183*5c90c05cSAndroid Build Coastguard Worker  * message corresponding to the error code.
4184*5c90c05cSAndroid Build Coastguard Worker  * `error_code` is a system error code as given by `errno`.
4185*5c90c05cSAndroid Build Coastguard Worker  */
4186*5c90c05cSAndroid Build Coastguard Worker FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
4187*5c90c05cSAndroid Build Coastguard Worker                                  const char* message) noexcept;
4188*5c90c05cSAndroid Build Coastguard Worker 
4189*5c90c05cSAndroid Build Coastguard Worker // Reports a system error without throwing an exception.
4190*5c90c05cSAndroid Build Coastguard Worker // Can be used to report errors from destructors.
4191*5c90c05cSAndroid Build Coastguard Worker FMT_API void report_system_error(int error_code, const char* message) noexcept;
4192*5c90c05cSAndroid Build Coastguard Worker 
4193*5c90c05cSAndroid Build Coastguard Worker inline auto vformat(detail::locale_ref loc, string_view fmt, format_args args)
4194*5c90c05cSAndroid Build Coastguard Worker     -> std::string {
4195*5c90c05cSAndroid Build Coastguard Worker   auto buf = memory_buffer();
4196*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt, args, loc);
4197*5c90c05cSAndroid Build Coastguard Worker   return {buf.data(), buf.size()};
4198*5c90c05cSAndroid Build Coastguard Worker }
4199*5c90c05cSAndroid Build Coastguard Worker 
4200*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
4201*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE auto format(detail::locale_ref loc, format_string<T...> fmt,
4202*5c90c05cSAndroid Build Coastguard Worker                        T&&... args) -> std::string {
4203*5c90c05cSAndroid Build Coastguard Worker   return vformat(loc, fmt.str, vargs<T...>{{args...}});
4204*5c90c05cSAndroid Build Coastguard Worker }
4205*5c90c05cSAndroid Build Coastguard Worker 
4206*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt,
4207*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
4208*5c90c05cSAndroid Build Coastguard Worker auto vformat_to(OutputIt out, detail::locale_ref loc, string_view fmt,
4209*5c90c05cSAndroid Build Coastguard Worker                 format_args args) -> OutputIt {
4210*5c90c05cSAndroid Build Coastguard Worker   auto&& buf = detail::get_buffer<char>(out);
4211*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt, args, loc);
4212*5c90c05cSAndroid Build Coastguard Worker   return detail::get_iterator(buf, out);
4213*5c90c05cSAndroid Build Coastguard Worker }
4214*5c90c05cSAndroid Build Coastguard Worker 
4215*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename... T,
4216*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
4217*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE auto format_to(OutputIt out, detail::locale_ref loc,
4218*5c90c05cSAndroid Build Coastguard Worker                           format_string<T...> fmt, T&&... args) -> OutputIt {
4219*5c90c05cSAndroid Build Coastguard Worker   return fmt::vformat_to(out, loc, fmt.str, vargs<T...>{{args...}});
4220*5c90c05cSAndroid Build Coastguard Worker }
4221*5c90c05cSAndroid Build Coastguard Worker 
4222*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
4223*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD FMT_INLINE auto formatted_size(detail::locale_ref loc,
4224*5c90c05cSAndroid Build Coastguard Worker                                              format_string<T...> fmt,
4225*5c90c05cSAndroid Build Coastguard Worker                                              T&&... args) -> size_t {
4226*5c90c05cSAndroid Build Coastguard Worker   auto buf = detail::counting_buffer<>();
4227*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, loc);
4228*5c90c05cSAndroid Build Coastguard Worker   return buf.count();
4229*5c90c05cSAndroid Build Coastguard Worker }
4230*5c90c05cSAndroid Build Coastguard Worker 
4231*5c90c05cSAndroid Build Coastguard Worker FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
4232*5c90c05cSAndroid Build Coastguard Worker 
4233*5c90c05cSAndroid Build Coastguard Worker /**
4234*5c90c05cSAndroid Build Coastguard Worker  * Formats `args` according to specifications in `fmt` and returns the result
4235*5c90c05cSAndroid Build Coastguard Worker  * as a string.
4236*5c90c05cSAndroid Build Coastguard Worker  *
4237*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
4238*5c90c05cSAndroid Build Coastguard Worker  *
4239*5c90c05cSAndroid Build Coastguard Worker  *     #include <fmt/format.h>
4240*5c90c05cSAndroid Build Coastguard Worker  *     std::string message = fmt::format("The answer is {}.", 42);
4241*5c90c05cSAndroid Build Coastguard Worker  */
4242*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
4243*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
4244*5c90c05cSAndroid Build Coastguard Worker     -> std::string {
4245*5c90c05cSAndroid Build Coastguard Worker   return vformat(fmt.str, vargs<T...>{{args...}});
4246*5c90c05cSAndroid Build Coastguard Worker }
4247*5c90c05cSAndroid Build Coastguard Worker 
4248*5c90c05cSAndroid Build Coastguard Worker /**
4249*5c90c05cSAndroid Build Coastguard Worker  * Converts `value` to `std::string` using the default format for type `T`.
4250*5c90c05cSAndroid Build Coastguard Worker  *
4251*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
4252*5c90c05cSAndroid Build Coastguard Worker  *
4253*5c90c05cSAndroid Build Coastguard Worker  *     std::string answer = fmt::to_string(42);
4254*5c90c05cSAndroid Build Coastguard Worker  */
4255*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4256*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD auto to_string(T value) -> std::string {
4257*5c90c05cSAndroid Build Coastguard Worker   // The buffer should be large enough to store the number including the sign
4258*5c90c05cSAndroid Build Coastguard Worker   // or "false" for bool.
4259*5c90c05cSAndroid Build Coastguard Worker   char buffer[max_of(detail::digits10<T>() + 2, 5)];
4260*5c90c05cSAndroid Build Coastguard Worker   char* begin = buffer;
4261*5c90c05cSAndroid Build Coastguard Worker   return {buffer, detail::write<char>(begin, value)};
4262*5c90c05cSAndroid Build Coastguard Worker }
4263*5c90c05cSAndroid Build Coastguard Worker 
4264*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(detail::use_format_as<T>::value)>
4265*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD auto to_string(const T& value) -> std::string {
4266*5c90c05cSAndroid Build Coastguard Worker   return to_string(format_as(value));
4267*5c90c05cSAndroid Build Coastguard Worker }
4268*5c90c05cSAndroid Build Coastguard Worker 
4269*5c90c05cSAndroid Build Coastguard Worker template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4270*5c90c05cSAndroid Build Coastguard Worker                                     !detail::use_format_as<T>::value)>
4271*5c90c05cSAndroid Build Coastguard Worker FMT_NODISCARD auto to_string(const T& value) -> std::string {
4272*5c90c05cSAndroid Build Coastguard Worker   auto buffer = memory_buffer();
4273*5c90c05cSAndroid Build Coastguard Worker   detail::write<char>(appender(buffer), value);
4274*5c90c05cSAndroid Build Coastguard Worker   return {buffer.data(), buffer.size()};
4275*5c90c05cSAndroid Build Coastguard Worker }
4276*5c90c05cSAndroid Build Coastguard Worker 
4277*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
4278*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
4279*5c90c05cSAndroid Build Coastguard Worker 
4280*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_HEADER_ONLY
4281*5c90c05cSAndroid Build Coastguard Worker #  define FMT_FUNC inline
4282*5c90c05cSAndroid Build Coastguard Worker #  include "format-inl.h"
4283*5c90c05cSAndroid Build Coastguard Worker #endif
4284*5c90c05cSAndroid Build Coastguard Worker 
4285*5c90c05cSAndroid Build Coastguard Worker // Restore _LIBCPP_REMOVE_TRANSITIVE_INCLUDES.
4286*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_REMOVE_TRANSITIVE_INCLUDES
4287*5c90c05cSAndroid Build Coastguard Worker #  undef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
4288*5c90c05cSAndroid Build Coastguard Worker #endif
4289*5c90c05cSAndroid Build Coastguard Worker 
4290*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_FORMAT_H_
4291