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 #include "core.h" 37 38 #include <algorithm> 39 #include <cerrno> 40 #include <cmath> 41 #include <cstdint> 42 #include <limits> 43 #include <memory> 44 #include <stdexcept> 45 46 #ifdef __clang__ 47 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) 48 #else 49 # define FMT_CLANG_VERSION 0 50 #endif 51 52 #ifdef __INTEL_COMPILER 53 # define FMT_ICC_VERSION __INTEL_COMPILER 54 #elif defined(__ICL) 55 # define FMT_ICC_VERSION __ICL 56 #else 57 # define FMT_ICC_VERSION 0 58 #endif 59 60 #ifdef __NVCC__ 61 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) 62 #else 63 # define FMT_CUDA_VERSION 0 64 #endif 65 66 #ifdef __has_builtin 67 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 68 #else 69 # define FMT_HAS_BUILTIN(x) 0 70 #endif 71 72 #if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \ 73 (__cplusplus >= 201703 || FMT_GCC_VERSION != 0) 74 # define FMT_FALLTHROUGH [[fallthrough]] 75 #else 76 # define FMT_FALLTHROUGH 77 #endif 78 79 #ifndef FMT_THROW 80 # if FMT_EXCEPTIONS 81 # if FMT_MSC_VER 82 FMT_BEGIN_NAMESPACE 83 namespace internal { 84 template <typename Exception> inline void do_throw(const Exception& x) { 85 // Silence unreachable code warnings in MSVC because these are nearly 86 // impossible to fix in a generic code. 87 volatile bool b = true; 88 if (b) throw x; 89 } 90 } // namespace internal 91 FMT_END_NAMESPACE 92 # define FMT_THROW(x) internal::do_throw(x) 93 # else 94 # define FMT_THROW(x) throw x 95 # endif 96 # else 97 # define FMT_THROW(x) \ 98 do { \ 99 static_cast<void>(sizeof(x)); \ 100 FMT_ASSERT(false, ""); \ 101 } while (false) 102 # endif 103 #endif 104 105 #ifndef FMT_USE_USER_DEFINED_LITERALS 106 // For Intel and NVIDIA compilers both they and the system gcc/msc support UDLs. 107 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ 108 FMT_MSC_VER >= 1900) && \ 109 (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \ 110 FMT_CUDA_VERSION >= 700) 111 # define FMT_USE_USER_DEFINED_LITERALS 1 112 # else 113 # define FMT_USE_USER_DEFINED_LITERALS 0 114 # endif 115 #endif 116 117 #ifndef FMT_USE_UDL_TEMPLATE 118 // EDG front end based compilers (icc, nvcc) do not support UDL templates yet 119 // and GCC 9 warns about them. 120 # if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \ 121 FMT_CUDA_VERSION == 0 && \ 122 ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 && \ 123 __cplusplus >= 201402L) || \ 124 FMT_CLANG_VERSION >= 304) 125 # define FMT_USE_UDL_TEMPLATE 1 126 # else 127 # define FMT_USE_UDL_TEMPLATE 0 128 # endif 129 #endif 130 131 // __builtin_clz is broken in clang with Microsoft CodeGen: 132 // https://github.com/fmtlib/fmt/issues/519 133 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER 134 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 135 #endif 136 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER 137 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 138 #endif 139 140 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support 141 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the 142 // MSVC intrinsics if the clz and clzll builtins are not available. 143 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) 144 # include <intrin.h> // _BitScanReverse, _BitScanReverse64 145 146 FMT_BEGIN_NAMESPACE 147 namespace internal { 148 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. 149 # ifndef __clang__ 150 # pragma intrinsic(_BitScanReverse) 151 # endif 152 inline uint32_t clz(uint32_t x) { 153 unsigned long r = 0; 154 _BitScanReverse(&r, x); 155 156 FMT_ASSERT(x != 0, ""); 157 // Static analysis complains about using uninitialized data 158 // "r", but the only way that can happen is if "x" is 0, 159 // which the callers guarantee to not happen. 160 # pragma warning(suppress : 6102) 161 return 31 - r; 162 } 163 # define FMT_BUILTIN_CLZ(n) internal::clz(n) 164 165 # if defined(_WIN64) && !defined(__clang__) 166 # pragma intrinsic(_BitScanReverse64) 167 # endif 168 169 inline uint32_t clzll(uint64_t x) { 170 unsigned long r = 0; 171 # ifdef _WIN64 172 _BitScanReverse64(&r, x); 173 # else 174 // Scan the high 32 bits. 175 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 - (r + 32); 176 177 // Scan the low 32 bits. 178 _BitScanReverse(&r, static_cast<uint32_t>(x)); 179 # endif 180 181 FMT_ASSERT(x != 0, ""); 182 // Static analysis complains about using uninitialized data 183 // "r", but the only way that can happen is if "x" is 0, 184 // which the callers guarantee to not happen. 185 # pragma warning(suppress : 6102) 186 return 63 - r; 187 } 188 # define FMT_BUILTIN_CLZLL(n) internal::clzll(n) 189 } // namespace internal 190 FMT_END_NAMESPACE 191 #endif 192 193 // Enable the deprecated numeric alignment. 194 #ifndef FMT_NUMERIC_ALIGN 195 # define FMT_NUMERIC_ALIGN 1 196 #endif 197 198 // Enable the deprecated percent specifier. 199 #ifndef FMT_DEPRECATED_PERCENT 200 # define FMT_DEPRECATED_PERCENT 0 201 #endif 202 203 FMT_BEGIN_NAMESPACE 204 namespace internal { 205 206 // A helper function to suppress bogus "conditional expression is constant" 207 // warnings. 208 template <typename T> inline T const_check(T value) { return value; } 209 210 // An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't have 211 // undefined behavior (e.g. due to type aliasing). 212 // Example: uint64_t d = bit_cast<uint64_t>(2.718); 213 template <typename Dest, typename Source> 214 inline Dest bit_cast(const Source& source) { 215 static_assert(sizeof(Dest) == sizeof(Source), "size mismatch"); 216 Dest dest; 217 std::memcpy(&dest, &source, sizeof(dest)); 218 return dest; 219 } 220 221 inline bool is_big_endian() { 222 auto u = 1u; 223 struct bytes { 224 char data[sizeof(u)]; 225 }; 226 return bit_cast<bytes>(u).data[0] == 0; 227 } 228 229 // A fallback implementation of uintptr_t for systems that lack it. 230 struct fallback_uintptr { 231 unsigned char value[sizeof(void*)]; 232 233 fallback_uintptr() = default; 234 explicit fallback_uintptr(const void* p) { 235 *this = bit_cast<fallback_uintptr>(p); 236 if (is_big_endian()) { 237 for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j) 238 std::swap(value[i], value[j]); 239 } 240 } 241 }; 242 #ifdef UINTPTR_MAX 243 using uintptr_t = ::uintptr_t; 244 inline uintptr_t to_uintptr(const void* p) { return bit_cast<uintptr_t>(p); } 245 #else 246 using uintptr_t = fallback_uintptr; 247 inline fallback_uintptr to_uintptr(const void* p) { 248 return fallback_uintptr(p); 249 } 250 #endif 251 252 // Returns the largest possible value for type T. Same as 253 // std::numeric_limits<T>::max() but shorter and not affected by the max macro. 254 template <typename T> constexpr T max_value() { 255 return (std::numeric_limits<T>::max)(); 256 } 257 template <typename T> constexpr int num_bits() { 258 return std::numeric_limits<T>::digits; 259 } 260 template <> constexpr int num_bits<fallback_uintptr>() { 261 return static_cast<int>(sizeof(void*) * 262 std::numeric_limits<unsigned char>::digits); 263 } 264 265 // An approximation of iterator_t for pre-C++20 systems. 266 template <typename T> 267 using iterator_t = decltype(std::begin(std::declval<T&>())); 268 269 // Detect the iterator category of *any* given type in a SFINAE-friendly way. 270 // Unfortunately, older implementations of std::iterator_traits are not safe 271 // for use in a SFINAE-context. 272 template <typename It, typename Enable = void> 273 struct iterator_category : std::false_type {}; 274 275 template <typename T> struct iterator_category<T*> { 276 using type = std::random_access_iterator_tag; 277 }; 278 279 template <typename It> 280 struct iterator_category<It, void_t<typename It::iterator_category>> { 281 using type = typename It::iterator_category; 282 }; 283 284 // Detect if *any* given type models the OutputIterator concept. 285 template <typename It> class is_output_iterator { 286 // Check for mutability because all iterator categories derived from 287 // std::input_iterator_tag *may* also meet the requirements of an 288 // OutputIterator, thereby falling into the category of 'mutable iterators' 289 // [iterator.requirements.general] clause 4. The compiler reveals this 290 // property only at the point of *actually dereferencing* the iterator! 291 template <typename U> 292 static decltype(*(std::declval<U>())) test(std::input_iterator_tag); 293 template <typename U> static char& test(std::output_iterator_tag); 294 template <typename U> static const char& test(...); 295 296 using type = decltype(test<It>(typename iterator_category<It>::type{})); 297 298 public: 299 static const bool value = !std::is_const<remove_reference_t<type>>::value; 300 }; 301 302 // A workaround for std::string not having mutable data() until C++17. 303 template <typename Char> inline Char* get_data(std::basic_string<Char>& s) { 304 return &s[0]; 305 } 306 template <typename Container> 307 inline typename Container::value_type* get_data(Container& c) { 308 return c.data(); 309 } 310 311 #ifdef _SECURE_SCL 312 // Make a checked iterator to avoid MSVC warnings. 313 template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>; 314 template <typename T> checked_ptr<T> make_checked(T* p, std::size_t size) { 315 return {p, size}; 316 } 317 #else 318 template <typename T> using checked_ptr = T*; 319 template <typename T> inline T* make_checked(T* p, std::size_t) { return p; } 320 #endif 321 322 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)> 323 inline checked_ptr<typename Container::value_type> reserve( 324 std::back_insert_iterator<Container>& it, std::size_t n) { 325 Container& c = get_container(it); 326 std::size_t size = c.size(); 327 c.resize(size + n); 328 return make_checked(get_data(c) + size, n); 329 } 330 331 template <typename Iterator> 332 inline Iterator& reserve(Iterator& it, std::size_t) { 333 return it; 334 } 335 336 // An output iterator that counts the number of objects written to it and 337 // discards them. 338 class counting_iterator { 339 private: 340 std::size_t count_; 341 342 public: 343 using iterator_category = std::output_iterator_tag; 344 using difference_type = std::ptrdiff_t; 345 using pointer = void; 346 using reference = void; 347 using _Unchecked_type = counting_iterator; // Mark iterator as checked. 348 349 struct value_type { 350 template <typename T> void operator=(const T&) {} 351 }; 352 353 counting_iterator() : count_(0) {} 354 355 std::size_t count() const { return count_; } 356 357 counting_iterator& operator++() { 358 ++count_; 359 return *this; 360 } 361 362 counting_iterator operator++(int) { 363 auto it = *this; 364 ++*this; 365 return it; 366 } 367 368 value_type operator*() const { return {}; } 369 }; 370 371 template <typename OutputIt> class truncating_iterator_base { 372 protected: 373 OutputIt out_; 374 std::size_t limit_; 375 std::size_t count_; 376 377 truncating_iterator_base(OutputIt out, std::size_t limit) 378 : out_(out), limit_(limit), count_(0) {} 379 380 public: 381 using iterator_category = std::output_iterator_tag; 382 using difference_type = void; 383 using pointer = void; 384 using reference = void; 385 using _Unchecked_type = 386 truncating_iterator_base; // Mark iterator as checked. 387 388 OutputIt base() const { return out_; } 389 std::size_t count() const { return count_; } 390 }; 391 392 // An output iterator that truncates the output and counts the number of objects 393 // written to it. 394 template <typename OutputIt, 395 typename Enable = typename std::is_void< 396 typename std::iterator_traits<OutputIt>::value_type>::type> 397 class truncating_iterator; 398 399 template <typename OutputIt> 400 class truncating_iterator<OutputIt, std::false_type> 401 : public truncating_iterator_base<OutputIt> { 402 using traits = std::iterator_traits<OutputIt>; 403 404 mutable typename traits::value_type blackhole_; 405 406 public: 407 using value_type = typename traits::value_type; 408 409 truncating_iterator(OutputIt out, std::size_t limit) 410 : truncating_iterator_base<OutputIt>(out, limit) {} 411 412 truncating_iterator& operator++() { 413 if (this->count_++ < this->limit_) ++this->out_; 414 return *this; 415 } 416 417 truncating_iterator operator++(int) { 418 auto it = *this; 419 ++*this; 420 return it; 421 } 422 423 value_type& operator*() const { 424 return this->count_ < this->limit_ ? *this->out_ : blackhole_; 425 } 426 }; 427 428 template <typename OutputIt> 429 class truncating_iterator<OutputIt, std::true_type> 430 : public truncating_iterator_base<OutputIt> { 431 public: 432 using value_type = typename OutputIt::container_type::value_type; 433 434 truncating_iterator(OutputIt out, std::size_t limit) 435 : truncating_iterator_base<OutputIt>(out, limit) {} 436 437 truncating_iterator& operator=(value_type val) { 438 if (this->count_++ < this->limit_) this->out_ = val; 439 return *this; 440 } 441 442 truncating_iterator& operator++() { return *this; } 443 truncating_iterator& operator++(int) { return *this; } 444 truncating_iterator& operator*() { return *this; } 445 }; 446 447 // A range with the specified output iterator and value type. 448 template <typename OutputIt, typename T = typename OutputIt::value_type> 449 class output_range { 450 private: 451 OutputIt it_; 452 453 public: 454 using value_type = T; 455 using iterator = OutputIt; 456 struct sentinel {}; 457 458 explicit output_range(OutputIt it) : it_(it) {} 459 OutputIt begin() const { return it_; } 460 sentinel end() const { return {}; } // Sentinel is not used yet. 461 }; 462 463 template <typename Char> 464 inline size_t count_code_points(basic_string_view<Char> s) { 465 return s.size(); 466 } 467 468 // Counts the number of code points in a UTF-8 string. 469 inline size_t count_code_points(basic_string_view<char8_t> s) { 470 const char8_t* data = s.data(); 471 size_t num_code_points = 0; 472 for (size_t i = 0, size = s.size(); i != size; ++i) { 473 if ((data[i] & 0xc0) != 0x80) ++num_code_points; 474 } 475 return num_code_points; 476 } 477 478 template <typename Char> 479 inline size_t code_point_index(basic_string_view<Char> s, size_t n) { 480 size_t size = s.size(); 481 return n < size ? n : size; 482 } 483 484 // Calculates the index of the nth code point in a UTF-8 string. 485 inline size_t code_point_index(basic_string_view<char8_t> s, size_t n) { 486 const char8_t* data = s.data(); 487 size_t num_code_points = 0; 488 for (size_t i = 0, size = s.size(); i != size; ++i) { 489 if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) { 490 return i; 491 } 492 } 493 return s.size(); 494 } 495 496 inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); } 497 498 template <typename InputIt, typename OutChar> 499 using needs_conversion = bool_constant< 500 std::is_same<typename std::iterator_traits<InputIt>::value_type, 501 char>::value && 502 std::is_same<OutChar, char8_t>::value>; 503 504 template <typename OutChar, typename InputIt, typename OutputIt, 505 FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)> 506 OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { 507 return std::copy(begin, end, it); 508 } 509 510 template <typename OutChar, typename InputIt, typename OutputIt, 511 FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)> 512 OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { 513 return std::transform(begin, end, it, to_char8_t); 514 } 515 516 #ifndef FMT_USE_GRISU 517 # define FMT_USE_GRISU 1 518 #endif 519 520 template <typename T> constexpr bool use_grisu() { 521 return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 && 522 sizeof(T) <= sizeof(double); 523 } 524 525 template <typename T> 526 template <typename U> 527 void buffer<T>::append(const U* begin, const U* end) { 528 std::size_t new_size = size_ + to_unsigned(end - begin); 529 reserve(new_size); 530 std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_); 531 size_ = new_size; 532 } 533 } // namespace internal 534 535 // A range with an iterator appending to a buffer. 536 template <typename T> 537 class buffer_range : public internal::output_range< 538 std::back_insert_iterator<internal::buffer<T>>, T> { 539 public: 540 using iterator = std::back_insert_iterator<internal::buffer<T>>; 541 using internal::output_range<iterator, T>::output_range; 542 buffer_range(internal::buffer<T>& buf) 543 : internal::output_range<iterator, T>(std::back_inserter(buf)) {} 544 }; 545 546 // A UTF-8 string view. 547 class u8string_view : public basic_string_view<char8_t> { 548 public: 549 u8string_view(const char* s) 550 : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s)) {} 551 u8string_view(const char* s, size_t count) FMT_NOEXCEPT 552 : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s), count) { 553 } 554 }; 555 556 #if FMT_USE_USER_DEFINED_LITERALS 557 inline namespace literals { 558 inline u8string_view operator"" _u(const char* s, std::size_t n) { 559 return {s, n}; 560 } 561 } // namespace literals 562 #endif 563 564 // The number of characters to store in the basic_memory_buffer object itself 565 // to avoid dynamic memory allocation. 566 enum { inline_buffer_size = 500 }; 567 568 /** 569 \rst 570 A dynamically growing memory buffer for trivially copyable/constructible types 571 with the first ``SIZE`` elements stored in the object itself. 572 573 You can use one of the following type aliases for common character types: 574 575 +----------------+------------------------------+ 576 | Type | Definition | 577 +================+==============================+ 578 | memory_buffer | basic_memory_buffer<char> | 579 +----------------+------------------------------+ 580 | wmemory_buffer | basic_memory_buffer<wchar_t> | 581 +----------------+------------------------------+ 582 583 **Example**:: 584 585 fmt::memory_buffer out; 586 format_to(out, "The answer is {}.", 42); 587 588 This will append the following output to the ``out`` object: 589 590 .. code-block:: none 591 592 The answer is 42. 593 594 The output can be converted to an ``std::string`` with ``to_string(out)``. 595 \endrst 596 */ 597 template <typename T, std::size_t SIZE = inline_buffer_size, 598 typename Allocator = std::allocator<T>> 599 class basic_memory_buffer : private Allocator, public internal::buffer<T> { 600 private: 601 T store_[SIZE]; 602 603 // Deallocate memory allocated by the buffer. 604 void deallocate() { 605 T* data = this->data(); 606 if (data != store_) Allocator::deallocate(data, this->capacity()); 607 } 608 609 protected: 610 void grow(std::size_t size) FMT_OVERRIDE; 611 612 public: 613 using value_type = T; 614 using const_reference = const T&; 615 616 explicit basic_memory_buffer(const Allocator& alloc = Allocator()) 617 : Allocator(alloc) { 618 this->set(store_, SIZE); 619 } 620 ~basic_memory_buffer() FMT_OVERRIDE { deallocate(); } 621 622 private: 623 // Move data from other to this buffer. 624 void move(basic_memory_buffer& other) { 625 Allocator &this_alloc = *this, &other_alloc = other; 626 this_alloc = std::move(other_alloc); 627 T* data = other.data(); 628 std::size_t size = other.size(), capacity = other.capacity(); 629 if (data == other.store_) { 630 this->set(store_, capacity); 631 std::uninitialized_copy(other.store_, other.store_ + size, 632 internal::make_checked(store_, capacity)); 633 } else { 634 this->set(data, capacity); 635 // Set pointer to the inline array so that delete is not called 636 // when deallocating. 637 other.set(other.store_, 0); 638 } 639 this->resize(size); 640 } 641 642 public: 643 /** 644 \rst 645 Constructs a :class:`fmt::basic_memory_buffer` object moving the content 646 of the other object to it. 647 \endrst 648 */ 649 basic_memory_buffer(basic_memory_buffer&& other) FMT_NOEXCEPT { move(other); } 650 651 /** 652 \rst 653 Moves the content of the other ``basic_memory_buffer`` object to this one. 654 \endrst 655 */ 656 basic_memory_buffer& operator=(basic_memory_buffer&& other) FMT_NOEXCEPT { 657 FMT_ASSERT(this != &other, ""); 658 deallocate(); 659 move(other); 660 return *this; 661 } 662 663 // Returns a copy of the allocator associated with this buffer. 664 Allocator get_allocator() const { return *this; } 665 }; 666 667 template <typename T, std::size_t SIZE, typename Allocator> 668 void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) { 669 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 670 if (size > 1000) throw std::runtime_error("fuzz mode - won't grow that much"); 671 #endif 672 std::size_t old_capacity = this->capacity(); 673 std::size_t new_capacity = old_capacity + old_capacity / 2; 674 if (size > new_capacity) new_capacity = size; 675 T* old_data = this->data(); 676 T* new_data = std::allocator_traits<Allocator>::allocate(*this, new_capacity); 677 // The following code doesn't throw, so the raw pointer above doesn't leak. 678 std::uninitialized_copy(old_data, old_data + this->size(), 679 internal::make_checked(new_data, new_capacity)); 680 this->set(new_data, new_capacity); 681 // deallocate must not throw according to the standard, but even if it does, 682 // the buffer already uses the new storage and will deallocate it in 683 // destructor. 684 if (old_data != store_) Allocator::deallocate(old_data, old_capacity); 685 } 686 687 using memory_buffer = basic_memory_buffer<char>; 688 using wmemory_buffer = basic_memory_buffer<wchar_t>; 689 690 /** A formatting error such as invalid format string. */ 691 class FMT_API format_error : public std::runtime_error { 692 public: 693 explicit format_error(const char* message) : std::runtime_error(message) {} 694 explicit format_error(const std::string& message) 695 : std::runtime_error(message) {} 696 format_error(const format_error&) = default; 697 format_error& operator=(const format_error&) = default; 698 format_error(format_error&&) = default; 699 format_error& operator=(format_error&&) = default; 700 ~format_error() FMT_NOEXCEPT FMT_OVERRIDE; 701 }; 702 703 namespace internal { 704 705 // Returns true if value is negative, false otherwise. 706 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. 707 template <typename T, FMT_ENABLE_IF(std::numeric_limits<T>::is_signed)> 708 FMT_CONSTEXPR bool is_negative(T value) { 709 return value < 0; 710 } 711 template <typename T, FMT_ENABLE_IF(!std::numeric_limits<T>::is_signed)> 712 FMT_CONSTEXPR bool is_negative(T) { 713 return false; 714 } 715 716 // Smallest of uint32_t, uint64_t, uint128_t that is large enough to 717 // represent all values of T. 718 template <typename T> 719 using uint32_or_64_or_128_t = conditional_t< 720 std::numeric_limits<T>::digits <= 32, uint32_t, 721 conditional_t<std::numeric_limits<T>::digits <= 64, uint64_t, uint128_t>>; 722 723 // Static data is placed in this class template for the header-only config. 724 template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data { 725 static const uint64_t powers_of_10_64[]; 726 static const uint32_t zero_or_powers_of_10_32[]; 727 static const uint64_t zero_or_powers_of_10_64[]; 728 static const uint64_t pow10_significands[]; 729 static const int16_t pow10_exponents[]; 730 static const char digits[]; 731 static const char hex_digits[]; 732 static const char foreground_color[]; 733 static const char background_color[]; 734 static const char reset_color[5]; 735 static const wchar_t wreset_color[5]; 736 static const char signs[]; 737 }; 738 739 FMT_EXTERN template struct basic_data<void>; 740 741 // This is a struct rather than an alias to avoid shadowing warnings in gcc. 742 struct data : basic_data<> {}; 743 744 #ifdef FMT_BUILTIN_CLZLL 745 // Returns the number of decimal digits in n. Leading zeros are not counted 746 // except for n == 0 in which case count_digits returns 1. 747 inline int count_digits(uint64_t n) { 748 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 749 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. 750 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; 751 return t - (n < data::zero_or_powers_of_10_64[t]) + 1; 752 } 753 #else 754 // Fallback version of count_digits used when __builtin_clz is not available. 755 inline int count_digits(uint64_t n) { 756 int count = 1; 757 for (;;) { 758 // Integer division is slow so do it for a group of four digits instead 759 // of for every digit. The idea comes from the talk by Alexandrescu 760 // "Three Optimization Tips for C++". See speed-test for a comparison. 761 if (n < 10) return count; 762 if (n < 100) return count + 1; 763 if (n < 1000) return count + 2; 764 if (n < 10000) return count + 3; 765 n /= 10000u; 766 count += 4; 767 } 768 } 769 #endif 770 771 #if FMT_USE_INT128 772 inline int count_digits(uint128_t n) { 773 int count = 1; 774 for (;;) { 775 // Integer division is slow so do it for a group of four digits instead 776 // of for every digit. The idea comes from the talk by Alexandrescu 777 // "Three Optimization Tips for C++". See speed-test for a comparison. 778 if (n < 10) return count; 779 if (n < 100) return count + 1; 780 if (n < 1000) return count + 2; 781 if (n < 10000) return count + 3; 782 n /= 10000U; 783 count += 4; 784 } 785 } 786 #endif 787 788 // Counts the number of digits in n. BITS = log2(radix). 789 template <unsigned BITS, typename UInt> inline int count_digits(UInt n) { 790 int num_digits = 0; 791 do { 792 ++num_digits; 793 } while ((n >>= BITS) != 0); 794 return num_digits; 795 } 796 797 template <> int count_digits<4>(internal::fallback_uintptr n); 798 799 #if FMT_GCC_VERSION || FMT_CLANG_VERSION 800 # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) 801 #else 802 # define FMT_ALWAYS_INLINE 803 #endif 804 805 #ifdef FMT_BUILTIN_CLZ 806 // Optional version of count_digits for better performance on 32-bit platforms. 807 inline int count_digits(uint32_t n) { 808 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; 809 return t - (n < data::zero_or_powers_of_10_32[t]) + 1; 810 } 811 #endif 812 813 template <typename Char> FMT_API std::string grouping_impl(locale_ref loc); 814 template <typename Char> inline std::string grouping(locale_ref loc) { 815 return grouping_impl<char>(loc); 816 } 817 template <> inline std::string grouping<wchar_t>(locale_ref loc) { 818 return grouping_impl<wchar_t>(loc); 819 } 820 821 template <typename Char> FMT_API Char thousands_sep_impl(locale_ref loc); 822 template <typename Char> inline Char thousands_sep(locale_ref loc) { 823 return Char(thousands_sep_impl<char>(loc)); 824 } 825 template <> inline wchar_t thousands_sep(locale_ref loc) { 826 return thousands_sep_impl<wchar_t>(loc); 827 } 828 829 template <typename Char> FMT_API Char decimal_point_impl(locale_ref loc); 830 template <typename Char> inline Char decimal_point(locale_ref loc) { 831 return Char(decimal_point_impl<char>(loc)); 832 } 833 template <> inline wchar_t decimal_point(locale_ref loc) { 834 return decimal_point_impl<wchar_t>(loc); 835 } 836 837 // Formats a decimal unsigned integer value writing into buffer. 838 // add_thousands_sep is called after writing each char to add a thousands 839 // separator if necessary. 840 template <typename UInt, typename Char, typename F> 841 inline Char* format_decimal(Char* buffer, UInt value, int num_digits, 842 F add_thousands_sep) { 843 FMT_ASSERT(num_digits >= 0, "invalid digit count"); 844 buffer += num_digits; 845 Char* end = buffer; 846 while (value >= 100) { 847 // Integer division is slow so do it for a group of two digits instead 848 // of for every digit. The idea comes from the talk by Alexandrescu 849 // "Three Optimization Tips for C++". See speed-test for a comparison. 850 auto index = static_cast<unsigned>((value % 100) * 2); 851 value /= 100; 852 *--buffer = static_cast<Char>(data::digits[index + 1]); 853 add_thousands_sep(buffer); 854 *--buffer = static_cast<Char>(data::digits[index]); 855 add_thousands_sep(buffer); 856 } 857 if (value < 10) { 858 *--buffer = static_cast<Char>('0' + value); 859 return end; 860 } 861 auto index = static_cast<unsigned>(value * 2); 862 *--buffer = static_cast<Char>(data::digits[index + 1]); 863 add_thousands_sep(buffer); 864 *--buffer = static_cast<Char>(data::digits[index]); 865 return end; 866 } 867 868 template <typename Int> constexpr int digits10() noexcept { 869 return std::numeric_limits<Int>::digits10; 870 } 871 template <> constexpr int digits10<int128_t>() noexcept { return 38; } 872 template <> constexpr int digits10<uint128_t>() noexcept { return 38; } 873 874 template <typename Char, typename UInt, typename Iterator, typename F> 875 inline Iterator format_decimal(Iterator out, UInt value, int num_digits, 876 F add_thousands_sep) { 877 FMT_ASSERT(num_digits >= 0, "invalid digit count"); 878 // Buffer should be large enough to hold all digits (<= digits10 + 1). 879 enum { max_size = digits10<UInt>() + 1 }; 880 Char buffer[2 * max_size]; 881 auto end = format_decimal(buffer, value, num_digits, add_thousands_sep); 882 return internal::copy_str<Char>(buffer, end, out); 883 } 884 885 template <typename Char, typename It, typename UInt> 886 inline It format_decimal(It out, UInt value, int num_digits) { 887 return format_decimal<Char>(out, value, num_digits, [](Char*) {}); 888 } 889 890 template <unsigned BASE_BITS, typename Char, typename UInt> 891 inline Char* format_uint(Char* buffer, UInt value, int num_digits, 892 bool upper = false) { 893 buffer += num_digits; 894 Char* end = buffer; 895 do { 896 const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits; 897 unsigned digit = (value & ((1 << BASE_BITS) - 1)); 898 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit) 899 : digits[digit]); 900 } while ((value >>= BASE_BITS) != 0); 901 return end; 902 } 903 904 template <unsigned BASE_BITS, typename Char> 905 Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits, 906 bool = false) { 907 auto char_digits = std::numeric_limits<unsigned char>::digits / 4; 908 int start = (num_digits + char_digits - 1) / char_digits - 1; 909 if (int start_digits = num_digits % char_digits) { 910 unsigned value = n.value[start--]; 911 buffer = format_uint<BASE_BITS>(buffer, value, start_digits); 912 } 913 for (; start >= 0; --start) { 914 unsigned value = n.value[start]; 915 buffer += char_digits; 916 auto p = buffer; 917 for (int i = 0; i < char_digits; ++i) { 918 unsigned digit = (value & ((1 << BASE_BITS) - 1)); 919 *--p = static_cast<Char>(data::hex_digits[digit]); 920 value >>= BASE_BITS; 921 } 922 } 923 return buffer; 924 } 925 926 template <unsigned BASE_BITS, typename Char, typename It, typename UInt> 927 inline It format_uint(It out, UInt value, int num_digits, bool upper = false) { 928 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1). 929 char buffer[num_bits<UInt>() / BASE_BITS + 1]; 930 format_uint<BASE_BITS>(buffer, value, num_digits, upper); 931 return internal::copy_str<Char>(buffer, buffer + num_digits, out); 932 } 933 934 #ifndef _WIN32 935 # define FMT_USE_WINDOWS_H 0 936 #elif !defined(FMT_USE_WINDOWS_H) 937 # define FMT_USE_WINDOWS_H 1 938 #endif 939 940 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h. 941 // All the functionality that relies on it will be disabled too. 942 #if FMT_USE_WINDOWS_H 943 // A converter from UTF-8 to UTF-16. 944 // It is only provided for Windows since other systems support UTF-8 natively. 945 class utf8_to_utf16 { 946 private: 947 wmemory_buffer buffer_; 948 949 public: 950 FMT_API explicit utf8_to_utf16(string_view s); 951 operator wstring_view() const { return wstring_view(&buffer_[0], size()); } 952 size_t size() const { return buffer_.size() - 1; } 953 const wchar_t* c_str() const { return &buffer_[0]; } 954 std::wstring str() const { return std::wstring(&buffer_[0], size()); } 955 }; 956 957 // A converter from UTF-16 to UTF-8. 958 // It is only provided for Windows since other systems support UTF-8 natively. 959 class utf16_to_utf8 { 960 private: 961 memory_buffer buffer_; 962 963 public: 964 utf16_to_utf8() {} 965 FMT_API explicit utf16_to_utf8(wstring_view s); 966 operator string_view() const { return string_view(&buffer_[0], size()); } 967 size_t size() const { return buffer_.size() - 1; } 968 const char* c_str() const { return &buffer_[0]; } 969 std::string str() const { return std::string(&buffer_[0], size()); } 970 971 // Performs conversion returning a system error code instead of 972 // throwing exception on conversion error. This method may still throw 973 // in case of memory allocation error. 974 FMT_API int convert(wstring_view s); 975 }; 976 977 FMT_API void format_windows_error(internal::buffer<char>& out, int error_code, 978 string_view message) FMT_NOEXCEPT; 979 #endif 980 981 template <typename T = void> struct null {}; 982 983 // Workaround an array initialization issue in gcc 4.8. 984 template <typename Char> struct fill_t { 985 private: 986 Char data_[6]; 987 988 public: 989 FMT_CONSTEXPR Char& operator[](size_t index) { return data_[index]; } 990 FMT_CONSTEXPR const Char& operator[](size_t index) const { 991 return data_[index]; 992 } 993 994 static FMT_CONSTEXPR fill_t<Char> make() { 995 auto fill = fill_t<Char>(); 996 fill[0] = Char(' '); 997 return fill; 998 } 999 }; 1000 } // namespace internal 1001 1002 // We cannot use enum classes as bit fields because of a gcc bug 1003 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. 1004 namespace align { 1005 enum type { none, left, right, center, numeric }; 1006 } 1007 using align_t = align::type; 1008 1009 namespace sign { 1010 enum type { none, minus, plus, space }; 1011 } 1012 using sign_t = sign::type; 1013 1014 // Format specifiers for built-in and string types. 1015 template <typename Char> struct basic_format_specs { 1016 int width; 1017 int precision; 1018 char type; 1019 align_t align : 4; 1020 sign_t sign : 3; 1021 bool alt : 1; // Alternate form ('#'). 1022 internal::fill_t<Char> fill; 1023 1024 constexpr basic_format_specs() 1025 : width(0), 1026 precision(-1), 1027 type(0), 1028 align(align::none), 1029 sign(sign::none), 1030 alt(false), 1031 fill(internal::fill_t<Char>::make()) {} 1032 }; 1033 1034 using format_specs = basic_format_specs<char>; 1035 1036 namespace internal { 1037 1038 // A floating-point presentation format. 1039 enum class float_format : unsigned char { 1040 general, // General: exponent notation or fixed point based on magnitude. 1041 exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3. 1042 fixed, // Fixed point with the default precision of 6, e.g. 0.0012. 1043 hex 1044 }; 1045 1046 struct float_specs { 1047 int precision; 1048 float_format format : 8; 1049 sign_t sign : 8; 1050 bool upper : 1; 1051 bool locale : 1; 1052 bool percent : 1; 1053 bool binary32 : 1; 1054 bool use_grisu : 1; 1055 bool trailing_zeros : 1; 1056 }; 1057 1058 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer. 1059 template <typename Char, typename It> It write_exponent(int exp, It it) { 1060 FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); 1061 if (exp < 0) { 1062 *it++ = static_cast<Char>('-'); 1063 exp = -exp; 1064 } else { 1065 *it++ = static_cast<Char>('+'); 1066 } 1067 if (exp >= 100) { 1068 const char* top = data::digits + (exp / 100) * 2; 1069 if (exp >= 1000) *it++ = static_cast<Char>(top[0]); 1070 *it++ = static_cast<Char>(top[1]); 1071 exp %= 100; 1072 } 1073 const char* d = data::digits + exp * 2; 1074 *it++ = static_cast<Char>(d[0]); 1075 *it++ = static_cast<Char>(d[1]); 1076 return it; 1077 } 1078 1079 template <typename Char> class float_writer { 1080 private: 1081 // The number is given as v = digits_ * pow(10, exp_). 1082 const char* digits_; 1083 int num_digits_; 1084 int exp_; 1085 size_t size_; 1086 float_specs specs_; 1087 Char decimal_point_; 1088 1089 template <typename It> It prettify(It it) const { 1090 // pow(10, full_exp - 1) <= v <= pow(10, full_exp). 1091 int full_exp = num_digits_ + exp_; 1092 if (specs_.format == float_format::exp) { 1093 // Insert a decimal point after the first digit and add an exponent. 1094 *it++ = static_cast<Char>(*digits_); 1095 int num_zeros = specs_.precision - num_digits_; 1096 bool trailing_zeros = num_zeros > 0 && specs_.trailing_zeros; 1097 if (num_digits_ > 1 || trailing_zeros) *it++ = decimal_point_; 1098 it = copy_str<Char>(digits_ + 1, digits_ + num_digits_, it); 1099 if (trailing_zeros) 1100 it = std::fill_n(it, num_zeros, static_cast<Char>('0')); 1101 *it++ = static_cast<Char>(specs_.upper ? 'E' : 'e'); 1102 return write_exponent<Char>(full_exp - 1, it); 1103 } 1104 if (num_digits_ <= full_exp) { 1105 // 1234e7 -> 12340000000[.0+] 1106 it = copy_str<Char>(digits_, digits_ + num_digits_, it); 1107 it = std::fill_n(it, full_exp - num_digits_, static_cast<Char>('0')); 1108 if (specs_.trailing_zeros) { 1109 *it++ = decimal_point_; 1110 int num_zeros = specs_.precision - full_exp; 1111 if (num_zeros <= 0) { 1112 if (specs_.format != float_format::fixed) 1113 *it++ = static_cast<Char>('0'); 1114 return it; 1115 } 1116 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 1117 if (num_zeros > 1000) 1118 throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); 1119 #endif 1120 it = std::fill_n(it, num_zeros, static_cast<Char>('0')); 1121 } 1122 } else if (full_exp > 0) { 1123 // 1234e-2 -> 12.34[0+] 1124 it = copy_str<Char>(digits_, digits_ + full_exp, it); 1125 if (!specs_.trailing_zeros) { 1126 // Remove trailing zeros. 1127 int num_digits = num_digits_; 1128 while (num_digits > full_exp && digits_[num_digits - 1] == '0') 1129 --num_digits; 1130 if (num_digits != full_exp) *it++ = decimal_point_; 1131 return copy_str<Char>(digits_ + full_exp, digits_ + num_digits, it); 1132 } 1133 *it++ = decimal_point_; 1134 it = copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it); 1135 if (specs_.precision > num_digits_) { 1136 // Add trailing zeros. 1137 int num_zeros = specs_.precision - num_digits_; 1138 it = std::fill_n(it, num_zeros, static_cast<Char>('0')); 1139 } 1140 } else { 1141 // 1234e-6 -> 0.001234 1142 *it++ = static_cast<Char>('0'); 1143 int num_zeros = -full_exp; 1144 if (specs_.precision >= 0 && specs_.precision < num_zeros) 1145 num_zeros = specs_.precision; 1146 int num_digits = num_digits_; 1147 if (!specs_.trailing_zeros) 1148 while (num_digits > 0 && digits_[num_digits - 1] == '0') --num_digits; 1149 if (num_zeros != 0 || num_digits != 0) { 1150 *it++ = decimal_point_; 1151 it = std::fill_n(it, num_zeros, static_cast<Char>('0')); 1152 it = copy_str<Char>(digits_, digits_ + num_digits, it); 1153 } 1154 } 1155 return it; 1156 } 1157 1158 public: 1159 float_writer(const char* digits, int num_digits, int exp, float_specs specs, 1160 Char decimal_point) 1161 : digits_(digits), 1162 num_digits_(num_digits), 1163 exp_(exp), 1164 specs_(specs), 1165 decimal_point_(decimal_point) { 1166 int full_exp = num_digits + exp - 1; 1167 int precision = specs.precision > 0 ? specs.precision : 16; 1168 if (specs_.format == float_format::general && 1169 !(full_exp >= -4 && full_exp < precision)) { 1170 specs_.format = float_format::exp; 1171 } 1172 size_ = prettify(counting_iterator()).count(); 1173 size_ += specs.sign ? 1 : 0; 1174 } 1175 1176 size_t size() const { return size_; } 1177 size_t width() const { return size(); } 1178 1179 template <typename It> void operator()(It&& it) { 1180 if (specs_.sign) *it++ = static_cast<Char>(data::signs[specs_.sign]); 1181 it = prettify(it); 1182 } 1183 }; 1184 1185 template <typename T> 1186 int format_float(T value, int precision, float_specs specs, buffer<char>& buf); 1187 1188 // Formats a floating-point number with snprintf. 1189 template <typename T> 1190 int snprintf_float(T value, int precision, float_specs specs, 1191 buffer<char>& buf); 1192 1193 template <typename T> T promote_float(T value) { return value; } 1194 inline double promote_float(float value) { return value; } 1195 1196 template <typename Handler> 1197 FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) { 1198 switch (spec) { 1199 case 0: 1200 case 'd': 1201 handler.on_dec(); 1202 break; 1203 case 'x': 1204 case 'X': 1205 handler.on_hex(); 1206 break; 1207 case 'b': 1208 case 'B': 1209 handler.on_bin(); 1210 break; 1211 case 'o': 1212 handler.on_oct(); 1213 break; 1214 case 'n': 1215 handler.on_num(); 1216 break; 1217 default: 1218 handler.on_error(); 1219 } 1220 } 1221 1222 template <typename ErrorHandler = error_handler, typename Char> 1223 FMT_CONSTEXPR float_specs parse_float_type_spec( 1224 const basic_format_specs<Char>& specs, ErrorHandler&& eh = {}) { 1225 auto result = float_specs(); 1226 result.trailing_zeros = specs.alt; 1227 switch (specs.type) { 1228 case 0: 1229 result.format = float_format::general; 1230 result.trailing_zeros |= specs.precision != 0; 1231 break; 1232 case 'G': 1233 result.upper = true; 1234 FMT_FALLTHROUGH; 1235 case 'g': 1236 result.format = float_format::general; 1237 break; 1238 case 'E': 1239 result.upper = true; 1240 FMT_FALLTHROUGH; 1241 case 'e': 1242 result.format = float_format::exp; 1243 result.trailing_zeros |= specs.precision != 0; 1244 break; 1245 case 'F': 1246 result.upper = true; 1247 FMT_FALLTHROUGH; 1248 case 'f': 1249 result.format = float_format::fixed; 1250 result.trailing_zeros |= specs.precision != 0; 1251 break; 1252 #if FMT_DEPRECATED_PERCENT 1253 case '%': 1254 result.format = float_format::fixed; 1255 result.percent = true; 1256 break; 1257 #endif 1258 case 'A': 1259 result.upper = true; 1260 FMT_FALLTHROUGH; 1261 case 'a': 1262 result.format = float_format::hex; 1263 break; 1264 case 'n': 1265 result.locale = true; 1266 break; 1267 default: 1268 eh.on_error("invalid type specifier"); 1269 break; 1270 } 1271 return result; 1272 } 1273 1274 template <typename Char, typename Handler> 1275 FMT_CONSTEXPR void handle_char_specs(const basic_format_specs<Char>* specs, 1276 Handler&& handler) { 1277 if (!specs) return handler.on_char(); 1278 if (specs->type && specs->type != 'c') return handler.on_int(); 1279 if (specs->align == align::numeric || specs->sign != sign::none || specs->alt) 1280 handler.on_error("invalid format specifier for char"); 1281 handler.on_char(); 1282 } 1283 1284 template <typename Char, typename Handler> 1285 FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler&& handler) { 1286 if (spec == 0 || spec == 's') 1287 handler.on_string(); 1288 else if (spec == 'p') 1289 handler.on_pointer(); 1290 else 1291 handler.on_error("invalid type specifier"); 1292 } 1293 1294 template <typename Char, typename ErrorHandler> 1295 FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler&& eh) { 1296 if (spec != 0 && spec != 's') eh.on_error("invalid type specifier"); 1297 } 1298 1299 template <typename Char, typename ErrorHandler> 1300 FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) { 1301 if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier"); 1302 } 1303 1304 template <typename ErrorHandler> class int_type_checker : private ErrorHandler { 1305 public: 1306 FMT_CONSTEXPR explicit int_type_checker(ErrorHandler eh) : ErrorHandler(eh) {} 1307 1308 FMT_CONSTEXPR void on_dec() {} 1309 FMT_CONSTEXPR void on_hex() {} 1310 FMT_CONSTEXPR void on_bin() {} 1311 FMT_CONSTEXPR void on_oct() {} 1312 FMT_CONSTEXPR void on_num() {} 1313 1314 FMT_CONSTEXPR void on_error() { 1315 ErrorHandler::on_error("invalid type specifier"); 1316 } 1317 }; 1318 1319 template <typename ErrorHandler> 1320 class char_specs_checker : public ErrorHandler { 1321 private: 1322 char type_; 1323 1324 public: 1325 FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh) 1326 : ErrorHandler(eh), type_(type) {} 1327 1328 FMT_CONSTEXPR void on_int() { 1329 handle_int_type_spec(type_, int_type_checker<ErrorHandler>(*this)); 1330 } 1331 FMT_CONSTEXPR void on_char() {} 1332 }; 1333 1334 template <typename ErrorHandler> 1335 class cstring_type_checker : public ErrorHandler { 1336 public: 1337 FMT_CONSTEXPR explicit cstring_type_checker(ErrorHandler eh) 1338 : ErrorHandler(eh) {} 1339 1340 FMT_CONSTEXPR void on_string() {} 1341 FMT_CONSTEXPR void on_pointer() {} 1342 }; 1343 1344 template <typename Context> 1345 void arg_map<Context>::init(const basic_format_args<Context>& args) { 1346 if (map_) return; 1347 map_ = new entry[internal::to_unsigned(args.max_size())]; 1348 if (args.is_packed()) { 1349 for (int i = 0;; ++i) { 1350 internal::type arg_type = args.type(i); 1351 if (arg_type == internal::none_type) return; 1352 if (arg_type == internal::named_arg_type) push_back(args.values_[i]); 1353 } 1354 } 1355 for (int i = 0, n = args.max_size(); i < n; ++i) { 1356 auto type = args.args_[i].type_; 1357 if (type == internal::named_arg_type) push_back(args.args_[i].value_); 1358 } 1359 } 1360 1361 template <typename Char> struct nonfinite_writer { 1362 sign_t sign; 1363 const char* str; 1364 static constexpr size_t str_size = 3; 1365 1366 size_t size() const { return str_size + (sign ? 1 : 0); } 1367 size_t width() const { return size(); } 1368 1369 template <typename It> void operator()(It&& it) const { 1370 if (sign) *it++ = static_cast<Char>(data::signs[sign]); 1371 it = copy_str<Char>(str, str + str_size, it); 1372 } 1373 }; 1374 1375 // This template provides operations for formatting and writing data into a 1376 // character range. 1377 template <typename Range> class basic_writer { 1378 public: 1379 using char_type = typename Range::value_type; 1380 using iterator = typename Range::iterator; 1381 using format_specs = basic_format_specs<char_type>; 1382 1383 private: 1384 iterator out_; // Output iterator. 1385 locale_ref locale_; 1386 1387 // Attempts to reserve space for n extra characters in the output range. 1388 // Returns a pointer to the reserved range or a reference to out_. 1389 auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) { 1390 return internal::reserve(out_, n); 1391 } 1392 1393 template <typename F> struct padded_int_writer { 1394 size_t size_; 1395 string_view prefix; 1396 char_type fill; 1397 std::size_t padding; 1398 F f; 1399 1400 size_t size() const { return size_; } 1401 size_t width() const { return size_; } 1402 1403 template <typename It> void operator()(It&& it) const { 1404 if (prefix.size() != 0) 1405 it = copy_str<char_type>(prefix.begin(), prefix.end(), it); 1406 it = std::fill_n(it, padding, fill); 1407 f(it); 1408 } 1409 }; 1410 1411 // Writes an integer in the format 1412 // <left-padding><prefix><numeric-padding><digits><right-padding> 1413 // where <digits> are written by f(it). 1414 template <typename F> 1415 void write_int(int num_digits, string_view prefix, format_specs specs, F f) { 1416 std::size_t size = prefix.size() + to_unsigned(num_digits); 1417 char_type fill = specs.fill[0]; 1418 std::size_t padding = 0; 1419 if (specs.align == align::numeric) { 1420 auto unsiged_width = to_unsigned(specs.width); 1421 if (unsiged_width > size) { 1422 padding = unsiged_width - size; 1423 size = unsiged_width; 1424 } 1425 } else if (specs.precision > num_digits) { 1426 size = prefix.size() + to_unsigned(specs.precision); 1427 padding = to_unsigned(specs.precision - num_digits); 1428 fill = static_cast<char_type>('0'); 1429 } 1430 if (specs.align == align::none) specs.align = align::right; 1431 write_padded(specs, padded_int_writer<F>{size, prefix, fill, padding, f}); 1432 } 1433 1434 // Writes a decimal integer. 1435 template <typename Int> void write_decimal(Int value) { 1436 auto abs_value = static_cast<uint32_or_64_or_128_t<Int>>(value); 1437 bool negative = is_negative(value); 1438 // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. 1439 if (negative) abs_value = ~abs_value + 1; 1440 int num_digits = count_digits(abs_value); 1441 auto&& it = reserve((negative ? 1 : 0) + static_cast<size_t>(num_digits)); 1442 if (negative) *it++ = static_cast<char_type>('-'); 1443 it = format_decimal<char_type>(it, abs_value, num_digits); 1444 } 1445 1446 // The handle_int_type_spec handler that writes an integer. 1447 template <typename Int, typename Specs> struct int_writer { 1448 using unsigned_type = uint32_or_64_or_128_t<Int>; 1449 1450 basic_writer<Range>& writer; 1451 const Specs& specs; 1452 unsigned_type abs_value; 1453 char prefix[4]; 1454 unsigned prefix_size; 1455 1456 string_view get_prefix() const { return string_view(prefix, prefix_size); } 1457 1458 int_writer(basic_writer<Range>& w, Int value, const Specs& s) 1459 : writer(w), 1460 specs(s), 1461 abs_value(static_cast<unsigned_type>(value)), 1462 prefix_size(0) { 1463 if (is_negative(value)) { 1464 prefix[0] = '-'; 1465 ++prefix_size; 1466 abs_value = 0 - abs_value; 1467 } else if (specs.sign != sign::none && specs.sign != sign::minus) { 1468 prefix[0] = specs.sign == sign::plus ? '+' : ' '; 1469 ++prefix_size; 1470 } 1471 } 1472 1473 struct dec_writer { 1474 unsigned_type abs_value; 1475 int num_digits; 1476 1477 template <typename It> void operator()(It&& it) const { 1478 it = internal::format_decimal<char_type>(it, abs_value, num_digits); 1479 } 1480 }; 1481 1482 void on_dec() { 1483 int num_digits = count_digits(abs_value); 1484 writer.write_int(num_digits, get_prefix(), specs, 1485 dec_writer{abs_value, num_digits}); 1486 } 1487 1488 struct hex_writer { 1489 int_writer& self; 1490 int num_digits; 1491 1492 template <typename It> void operator()(It&& it) const { 1493 it = format_uint<4, char_type>(it, self.abs_value, num_digits, 1494 self.specs.type != 'x'); 1495 } 1496 }; 1497 1498 void on_hex() { 1499 if (specs.alt) { 1500 prefix[prefix_size++] = '0'; 1501 prefix[prefix_size++] = specs.type; 1502 } 1503 int num_digits = count_digits<4>(abs_value); 1504 writer.write_int(num_digits, get_prefix(), specs, 1505 hex_writer{*this, num_digits}); 1506 } 1507 1508 template <int BITS> struct bin_writer { 1509 unsigned_type abs_value; 1510 int num_digits; 1511 1512 template <typename It> void operator()(It&& it) const { 1513 it = format_uint<BITS, char_type>(it, abs_value, num_digits); 1514 } 1515 }; 1516 1517 void on_bin() { 1518 if (specs.alt) { 1519 prefix[prefix_size++] = '0'; 1520 prefix[prefix_size++] = static_cast<char>(specs.type); 1521 } 1522 int num_digits = count_digits<1>(abs_value); 1523 writer.write_int(num_digits, get_prefix(), specs, 1524 bin_writer<1>{abs_value, num_digits}); 1525 } 1526 1527 void on_oct() { 1528 int num_digits = count_digits<3>(abs_value); 1529 if (specs.alt && specs.precision <= num_digits && abs_value != 0) { 1530 // Octal prefix '0' is counted as a digit, so only add it if precision 1531 // is not greater than the number of digits. 1532 prefix[prefix_size++] = '0'; 1533 } 1534 writer.write_int(num_digits, get_prefix(), specs, 1535 bin_writer<3>{abs_value, num_digits}); 1536 } 1537 1538 enum { sep_size = 1 }; 1539 1540 struct num_writer { 1541 unsigned_type abs_value; 1542 int size; 1543 const std::string& groups; 1544 char_type sep; 1545 1546 template <typename It> void operator()(It&& it) const { 1547 basic_string_view<char_type> s(&sep, sep_size); 1548 // Index of a decimal digit with the least significant digit having 1549 // index 0. 1550 int digit_index = 0; 1551 std::string::const_iterator group = groups.cbegin(); 1552 it = format_decimal<char_type>( 1553 it, abs_value, size, 1554 [this, s, &group, &digit_index](char_type*& buffer) { 1555 if (*group <= 0 || ++digit_index % *group != 0 || 1556 *group == max_value<char>()) 1557 return; 1558 if (group + 1 != groups.cend()) { 1559 digit_index = 0; 1560 ++group; 1561 } 1562 buffer -= s.size(); 1563 std::uninitialized_copy(s.data(), s.data() + s.size(), 1564 make_checked(buffer, s.size())); 1565 }); 1566 } 1567 }; 1568 1569 void on_num() { 1570 std::string groups = grouping<char_type>(writer.locale_); 1571 if (groups.empty()) return on_dec(); 1572 auto sep = thousands_sep<char_type>(writer.locale_); 1573 if (!sep) return on_dec(); 1574 int num_digits = count_digits(abs_value); 1575 int size = num_digits; 1576 std::string::const_iterator group = groups.cbegin(); 1577 while (group != groups.cend() && num_digits > *group && *group > 0 && 1578 *group != max_value<char>()) { 1579 size += sep_size; 1580 num_digits -= *group; 1581 ++group; 1582 } 1583 if (group == groups.cend()) 1584 size += sep_size * ((num_digits - 1) / groups.back()); 1585 writer.write_int(size, get_prefix(), specs, 1586 num_writer{abs_value, size, groups, sep}); 1587 } 1588 1589 FMT_NORETURN void on_error() { 1590 FMT_THROW(format_error("invalid type specifier")); 1591 } 1592 }; 1593 1594 template <typename Char> struct str_writer { 1595 const Char* s; 1596 size_t size_; 1597 1598 size_t size() const { return size_; } 1599 size_t width() const { 1600 return count_code_points(basic_string_view<Char>(s, size_)); 1601 } 1602 1603 template <typename It> void operator()(It&& it) const { 1604 it = copy_str<char_type>(s, s + size_, it); 1605 } 1606 }; 1607 1608 template <typename UIntPtr> struct pointer_writer { 1609 UIntPtr value; 1610 int num_digits; 1611 1612 size_t size() const { return to_unsigned(num_digits) + 2; } 1613 size_t width() const { return size(); } 1614 1615 template <typename It> void operator()(It&& it) const { 1616 *it++ = static_cast<char_type>('0'); 1617 *it++ = static_cast<char_type>('x'); 1618 it = format_uint<4, char_type>(it, value, num_digits); 1619 } 1620 }; 1621 1622 public: 1623 explicit basic_writer(Range out, locale_ref loc = locale_ref()) 1624 : out_(out.begin()), locale_(loc) {} 1625 1626 iterator out() const { return out_; } 1627 1628 // Writes a value in the format 1629 // <left-padding><value><right-padding> 1630 // where <value> is written by f(it). 1631 template <typename F> void write_padded(const format_specs& specs, F&& f) { 1632 // User-perceived width (in code points). 1633 unsigned width = to_unsigned(specs.width); 1634 size_t size = f.size(); // The number of code units. 1635 size_t num_code_points = width != 0 ? f.width() : size; 1636 if (width <= num_code_points) return f(reserve(size)); 1637 auto&& it = reserve(width + (size - num_code_points)); 1638 char_type fill = specs.fill[0]; 1639 std::size_t padding = width - num_code_points; 1640 if (specs.align == align::right) { 1641 it = std::fill_n(it, padding, fill); 1642 f(it); 1643 } else if (specs.align == align::center) { 1644 std::size_t left_padding = padding / 2; 1645 it = std::fill_n(it, left_padding, fill); 1646 f(it); 1647 it = std::fill_n(it, padding - left_padding, fill); 1648 } else { 1649 f(it); 1650 it = std::fill_n(it, padding, fill); 1651 } 1652 } 1653 1654 void write(int value) { write_decimal(value); } 1655 void write(long value) { write_decimal(value); } 1656 void write(long long value) { write_decimal(value); } 1657 1658 void write(unsigned value) { write_decimal(value); } 1659 void write(unsigned long value) { write_decimal(value); } 1660 void write(unsigned long long value) { write_decimal(value); } 1661 1662 #if FMT_USE_INT128 1663 void write(int128_t value) { write_decimal(value); } 1664 void write(uint128_t value) { write_decimal(value); } 1665 #endif 1666 1667 template <typename T, typename Spec> 1668 void write_int(T value, const Spec& spec) { 1669 handle_int_type_spec(spec.type, int_writer<T, Spec>(*this, value, spec)); 1670 } 1671 1672 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> 1673 void write(T value, format_specs specs = {}) { 1674 float_specs fspecs = parse_float_type_spec(specs); 1675 fspecs.sign = specs.sign; 1676 if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. 1677 fspecs.sign = sign::minus; 1678 value = -value; 1679 } else if (fspecs.sign == sign::minus) { 1680 fspecs.sign = sign::none; 1681 } 1682 1683 if (!std::isfinite(value)) { 1684 auto str = std::isinf(value) ? (fspecs.upper ? "INF" : "inf") 1685 : (fspecs.upper ? "NAN" : "nan"); 1686 return write_padded(specs, nonfinite_writer<char_type>{fspecs.sign, str}); 1687 } 1688 1689 if (specs.align == align::none) { 1690 specs.align = align::right; 1691 } else if (specs.align == align::numeric) { 1692 if (fspecs.sign) { 1693 auto&& it = reserve(1); 1694 *it++ = static_cast<char_type>(data::signs[fspecs.sign]); 1695 fspecs.sign = sign::none; 1696 if (specs.width != 0) --specs.width; 1697 } 1698 specs.align = align::right; 1699 } 1700 1701 memory_buffer buffer; 1702 if (fspecs.format == float_format::hex) { 1703 if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); 1704 snprintf_float(promote_float(value), specs.precision, fspecs, buffer); 1705 write_padded(specs, str_writer<char>{buffer.data(), buffer.size()}); 1706 return; 1707 } 1708 int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; 1709 if (fspecs.format == float_format::exp) ++precision; 1710 if (const_check(std::is_same<T, float>())) fspecs.binary32 = true; 1711 fspecs.use_grisu = use_grisu<T>(); 1712 if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) value *= 100; 1713 int exp = format_float(promote_float(value), precision, fspecs, buffer); 1714 if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) { 1715 buffer.push_back('%'); 1716 --exp; // Adjust decimal place position. 1717 } 1718 fspecs.precision = precision; 1719 char_type point = fspecs.locale ? decimal_point<char_type>(locale_) 1720 : static_cast<char_type>('.'); 1721 write_padded(specs, float_writer<char_type>(buffer.data(), 1722 static_cast<int>(buffer.size()), 1723 exp, fspecs, point)); 1724 } 1725 1726 void write(char value) { 1727 auto&& it = reserve(1); 1728 *it++ = value; 1729 } 1730 1731 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)> 1732 void write(Char value) { 1733 auto&& it = reserve(1); 1734 *it++ = value; 1735 } 1736 1737 void write(string_view value) { 1738 auto&& it = reserve(value.size()); 1739 it = copy_str<char_type>(value.begin(), value.end(), it); 1740 } 1741 void write(wstring_view value) { 1742 static_assert(std::is_same<char_type, wchar_t>::value, ""); 1743 auto&& it = reserve(value.size()); 1744 it = std::copy(value.begin(), value.end(), it); 1745 } 1746 1747 template <typename Char> 1748 void write(const Char* s, std::size_t size, const format_specs& specs) { 1749 write_padded(specs, str_writer<Char>{s, size}); 1750 } 1751 1752 template <typename Char> 1753 void write(basic_string_view<Char> s, const format_specs& specs = {}) { 1754 const Char* data = s.data(); 1755 std::size_t size = s.size(); 1756 if (specs.precision >= 0 && to_unsigned(specs.precision) < size) 1757 size = code_point_index(s, to_unsigned(specs.precision)); 1758 write(data, size, specs); 1759 } 1760 1761 template <typename UIntPtr> 1762 void write_pointer(UIntPtr value, const format_specs* specs) { 1763 int num_digits = count_digits<4>(value); 1764 auto pw = pointer_writer<UIntPtr>{value, num_digits}; 1765 if (!specs) return pw(reserve(to_unsigned(num_digits) + 2)); 1766 format_specs specs_copy = *specs; 1767 if (specs_copy.align == align::none) specs_copy.align = align::right; 1768 write_padded(specs_copy, pw); 1769 } 1770 }; 1771 1772 using writer = basic_writer<buffer_range<char>>; 1773 1774 template <typename T> struct is_integral : std::is_integral<T> {}; 1775 template <> struct is_integral<int128_t> : std::true_type {}; 1776 template <> struct is_integral<uint128_t> : std::true_type {}; 1777 1778 template <typename Range, typename ErrorHandler = internal::error_handler> 1779 class arg_formatter_base { 1780 public: 1781 using char_type = typename Range::value_type; 1782 using iterator = typename Range::iterator; 1783 using format_specs = basic_format_specs<char_type>; 1784 1785 private: 1786 using writer_type = basic_writer<Range>; 1787 writer_type writer_; 1788 format_specs* specs_; 1789 1790 struct char_writer { 1791 char_type value; 1792 1793 size_t size() const { return 1; } 1794 size_t width() const { return 1; } 1795 1796 template <typename It> void operator()(It&& it) const { *it++ = value; } 1797 }; 1798 1799 void write_char(char_type value) { 1800 if (specs_) 1801 writer_.write_padded(*specs_, char_writer{value}); 1802 else 1803 writer_.write(value); 1804 } 1805 1806 void write_pointer(const void* p) { 1807 writer_.write_pointer(internal::to_uintptr(p), specs_); 1808 } 1809 1810 protected: 1811 writer_type& writer() { return writer_; } 1812 FMT_DEPRECATED format_specs* spec() { return specs_; } 1813 format_specs* specs() { return specs_; } 1814 iterator out() { return writer_.out(); } 1815 1816 void write(bool value) { 1817 string_view sv(value ? "true" : "false"); 1818 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); 1819 } 1820 1821 void write(const char_type* value) { 1822 if (!value) { 1823 FMT_THROW(format_error("string pointer is null")); 1824 } else { 1825 auto length = std::char_traits<char_type>::length(value); 1826 basic_string_view<char_type> sv(value, length); 1827 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); 1828 } 1829 } 1830 1831 public: 1832 arg_formatter_base(Range r, format_specs* s, locale_ref loc) 1833 : writer_(r, loc), specs_(s) {} 1834 1835 iterator operator()(monostate) { 1836 FMT_ASSERT(false, "invalid argument type"); 1837 return out(); 1838 } 1839 1840 template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> 1841 iterator operator()(T value) { 1842 if (specs_) 1843 writer_.write_int(value, *specs_); 1844 else 1845 writer_.write(value); 1846 return out(); 1847 } 1848 1849 iterator operator()(char_type value) { 1850 internal::handle_char_specs( 1851 specs_, char_spec_handler(*this, static_cast<char_type>(value))); 1852 return out(); 1853 } 1854 1855 iterator operator()(bool value) { 1856 if (specs_ && specs_->type) return (*this)(value ? 1 : 0); 1857 write(value != 0); 1858 return out(); 1859 } 1860 1861 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> 1862 iterator operator()(T value) { 1863 writer_.write(value, specs_ ? *specs_ : format_specs()); 1864 return out(); 1865 } 1866 1867 struct char_spec_handler : ErrorHandler { 1868 arg_formatter_base& formatter; 1869 char_type value; 1870 1871 char_spec_handler(arg_formatter_base& f, char_type val) 1872 : formatter(f), value(val) {} 1873 1874 void on_int() { 1875 if (formatter.specs_) 1876 formatter.writer_.write_int(value, *formatter.specs_); 1877 else 1878 formatter.writer_.write(value); 1879 } 1880 void on_char() { formatter.write_char(value); } 1881 }; 1882 1883 struct cstring_spec_handler : internal::error_handler { 1884 arg_formatter_base& formatter; 1885 const char_type* value; 1886 1887 cstring_spec_handler(arg_formatter_base& f, const char_type* val) 1888 : formatter(f), value(val) {} 1889 1890 void on_string() { formatter.write(value); } 1891 void on_pointer() { formatter.write_pointer(value); } 1892 }; 1893 1894 iterator operator()(const char_type* value) { 1895 if (!specs_) return write(value), out(); 1896 internal::handle_cstring_type_spec(specs_->type, 1897 cstring_spec_handler(*this, value)); 1898 return out(); 1899 } 1900 1901 iterator operator()(basic_string_view<char_type> value) { 1902 if (specs_) { 1903 internal::check_string_type_spec(specs_->type, internal::error_handler()); 1904 writer_.write(value, *specs_); 1905 } else { 1906 writer_.write(value); 1907 } 1908 return out(); 1909 } 1910 1911 iterator operator()(const void* value) { 1912 if (specs_) 1913 check_pointer_type_spec(specs_->type, internal::error_handler()); 1914 write_pointer(value); 1915 return out(); 1916 } 1917 }; 1918 1919 template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) { 1920 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; 1921 } 1922 1923 // Parses the range [begin, end) as an unsigned integer. This function assumes 1924 // that the range is non-empty and the first character is a digit. 1925 template <typename Char, typename ErrorHandler> 1926 FMT_CONSTEXPR int parse_nonnegative_int(const Char*& begin, const Char* end, 1927 ErrorHandler&& eh) { 1928 FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', ""); 1929 if (*begin == '0') { 1930 ++begin; 1931 return 0; 1932 } 1933 unsigned value = 0; 1934 // Convert to unsigned to prevent a warning. 1935 constexpr unsigned max_int = max_value<int>(); 1936 unsigned big = max_int / 10; 1937 do { 1938 // Check for overflow. 1939 if (value > big) { 1940 value = max_int + 1; 1941 break; 1942 } 1943 value = value * 10 + unsigned(*begin - '0'); 1944 ++begin; 1945 } while (begin != end && '0' <= *begin && *begin <= '9'); 1946 if (value > max_int) eh.on_error("number is too big"); 1947 return static_cast<int>(value); 1948 } 1949 1950 template <typename Context> class custom_formatter { 1951 private: 1952 using char_type = typename Context::char_type; 1953 1954 basic_format_parse_context<char_type>& parse_ctx_; 1955 Context& ctx_; 1956 1957 public: 1958 explicit custom_formatter(basic_format_parse_context<char_type>& parse_ctx, 1959 Context& ctx) 1960 : parse_ctx_(parse_ctx), ctx_(ctx) {} 1961 1962 bool operator()(typename basic_format_arg<Context>::handle h) const { 1963 h.format(parse_ctx_, ctx_); 1964 return true; 1965 } 1966 1967 template <typename T> bool operator()(T) const { return false; } 1968 }; 1969 1970 template <typename T> 1971 using is_integer = 1972 bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value && 1973 !std::is_same<T, char>::value && 1974 !std::is_same<T, wchar_t>::value>; 1975 1976 template <typename ErrorHandler> class width_checker { 1977 public: 1978 explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} 1979 1980 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)> 1981 FMT_CONSTEXPR unsigned long long operator()(T value) { 1982 if (is_negative(value)) handler_.on_error("negative width"); 1983 return static_cast<unsigned long long>(value); 1984 } 1985 1986 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)> 1987 FMT_CONSTEXPR unsigned long long operator()(T) { 1988 handler_.on_error("width is not integer"); 1989 return 0; 1990 } 1991 1992 private: 1993 ErrorHandler& handler_; 1994 }; 1995 1996 template <typename ErrorHandler> class precision_checker { 1997 public: 1998 explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} 1999 2000 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)> 2001 FMT_CONSTEXPR unsigned long long operator()(T value) { 2002 if (is_negative(value)) handler_.on_error("negative precision"); 2003 return static_cast<unsigned long long>(value); 2004 } 2005 2006 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)> 2007 FMT_CONSTEXPR unsigned long long operator()(T) { 2008 handler_.on_error("precision is not integer"); 2009 return 0; 2010 } 2011 2012 private: 2013 ErrorHandler& handler_; 2014 }; 2015 2016 // A format specifier handler that sets fields in basic_format_specs. 2017 template <typename Char> class specs_setter { 2018 public: 2019 explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs) 2020 : specs_(specs) {} 2021 2022 FMT_CONSTEXPR specs_setter(const specs_setter& other) 2023 : specs_(other.specs_) {} 2024 2025 FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } 2026 FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; } 2027 FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; } 2028 FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; } 2029 FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; } 2030 FMT_CONSTEXPR void on_hash() { specs_.alt = true; } 2031 2032 FMT_CONSTEXPR void on_zero() { 2033 specs_.align = align::numeric; 2034 specs_.fill[0] = Char('0'); 2035 } 2036 2037 FMT_CONSTEXPR void on_width(int width) { specs_.width = width; } 2038 FMT_CONSTEXPR void on_precision(int precision) { 2039 specs_.precision = precision; 2040 } 2041 FMT_CONSTEXPR void end_precision() {} 2042 2043 FMT_CONSTEXPR void on_type(Char type) { 2044 specs_.type = static_cast<char>(type); 2045 } 2046 2047 protected: 2048 basic_format_specs<Char>& specs_; 2049 }; 2050 2051 template <typename ErrorHandler> class numeric_specs_checker { 2052 public: 2053 FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, internal::type arg_type) 2054 : error_handler_(eh), arg_type_(arg_type) {} 2055 2056 FMT_CONSTEXPR void require_numeric_argument() { 2057 if (!is_arithmetic_type(arg_type_)) 2058 error_handler_.on_error("format specifier requires numeric argument"); 2059 } 2060 2061 FMT_CONSTEXPR void check_sign() { 2062 require_numeric_argument(); 2063 if (is_integral_type(arg_type_) && arg_type_ != int_type && 2064 arg_type_ != long_long_type && arg_type_ != internal::char_type) { 2065 error_handler_.on_error("format specifier requires signed argument"); 2066 } 2067 } 2068 2069 FMT_CONSTEXPR void check_precision() { 2070 if (is_integral_type(arg_type_) || arg_type_ == internal::pointer_type) 2071 error_handler_.on_error("precision not allowed for this argument type"); 2072 } 2073 2074 private: 2075 ErrorHandler& error_handler_; 2076 internal::type arg_type_; 2077 }; 2078 2079 // A format specifier handler that checks if specifiers are consistent with the 2080 // argument type. 2081 template <typename Handler> class specs_checker : public Handler { 2082 public: 2083 FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type) 2084 : Handler(handler), checker_(*this, arg_type) {} 2085 2086 FMT_CONSTEXPR specs_checker(const specs_checker& other) 2087 : Handler(other), checker_(*this, other.arg_type_) {} 2088 2089 FMT_CONSTEXPR void on_align(align_t align) { 2090 if (align == align::numeric) checker_.require_numeric_argument(); 2091 Handler::on_align(align); 2092 } 2093 2094 FMT_CONSTEXPR void on_plus() { 2095 checker_.check_sign(); 2096 Handler::on_plus(); 2097 } 2098 2099 FMT_CONSTEXPR void on_minus() { 2100 checker_.check_sign(); 2101 Handler::on_minus(); 2102 } 2103 2104 FMT_CONSTEXPR void on_space() { 2105 checker_.check_sign(); 2106 Handler::on_space(); 2107 } 2108 2109 FMT_CONSTEXPR void on_hash() { 2110 checker_.require_numeric_argument(); 2111 Handler::on_hash(); 2112 } 2113 2114 FMT_CONSTEXPR void on_zero() { 2115 checker_.require_numeric_argument(); 2116 Handler::on_zero(); 2117 } 2118 2119 FMT_CONSTEXPR void end_precision() { checker_.check_precision(); } 2120 2121 private: 2122 numeric_specs_checker<Handler> checker_; 2123 }; 2124 2125 template <template <typename> class Handler, typename FormatArg, 2126 typename ErrorHandler> 2127 FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh) { 2128 unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg); 2129 if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big"); 2130 return static_cast<int>(value); 2131 } 2132 2133 struct auto_id {}; 2134 2135 template <typename Context> 2136 FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx, int id) { 2137 auto arg = ctx.arg(id); 2138 if (!arg) ctx.on_error("argument index out of range"); 2139 return arg; 2140 } 2141 2142 // The standard format specifier handler with checking. 2143 template <typename ParseContext, typename Context> 2144 class specs_handler : public specs_setter<typename Context::char_type> { 2145 public: 2146 using char_type = typename Context::char_type; 2147 2148 FMT_CONSTEXPR specs_handler(basic_format_specs<char_type>& specs, 2149 ParseContext& parse_ctx, Context& ctx) 2150 : specs_setter<char_type>(specs), 2151 parse_context_(parse_ctx), 2152 context_(ctx) {} 2153 2154 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { 2155 this->specs_.width = get_dynamic_spec<width_checker>( 2156 get_arg(arg_id), context_.error_handler()); 2157 } 2158 2159 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { 2160 this->specs_.precision = get_dynamic_spec<precision_checker>( 2161 get_arg(arg_id), context_.error_handler()); 2162 } 2163 2164 void on_error(const char* message) { context_.on_error(message); } 2165 2166 private: 2167 // This is only needed for compatibility with gcc 4.4. 2168 using format_arg = typename Context::format_arg; 2169 2170 FMT_CONSTEXPR format_arg get_arg(auto_id) { 2171 return internal::get_arg(context_, parse_context_.next_arg_id()); 2172 } 2173 2174 FMT_CONSTEXPR format_arg get_arg(int arg_id) { 2175 parse_context_.check_arg_id(arg_id); 2176 return internal::get_arg(context_, arg_id); 2177 } 2178 2179 FMT_CONSTEXPR format_arg get_arg(basic_string_view<char_type> arg_id) { 2180 parse_context_.check_arg_id(arg_id); 2181 return context_.arg(arg_id); 2182 } 2183 2184 ParseContext& parse_context_; 2185 Context& context_; 2186 }; 2187 2188 enum class arg_id_kind { none, index, name }; 2189 2190 // An argument reference. 2191 template <typename Char> struct arg_ref { 2192 FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {} 2193 FMT_CONSTEXPR explicit arg_ref(int index) 2194 : kind(arg_id_kind::index), val(index) {} 2195 FMT_CONSTEXPR explicit arg_ref(basic_string_view<Char> name) 2196 : kind(arg_id_kind::name), val(name) {} 2197 2198 FMT_CONSTEXPR arg_ref& operator=(int idx) { 2199 kind = arg_id_kind::index; 2200 val.index = idx; 2201 return *this; 2202 } 2203 2204 arg_id_kind kind; 2205 union value { 2206 FMT_CONSTEXPR value(int id = 0) : index{id} {} 2207 FMT_CONSTEXPR value(basic_string_view<Char> n) : name(n) {} 2208 2209 int index; 2210 basic_string_view<Char> name; 2211 } val; 2212 }; 2213 2214 // Format specifiers with width and precision resolved at formatting rather 2215 // than parsing time to allow re-using the same parsed specifiers with 2216 // different sets of arguments (precompilation of format strings). 2217 template <typename Char> 2218 struct dynamic_format_specs : basic_format_specs<Char> { 2219 arg_ref<Char> width_ref; 2220 arg_ref<Char> precision_ref; 2221 }; 2222 2223 // Format spec handler that saves references to arguments representing dynamic 2224 // width and precision to be resolved at formatting time. 2225 template <typename ParseContext> 2226 class dynamic_specs_handler 2227 : public specs_setter<typename ParseContext::char_type> { 2228 public: 2229 using char_type = typename ParseContext::char_type; 2230 2231 FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs<char_type>& specs, 2232 ParseContext& ctx) 2233 : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {} 2234 2235 FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other) 2236 : specs_setter<char_type>(other), 2237 specs_(other.specs_), 2238 context_(other.context_) {} 2239 2240 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { 2241 specs_.width_ref = make_arg_ref(arg_id); 2242 } 2243 2244 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { 2245 specs_.precision_ref = make_arg_ref(arg_id); 2246 } 2247 2248 FMT_CONSTEXPR void on_error(const char* message) { 2249 context_.on_error(message); 2250 } 2251 2252 private: 2253 using arg_ref_type = arg_ref<char_type>; 2254 2255 FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id) { 2256 context_.check_arg_id(arg_id); 2257 return arg_ref_type(arg_id); 2258 } 2259 2260 FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id) { 2261 return arg_ref_type(context_.next_arg_id()); 2262 } 2263 2264 FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view<char_type> arg_id) { 2265 context_.check_arg_id(arg_id); 2266 basic_string_view<char_type> format_str( 2267 context_.begin(), to_unsigned(context_.end() - context_.begin())); 2268 return arg_ref_type(arg_id); 2269 } 2270 2271 dynamic_format_specs<char_type>& specs_; 2272 ParseContext& context_; 2273 }; 2274 2275 template <typename Char, typename IDHandler> 2276 FMT_CONSTEXPR const Char* parse_arg_id(const Char* begin, const Char* end, 2277 IDHandler&& handler) { 2278 FMT_ASSERT(begin != end, ""); 2279 Char c = *begin; 2280 if (c == '}' || c == ':') { 2281 handler(); 2282 return begin; 2283 } 2284 if (c >= '0' && c <= '9') { 2285 int index = parse_nonnegative_int(begin, end, handler); 2286 if (begin == end || (*begin != '}' && *begin != ':')) 2287 handler.on_error("invalid format string"); 2288 else 2289 handler(index); 2290 return begin; 2291 } 2292 if (!is_name_start(c)) { 2293 handler.on_error("invalid format string"); 2294 return begin; 2295 } 2296 auto it = begin; 2297 do { 2298 ++it; 2299 } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9'))); 2300 handler(basic_string_view<Char>(begin, to_unsigned(it - begin))); 2301 return it; 2302 } 2303 2304 // Adapts SpecHandler to IDHandler API for dynamic width. 2305 template <typename SpecHandler, typename Char> struct width_adapter { 2306 explicit FMT_CONSTEXPR width_adapter(SpecHandler& h) : handler(h) {} 2307 2308 FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); } 2309 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); } 2310 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { 2311 handler.on_dynamic_width(id); 2312 } 2313 2314 FMT_CONSTEXPR void on_error(const char* message) { 2315 handler.on_error(message); 2316 } 2317 2318 SpecHandler& handler; 2319 }; 2320 2321 // Adapts SpecHandler to IDHandler API for dynamic precision. 2322 template <typename SpecHandler, typename Char> struct precision_adapter { 2323 explicit FMT_CONSTEXPR precision_adapter(SpecHandler& h) : handler(h) {} 2324 2325 FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); } 2326 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); } 2327 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { 2328 handler.on_dynamic_precision(id); 2329 } 2330 2331 FMT_CONSTEXPR void on_error(const char* message) { 2332 handler.on_error(message); 2333 } 2334 2335 SpecHandler& handler; 2336 }; 2337 2338 // Parses fill and alignment. 2339 template <typename Char, typename Handler> 2340 FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end, 2341 Handler&& handler) { 2342 FMT_ASSERT(begin != end, ""); 2343 auto align = align::none; 2344 int i = 0; 2345 if (begin + 1 != end) ++i; 2346 do { 2347 switch (static_cast<char>(begin[i])) { 2348 case '<': 2349 align = align::left; 2350 break; 2351 case '>': 2352 align = align::right; 2353 break; 2354 #if FMT_NUMERIC_ALIGN 2355 case '=': 2356 align = align::numeric; 2357 break; 2358 #endif 2359 case '^': 2360 align = align::center; 2361 break; 2362 } 2363 if (align != align::none) { 2364 if (i > 0) { 2365 auto c = *begin; 2366 if (c == '{') 2367 return handler.on_error("invalid fill character '{'"), begin; 2368 begin += 2; 2369 handler.on_fill(c); 2370 } else 2371 ++begin; 2372 handler.on_align(align); 2373 break; 2374 } 2375 } while (i-- > 0); 2376 return begin; 2377 } 2378 2379 template <typename Char, typename Handler> 2380 FMT_CONSTEXPR const Char* parse_width(const Char* begin, const Char* end, 2381 Handler&& handler) { 2382 FMT_ASSERT(begin != end, ""); 2383 if ('0' <= *begin && *begin <= '9') { 2384 handler.on_width(parse_nonnegative_int(begin, end, handler)); 2385 } else if (*begin == '{') { 2386 ++begin; 2387 if (begin != end) 2388 begin = parse_arg_id(begin, end, width_adapter<Handler, Char>(handler)); 2389 if (begin == end || *begin != '}') 2390 return handler.on_error("invalid format string"), begin; 2391 ++begin; 2392 } 2393 return begin; 2394 } 2395 2396 template <typename Char, typename Handler> 2397 FMT_CONSTEXPR const Char* parse_precision(const Char* begin, const Char* end, 2398 Handler&& handler) { 2399 ++begin; 2400 auto c = begin != end ? *begin : Char(); 2401 if ('0' <= c && c <= '9') { 2402 handler.on_precision(parse_nonnegative_int(begin, end, handler)); 2403 } else if (c == '{') { 2404 ++begin; 2405 if (begin != end) { 2406 begin = 2407 parse_arg_id(begin, end, precision_adapter<Handler, Char>(handler)); 2408 } 2409 if (begin == end || *begin++ != '}') 2410 return handler.on_error("invalid format string"), begin; 2411 } else { 2412 return handler.on_error("missing precision specifier"), begin; 2413 } 2414 handler.end_precision(); 2415 return begin; 2416 } 2417 2418 // Parses standard format specifiers and sends notifications about parsed 2419 // components to handler. 2420 template <typename Char, typename SpecHandler> 2421 FMT_CONSTEXPR const Char* parse_format_specs(const Char* begin, const Char* end, 2422 SpecHandler&& handler) { 2423 if (begin == end || *begin == '}') return begin; 2424 2425 begin = parse_align(begin, end, handler); 2426 if (begin == end) return begin; 2427 2428 // Parse sign. 2429 switch (static_cast<char>(*begin)) { 2430 case '+': 2431 handler.on_plus(); 2432 ++begin; 2433 break; 2434 case '-': 2435 handler.on_minus(); 2436 ++begin; 2437 break; 2438 case ' ': 2439 handler.on_space(); 2440 ++begin; 2441 break; 2442 } 2443 if (begin == end) return begin; 2444 2445 if (*begin == '#') { 2446 handler.on_hash(); 2447 if (++begin == end) return begin; 2448 } 2449 2450 // Parse zero flag. 2451 if (*begin == '0') { 2452 handler.on_zero(); 2453 if (++begin == end) return begin; 2454 } 2455 2456 begin = parse_width(begin, end, handler); 2457 if (begin == end) return begin; 2458 2459 // Parse precision. 2460 if (*begin == '.') { 2461 begin = parse_precision(begin, end, handler); 2462 } 2463 2464 // Parse type. 2465 if (begin != end && *begin != '}') handler.on_type(*begin++); 2466 return begin; 2467 } 2468 2469 // Return the result via the out param to workaround gcc bug 77539. 2470 template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*> 2471 FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr& out) { 2472 for (out = first; out != last; ++out) { 2473 if (*out == value) return true; 2474 } 2475 return false; 2476 } 2477 2478 template <> 2479 inline bool find<false, char>(const char* first, const char* last, char value, 2480 const char*& out) { 2481 out = static_cast<const char*>( 2482 std::memchr(first, value, internal::to_unsigned(last - first))); 2483 return out != nullptr; 2484 } 2485 2486 template <typename Handler, typename Char> struct id_adapter { 2487 FMT_CONSTEXPR void operator()() { handler.on_arg_id(); } 2488 FMT_CONSTEXPR void operator()(int id) { handler.on_arg_id(id); } 2489 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) { 2490 handler.on_arg_id(id); 2491 } 2492 FMT_CONSTEXPR void on_error(const char* message) { 2493 handler.on_error(message); 2494 } 2495 Handler& handler; 2496 }; 2497 2498 template <bool IS_CONSTEXPR, typename Char, typename Handler> 2499 FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str, 2500 Handler&& handler) { 2501 struct pfs_writer { 2502 FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) { 2503 if (begin == end) return; 2504 for (;;) { 2505 const Char* p = nullptr; 2506 if (!find<IS_CONSTEXPR>(begin, end, '}', p)) 2507 return handler_.on_text(begin, end); 2508 ++p; 2509 if (p == end || *p != '}') 2510 return handler_.on_error("unmatched '}' in format string"); 2511 handler_.on_text(begin, p); 2512 begin = p + 1; 2513 } 2514 } 2515 Handler& handler_; 2516 } write{handler}; 2517 auto begin = format_str.data(); 2518 auto end = begin + format_str.size(); 2519 while (begin != end) { 2520 // Doing two passes with memchr (one for '{' and another for '}') is up to 2521 // 2.5x faster than the naive one-pass implementation on big format strings. 2522 const Char* p = begin; 2523 if (*begin != '{' && !find<IS_CONSTEXPR>(begin, end, '{', p)) 2524 return write(begin, end); 2525 write(begin, p); 2526 ++p; 2527 if (p == end) return handler.on_error("invalid format string"); 2528 if (static_cast<char>(*p) == '}') { 2529 handler.on_arg_id(); 2530 handler.on_replacement_field(p); 2531 } else if (*p == '{') { 2532 handler.on_text(p, p + 1); 2533 } else { 2534 p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler}); 2535 Char c = p != end ? *p : Char(); 2536 if (c == '}') { 2537 handler.on_replacement_field(p); 2538 } else if (c == ':') { 2539 p = handler.on_format_specs(p + 1, end); 2540 if (p == end || *p != '}') 2541 return handler.on_error("unknown format specifier"); 2542 } else { 2543 return handler.on_error("missing '}' in format string"); 2544 } 2545 } 2546 begin = p + 1; 2547 } 2548 } 2549 2550 template <typename T, typename ParseContext> 2551 FMT_CONSTEXPR const typename ParseContext::char_type* parse_format_specs( 2552 ParseContext& ctx) { 2553 using char_type = typename ParseContext::char_type; 2554 using context = buffer_context<char_type>; 2555 using mapped_type = 2556 conditional_t<internal::mapped_type_constant<T, context>::value != 2557 internal::custom_type, 2558 decltype(arg_mapper<context>().map(std::declval<T>())), T>; 2559 auto f = conditional_t<has_formatter<mapped_type, context>::value, 2560 formatter<mapped_type, char_type>, 2561 internal::fallback_formatter<T, char_type>>(); 2562 return f.parse(ctx); 2563 } 2564 2565 template <typename Char, typename ErrorHandler, typename... Args> 2566 class format_string_checker { 2567 public: 2568 explicit FMT_CONSTEXPR format_string_checker( 2569 basic_string_view<Char> format_str, ErrorHandler eh) 2570 : arg_id_(-1), 2571 context_(format_str, eh), 2572 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {} 2573 2574 FMT_CONSTEXPR void on_text(const Char*, const Char*) {} 2575 2576 FMT_CONSTEXPR void on_arg_id() { 2577 arg_id_ = context_.next_arg_id(); 2578 check_arg_id(); 2579 } 2580 FMT_CONSTEXPR void on_arg_id(int id) { 2581 arg_id_ = id; 2582 context_.check_arg_id(id); 2583 check_arg_id(); 2584 } 2585 FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) { 2586 on_error("compile-time checks don't support named arguments"); 2587 } 2588 2589 FMT_CONSTEXPR void on_replacement_field(const Char*) {} 2590 2591 FMT_CONSTEXPR const Char* on_format_specs(const Char* begin, const Char*) { 2592 advance_to(context_, begin); 2593 return arg_id_ < num_args ? parse_funcs_[arg_id_](context_) : begin; 2594 } 2595 2596 FMT_CONSTEXPR void on_error(const char* message) { 2597 context_.on_error(message); 2598 } 2599 2600 private: 2601 using parse_context_type = basic_format_parse_context<Char, ErrorHandler>; 2602 enum { num_args = sizeof...(Args) }; 2603 2604 FMT_CONSTEXPR void check_arg_id() { 2605 if (arg_id_ >= num_args) context_.on_error("argument index out of range"); 2606 } 2607 2608 // Format specifier parsing function. 2609 using parse_func = const Char* (*)(parse_context_type&); 2610 2611 int arg_id_; 2612 parse_context_type context_; 2613 parse_func parse_funcs_[num_args > 0 ? num_args : 1]; 2614 }; 2615 2616 template <typename Char, typename ErrorHandler, typename... Args> 2617 FMT_CONSTEXPR bool do_check_format_string(basic_string_view<Char> s, 2618 ErrorHandler eh = ErrorHandler()) { 2619 format_string_checker<Char, ErrorHandler, Args...> checker(s, eh); 2620 parse_format_string<true>(s, checker); 2621 return true; 2622 } 2623 2624 template <typename... Args, typename S, 2625 enable_if_t<(is_compile_string<S>::value), int>> 2626 void check_format_string(S format_str) { 2627 FMT_CONSTEXPR_DECL bool invalid_format = 2628 internal::do_check_format_string<typename S::char_type, 2629 internal::error_handler, Args...>( 2630 to_string_view(format_str)); 2631 (void)invalid_format; 2632 } 2633 2634 template <template <typename> class Handler, typename Context> 2635 void handle_dynamic_spec(int& value, arg_ref<typename Context::char_type> ref, 2636 Context& ctx) { 2637 switch (ref.kind) { 2638 case arg_id_kind::none: 2639 break; 2640 case arg_id_kind::index: 2641 value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.index), 2642 ctx.error_handler()); 2643 break; 2644 case arg_id_kind::name: 2645 value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.name), 2646 ctx.error_handler()); 2647 break; 2648 } 2649 } 2650 } // namespace internal 2651 2652 template <typename Range> 2653 using basic_writer FMT_DEPRECATED_ALIAS = internal::basic_writer<Range>; 2654 using writer FMT_DEPRECATED_ALIAS = internal::writer; 2655 using wwriter FMT_DEPRECATED_ALIAS = 2656 internal::basic_writer<buffer_range<wchar_t>>; 2657 2658 /** The default argument formatter. */ 2659 template <typename Range> 2660 class arg_formatter : public internal::arg_formatter_base<Range> { 2661 private: 2662 using char_type = typename Range::value_type; 2663 using base = internal::arg_formatter_base<Range>; 2664 using context_type = basic_format_context<typename base::iterator, char_type>; 2665 2666 context_type& ctx_; 2667 basic_format_parse_context<char_type>* parse_ctx_; 2668 2669 public: 2670 using range = Range; 2671 using iterator = typename base::iterator; 2672 using format_specs = typename base::format_specs; 2673 2674 /** 2675 \rst 2676 Constructs an argument formatter object. 2677 *ctx* is a reference to the formatting context, 2678 *specs* contains format specifier information for standard argument types. 2679 \endrst 2680 */ 2681 explicit arg_formatter( 2682 context_type& ctx, 2683 basic_format_parse_context<char_type>* parse_ctx = nullptr, 2684 format_specs* specs = nullptr) 2685 : base(Range(ctx.out()), specs, ctx.locale()), 2686 ctx_(ctx), 2687 parse_ctx_(parse_ctx) {} 2688 2689 using base::operator(); 2690 2691 /** Formats an argument of a user-defined type. */ 2692 iterator operator()(typename basic_format_arg<context_type>::handle handle) { 2693 handle.format(*parse_ctx_, ctx_); 2694 return ctx_.out(); 2695 } 2696 }; 2697 2698 /** 2699 An error returned by an operating system or a language runtime, 2700 for example a file opening error. 2701 */ 2702 class FMT_API system_error : public std::runtime_error { 2703 private: 2704 void init(int err_code, string_view format_str, format_args args); 2705 2706 protected: 2707 int error_code_; 2708 2709 system_error() : std::runtime_error(""), error_code_(0) {} 2710 2711 public: 2712 /** 2713 \rst 2714 Constructs a :class:`fmt::system_error` object with a description 2715 formatted with `fmt::format_system_error`. *message* and additional 2716 arguments passed into the constructor are formatted similarly to 2717 `fmt::format`. 2718 2719 **Example**:: 2720 2721 // This throws a system_error with the description 2722 // cannot open file 'madeup': No such file or directory 2723 // or similar (system message may vary). 2724 const char *filename = "madeup"; 2725 std::FILE *file = std::fopen(filename, "r"); 2726 if (!file) 2727 throw fmt::system_error(errno, "cannot open file '{}'", filename); 2728 \endrst 2729 */ 2730 template <typename... Args> 2731 system_error(int error_code, string_view message, const Args&... args) 2732 : std::runtime_error("") { 2733 init(error_code, message, make_format_args(args...)); 2734 } 2735 system_error(const system_error&) = default; 2736 system_error& operator=(const system_error&) = default; 2737 system_error(system_error&&) = default; 2738 system_error& operator=(system_error&&) = default; 2739 ~system_error() FMT_NOEXCEPT FMT_OVERRIDE; 2740 2741 int error_code() const { return error_code_; } 2742 }; 2743 2744 /** 2745 \rst 2746 Formats an error returned by an operating system or a language runtime, 2747 for example a file opening error, and writes it to *out* in the following 2748 form: 2749 2750 .. parsed-literal:: 2751 *<message>*: *<system-message>* 2752 2753 where *<message>* is the passed message and *<system-message>* is 2754 the system message corresponding to the error code. 2755 *error_code* is a system error code as given by ``errno``. 2756 If *error_code* is not a valid error code such as -1, the system message 2757 may look like "Unknown error -1" and is platform-dependent. 2758 \endrst 2759 */ 2760 FMT_API void format_system_error(internal::buffer<char>& out, int error_code, 2761 string_view message) FMT_NOEXCEPT; 2762 2763 // Reports a system error without throwing an exception. 2764 // Can be used to report errors from destructors. 2765 FMT_API void report_system_error(int error_code, 2766 string_view message) FMT_NOEXCEPT; 2767 2768 #if FMT_USE_WINDOWS_H 2769 2770 /** A Windows error. */ 2771 class windows_error : public system_error { 2772 private: 2773 FMT_API void init(int error_code, string_view format_str, format_args args); 2774 2775 public: 2776 /** 2777 \rst 2778 Constructs a :class:`fmt::windows_error` object with the description 2779 of the form 2780 2781 .. parsed-literal:: 2782 *<message>*: *<system-message>* 2783 2784 where *<message>* is the formatted message and *<system-message>* is the 2785 system message corresponding to the error code. 2786 *error_code* is a Windows error code as given by ``GetLastError``. 2787 If *error_code* is not a valid error code such as -1, the system message 2788 will look like "error -1". 2789 2790 **Example**:: 2791 2792 // This throws a windows_error with the description 2793 // cannot open file 'madeup': The system cannot find the file specified. 2794 // or similar (system message may vary). 2795 const char *filename = "madeup"; 2796 LPOFSTRUCT of = LPOFSTRUCT(); 2797 HFILE file = OpenFile(filename, &of, OF_READ); 2798 if (file == HFILE_ERROR) { 2799 throw fmt::windows_error(GetLastError(), 2800 "cannot open file '{}'", filename); 2801 } 2802 \endrst 2803 */ 2804 template <typename... Args> 2805 windows_error(int error_code, string_view message, const Args&... args) { 2806 init(error_code, message, make_format_args(args...)); 2807 } 2808 }; 2809 2810 // Reports a Windows error without throwing an exception. 2811 // Can be used to report errors from destructors. 2812 FMT_API void report_windows_error(int error_code, 2813 string_view message) FMT_NOEXCEPT; 2814 2815 #endif 2816 2817 /** Fast integer formatter. */ 2818 class format_int { 2819 private: 2820 // Buffer should be large enough to hold all digits (digits10 + 1), 2821 // a sign and a null character. 2822 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 }; 2823 mutable char buffer_[buffer_size]; 2824 char* str_; 2825 2826 // Formats value in reverse and returns a pointer to the beginning. 2827 char* format_decimal(unsigned long long value) { 2828 char* ptr = buffer_ + (buffer_size - 1); // Parens to workaround MSVC bug. 2829 while (value >= 100) { 2830 // Integer division is slow so do it for a group of two digits instead 2831 // of for every digit. The idea comes from the talk by Alexandrescu 2832 // "Three Optimization Tips for C++". See speed-test for a comparison. 2833 auto index = static_cast<unsigned>((value % 100) * 2); 2834 value /= 100; 2835 *--ptr = internal::data::digits[index + 1]; 2836 *--ptr = internal::data::digits[index]; 2837 } 2838 if (value < 10) { 2839 *--ptr = static_cast<char>('0' + value); 2840 return ptr; 2841 } 2842 auto index = static_cast<unsigned>(value * 2); 2843 *--ptr = internal::data::digits[index + 1]; 2844 *--ptr = internal::data::digits[index]; 2845 return ptr; 2846 } 2847 2848 void format_signed(long long value) { 2849 auto abs_value = static_cast<unsigned long long>(value); 2850 bool negative = value < 0; 2851 if (negative) abs_value = 0 - abs_value; 2852 str_ = format_decimal(abs_value); 2853 if (negative) *--str_ = '-'; 2854 } 2855 2856 public: 2857 explicit format_int(int value) { format_signed(value); } 2858 explicit format_int(long value) { format_signed(value); } 2859 explicit format_int(long long value) { format_signed(value); } 2860 explicit format_int(unsigned value) : str_(format_decimal(value)) {} 2861 explicit format_int(unsigned long value) : str_(format_decimal(value)) {} 2862 explicit format_int(unsigned long long value) : str_(format_decimal(value)) {} 2863 2864 /** Returns the number of characters written to the output buffer. */ 2865 std::size_t size() const { 2866 return internal::to_unsigned(buffer_ - str_ + buffer_size - 1); 2867 } 2868 2869 /** 2870 Returns a pointer to the output buffer content. No terminating null 2871 character is appended. 2872 */ 2873 const char* data() const { return str_; } 2874 2875 /** 2876 Returns a pointer to the output buffer content with terminating null 2877 character appended. 2878 */ 2879 const char* c_str() const { 2880 buffer_[buffer_size - 1] = '\0'; 2881 return str_; 2882 } 2883 2884 /** 2885 \rst 2886 Returns the content of the output buffer as an ``std::string``. 2887 \endrst 2888 */ 2889 std::string str() const { return std::string(str_, size()); } 2890 }; 2891 2892 // A formatter specialization for the core types corresponding to internal::type 2893 // constants. 2894 template <typename T, typename Char> 2895 struct formatter<T, Char, 2896 enable_if_t<internal::type_constant<T, Char>::value != 2897 internal::custom_type>> { 2898 FMT_CONSTEXPR formatter() = default; 2899 2900 // Parses format specifiers stopping either at the end of the range or at the 2901 // terminating '}'. 2902 template <typename ParseContext> 2903 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 2904 using handler_type = internal::dynamic_specs_handler<ParseContext>; 2905 auto type = internal::type_constant<T, Char>::value; 2906 internal::specs_checker<handler_type> handler(handler_type(specs_, ctx), 2907 type); 2908 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); 2909 auto eh = ctx.error_handler(); 2910 switch (type) { 2911 case internal::none_type: 2912 case internal::named_arg_type: 2913 FMT_ASSERT(false, "invalid argument type"); 2914 break; 2915 case internal::int_type: 2916 case internal::uint_type: 2917 case internal::long_long_type: 2918 case internal::ulong_long_type: 2919 case internal::int128_type: 2920 case internal::uint128_type: 2921 case internal::bool_type: 2922 handle_int_type_spec(specs_.type, 2923 internal::int_type_checker<decltype(eh)>(eh)); 2924 break; 2925 case internal::char_type: 2926 handle_char_specs( 2927 &specs_, internal::char_specs_checker<decltype(eh)>(specs_.type, eh)); 2928 break; 2929 case internal::float_type: 2930 case internal::double_type: 2931 case internal::long_double_type: 2932 internal::parse_float_type_spec(specs_, eh); 2933 break; 2934 case internal::cstring_type: 2935 internal::handle_cstring_type_spec( 2936 specs_.type, internal::cstring_type_checker<decltype(eh)>(eh)); 2937 break; 2938 case internal::string_type: 2939 internal::check_string_type_spec(specs_.type, eh); 2940 break; 2941 case internal::pointer_type: 2942 internal::check_pointer_type_spec(specs_.type, eh); 2943 break; 2944 case internal::custom_type: 2945 // Custom format specifiers should be checked in parse functions of 2946 // formatter specializations. 2947 break; 2948 } 2949 return it; 2950 } 2951 2952 template <typename FormatContext> 2953 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) { 2954 internal::handle_dynamic_spec<internal::width_checker>( 2955 specs_.width, specs_.width_ref, ctx); 2956 internal::handle_dynamic_spec<internal::precision_checker>( 2957 specs_.precision, specs_.precision_ref, ctx); 2958 using range_type = 2959 internal::output_range<typename FormatContext::iterator, 2960 typename FormatContext::char_type>; 2961 return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_), 2962 internal::make_arg<FormatContext>(val)); 2963 } 2964 2965 private: 2966 internal::dynamic_format_specs<Char> specs_; 2967 }; 2968 2969 #define FMT_FORMAT_AS(Type, Base) \ 2970 template <typename Char> \ 2971 struct formatter<Type, Char> : formatter<Base, Char> { \ 2972 template <typename FormatContext> \ 2973 auto format(const Type& val, FormatContext& ctx) -> decltype(ctx.out()) { \ 2974 return formatter<Base, Char>::format(val, ctx); \ 2975 } \ 2976 } 2977 2978 FMT_FORMAT_AS(signed char, int); 2979 FMT_FORMAT_AS(unsigned char, unsigned); 2980 FMT_FORMAT_AS(short, int); 2981 FMT_FORMAT_AS(unsigned short, unsigned); 2982 FMT_FORMAT_AS(long, long long); 2983 FMT_FORMAT_AS(unsigned long, unsigned long long); 2984 FMT_FORMAT_AS(Char*, const Char*); 2985 FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>); 2986 FMT_FORMAT_AS(std::nullptr_t, const void*); 2987 FMT_FORMAT_AS(internal::std_string_view<Char>, basic_string_view<Char>); 2988 2989 template <typename Char> 2990 struct formatter<void*, Char> : formatter<const void*, Char> { 2991 template <typename FormatContext> 2992 auto format(void* val, FormatContext& ctx) -> decltype(ctx.out()) { 2993 return formatter<const void*, Char>::format(val, ctx); 2994 } 2995 }; 2996 2997 template <typename Char, size_t N> 2998 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> { 2999 template <typename FormatContext> 3000 auto format(const Char* val, FormatContext& ctx) -> decltype(ctx.out()) { 3001 return formatter<basic_string_view<Char>, Char>::format(val, ctx); 3002 } 3003 }; 3004 3005 // A formatter for types known only at run time such as variant alternatives. 3006 // 3007 // Usage: 3008 // using variant = std::variant<int, std::string>; 3009 // template <> 3010 // struct formatter<variant>: dynamic_formatter<> { 3011 // void format(buffer &buf, const variant &v, context &ctx) { 3012 // visit([&](const auto &val) { format(buf, val, ctx); }, v); 3013 // } 3014 // }; 3015 template <typename Char = char> class dynamic_formatter { 3016 private: 3017 struct null_handler : internal::error_handler { 3018 void on_align(align_t) {} 3019 void on_plus() {} 3020 void on_minus() {} 3021 void on_space() {} 3022 void on_hash() {} 3023 }; 3024 3025 public: 3026 template <typename ParseContext> 3027 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 3028 format_str_ = ctx.begin(); 3029 // Checks are deferred to formatting time when the argument type is known. 3030 internal::dynamic_specs_handler<ParseContext> handler(specs_, ctx); 3031 return parse_format_specs(ctx.begin(), ctx.end(), handler); 3032 } 3033 3034 template <typename T, typename FormatContext> 3035 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) { 3036 handle_specs(ctx); 3037 internal::specs_checker<null_handler> checker( 3038 null_handler(), 3039 internal::mapped_type_constant<T, FormatContext>::value); 3040 checker.on_align(specs_.align); 3041 switch (specs_.sign) { 3042 case sign::none: 3043 break; 3044 case sign::plus: 3045 checker.on_plus(); 3046 break; 3047 case sign::minus: 3048 checker.on_minus(); 3049 break; 3050 case sign::space: 3051 checker.on_space(); 3052 break; 3053 } 3054 if (specs_.alt) checker.on_hash(); 3055 if (specs_.precision >= 0) checker.end_precision(); 3056 using range = internal::output_range<typename FormatContext::iterator, 3057 typename FormatContext::char_type>; 3058 visit_format_arg(arg_formatter<range>(ctx, nullptr, &specs_), 3059 internal::make_arg<FormatContext>(val)); 3060 return ctx.out(); 3061 } 3062 3063 private: 3064 template <typename Context> void handle_specs(Context& ctx) { 3065 internal::handle_dynamic_spec<internal::width_checker>( 3066 specs_.width, specs_.width_ref, ctx); 3067 internal::handle_dynamic_spec<internal::precision_checker>( 3068 specs_.precision, specs_.precision_ref, ctx); 3069 } 3070 3071 internal::dynamic_format_specs<Char> specs_; 3072 const Char* format_str_; 3073 }; 3074 3075 template <typename Range, typename Char> 3076 typename basic_format_context<Range, Char>::format_arg 3077 basic_format_context<Range, Char>::arg(basic_string_view<char_type> name) { 3078 map_.init(args_); 3079 format_arg arg = map_.find(name); 3080 if (arg.type() == internal::none_type) this->on_error("argument not found"); 3081 return arg; 3082 } 3083 3084 template <typename Char, typename ErrorHandler> 3085 FMT_CONSTEXPR void advance_to( 3086 basic_format_parse_context<Char, ErrorHandler>& ctx, const Char* p) { 3087 ctx.advance_to(ctx.begin() + (p - &*ctx.begin())); 3088 } 3089 3090 template <typename ArgFormatter, typename Char, typename Context> 3091 struct format_handler : internal::error_handler { 3092 using range = typename ArgFormatter::range; 3093 3094 format_handler(range r, basic_string_view<Char> str, 3095 basic_format_args<Context> format_args, 3096 internal::locale_ref loc) 3097 : parse_context(str), context(r.begin(), format_args, loc) {} 3098 3099 void on_text(const Char* begin, const Char* end) { 3100 auto size = internal::to_unsigned(end - begin); 3101 auto out = context.out(); 3102 auto&& it = internal::reserve(out, size); 3103 it = std::copy_n(begin, size, it); 3104 context.advance_to(out); 3105 } 3106 3107 void get_arg(int id) { arg = internal::get_arg(context, id); } 3108 3109 void on_arg_id() { get_arg(parse_context.next_arg_id()); } 3110 void on_arg_id(int id) { 3111 parse_context.check_arg_id(id); 3112 get_arg(id); 3113 } 3114 void on_arg_id(basic_string_view<Char> id) { arg = context.arg(id); } 3115 3116 void on_replacement_field(const Char* p) { 3117 advance_to(parse_context, p); 3118 context.advance_to( 3119 visit_format_arg(ArgFormatter(context, &parse_context), arg)); 3120 } 3121 3122 const Char* on_format_specs(const Char* begin, const Char* end) { 3123 advance_to(parse_context, begin); 3124 internal::custom_formatter<Context> f(parse_context, context); 3125 if (visit_format_arg(f, arg)) return parse_context.begin(); 3126 basic_format_specs<Char> specs; 3127 using internal::specs_handler; 3128 using parse_context_t = basic_format_parse_context<Char>; 3129 internal::specs_checker<specs_handler<parse_context_t, Context>> handler( 3130 specs_handler<parse_context_t, Context>(specs, parse_context, context), 3131 arg.type()); 3132 begin = parse_format_specs(begin, end, handler); 3133 if (begin == end || *begin != '}') on_error("missing '}' in format string"); 3134 advance_to(parse_context, begin); 3135 context.advance_to( 3136 visit_format_arg(ArgFormatter(context, &parse_context, &specs), arg)); 3137 return begin; 3138 } 3139 3140 basic_format_parse_context<Char> parse_context; 3141 Context context; 3142 basic_format_arg<Context> arg; 3143 }; 3144 3145 /** Formats arguments and writes the output to the range. */ 3146 template <typename ArgFormatter, typename Char, typename Context> 3147 typename Context::iterator vformat_to( 3148 typename ArgFormatter::range out, basic_string_view<Char> format_str, 3149 basic_format_args<Context> args, 3150 internal::locale_ref loc = internal::locale_ref()) { 3151 format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc); 3152 internal::parse_format_string<false>(format_str, h); 3153 return h.context.out(); 3154 } 3155 3156 // Casts ``p`` to ``const void*`` for pointer formatting. 3157 // Example: 3158 // auto s = format("{}", ptr(p)); 3159 template <typename T> inline const void* ptr(const T* p) { return p; } 3160 template <typename T> inline const void* ptr(const std::unique_ptr<T>& p) { 3161 return p.get(); 3162 } 3163 template <typename T> inline const void* ptr(const std::shared_ptr<T>& p) { 3164 return p.get(); 3165 } 3166 3167 template <typename It, typename Char> struct arg_join : internal::view { 3168 It begin; 3169 It end; 3170 basic_string_view<Char> sep; 3171 3172 arg_join(It b, It e, basic_string_view<Char> s) : begin(b), end(e), sep(s) {} 3173 }; 3174 3175 template <typename It, typename Char> 3176 struct formatter<arg_join<It, Char>, Char> 3177 : formatter<typename std::iterator_traits<It>::value_type, Char> { 3178 template <typename FormatContext> 3179 auto format(const arg_join<It, Char>& value, FormatContext& ctx) 3180 -> decltype(ctx.out()) { 3181 using base = formatter<typename std::iterator_traits<It>::value_type, Char>; 3182 auto it = value.begin; 3183 auto out = ctx.out(); 3184 if (it != value.end) { 3185 out = base::format(*it++, ctx); 3186 while (it != value.end) { 3187 out = std::copy(value.sep.begin(), value.sep.end(), out); 3188 ctx.advance_to(out); 3189 out = base::format(*it++, ctx); 3190 } 3191 } 3192 return out; 3193 } 3194 }; 3195 3196 /** 3197 Returns an object that formats the iterator range `[begin, end)` with elements 3198 separated by `sep`. 3199 */ 3200 template <typename It> 3201 arg_join<It, char> join(It begin, It end, string_view sep) { 3202 return {begin, end, sep}; 3203 } 3204 3205 template <typename It> 3206 arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) { 3207 return {begin, end, sep}; 3208 } 3209 3210 /** 3211 \rst 3212 Returns an object that formats `range` with elements separated by `sep`. 3213 3214 **Example**:: 3215 3216 std::vector<int> v = {1, 2, 3}; 3217 fmt::print("{}", fmt::join(v, ", ")); 3218 // Output: "1, 2, 3" 3219 \endrst 3220 */ 3221 template <typename Range> 3222 arg_join<internal::iterator_t<const Range>, char> join(const Range& range, 3223 string_view sep) { 3224 return join(std::begin(range), std::end(range), sep); 3225 } 3226 3227 template <typename Range> 3228 arg_join<internal::iterator_t<const Range>, wchar_t> join(const Range& range, 3229 wstring_view sep) { 3230 return join(std::begin(range), std::end(range), sep); 3231 } 3232 3233 /** 3234 \rst 3235 Converts *value* to ``std::string`` using the default format for type *T*. 3236 It doesn't support user-defined types with custom formatters. 3237 3238 **Example**:: 3239 3240 #include <fmt/format.h> 3241 3242 std::string answer = fmt::to_string(42); 3243 \endrst 3244 */ 3245 template <typename T> inline std::string to_string(const T& value) { 3246 return format("{}", value); 3247 } 3248 3249 /** 3250 Converts *value* to ``std::wstring`` using the default format for type *T*. 3251 */ 3252 template <typename T> inline std::wstring to_wstring(const T& value) { 3253 return format(L"{}", value); 3254 } 3255 3256 template <typename Char, std::size_t SIZE> 3257 std::basic_string<Char> to_string(const basic_memory_buffer<Char, SIZE>& buf) { 3258 return std::basic_string<Char>(buf.data(), buf.size()); 3259 } 3260 3261 template <typename Char> 3262 typename buffer_context<Char>::iterator internal::vformat_to( 3263 internal::buffer<Char>& buf, basic_string_view<Char> format_str, 3264 basic_format_args<buffer_context<Char>> args) { 3265 using range = buffer_range<Char>; 3266 return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str), 3267 args); 3268 } 3269 3270 template <typename S, typename Char = char_t<S>, 3271 FMT_ENABLE_IF(internal::is_string<S>::value)> 3272 inline typename buffer_context<Char>::iterator vformat_to( 3273 internal::buffer<Char>& buf, const S& format_str, 3274 basic_format_args<buffer_context<Char>> args) { 3275 return internal::vformat_to(buf, to_string_view(format_str), args); 3276 } 3277 3278 template <typename S, typename... Args, std::size_t SIZE = inline_buffer_size, 3279 typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>> 3280 inline typename buffer_context<Char>::iterator format_to( 3281 basic_memory_buffer<Char, SIZE>& buf, const S& format_str, Args&&... args) { 3282 internal::check_format_string<Args...>(format_str); 3283 using context = buffer_context<Char>; 3284 return internal::vformat_to(buf, to_string_view(format_str), 3285 {make_format_args<context>(args...)}); 3286 } 3287 3288 template <typename OutputIt, typename Char = char> 3289 using format_context_t = basic_format_context<OutputIt, Char>; 3290 3291 template <typename OutputIt, typename Char = char> 3292 using format_args_t = basic_format_args<format_context_t<OutputIt, Char>>; 3293 3294 template <typename S, typename OutputIt, typename... Args, 3295 FMT_ENABLE_IF( 3296 internal::is_output_iterator<OutputIt>::value && 3297 !internal::is_contiguous_back_insert_iterator<OutputIt>::value)> 3298 inline OutputIt vformat_to(OutputIt out, const S& format_str, 3299 format_args_t<OutputIt, char_t<S>> args) { 3300 using range = internal::output_range<OutputIt, char_t<S>>; 3301 return vformat_to<arg_formatter<range>>(range(out), 3302 to_string_view(format_str), args); 3303 } 3304 3305 /** 3306 \rst 3307 Formats arguments, writes the result to the output iterator ``out`` and returns 3308 the iterator past the end of the output range. 3309 3310 **Example**:: 3311 3312 std::vector<char> out; 3313 fmt::format_to(std::back_inserter(out), "{}", 42); 3314 \endrst 3315 */ 3316 template <typename OutputIt, typename S, typename... Args, 3317 FMT_ENABLE_IF( 3318 internal::is_output_iterator<OutputIt>::value && 3319 !internal::is_contiguous_back_insert_iterator<OutputIt>::value && 3320 internal::is_string<S>::value)> 3321 inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) { 3322 internal::check_format_string<Args...>(format_str); 3323 using context = format_context_t<OutputIt, char_t<S>>; 3324 return vformat_to(out, to_string_view(format_str), 3325 {make_format_args<context>(args...)}); 3326 } 3327 3328 template <typename OutputIt> struct format_to_n_result { 3329 /** Iterator past the end of the output range. */ 3330 OutputIt out; 3331 /** Total (not truncated) output size. */ 3332 std::size_t size; 3333 }; 3334 3335 template <typename OutputIt, typename Char = typename OutputIt::value_type> 3336 using format_to_n_context = 3337 format_context_t<internal::truncating_iterator<OutputIt>, Char>; 3338 3339 template <typename OutputIt, typename Char = typename OutputIt::value_type> 3340 using format_to_n_args = basic_format_args<format_to_n_context<OutputIt, Char>>; 3341 3342 template <typename OutputIt, typename Char, typename... Args> 3343 inline format_arg_store<format_to_n_context<OutputIt, Char>, Args...> 3344 make_format_to_n_args(const Args&... args) { 3345 return format_arg_store<format_to_n_context<OutputIt, Char>, Args...>( 3346 args...); 3347 } 3348 3349 template <typename OutputIt, typename Char, typename... Args, 3350 FMT_ENABLE_IF(internal::is_output_iterator<OutputIt>::value)> 3351 inline format_to_n_result<OutputIt> vformat_to_n( 3352 OutputIt out, std::size_t n, basic_string_view<Char> format_str, 3353 format_to_n_args<OutputIt, Char> args) { 3354 auto it = vformat_to(internal::truncating_iterator<OutputIt>(out, n), 3355 format_str, args); 3356 return {it.base(), it.count()}; 3357 } 3358 3359 /** 3360 \rst 3361 Formats arguments, writes up to ``n`` characters of the result to the output 3362 iterator ``out`` and returns the total output size and the iterator past the 3363 end of the output range. 3364 \endrst 3365 */ 3366 template <typename OutputIt, typename S, typename... Args, 3367 FMT_ENABLE_IF(internal::is_string<S>::value&& 3368 internal::is_output_iterator<OutputIt>::value)> 3369 inline format_to_n_result<OutputIt> format_to_n(OutputIt out, std::size_t n, 3370 const S& format_str, 3371 const Args&... args) { 3372 internal::check_format_string<Args...>(format_str); 3373 using context = format_to_n_context<OutputIt, char_t<S>>; 3374 return vformat_to_n(out, n, to_string_view(format_str), 3375 {make_format_args<context>(args...)}); 3376 } 3377 3378 template <typename Char> 3379 inline std::basic_string<Char> internal::vformat( 3380 basic_string_view<Char> format_str, 3381 basic_format_args<buffer_context<Char>> args) { 3382 basic_memory_buffer<Char> buffer; 3383 internal::vformat_to(buffer, format_str, args); 3384 return to_string(buffer); 3385 } 3386 3387 /** 3388 Returns the number of characters in the output of 3389 ``format(format_str, args...)``. 3390 */ 3391 template <typename... Args> 3392 inline std::size_t formatted_size(string_view format_str, const Args&... args) { 3393 return format_to(internal::counting_iterator(), format_str, args...).count(); 3394 } 3395 3396 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)> 3397 void vprint(std::FILE* f, basic_string_view<Char> format_str, 3398 wformat_args args) { 3399 wmemory_buffer buffer; 3400 internal::vformat_to(buffer, format_str, args); 3401 buffer.push_back(L'\0'); 3402 if (std::fputws(buffer.data(), f) == -1) 3403 FMT_THROW(system_error(errno, "cannot write to file")); 3404 } 3405 3406 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)> 3407 void vprint(basic_string_view<Char> format_str, wformat_args args) { 3408 vprint(stdout, format_str, args); 3409 } 3410 3411 #if FMT_USE_USER_DEFINED_LITERALS 3412 namespace internal { 3413 3414 # if FMT_USE_UDL_TEMPLATE 3415 template <typename Char, Char... CHARS> class udl_formatter { 3416 public: 3417 template <typename... Args> 3418 std::basic_string<Char> operator()(Args&&... args) const { 3419 FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'}; 3420 FMT_CONSTEXPR_DECL bool invalid_format = 3421 do_check_format_string<Char, error_handler, remove_cvref_t<Args>...>( 3422 basic_string_view<Char>(s, sizeof...(CHARS))); 3423 (void)invalid_format; 3424 return format(s, std::forward<Args>(args)...); 3425 } 3426 }; 3427 # else 3428 template <typename Char> struct udl_formatter { 3429 basic_string_view<Char> str; 3430 3431 template <typename... Args> 3432 std::basic_string<Char> operator()(Args&&... args) const { 3433 return format(str, std::forward<Args>(args)...); 3434 } 3435 }; 3436 # endif // FMT_USE_UDL_TEMPLATE 3437 3438 template <typename Char> struct udl_arg { 3439 basic_string_view<Char> str; 3440 3441 template <typename T> named_arg<T, Char> operator=(T&& value) const { 3442 return {str, std::forward<T>(value)}; 3443 } 3444 }; 3445 3446 } // namespace internal 3447 3448 inline namespace literals { 3449 # if FMT_USE_UDL_TEMPLATE 3450 # pragma GCC diagnostic push 3451 # if FMT_CLANG_VERSION 3452 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template" 3453 # endif 3454 template <typename Char, Char... CHARS> 3455 FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...> operator""_format() { 3456 return {}; 3457 } 3458 # pragma GCC diagnostic pop 3459 # else 3460 /** 3461 \rst 3462 User-defined literal equivalent of :func:`fmt::format`. 3463 3464 **Example**:: 3465 3466 using namespace fmt::literals; 3467 std::string message = "The answer is {}"_format(42); 3468 \endrst 3469 */ 3470 FMT_CONSTEXPR internal::udl_formatter<char> operator"" _format(const char* s, 3471 std::size_t n) { 3472 return {{s, n}}; 3473 } 3474 FMT_CONSTEXPR internal::udl_formatter<wchar_t> operator"" _format( 3475 const wchar_t* s, std::size_t n) { 3476 return {{s, n}}; 3477 } 3478 # endif // FMT_USE_UDL_TEMPLATE 3479 3480 /** 3481 \rst 3482 User-defined literal equivalent of :func:`fmt::arg`. 3483 3484 **Example**:: 3485 3486 using namespace fmt::literals; 3487 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); 3488 \endrst 3489 */ 3490 FMT_CONSTEXPR internal::udl_arg<char> operator"" _a(const char* s, 3491 std::size_t n) { 3492 return {{s, n}}; 3493 } 3494 FMT_CONSTEXPR internal::udl_arg<wchar_t> operator"" _a(const wchar_t* s, 3495 std::size_t n) { 3496 return {{s, n}}; 3497 } 3498 } // namespace literals 3499 #endif // FMT_USE_USER_DEFINED_LITERALS 3500 FMT_END_NAMESPACE 3501 3502 #define FMT_STRING_IMPL(s, ...) \ 3503 [] { \ 3504 struct str : fmt::compile_string { \ 3505 using char_type = typename std::remove_cv<std::remove_pointer< \ 3506 typename std::decay<decltype(s)>::type>::type>::type; \ 3507 __VA_ARGS__ FMT_CONSTEXPR \ 3508 operator fmt::basic_string_view<char_type>() const { \ 3509 return {s, sizeof(s) / sizeof(char_type) - 1}; \ 3510 } \ 3511 } result; \ 3512 /* Suppress Qt Creator warning about unused operator. */ \ 3513 (void)static_cast<fmt::basic_string_view<typename str::char_type>>( \ 3514 result); \ 3515 return result; \ 3516 }() 3517 3518 /** 3519 \rst 3520 Constructs a compile-time format string. 3521 3522 **Example**:: 3523 3524 // A compile-time error because 'd' is an invalid specifier for strings. 3525 std::string s = format(FMT_STRING("{:d}"), "foo"); 3526 \endrst 3527 */ 3528 #define FMT_STRING(s) FMT_STRING_IMPL(s, ) 3529 3530 #if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS 3531 # define fmt(s) FMT_STRING_IMPL(s, [[deprecated]]) 3532 #endif 3533 3534 #ifdef FMT_HEADER_ONLY 3535 # define FMT_FUNC inline 3536 # include "format-inl.h" 3537 #else 3538 # define FMT_FUNC 3539 #endif 3540 3541 #endif // FMT_FORMAT_H_ 3542