1 // Formatting library for C++ - the core API 2 // 3 // Copyright (c) 2012 - present, Victor Zverovich 4 // All rights reserved. 5 // 6 // For the license information refer to format.h. 7 8 #ifndef FMT_CORE_H_ 9 #define FMT_CORE_H_ 10 11 #include <cstdio> // std::FILE 12 #include <cstring> 13 #include <iterator> 14 #include <string> 15 #include <type_traits> 16 17 // The fmt library version in the form major * 10000 + minor * 100 + patch. 18 #define FMT_VERSION 60102 19 20 #ifdef __has_feature 21 # define FMT_HAS_FEATURE(x) __has_feature(x) 22 #else 23 # define FMT_HAS_FEATURE(x) 0 24 #endif 25 26 #if defined(__has_include) && !defined(__INTELLISENSE__) && \ 27 !(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600) 28 # define FMT_HAS_INCLUDE(x) __has_include(x) 29 #else 30 # define FMT_HAS_INCLUDE(x) 0 31 #endif 32 33 #ifdef __has_cpp_attribute 34 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 35 #else 36 # define FMT_HAS_CPP_ATTRIBUTE(x) 0 37 #endif 38 39 #if defined(__GNUC__) && !defined(__clang__) 40 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 41 #else 42 # define FMT_GCC_VERSION 0 43 #endif 44 45 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) 46 # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION 47 #else 48 # define FMT_HAS_GXX_CXX11 0 49 #endif 50 51 #ifdef __NVCC__ 52 # define FMT_NVCC __NVCC__ 53 #else 54 # define FMT_NVCC 0 55 #endif 56 57 #ifdef _MSC_VER 58 # define FMT_MSC_VER _MSC_VER 59 #else 60 # define FMT_MSC_VER 0 61 #endif 62 63 // Check if relaxed C++14 constexpr is supported. 64 // GCC doesn't allow throw in constexpr until version 6 (bug 67371). 65 #ifndef FMT_USE_CONSTEXPR 66 # define FMT_USE_CONSTEXPR \ 67 (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ 68 (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ 69 !FMT_NVCC 70 #endif 71 #if FMT_USE_CONSTEXPR 72 # define FMT_CONSTEXPR constexpr 73 # define FMT_CONSTEXPR_DECL constexpr 74 #else 75 # define FMT_CONSTEXPR inline 76 # define FMT_CONSTEXPR_DECL 77 #endif 78 79 #ifndef FMT_OVERRIDE 80 # if FMT_HAS_FEATURE(cxx_override) || \ 81 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 82 # define FMT_OVERRIDE override 83 # else 84 # define FMT_OVERRIDE 85 # endif 86 #endif 87 88 // Check if exceptions are disabled. 89 #ifndef FMT_EXCEPTIONS 90 # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ 91 FMT_MSC_VER && !_HAS_EXCEPTIONS 92 # define FMT_EXCEPTIONS 0 93 # else 94 # define FMT_EXCEPTIONS 1 95 # endif 96 #endif 97 98 // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). 99 #ifndef FMT_USE_NOEXCEPT 100 # define FMT_USE_NOEXCEPT 0 101 #endif 102 103 #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ 104 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 105 # define FMT_DETECTED_NOEXCEPT noexcept 106 # define FMT_HAS_CXX11_NOEXCEPT 1 107 #else 108 # define FMT_DETECTED_NOEXCEPT throw() 109 # define FMT_HAS_CXX11_NOEXCEPT 0 110 #endif 111 112 #ifndef FMT_NOEXCEPT 113 # if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT 114 # define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT 115 # else 116 # define FMT_NOEXCEPT 117 # endif 118 #endif 119 120 // [[noreturn]] is disabled on MSVC because of bogus unreachable code warnings. 121 #if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER 122 # define FMT_NORETURN [[noreturn]] 123 #else 124 # define FMT_NORETURN 125 #endif 126 127 #ifndef FMT_DEPRECATED 128 # if (FMT_HAS_CPP_ATTRIBUTE(deprecated) && __cplusplus >= 201402L) || \ 129 FMT_MSC_VER >= 1900 130 # define FMT_DEPRECATED [[deprecated]] 131 # else 132 # if defined(__GNUC__) || defined(__clang__) 133 # define FMT_DEPRECATED __attribute__((deprecated)) 134 # elif FMT_MSC_VER 135 # define FMT_DEPRECATED __declspec(deprecated) 136 # else 137 # define FMT_DEPRECATED /* deprecated */ 138 # endif 139 # endif 140 #endif 141 142 // Workaround broken [[deprecated]] in the Intel compiler and NVCC. 143 #if defined(__INTEL_COMPILER) || FMT_NVCC 144 # define FMT_DEPRECATED_ALIAS 145 #else 146 # define FMT_DEPRECATED_ALIAS FMT_DEPRECATED 147 #endif 148 149 #ifndef FMT_BEGIN_NAMESPACE 150 # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ 151 FMT_MSC_VER >= 1900 152 # define FMT_INLINE_NAMESPACE inline namespace 153 # define FMT_END_NAMESPACE \ 154 } \ 155 } 156 # else 157 # define FMT_INLINE_NAMESPACE namespace 158 # define FMT_END_NAMESPACE \ 159 } \ 160 using namespace v6; \ 161 } 162 # endif 163 # define FMT_BEGIN_NAMESPACE \ 164 namespace fmt { \ 165 FMT_INLINE_NAMESPACE v6 { 166 #endif 167 168 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) 169 # ifdef FMT_EXPORT 170 # define FMT_API __declspec(dllexport) 171 # elif defined(FMT_SHARED) 172 # define FMT_API __declspec(dllimport) 173 # define FMT_EXTERN_TEMPLATE_API FMT_API 174 # endif 175 #endif 176 #ifndef FMT_API 177 # define FMT_API 178 #endif 179 #ifndef FMT_EXTERN_TEMPLATE_API 180 # define FMT_EXTERN_TEMPLATE_API 181 #endif 182 183 #ifndef FMT_HEADER_ONLY 184 # define FMT_EXTERN extern 185 #else 186 # define FMT_EXTERN 187 #endif 188 189 // libc++ supports string_view in pre-c++17. 190 #if (FMT_HAS_INCLUDE(<string_view>) && \ 191 (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \ 192 (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) 193 # include <string_view> 194 # define FMT_USE_STRING_VIEW 195 #elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L 196 # include <experimental/string_view> 197 # define FMT_USE_EXPERIMENTAL_STRING_VIEW 198 #endif 199 200 FMT_BEGIN_NAMESPACE 201 202 // Implementations of enable_if_t and other types for pre-C++14 systems. 203 template <bool B, class T = void> 204 using enable_if_t = typename std::enable_if<B, T>::type; 205 template <bool B, class T, class F> 206 using conditional_t = typename std::conditional<B, T, F>::type; 207 template <bool B> using bool_constant = std::integral_constant<bool, B>; 208 template <typename T> 209 using remove_reference_t = typename std::remove_reference<T>::type; 210 template <typename T> 211 using remove_const_t = typename std::remove_const<T>::type; 212 template <typename T> 213 using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type; 214 215 struct monostate {}; 216 217 // An enable_if helper to be used in template parameters which results in much 218 // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed 219 // to workaround a bug in MSVC 2019 (see #1140 and #1186). 220 #define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 221 222 namespace internal { 223 224 // A workaround for gcc 4.8 to make void_t work in a SFINAE context. 225 template <typename... Ts> struct void_t_impl { using type = void; }; 226 227 FMT_API void assert_fail(const char* file, int line, const char* message); 228 229 #ifndef FMT_ASSERT 230 # ifdef NDEBUG 231 # define FMT_ASSERT(condition, message) 232 # else 233 # define FMT_ASSERT(condition, message) \ 234 ((condition) \ 235 ? void() \ 236 : fmt::internal::assert_fail(__FILE__, __LINE__, (message))) 237 # endif 238 #endif 239 240 #if defined(FMT_USE_STRING_VIEW) 241 template <typename Char> using std_string_view = std::basic_string_view<Char>; 242 #elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW) 243 template <typename Char> 244 using std_string_view = std::experimental::basic_string_view<Char>; 245 #else 246 template <typename T> struct std_string_view {}; 247 #endif 248 249 #ifdef FMT_USE_INT128 250 // Do nothing. 251 #elif defined(__SIZEOF_INT128__) 252 # define FMT_USE_INT128 1 253 using int128_t = __int128_t; 254 using uint128_t = __uint128_t; 255 #else 256 # define FMT_USE_INT128 0 257 #endif 258 #if !FMT_USE_INT128 259 struct int128_t {}; 260 struct uint128_t {}; 261 #endif 262 263 // Casts a nonnegative integer to unsigned. 264 template <typename Int> 265 FMT_CONSTEXPR typename std::make_unsigned<Int>::type to_unsigned(Int value) { 266 FMT_ASSERT(value >= 0, "negative value"); 267 return static_cast<typename std::make_unsigned<Int>::type>(value); 268 } 269 } // namespace internal 270 271 template <typename... Ts> 272 using void_t = typename internal::void_t_impl<Ts...>::type; 273 274 /** 275 An implementation of ``std::basic_string_view`` for pre-C++17. It provides a 276 subset of the API. ``fmt::basic_string_view`` is used for format strings even 277 if ``std::string_view`` is available to prevent issues when a library is 278 compiled with a different ``-std`` option than the client code (which is not 279 recommended). 280 */ 281 template <typename Char> class basic_string_view { 282 private: 283 const Char* data_; 284 size_t size_; 285 286 public: 287 using char_type = Char; 288 using iterator = const Char*; 289 290 FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} 291 292 /** Constructs a string reference object from a C string and a size. */ 293 FMT_CONSTEXPR basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT 294 : data_(s), 295 size_(count) {} 296 297 /** 298 \rst 299 Constructs a string reference object from a C string computing 300 the size with ``std::char_traits<Char>::length``. 301 \endrst 302 */ 303 basic_string_view(const Char* s) 304 : data_(s), size_(std::char_traits<Char>::length(s)) {} 305 306 /** Constructs a string reference from a ``std::basic_string`` object. */ 307 template <typename Traits, typename Alloc> 308 FMT_CONSTEXPR basic_string_view( 309 const std::basic_string<Char, Traits, Alloc>& s) FMT_NOEXCEPT 310 : data_(s.data()), 311 size_(s.size()) {} 312 313 template < 314 typename S, 315 FMT_ENABLE_IF(std::is_same<S, internal::std_string_view<Char>>::value)> 316 FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), 317 size_(s.size()) {} 318 319 /** Returns a pointer to the string data. */ 320 FMT_CONSTEXPR const Char* data() const { return data_; } 321 322 /** Returns the string size. */ 323 FMT_CONSTEXPR size_t size() const { return size_; } 324 325 FMT_CONSTEXPR iterator begin() const { return data_; } 326 FMT_CONSTEXPR iterator end() const { return data_ + size_; } 327 328 FMT_CONSTEXPR const Char& operator[](size_t pos) const { return data_[pos]; } 329 330 FMT_CONSTEXPR void remove_prefix(size_t n) { 331 data_ += n; 332 size_ -= n; 333 } 334 335 // Lexicographically compare this string reference to other. 336 int compare(basic_string_view other) const { 337 size_t str_size = size_ < other.size_ ? size_ : other.size_; 338 int result = std::char_traits<Char>::compare(data_, other.data_, str_size); 339 if (result == 0) 340 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); 341 return result; 342 } 343 344 friend bool operator==(basic_string_view lhs, basic_string_view rhs) { 345 return lhs.compare(rhs) == 0; 346 } 347 friend bool operator!=(basic_string_view lhs, basic_string_view rhs) { 348 return lhs.compare(rhs) != 0; 349 } 350 friend bool operator<(basic_string_view lhs, basic_string_view rhs) { 351 return lhs.compare(rhs) < 0; 352 } 353 friend bool operator<=(basic_string_view lhs, basic_string_view rhs) { 354 return lhs.compare(rhs) <= 0; 355 } 356 friend bool operator>(basic_string_view lhs, basic_string_view rhs) { 357 return lhs.compare(rhs) > 0; 358 } 359 friend bool operator>=(basic_string_view lhs, basic_string_view rhs) { 360 return lhs.compare(rhs) >= 0; 361 } 362 }; 363 364 using string_view = basic_string_view<char>; 365 using wstring_view = basic_string_view<wchar_t>; 366 367 #ifndef __cpp_char8_t 368 // A UTF-8 code unit type. 369 enum char8_t : unsigned char {}; 370 #endif 371 372 /** Specifies if ``T`` is a character type. Can be specialized by users. */ 373 template <typename T> struct is_char : std::false_type {}; 374 template <> struct is_char<char> : std::true_type {}; 375 template <> struct is_char<wchar_t> : std::true_type {}; 376 template <> struct is_char<char8_t> : std::true_type {}; 377 template <> struct is_char<char16_t> : std::true_type {}; 378 template <> struct is_char<char32_t> : std::true_type {}; 379 380 /** 381 \rst 382 Returns a string view of `s`. In order to add custom string type support to 383 {fmt} provide an overload of `to_string_view` for it in the same namespace as 384 the type for the argument-dependent lookup to work. 385 386 **Example**:: 387 388 namespace my_ns { 389 inline string_view to_string_view(const my_string& s) { 390 return {s.data(), s.length()}; 391 } 392 } 393 std::string message = fmt::format(my_string("The answer is {}"), 42); 394 \endrst 395 */ 396 template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)> 397 inline basic_string_view<Char> to_string_view(const Char* s) { 398 return s; 399 } 400 401 template <typename Char, typename Traits, typename Alloc> 402 inline basic_string_view<Char> to_string_view( 403 const std::basic_string<Char, Traits, Alloc>& s) { 404 return s; 405 } 406 407 template <typename Char> 408 inline basic_string_view<Char> to_string_view(basic_string_view<Char> s) { 409 return s; 410 } 411 412 template <typename Char, 413 FMT_ENABLE_IF(!std::is_empty<internal::std_string_view<Char>>::value)> 414 inline basic_string_view<Char> to_string_view( 415 internal::std_string_view<Char> s) { 416 return s; 417 } 418 419 // A base class for compile-time strings. It is defined in the fmt namespace to 420 // make formatting functions visible via ADL, e.g. format(fmt("{}"), 42). 421 struct compile_string {}; 422 423 template <typename S> 424 struct is_compile_string : std::is_base_of<compile_string, S> {}; 425 426 template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)> 427 constexpr basic_string_view<typename S::char_type> to_string_view(const S& s) { 428 return s; 429 } 430 431 namespace internal { 432 void to_string_view(...); 433 using fmt::v6::to_string_view; 434 435 // Specifies whether S is a string type convertible to fmt::basic_string_view. 436 // It should be a constexpr function but MSVC 2017 fails to compile it in 437 // enable_if and MSVC 2015 fails to compile it as an alias template. 438 template <typename S> 439 struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> { 440 }; 441 442 template <typename S, typename = void> struct char_t_impl {}; 443 template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> { 444 using result = decltype(to_string_view(std::declval<S>())); 445 using type = typename result::char_type; 446 }; 447 448 struct error_handler { 449 FMT_CONSTEXPR error_handler() = default; 450 FMT_CONSTEXPR error_handler(const error_handler&) = default; 451 452 // This function is intentionally not constexpr to give a compile-time error. 453 FMT_NORETURN FMT_API void on_error(const char* message); 454 }; 455 } // namespace internal 456 457 /** String's character type. */ 458 template <typename S> using char_t = typename internal::char_t_impl<S>::type; 459 460 /** 461 \rst 462 Parsing context consisting of a format string range being parsed and an 463 argument counter for automatic indexing. 464 465 You can use one of the following type aliases for common character types: 466 467 +-----------------------+-------------------------------------+ 468 | Type | Definition | 469 +=======================+=====================================+ 470 | format_parse_context | basic_format_parse_context<char> | 471 +-----------------------+-------------------------------------+ 472 | wformat_parse_context | basic_format_parse_context<wchar_t> | 473 +-----------------------+-------------------------------------+ 474 \endrst 475 */ 476 template <typename Char, typename ErrorHandler = internal::error_handler> 477 class basic_format_parse_context : private ErrorHandler { 478 private: 479 basic_string_view<Char> format_str_; 480 int next_arg_id_; 481 482 public: 483 using char_type = Char; 484 using iterator = typename basic_string_view<Char>::iterator; 485 486 explicit FMT_CONSTEXPR basic_format_parse_context( 487 basic_string_view<Char> format_str, ErrorHandler eh = ErrorHandler()) 488 : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {} 489 490 /** 491 Returns an iterator to the beginning of the format string range being 492 parsed. 493 */ 494 FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT { 495 return format_str_.begin(); 496 } 497 498 /** 499 Returns an iterator past the end of the format string range being parsed. 500 */ 501 FMT_CONSTEXPR iterator end() const FMT_NOEXCEPT { return format_str_.end(); } 502 503 /** Advances the begin iterator to ``it``. */ 504 FMT_CONSTEXPR void advance_to(iterator it) { 505 format_str_.remove_prefix(internal::to_unsigned(it - begin())); 506 } 507 508 /** 509 Reports an error if using the manual argument indexing; otherwise returns 510 the next argument index and switches to the automatic indexing. 511 */ 512 FMT_CONSTEXPR int next_arg_id() { 513 if (next_arg_id_ >= 0) return next_arg_id_++; 514 on_error("cannot switch from manual to automatic argument indexing"); 515 return 0; 516 } 517 518 /** 519 Reports an error if using the automatic argument indexing; otherwise 520 switches to the manual indexing. 521 */ 522 FMT_CONSTEXPR void check_arg_id(int) { 523 if (next_arg_id_ > 0) 524 on_error("cannot switch from automatic to manual argument indexing"); 525 else 526 next_arg_id_ = -1; 527 } 528 529 FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {} 530 531 FMT_CONSTEXPR void on_error(const char* message) { 532 ErrorHandler::on_error(message); 533 } 534 535 FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; } 536 }; 537 538 using format_parse_context = basic_format_parse_context<char>; 539 using wformat_parse_context = basic_format_parse_context<wchar_t>; 540 541 template <typename Char, typename ErrorHandler = internal::error_handler> 542 using basic_parse_context FMT_DEPRECATED_ALIAS = 543 basic_format_parse_context<Char, ErrorHandler>; 544 using parse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context<char>; 545 using wparse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context<wchar_t>; 546 547 template <typename Context> class basic_format_arg; 548 template <typename Context> class basic_format_args; 549 550 // A formatter for objects of type T. 551 template <typename T, typename Char = char, typename Enable = void> 552 struct formatter { 553 // A deleted default constructor indicates a disabled formatter. 554 formatter() = delete; 555 }; 556 557 template <typename T, typename Char, typename Enable = void> 558 struct FMT_DEPRECATED convert_to_int 559 : bool_constant<!std::is_arithmetic<T>::value && 560 std::is_convertible<T, int>::value> {}; 561 562 // Specifies if T has an enabled formatter specialization. A type can be 563 // formattable even if it doesn't have a formatter e.g. via a conversion. 564 template <typename T, typename Context> 565 using has_formatter = 566 std::is_constructible<typename Context::template formatter_type<T>>; 567 568 namespace internal { 569 570 /** A contiguous memory buffer with an optional growing ability. */ 571 template <typename T> class buffer { 572 private: 573 T* ptr_; 574 std::size_t size_; 575 std::size_t capacity_; 576 577 protected: 578 // Don't initialize ptr_ since it is not accessed to save a few cycles. 579 buffer(std::size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} 580 581 buffer(T* p = nullptr, std::size_t sz = 0, std::size_t cap = 0) FMT_NOEXCEPT 582 : ptr_(p), 583 size_(sz), 584 capacity_(cap) {} 585 586 /** Sets the buffer data and capacity. */ 587 void set(T* buf_data, std::size_t buf_capacity) FMT_NOEXCEPT { 588 ptr_ = buf_data; 589 capacity_ = buf_capacity; 590 } 591 592 /** Increases the buffer capacity to hold at least *capacity* elements. */ 593 virtual void grow(std::size_t capacity) = 0; 594 595 public: 596 using value_type = T; 597 using const_reference = const T&; 598 599 buffer(const buffer&) = delete; 600 void operator=(const buffer&) = delete; 601 virtual ~buffer() = default; 602 603 T* begin() FMT_NOEXCEPT { return ptr_; } 604 T* end() FMT_NOEXCEPT { return ptr_ + size_; } 605 606 /** Returns the size of this buffer. */ 607 std::size_t size() const FMT_NOEXCEPT { return size_; } 608 609 /** Returns the capacity of this buffer. */ 610 std::size_t capacity() const FMT_NOEXCEPT { return capacity_; } 611 612 /** Returns a pointer to the buffer data. */ 613 T* data() FMT_NOEXCEPT { return ptr_; } 614 615 /** Returns a pointer to the buffer data. */ 616 const T* data() const FMT_NOEXCEPT { return ptr_; } 617 618 /** 619 Resizes the buffer. If T is a POD type new elements may not be initialized. 620 */ 621 void resize(std::size_t new_size) { 622 reserve(new_size); 623 size_ = new_size; 624 } 625 626 /** Clears this buffer. */ 627 void clear() { size_ = 0; } 628 629 /** Reserves space to store at least *capacity* elements. */ 630 void reserve(std::size_t new_capacity) { 631 if (new_capacity > capacity_) grow(new_capacity); 632 } 633 634 void push_back(const T& value) { 635 reserve(size_ + 1); 636 ptr_[size_++] = value; 637 } 638 639 /** Appends data to the end of the buffer. */ 640 template <typename U> void append(const U* begin, const U* end); 641 642 T& operator[](std::size_t index) { return ptr_[index]; } 643 const T& operator[](std::size_t index) const { return ptr_[index]; } 644 }; 645 646 // A container-backed buffer. 647 template <typename Container> 648 class container_buffer : public buffer<typename Container::value_type> { 649 private: 650 Container& container_; 651 652 protected: 653 void grow(std::size_t capacity) FMT_OVERRIDE { 654 container_.resize(capacity); 655 this->set(&container_[0], capacity); 656 } 657 658 public: 659 explicit container_buffer(Container& c) 660 : buffer<typename Container::value_type>(c.size()), container_(c) {} 661 }; 662 663 // Extracts a reference to the container from back_insert_iterator. 664 template <typename Container> 665 inline Container& get_container(std::back_insert_iterator<Container> it) { 666 using bi_iterator = std::back_insert_iterator<Container>; 667 struct accessor : bi_iterator { 668 accessor(bi_iterator iter) : bi_iterator(iter) {} 669 using bi_iterator::container; 670 }; 671 return *accessor(it).container; 672 } 673 674 template <typename T, typename Char = char, typename Enable = void> 675 struct fallback_formatter { 676 fallback_formatter() = delete; 677 }; 678 679 // Specifies if T has an enabled fallback_formatter specialization. 680 template <typename T, typename Context> 681 using has_fallback_formatter = 682 std::is_constructible<fallback_formatter<T, typename Context::char_type>>; 683 684 template <typename Char> struct named_arg_base; 685 template <typename T, typename Char> struct named_arg; 686 687 enum type { 688 none_type, 689 named_arg_type, 690 // Integer types should go first, 691 int_type, 692 uint_type, 693 long_long_type, 694 ulong_long_type, 695 int128_type, 696 uint128_type, 697 bool_type, 698 char_type, 699 last_integer_type = char_type, 700 // followed by floating-point types. 701 float_type, 702 double_type, 703 long_double_type, 704 last_numeric_type = long_double_type, 705 cstring_type, 706 string_type, 707 pointer_type, 708 custom_type 709 }; 710 711 // Maps core type T to the corresponding type enum constant. 712 template <typename T, typename Char> 713 struct type_constant : std::integral_constant<type, custom_type> {}; 714 715 #define FMT_TYPE_CONSTANT(Type, constant) \ 716 template <typename Char> \ 717 struct type_constant<Type, Char> : std::integral_constant<type, constant> {} 718 719 FMT_TYPE_CONSTANT(const named_arg_base<Char>&, named_arg_type); 720 FMT_TYPE_CONSTANT(int, int_type); 721 FMT_TYPE_CONSTANT(unsigned, uint_type); 722 FMT_TYPE_CONSTANT(long long, long_long_type); 723 FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); 724 FMT_TYPE_CONSTANT(int128_t, int128_type); 725 FMT_TYPE_CONSTANT(uint128_t, uint128_type); 726 FMT_TYPE_CONSTANT(bool, bool_type); 727 FMT_TYPE_CONSTANT(Char, char_type); 728 FMT_TYPE_CONSTANT(float, float_type); 729 FMT_TYPE_CONSTANT(double, double_type); 730 FMT_TYPE_CONSTANT(long double, long_double_type); 731 FMT_TYPE_CONSTANT(const Char*, cstring_type); 732 FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type); 733 FMT_TYPE_CONSTANT(const void*, pointer_type); 734 735 FMT_CONSTEXPR bool is_integral_type(type t) { 736 FMT_ASSERT(t != named_arg_type, "invalid argument type"); 737 return t > none_type && t <= last_integer_type; 738 } 739 740 FMT_CONSTEXPR bool is_arithmetic_type(type t) { 741 FMT_ASSERT(t != named_arg_type, "invalid argument type"); 742 return t > none_type && t <= last_numeric_type; 743 } 744 745 template <typename Char> struct string_value { 746 const Char* data; 747 std::size_t size; 748 }; 749 750 template <typename Context> struct custom_value { 751 using parse_context = basic_format_parse_context<typename Context::char_type>; 752 const void* value; 753 void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); 754 }; 755 756 // A formatting argument value. 757 template <typename Context> class value { 758 public: 759 using char_type = typename Context::char_type; 760 761 union { 762 int int_value; 763 unsigned uint_value; 764 long long long_long_value; 765 unsigned long long ulong_long_value; 766 int128_t int128_value; 767 uint128_t uint128_value; 768 bool bool_value; 769 char_type char_value; 770 float float_value; 771 double double_value; 772 long double long_double_value; 773 const void* pointer; 774 string_value<char_type> string; 775 custom_value<Context> custom; 776 const named_arg_base<char_type>* named_arg; 777 }; 778 779 FMT_CONSTEXPR value(int val = 0) : int_value(val) {} 780 FMT_CONSTEXPR value(unsigned val) : uint_value(val) {} 781 value(long long val) : long_long_value(val) {} 782 value(unsigned long long val) : ulong_long_value(val) {} 783 value(int128_t val) : int128_value(val) {} 784 value(uint128_t val) : uint128_value(val) {} 785 value(float val) : float_value(val) {} 786 value(double val) : double_value(val) {} 787 value(long double val) : long_double_value(val) {} 788 value(bool val) : bool_value(val) {} 789 value(char_type val) : char_value(val) {} 790 value(const char_type* val) { string.data = val; } 791 value(basic_string_view<char_type> val) { 792 string.data = val.data(); 793 string.size = val.size(); 794 } 795 value(const void* val) : pointer(val) {} 796 797 template <typename T> value(const T& val) { 798 custom.value = &val; 799 // Get the formatter type through the context to allow different contexts 800 // have different extension points, e.g. `formatter<T>` for `format` and 801 // `printf_formatter<T>` for `printf`. 802 custom.format = format_custom_arg< 803 T, conditional_t<has_formatter<T, Context>::value, 804 typename Context::template formatter_type<T>, 805 fallback_formatter<T, char_type>>>; 806 } 807 808 value(const named_arg_base<char_type>& val) { named_arg = &val; } 809 810 private: 811 // Formats an argument of a custom type, such as a user-defined class. 812 template <typename T, typename Formatter> 813 static void format_custom_arg( 814 const void* arg, basic_format_parse_context<char_type>& parse_ctx, 815 Context& ctx) { 816 Formatter f; 817 parse_ctx.advance_to(f.parse(parse_ctx)); 818 ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx)); 819 } 820 }; 821 822 template <typename Context, typename T> 823 FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T& value); 824 825 // To minimize the number of types we need to deal with, long is translated 826 // either to int or to long long depending on its size. 827 enum { long_short = sizeof(long) == sizeof(int) }; 828 using long_type = conditional_t<long_short, int, long long>; 829 using ulong_type = conditional_t<long_short, unsigned, unsigned long long>; 830 831 // Maps formatting arguments to core types. 832 template <typename Context> struct arg_mapper { 833 using char_type = typename Context::char_type; 834 835 FMT_CONSTEXPR int map(signed char val) { return val; } 836 FMT_CONSTEXPR unsigned map(unsigned char val) { return val; } 837 FMT_CONSTEXPR int map(short val) { return val; } 838 FMT_CONSTEXPR unsigned map(unsigned short val) { return val; } 839 FMT_CONSTEXPR int map(int val) { return val; } 840 FMT_CONSTEXPR unsigned map(unsigned val) { return val; } 841 FMT_CONSTEXPR long_type map(long val) { return val; } 842 FMT_CONSTEXPR ulong_type map(unsigned long val) { return val; } 843 FMT_CONSTEXPR long long map(long long val) { return val; } 844 FMT_CONSTEXPR unsigned long long map(unsigned long long val) { return val; } 845 FMT_CONSTEXPR int128_t map(int128_t val) { return val; } 846 FMT_CONSTEXPR uint128_t map(uint128_t val) { return val; } 847 FMT_CONSTEXPR bool map(bool val) { return val; } 848 849 template <typename T, FMT_ENABLE_IF(is_char<T>::value)> 850 FMT_CONSTEXPR char_type map(T val) { 851 static_assert( 852 std::is_same<T, char>::value || std::is_same<T, char_type>::value, 853 "mixing character types is disallowed"); 854 return val; 855 } 856 857 FMT_CONSTEXPR float map(float val) { return val; } 858 FMT_CONSTEXPR double map(double val) { return val; } 859 FMT_CONSTEXPR long double map(long double val) { return val; } 860 861 FMT_CONSTEXPR const char_type* map(char_type* val) { return val; } 862 FMT_CONSTEXPR const char_type* map(const char_type* val) { return val; } 863 template <typename T, FMT_ENABLE_IF(is_string<T>::value)> 864 FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) { 865 static_assert(std::is_same<char_type, char_t<T>>::value, 866 "mixing character types is disallowed"); 867 return to_string_view(val); 868 } 869 template <typename T, 870 FMT_ENABLE_IF( 871 std::is_constructible<basic_string_view<char_type>, T>::value && 872 !is_string<T>::value)> 873 FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) { 874 return basic_string_view<char_type>(val); 875 } 876 template < 877 typename T, 878 FMT_ENABLE_IF( 879 std::is_constructible<std_string_view<char_type>, T>::value && 880 !std::is_constructible<basic_string_view<char_type>, T>::value && 881 !is_string<T>::value && !has_formatter<T, Context>::value)> 882 FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) { 883 return std_string_view<char_type>(val); 884 } 885 FMT_CONSTEXPR const char* map(const signed char* val) { 886 static_assert(std::is_same<char_type, char>::value, "invalid string type"); 887 return reinterpret_cast<const char*>(val); 888 } 889 FMT_CONSTEXPR const char* map(const unsigned char* val) { 890 static_assert(std::is_same<char_type, char>::value, "invalid string type"); 891 return reinterpret_cast<const char*>(val); 892 } 893 894 FMT_CONSTEXPR const void* map(void* val) { return val; } 895 FMT_CONSTEXPR const void* map(const void* val) { return val; } 896 FMT_CONSTEXPR const void* map(std::nullptr_t val) { return val; } 897 template <typename T> FMT_CONSTEXPR int map(const T*) { 898 // Formatting of arbitrary pointers is disallowed. If you want to output 899 // a pointer cast it to "void *" or "const void *". In particular, this 900 // forbids formatting of "[const] volatile char *" which is printed as bool 901 // by iostreams. 902 static_assert(!sizeof(T), "formatting of non-void pointers is disallowed"); 903 return 0; 904 } 905 906 template <typename T, 907 FMT_ENABLE_IF(std::is_enum<T>::value && 908 !has_formatter<T, Context>::value && 909 !has_fallback_formatter<T, Context>::value)> 910 FMT_CONSTEXPR auto map(const T& val) -> decltype( 911 map(static_cast<typename std::underlying_type<T>::type>(val))) { 912 return map(static_cast<typename std::underlying_type<T>::type>(val)); 913 } 914 template < 915 typename T, 916 FMT_ENABLE_IF( 917 !is_string<T>::value && !is_char<T>::value && 918 !std::is_constructible<basic_string_view<char_type>, T>::value && 919 (has_formatter<T, Context>::value || 920 (has_fallback_formatter<T, Context>::value && 921 !std::is_constructible<std_string_view<char_type>, T>::value)))> 922 FMT_CONSTEXPR const T& map(const T& val) { 923 return val; 924 } 925 926 template <typename T> 927 FMT_CONSTEXPR const named_arg_base<char_type>& map( 928 const named_arg<T, char_type>& val) { 929 auto arg = make_arg<Context>(val.value); 930 std::memcpy(val.data, &arg, sizeof(arg)); 931 return val; 932 } 933 }; 934 935 // A type constant after applying arg_mapper<Context>. 936 template <typename T, typename Context> 937 using mapped_type_constant = 938 type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())), 939 typename Context::char_type>; 940 941 enum { packed_arg_bits = 5 }; 942 // Maximum number of arguments with packed types. 943 enum { max_packed_args = 63 / packed_arg_bits }; 944 enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; 945 946 template <typename Context> class arg_map; 947 } // namespace internal 948 949 // A formatting argument. It is a trivially copyable/constructible type to 950 // allow storage in basic_memory_buffer. 951 template <typename Context> class basic_format_arg { 952 private: 953 internal::value<Context> value_; 954 internal::type type_; 955 956 template <typename ContextType, typename T> 957 friend FMT_CONSTEXPR basic_format_arg<ContextType> internal::make_arg( 958 const T& value); 959 960 template <typename Visitor, typename Ctx> 961 friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, 962 const basic_format_arg<Ctx>& arg) 963 -> decltype(vis(0)); 964 965 friend class basic_format_args<Context>; 966 friend class internal::arg_map<Context>; 967 968 using char_type = typename Context::char_type; 969 970 public: 971 class handle { 972 public: 973 explicit handle(internal::custom_value<Context> custom) : custom_(custom) {} 974 975 void format(basic_format_parse_context<char_type>& parse_ctx, 976 Context& ctx) const { 977 custom_.format(custom_.value, parse_ctx, ctx); 978 } 979 980 private: 981 internal::custom_value<Context> custom_; 982 }; 983 984 FMT_CONSTEXPR basic_format_arg() : type_(internal::none_type) {} 985 986 FMT_CONSTEXPR explicit operator bool() const FMT_NOEXCEPT { 987 return type_ != internal::none_type; 988 } 989 990 internal::type type() const { return type_; } 991 992 bool is_integral() const { return internal::is_integral_type(type_); } 993 bool is_arithmetic() const { return internal::is_arithmetic_type(type_); } 994 }; 995 996 /** 997 \rst 998 Visits an argument dispatching to the appropriate visit method based on 999 the argument type. For example, if the argument type is ``double`` then 1000 ``vis(value)`` will be called with the value of type ``double``. 1001 \endrst 1002 */ 1003 template <typename Visitor, typename Context> 1004 FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, 1005 const basic_format_arg<Context>& arg) 1006 -> decltype(vis(0)) { 1007 using char_type = typename Context::char_type; 1008 switch (arg.type_) { 1009 case internal::none_type: 1010 break; 1011 case internal::named_arg_type: 1012 FMT_ASSERT(false, "invalid argument type"); 1013 break; 1014 case internal::int_type: 1015 return vis(arg.value_.int_value); 1016 case internal::uint_type: 1017 return vis(arg.value_.uint_value); 1018 case internal::long_long_type: 1019 return vis(arg.value_.long_long_value); 1020 case internal::ulong_long_type: 1021 return vis(arg.value_.ulong_long_value); 1022 #if FMT_USE_INT128 1023 case internal::int128_type: 1024 return vis(arg.value_.int128_value); 1025 case internal::uint128_type: 1026 return vis(arg.value_.uint128_value); 1027 #else 1028 case internal::int128_type: 1029 case internal::uint128_type: 1030 break; 1031 #endif 1032 case internal::bool_type: 1033 return vis(arg.value_.bool_value); 1034 case internal::char_type: 1035 return vis(arg.value_.char_value); 1036 case internal::float_type: 1037 return vis(arg.value_.float_value); 1038 case internal::double_type: 1039 return vis(arg.value_.double_value); 1040 case internal::long_double_type: 1041 return vis(arg.value_.long_double_value); 1042 case internal::cstring_type: 1043 return vis(arg.value_.string.data); 1044 case internal::string_type: 1045 return vis(basic_string_view<char_type>(arg.value_.string.data, 1046 arg.value_.string.size)); 1047 case internal::pointer_type: 1048 return vis(arg.value_.pointer); 1049 case internal::custom_type: 1050 return vis(typename basic_format_arg<Context>::handle(arg.value_.custom)); 1051 } 1052 return vis(monostate()); 1053 } 1054 1055 namespace internal { 1056 // A map from argument names to their values for named arguments. 1057 template <typename Context> class arg_map { 1058 private: 1059 using char_type = typename Context::char_type; 1060 1061 struct entry { 1062 basic_string_view<char_type> name; 1063 basic_format_arg<Context> arg; 1064 }; 1065 1066 entry* map_; 1067 unsigned size_; 1068 1069 void push_back(value<Context> val) { 1070 const auto& named = *val.named_arg; 1071 map_[size_] = {named.name, named.template deserialize<Context>()}; 1072 ++size_; 1073 } 1074 1075 public: 1076 arg_map(const arg_map&) = delete; 1077 void operator=(const arg_map&) = delete; 1078 arg_map() : map_(nullptr), size_(0) {} 1079 void init(const basic_format_args<Context>& args); 1080 ~arg_map() { delete[] map_; } 1081 1082 basic_format_arg<Context> find(basic_string_view<char_type> name) const { 1083 // The list is unsorted, so just return the first matching name. 1084 for (entry *it = map_, *end = map_ + size_; it != end; ++it) { 1085 if (it->name == name) return it->arg; 1086 } 1087 return {}; 1088 } 1089 }; 1090 1091 // A type-erased reference to an std::locale to avoid heavy <locale> include. 1092 class locale_ref { 1093 private: 1094 const void* locale_; // A type-erased pointer to std::locale. 1095 1096 public: 1097 locale_ref() : locale_(nullptr) {} 1098 template <typename Locale> explicit locale_ref(const Locale& loc); 1099 1100 explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; } 1101 1102 template <typename Locale> Locale get() const; 1103 }; 1104 1105 template <typename> constexpr unsigned long long encode_types() { return 0; } 1106 1107 template <typename Context, typename Arg, typename... Args> 1108 constexpr unsigned long long encode_types() { 1109 return mapped_type_constant<Arg, Context>::value | 1110 (encode_types<Context, Args...>() << packed_arg_bits); 1111 } 1112 1113 template <typename Context, typename T> 1114 FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T& value) { 1115 basic_format_arg<Context> arg; 1116 arg.type_ = mapped_type_constant<T, Context>::value; 1117 arg.value_ = arg_mapper<Context>().map(value); 1118 return arg; 1119 } 1120 1121 template <bool IS_PACKED, typename Context, typename T, 1122 FMT_ENABLE_IF(IS_PACKED)> 1123 inline value<Context> make_arg(const T& val) { 1124 return arg_mapper<Context>().map(val); 1125 } 1126 1127 template <bool IS_PACKED, typename Context, typename T, 1128 FMT_ENABLE_IF(!IS_PACKED)> 1129 inline basic_format_arg<Context> make_arg(const T& value) { 1130 return make_arg<Context>(value); 1131 } 1132 } // namespace internal 1133 1134 // Formatting context. 1135 template <typename OutputIt, typename Char> class basic_format_context { 1136 public: 1137 /** The character type for the output. */ 1138 using char_type = Char; 1139 1140 private: 1141 OutputIt out_; 1142 basic_format_args<basic_format_context> args_; 1143 internal::arg_map<basic_format_context> map_; 1144 internal::locale_ref loc_; 1145 1146 public: 1147 using iterator = OutputIt; 1148 using format_arg = basic_format_arg<basic_format_context>; 1149 template <typename T> using formatter_type = formatter<T, char_type>; 1150 1151 basic_format_context(const basic_format_context&) = delete; 1152 void operator=(const basic_format_context&) = delete; 1153 /** 1154 Constructs a ``basic_format_context`` object. References to the arguments are 1155 stored in the object so make sure they have appropriate lifetimes. 1156 */ 1157 basic_format_context(OutputIt out, 1158 basic_format_args<basic_format_context> ctx_args, 1159 internal::locale_ref loc = internal::locale_ref()) 1160 : out_(out), args_(ctx_args), loc_(loc) {} 1161 1162 format_arg arg(int id) const { return args_.get(id); } 1163 1164 // Checks if manual indexing is used and returns the argument with the 1165 // specified name. 1166 format_arg arg(basic_string_view<char_type> name); 1167 1168 internal::error_handler error_handler() { return {}; } 1169 void on_error(const char* message) { error_handler().on_error(message); } 1170 1171 // Returns an iterator to the beginning of the output range. 1172 iterator out() { return out_; } 1173 1174 // Advances the begin iterator to ``it``. 1175 void advance_to(iterator it) { out_ = it; } 1176 1177 internal::locale_ref locale() { return loc_; } 1178 }; 1179 1180 template <typename Char> 1181 using buffer_context = 1182 basic_format_context<std::back_insert_iterator<internal::buffer<Char>>, 1183 Char>; 1184 using format_context = buffer_context<char>; 1185 using wformat_context = buffer_context<wchar_t>; 1186 1187 /** 1188 \rst 1189 An array of references to arguments. It can be implicitly converted into 1190 `~fmt::basic_format_args` for passing into type-erased formatting functions 1191 such as `~fmt::vformat`. 1192 \endrst 1193 */ 1194 template <typename Context, typename... Args> class format_arg_store { 1195 private: 1196 static const size_t num_args = sizeof...(Args); 1197 static const bool is_packed = num_args < internal::max_packed_args; 1198 1199 using value_type = conditional_t<is_packed, internal::value<Context>, 1200 basic_format_arg<Context>>; 1201 1202 // If the arguments are not packed, add one more element to mark the end. 1203 value_type data_[num_args + (num_args == 0 ? 1 : 0)]; 1204 1205 friend class basic_format_args<Context>; 1206 1207 public: 1208 static constexpr unsigned long long types = 1209 is_packed ? internal::encode_types<Context, Args...>() 1210 : internal::is_unpacked_bit | num_args; 1211 1212 format_arg_store(const Args&... args) 1213 : data_{internal::make_arg<is_packed, Context>(args)...} {} 1214 }; 1215 1216 /** 1217 \rst 1218 Constructs an `~fmt::format_arg_store` object that contains references to 1219 arguments and can be implicitly converted to `~fmt::format_args`. `Context` 1220 can be omitted in which case it defaults to `~fmt::context`. 1221 See `~fmt::arg` for lifetime considerations. 1222 \endrst 1223 */ 1224 template <typename Context = format_context, typename... Args> 1225 inline format_arg_store<Context, Args...> make_format_args( 1226 const Args&... args) { 1227 return {args...}; 1228 } 1229 1230 /** Formatting arguments. */ 1231 template <typename Context> class basic_format_args { 1232 public: 1233 using size_type = int; 1234 using format_arg = basic_format_arg<Context>; 1235 1236 private: 1237 // To reduce compiled code size per formatting function call, types of first 1238 // max_packed_args arguments are passed in the types_ field. 1239 unsigned long long types_; 1240 union { 1241 // If the number of arguments is less than max_packed_args, the argument 1242 // values are stored in values_, otherwise they are stored in args_. 1243 // This is done to reduce compiled code size as storing larger objects 1244 // may require more code (at least on x86-64) even if the same amount of 1245 // data is actually copied to stack. It saves ~10% on the bloat test. 1246 const internal::value<Context>* values_; 1247 const format_arg* args_; 1248 }; 1249 1250 bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } 1251 1252 internal::type type(int index) const { 1253 int shift = index * internal::packed_arg_bits; 1254 unsigned int mask = (1 << internal::packed_arg_bits) - 1; 1255 return static_cast<internal::type>((types_ >> shift) & mask); 1256 } 1257 1258 friend class internal::arg_map<Context>; 1259 1260 void set_data(const internal::value<Context>* values) { values_ = values; } 1261 void set_data(const format_arg* args) { args_ = args; } 1262 1263 format_arg do_get(int index) const { 1264 format_arg arg; 1265 if (!is_packed()) { 1266 auto num_args = max_size(); 1267 if (index < num_args) arg = args_[index]; 1268 return arg; 1269 } 1270 if (index > internal::max_packed_args) return arg; 1271 arg.type_ = type(index); 1272 if (arg.type_ == internal::none_type) return arg; 1273 internal::value<Context>& val = arg.value_; 1274 val = values_[index]; 1275 return arg; 1276 } 1277 1278 public: 1279 basic_format_args() : types_(0) {} 1280 1281 /** 1282 \rst 1283 Constructs a `basic_format_args` object from `~fmt::format_arg_store`. 1284 \endrst 1285 */ 1286 template <typename... Args> 1287 basic_format_args(const format_arg_store<Context, Args...>& store) 1288 : types_(store.types) { 1289 set_data(store.data_); 1290 } 1291 1292 /** 1293 \rst 1294 Constructs a `basic_format_args` object from a dynamic set of arguments. 1295 \endrst 1296 */ 1297 basic_format_args(const format_arg* args, int count) 1298 : types_(internal::is_unpacked_bit | internal::to_unsigned(count)) { 1299 set_data(args); 1300 } 1301 1302 /** Returns the argument at specified index. */ 1303 format_arg get(int index) const { 1304 format_arg arg = do_get(index); 1305 if (arg.type_ == internal::named_arg_type) 1306 arg = arg.value_.named_arg->template deserialize<Context>(); 1307 return arg; 1308 } 1309 1310 int max_size() const { 1311 unsigned long long max_packed = internal::max_packed_args; 1312 return static_cast<int>(is_packed() ? max_packed 1313 : types_ & ~internal::is_unpacked_bit); 1314 } 1315 }; 1316 1317 /** An alias to ``basic_format_args<context>``. */ 1318 // It is a separate type rather than an alias to make symbols readable. 1319 struct format_args : basic_format_args<format_context> { 1320 template <typename... Args> 1321 format_args(Args&&... args) 1322 : basic_format_args<format_context>(std::forward<Args>(args)...) {} 1323 }; 1324 struct wformat_args : basic_format_args<wformat_context> { 1325 template <typename... Args> 1326 wformat_args(Args&&... args) 1327 : basic_format_args<wformat_context>(std::forward<Args>(args)...) {} 1328 }; 1329 1330 template <typename Container> struct is_contiguous : std::false_type {}; 1331 1332 template <typename Char> 1333 struct is_contiguous<std::basic_string<Char>> : std::true_type {}; 1334 1335 template <typename Char> 1336 struct is_contiguous<internal::buffer<Char>> : std::true_type {}; 1337 1338 namespace internal { 1339 1340 template <typename OutputIt> 1341 struct is_contiguous_back_insert_iterator : std::false_type {}; 1342 template <typename Container> 1343 struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>> 1344 : is_contiguous<Container> {}; 1345 1346 template <typename Char> struct named_arg_base { 1347 basic_string_view<Char> name; 1348 1349 // Serialized value<context>. 1350 mutable char data[sizeof(basic_format_arg<buffer_context<Char>>)]; 1351 1352 named_arg_base(basic_string_view<Char> nm) : name(nm) {} 1353 1354 template <typename Context> basic_format_arg<Context> deserialize() const { 1355 basic_format_arg<Context> arg; 1356 std::memcpy(&arg, data, sizeof(basic_format_arg<Context>)); 1357 return arg; 1358 } 1359 }; 1360 1361 template <typename T, typename Char> struct named_arg : named_arg_base<Char> { 1362 const T& value; 1363 1364 named_arg(basic_string_view<Char> name, const T& val) 1365 : named_arg_base<Char>(name), value(val) {} 1366 }; 1367 1368 template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)> 1369 inline void check_format_string(const S&) { 1370 #if defined(FMT_ENFORCE_COMPILE_STRING) 1371 static_assert(is_compile_string<S>::value, 1372 "FMT_ENFORCE_COMPILE_STRING requires all format strings to " 1373 "utilize FMT_STRING() or fmt()."); 1374 #endif 1375 } 1376 template <typename..., typename S, FMT_ENABLE_IF(is_compile_string<S>::value)> 1377 void check_format_string(S); 1378 1379 struct view {}; 1380 template <bool...> struct bool_pack; 1381 template <bool... Args> 1382 using all_true = 1383 std::is_same<bool_pack<Args..., true>, bool_pack<true, Args...>>; 1384 1385 template <typename... Args, typename S, typename Char = char_t<S>> 1386 inline format_arg_store<buffer_context<Char>, remove_reference_t<Args>...> 1387 make_args_checked(const S& format_str, 1388 const remove_reference_t<Args>&... args) { 1389 static_assert(all_true<(!std::is_base_of<view, remove_reference_t<Args>>() || 1390 !std::is_reference<Args>())...>::value, 1391 "passing views as lvalues is disallowed"); 1392 check_format_string<remove_const_t<remove_reference_t<Args>>...>(format_str); 1393 return {args...}; 1394 } 1395 1396 template <typename Char> 1397 std::basic_string<Char> vformat(basic_string_view<Char> format_str, 1398 basic_format_args<buffer_context<Char>> args); 1399 1400 template <typename Char> 1401 typename buffer_context<Char>::iterator vformat_to( 1402 buffer<Char>& buf, basic_string_view<Char> format_str, 1403 basic_format_args<buffer_context<Char>> args); 1404 } // namespace internal 1405 1406 /** 1407 \rst 1408 Returns a named argument to be used in a formatting function. 1409 1410 The named argument holds a reference and does not extend the lifetime 1411 of its arguments. 1412 Consequently, a dangling reference can accidentally be created. 1413 The user should take care to only pass this function temporaries when 1414 the named argument is itself a temporary, as per the following example. 1415 1416 **Example**:: 1417 1418 fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); 1419 \endrst 1420 */ 1421 template <typename S, typename T, typename Char = char_t<S>> 1422 inline internal::named_arg<T, Char> arg(const S& name, const T& arg) { 1423 static_assert(internal::is_string<S>::value, ""); 1424 return {name, arg}; 1425 } 1426 1427 // Disable nested named arguments, e.g. ``arg("a", arg("b", 42))``. 1428 template <typename S, typename T, typename Char> 1429 void arg(S, internal::named_arg<T, Char>) = delete; 1430 1431 /** Formats a string and writes the output to ``out``. */ 1432 // GCC 8 and earlier cannot handle std::back_insert_iterator<Container> with 1433 // vformat_to<ArgFormatter>(...) overload, so SFINAE on iterator type instead. 1434 template <typename OutputIt, typename S, typename Char = char_t<S>, 1435 FMT_ENABLE_IF( 1436 internal::is_contiguous_back_insert_iterator<OutputIt>::value)> 1437 OutputIt vformat_to(OutputIt out, const S& format_str, 1438 basic_format_args<buffer_context<Char>> args) { 1439 using container = remove_reference_t<decltype(internal::get_container(out))>; 1440 internal::container_buffer<container> buf((internal::get_container(out))); 1441 internal::vformat_to(buf, to_string_view(format_str), args); 1442 return out; 1443 } 1444 1445 template <typename Container, typename S, typename... Args, 1446 FMT_ENABLE_IF( 1447 is_contiguous<Container>::value&& internal::is_string<S>::value)> 1448 inline std::back_insert_iterator<Container> format_to( 1449 std::back_insert_iterator<Container> out, const S& format_str, 1450 Args&&... args) { 1451 return vformat_to( 1452 out, to_string_view(format_str), 1453 {internal::make_args_checked<Args...>(format_str, args...)}); 1454 } 1455 1456 template <typename S, typename Char = char_t<S>> 1457 inline std::basic_string<Char> vformat( 1458 const S& format_str, basic_format_args<buffer_context<Char>> args) { 1459 return internal::vformat(to_string_view(format_str), args); 1460 } 1461 1462 /** 1463 \rst 1464 Formats arguments and returns the result as a string. 1465 1466 **Example**:: 1467 1468 #include <fmt/core.h> 1469 std::string message = fmt::format("The answer is {}", 42); 1470 \endrst 1471 */ 1472 // Pass char_t as a default template parameter instead of using 1473 // std::basic_string<char_t<S>> to reduce the symbol size. 1474 template <typename S, typename... Args, typename Char = char_t<S>> 1475 inline std::basic_string<Char> format(const S& format_str, Args&&... args) { 1476 return internal::vformat( 1477 to_string_view(format_str), 1478 {internal::make_args_checked<Args...>(format_str, args...)}); 1479 } 1480 1481 FMT_API void vprint(std::FILE* f, string_view format_str, format_args args); 1482 FMT_API void vprint(string_view format_str, format_args args); 1483 1484 /** 1485 \rst 1486 Prints formatted data to the file *f*. For wide format strings, 1487 *f* should be in wide-oriented mode set via ``fwide(f, 1)`` or 1488 ``_setmode(_fileno(f), _O_U8TEXT)`` on Windows. 1489 1490 **Example**:: 1491 1492 fmt::print(stderr, "Don't {}!", "panic"); 1493 \endrst 1494 */ 1495 template <typename S, typename... Args, 1496 FMT_ENABLE_IF(internal::is_string<S>::value)> 1497 inline void print(std::FILE* f, const S& format_str, Args&&... args) { 1498 vprint(f, to_string_view(format_str), 1499 internal::make_args_checked<Args...>(format_str, args...)); 1500 } 1501 1502 /** 1503 \rst 1504 Prints formatted data to ``stdout``. 1505 1506 **Example**:: 1507 1508 fmt::print("Elapsed time: {0:.2f} seconds", 1.23); 1509 \endrst 1510 */ 1511 template <typename S, typename... Args, 1512 FMT_ENABLE_IF(internal::is_string<S>::value)> 1513 inline void print(const S& format_str, Args&&... args) { 1514 vprint(to_string_view(format_str), 1515 internal::make_args_checked<Args...>(format_str, args...)); 1516 } 1517 FMT_END_NAMESPACE 1518 1519 #endif // FMT_CORE_H_ 1520