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