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