HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
format.h
Go to the documentation of this file.
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 <cmath> // std::signbit
37 #include <cstdint> // uint32_t
38 #include <limits> // std::numeric_limits
39 #include <memory> // std::uninitialized_copy
40 #include <stdexcept> // std::runtime_error
41 #include <system_error> // std::system_error
42 #include <utility> // std::swap
43 
44 #include "core.h"
45 
46 #ifdef __INTEL_COMPILER
47 # define FMT_ICC_VERSION __INTEL_COMPILER
48 #elif defined(__ICL)
49 # define FMT_ICC_VERSION __ICL
50 #else
51 # define FMT_ICC_VERSION 0
52 #endif
53 
54 #ifdef __NVCC__
55 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
56 #else
57 # define FMT_CUDA_VERSION 0
58 #endif
59 
60 #ifdef __has_builtin
61 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
62 #else
63 # define FMT_HAS_BUILTIN(x) 0
64 #endif
65 
66 #if FMT_GCC_VERSION || FMT_CLANG_VERSION
67 # define FMT_NOINLINE __attribute__((noinline))
68 #else
69 # define FMT_NOINLINE
70 #endif
71 
72 #if FMT_MSC_VER
73 # define FMT_MSC_DEFAULT = default
74 #else
75 # define FMT_MSC_DEFAULT
76 #endif
77 
78 #ifndef FMT_THROW
79 # if FMT_EXCEPTIONS
80 # if FMT_MSC_VER || FMT_NVCC
82 namespace detail {
83 template <typename Exception> inline void do_throw(const Exception& x) {
84  // Silence unreachable code warnings in MSVC and NVCC because these
85  // are nearly impossible to fix in a generic code.
86  volatile bool b = true;
87  if (b) throw x;
88 }
89 } // namespace detail
91 # define FMT_THROW(x) detail::do_throw(x)
92 # else
93 # define FMT_THROW(x) throw x
94 # endif
95 # else
96 # define FMT_THROW(x) \
97  do { \
98  FMT_ASSERT(false, (x).what()); \
99  } while (false)
100 # endif
101 #endif
102 
103 #if FMT_EXCEPTIONS
104 # define FMT_TRY try
105 # define FMT_CATCH(x) catch (x)
106 #else
107 # define FMT_TRY if (true)
108 # define FMT_CATCH(x) if (false)
109 #endif
110 
111 #ifndef FMT_DEPRECATED
112 # if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900
113 # define FMT_DEPRECATED [[deprecated]]
114 # else
115 # if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
116 # define FMT_DEPRECATED __attribute__((deprecated))
117 # elif FMT_MSC_VER
118 # define FMT_DEPRECATED __declspec(deprecated)
119 # else
120 # define FMT_DEPRECATED /* deprecated */
121 # endif
122 # endif
123 #endif
124 
125 // Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers.
126 #if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC
127 # define FMT_DEPRECATED_ALIAS
128 #else
129 # define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
130 #endif
131 
132 #ifndef FMT_USE_USER_DEFINED_LITERALS
133 // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
134 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
135  FMT_MSC_VER >= 1900) && \
136  (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
137 # define FMT_USE_USER_DEFINED_LITERALS 1
138 # else
139 # define FMT_USE_USER_DEFINED_LITERALS 0
140 # endif
141 #endif
142 
143 // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
144 // integer formatter template instantiations to just one by only using the
145 // largest integer type. This results in a reduction in binary size but will
146 // cause a decrease in integer formatting performance.
147 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
148 # define FMT_REDUCE_INT_INSTANTIATIONS 0
149 #endif
150 
151 // __builtin_clz is broken in clang with Microsoft CodeGen:
152 // https://github.com/fmtlib/fmt/issues/519
153 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER
154 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
155 #endif
156 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
157 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
158 #endif
159 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz))
160 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
161 #endif
162 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll))
163 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
164 #endif
165 
166 #if FMT_MSC_VER
167 # include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
168 #endif
169 
170 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
171 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
172 // MSVC intrinsics if the clz and clzll builtins are not available.
173 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL)
175 namespace detail {
176 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
177 # if !defined(__clang__)
178 # pragma managed(push, off)
179 # pragma intrinsic(_BitScanForward)
180 # pragma intrinsic(_BitScanReverse)
181 # if defined(_WIN64)
182 # pragma intrinsic(_BitScanForward64)
183 # pragma intrinsic(_BitScanReverse64)
184 # endif
185 # endif
186 
187 inline auto clz(uint32_t x) -> int {
188  unsigned long r = 0;
189  _BitScanReverse(&r, x);
190  FMT_ASSERT(x != 0, "");
191  // Static analysis complains about using uninitialized data
192  // "r", but the only way that can happen is if "x" is 0,
193  // which the callers guarantee to not happen.
194  FMT_MSC_WARNING(suppress : 6102)
195  return 31 ^ static_cast<int>(r);
196 }
197 # define FMT_BUILTIN_CLZ(n) detail::clz(n)
198 
199 inline auto clzll(uint64_t x) -> int {
200  unsigned long r = 0;
201 # ifdef _WIN64
202  _BitScanReverse64(&r, x);
203 # else
204  // Scan the high 32 bits.
205  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 ^ (r + 32);
206  // Scan the low 32 bits.
207  _BitScanReverse(&r, static_cast<uint32_t>(x));
208 # endif
209  FMT_ASSERT(x != 0, "");
210  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
211  return 63 ^ static_cast<int>(r);
212 }
213 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
214 
215 inline auto ctz(uint32_t x) -> int {
216  unsigned long r = 0;
217  _BitScanForward(&r, x);
218  FMT_ASSERT(x != 0, "");
219  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
220  return static_cast<int>(r);
221 }
222 # define FMT_BUILTIN_CTZ(n) detail::ctz(n)
223 
224 inline auto ctzll(uint64_t x) -> int {
225  unsigned long r = 0;
226  FMT_ASSERT(x != 0, "");
227  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
228 # ifdef _WIN64
229  _BitScanForward64(&r, x);
230 # else
231  // Scan the low 32 bits.
232  if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
233  // Scan the high 32 bits.
234  _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
235  r += 32;
236 # endif
237  return static_cast<int>(r);
238 }
239 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
240 # if !defined(__clang__)
241 # pragma managed(pop)
242 # endif
243 } // namespace detail
245 #endif
246 
248 namespace detail {
249 
250 #if __cplusplus >= 202002L || \
251  (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002)
252 # define FMT_CONSTEXPR20 constexpr
253 #else
254 # define FMT_CONSTEXPR20
255 #endif
256 
257 // An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't have
258 // undefined behavior (e.g. due to type aliasing).
259 // Example: uint64_t d = bit_cast<uint64_t>(2.718);
260 template <typename Dest, typename Source>
261 inline auto bit_cast(const Source& source) -> Dest {
262  static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
263  Dest dest;
264  std::memcpy(&dest, &source, sizeof(dest));
265  return dest;
266 }
267 
268 inline auto is_big_endian() -> bool {
269  const auto u = 1u;
270  struct bytes {
271  char data[sizeof(u)];
272  };
273  return bit_cast<bytes>(u).data[0] == 0;
274 }
275 
276 // A fallback implementation of uintptr_t for systems that lack it.
278  unsigned char value[sizeof(void*)];
279 
280  fallback_uintptr() = default;
281  explicit fallback_uintptr(const void* p) {
282  *this = bit_cast<fallback_uintptr>(p);
283  if (is_big_endian()) {
284  for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j)
285  std::swap(value[i], value[j]);
286  }
287  }
288 };
289 #ifdef UINTPTR_MAX
290 using uintptr_t = ::uintptr_t;
291 inline auto to_uintptr(const void* p) -> uintptr_t {
292  return bit_cast<uintptr_t>(p);
293 }
294 #else
296 inline auto to_uintptr(const void* p) -> fallback_uintptr {
297  return fallback_uintptr(p);
298 }
299 #endif
300 
301 // Returns the largest possible value for type T. Same as
302 // std::numeric_limits<T>::max() but shorter and not affected by the max macro.
303 template <typename T> constexpr auto max_value() -> T {
304  return (std::numeric_limits<T>::max)();
305 }
306 template <typename T> constexpr auto num_bits() -> int {
307  return std::numeric_limits<T>::digits;
308 }
309 // std::numeric_limits<T>::digits may return 0 for 128-bit ints.
310 template <> constexpr auto num_bits<int128_t>() -> int { return 128; }
311 template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
312 template <> constexpr auto num_bits<fallback_uintptr>() -> int {
313  return static_cast<int>(sizeof(void*) *
314  std::numeric_limits<unsigned char>::digits);
315 }
316 
317 FMT_INLINE void assume(bool condition) {
318  (void)condition;
319 #if FMT_HAS_BUILTIN(__builtin_assume)
320  __builtin_assume(condition);
321 #endif
322 }
323 
324 // An approximation of iterator_t for pre-C++20 systems.
325 template <typename T>
326 using iterator_t = decltype(std::begin(std::declval<T&>()));
327 template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
328 
329 // A workaround for std::string not having mutable data() until C++17.
330 template <typename Char>
331 inline auto get_data(std::basic_string<Char>& s) -> Char* {
332  return &s[0];
333 }
334 template <typename Container>
335 inline auto get_data(Container& c) -> typename Container::value_type* {
336  return c.data();
337 }
338 
339 #if defined(_SECURE_SCL) && _SECURE_SCL
340 // Make a checked iterator to avoid MSVC warnings.
341 template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
342 template <typename T> auto make_checked(T* p, size_t size) -> checked_ptr<T> {
343  return {p, size};
344 }
345 #else
346 template <typename T> using checked_ptr = T*;
347 template <typename T> inline auto make_checked(T* p, size_t) -> T* { return p; }
348 #endif
349 
350 // Attempts to reserve space for n extra characters in the output range.
351 // Returns a pointer to the reserved range or a reference to it.
353 #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
354 __attribute__((no_sanitize("undefined")))
355 #endif
356 inline auto
357 reserve(std::back_insert_iterator<Container> it, size_t n)
359  Container& c = get_container(it);
360  size_t size = c.size();
361  c.resize(size + n);
362  return make_checked(get_data(c) + size, n);
363 }
364 
365 template <typename T>
366 inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
367  buffer<T>& buf = get_container(it);
368  buf.try_reserve(buf.size() + n);
369  return it;
370 }
371 
372 template <typename Iterator>
373 constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
374  return it;
375 }
376 
377 template <typename OutputIt>
378 using reserve_iterator =
380 
381 template <typename T, typename OutputIt>
382 constexpr auto to_pointer(OutputIt, size_t) -> T* {
383  return nullptr;
384 }
385 template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
386  buffer<T>& buf = get_container(it);
387  auto size = buf.size();
388  if (buf.capacity() < size + n) return nullptr;
389  buf.try_resize(size + n);
390  return buf.data() + size;
391 }
392 
394 inline auto base_iterator(std::back_insert_iterator<Container>& it,
396  -> std::back_insert_iterator<Container> {
397  return it;
398 }
399 
400 template <typename Iterator>
401 constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
402  return it;
403 }
404 
405 // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
406 // instead (#1998).
407 template <typename OutputIt, typename Size, typename T>
408 FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
409  -> OutputIt {
410  for (Size i = 0; i < count; ++i) *out++ = value;
411  return out;
412 }
413 template <typename T, typename Size>
414 FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
415  if (is_constant_evaluated()) {
416  return fill_n<T*, Size, T>(out, count, value);
417  }
418  std::memset(out, value, to_unsigned(count));
419  return out + count;
420 }
421 
422 #ifdef __cpp_char8_t
423 using char8_type = char8_t;
424 #else
425 enum char8_type : unsigned char {};
426 #endif
427 
428 template <typename OutChar, typename InputIt, typename OutputIt>
430  OutputIt out) -> OutputIt {
431  return copy_str<OutChar>(begin, end, out);
432 }
433 
434 // A public domain branchless UTF-8 decoder by Christopher Wellons:
435 // https://github.com/skeeto/branchless-utf8
436 /* Decode the next character, c, from s, reporting errors in e.
437  *
438  * Since this is a branchless decoder, four bytes will be read from the
439  * buffer regardless of the actual length of the next character. This
440  * means the buffer _must_ have at least three bytes of zero padding
441  * following the end of the data stream.
442  *
443  * Errors are reported in e, which will be non-zero if the parsed
444  * character was somehow invalid: invalid byte sequence, non-canonical
445  * encoding, or a surrogate half.
446  *
447  * The function returns a pointer to the next character. When an error
448  * occurs, this pointer will be a guess that depends on the particular
449  * error, but it will always advance at least one byte.
450  */
451 FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
452  -> const char* {
453  constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
454  constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
455  constexpr const int shiftc[] = {0, 18, 12, 6, 0};
456  constexpr const int shifte[] = {0, 6, 4, 2, 0};
457 
458  int len = code_point_length(s);
459  const char* next = s + len;
460 
461  // Assume a four-byte character and load four bytes. Unused bits are
462  // shifted out.
463  *c = uint32_t(s[0] & masks[len]) << 18;
464  *c |= uint32_t(s[1] & 0x3f) << 12;
465  *c |= uint32_t(s[2] & 0x3f) << 6;
466  *c |= uint32_t(s[3] & 0x3f) << 0;
467  *c >>= shiftc[len];
468 
469  // Accumulate the various error conditions.
470  using uchar = unsigned char;
471  *e = (*c < mins[len]) << 6; // non-canonical encoding
472  *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
473  *e |= (*c > 0x10FFFF) << 8; // out of range?
474  *e |= (uchar(s[1]) & 0xc0) >> 2;
475  *e |= (uchar(s[2]) & 0xc0) >> 4;
476  *e |= uchar(s[3]) >> 6;
477  *e ^= 0x2a; // top two bits of each tail byte correct?
478  *e >>= shifte[len];
479 
480  return next;
481 }
482 
483 template <typename F>
485  auto decode = [f](const char* p) {
486  auto cp = uint32_t();
487  auto error = 0;
488  p = utf8_decode(p, &cp, &error);
489  f(cp, error);
490  return p;
491  };
492  auto p = s.data();
493  const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
494  if (s.size() >= block_size) {
495  for (auto end = p + s.size() - block_size + 1; p < end;) p = decode(p);
496  }
497  if (auto num_chars_left = s.data() + s.size() - p) {
498  char buf[2 * block_size - 1] = {};
499  copy_str<char>(p, p + num_chars_left, buf);
500  p = buf;
501  do {
502  p = decode(p);
503  } while (p - buf < num_chars_left);
504  }
505 }
506 
507 template <typename Char>
508 inline auto compute_width(basic_string_view<Char> s) -> size_t {
509  return s.size();
510 }
511 
512 // Computes approximate display width of a UTF-8 string.
514  size_t num_code_points = 0;
515  // It is not a lambda for compatibility with C++14.
516  struct count_code_points {
517  size_t* count;
518  FMT_CONSTEXPR void operator()(uint32_t cp, int error) const {
520  1 +
521  (error == 0 && cp >= 0x1100 &&
522  (cp <= 0x115f || // Hangul Jamo init. consonants
523  cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET〈
524  cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET 〉
525  // CJK ... Yi except Unicode Character “〿”:
526  (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
527  (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
528  (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
529  (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
530  (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
531  (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
532  (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
533  (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
534  (cp >= 0x30000 && cp <= 0x3fffd) ||
535  // Miscellaneous Symbols and Pictographs + Emoticons:
536  (cp >= 0x1f300 && cp <= 0x1f64f) ||
537  // Supplemental Symbols and Pictographs:
538  (cp >= 0x1f900 && cp <= 0x1f9ff))));
539  }
540  };
541  for_each_codepoint(s, count_code_points{&num_code_points});
542  return num_code_points;
543 }
544 
547  reinterpret_cast<const char*>(s.data()), s.size()));
548 }
549 
550 template <typename Char>
551 inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
552  size_t size = s.size();
553  return n < size ? n : size;
554 }
555 
556 // Calculates the index of the nth code point in a UTF-8 string.
558  -> size_t {
559  const char8_type* data = s.data();
560  size_t num_code_points = 0;
561  for (size_t i = 0, size = s.size(); i != size; ++i) {
562  if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i;
563  }
564  return s.size();
565 }
566 
567 template <typename T>
569  sizeof(T) <= sizeof(double)>;
570 
571 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
572 # define FMT_USE_FULL_CACHE_DRAGONBOX 0
573 #endif
574 
575 template <typename T>
576 template <typename U>
577 void buffer<T>::append(const U* begin, const U* end) {
578  while (begin != end) {
579  auto count = to_unsigned(end - begin);
580  try_reserve(size_ + count);
581  auto free_cap = capacity_ - size_;
582  if (free_cap < count) count = free_cap;
583  std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
584  size_ += count;
585  begin += count;
586  }
587 }
588 
589 template <typename T, typename Enable = void>
590 struct is_locale : std::false_type {};
591 template <typename T>
592 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
593 } // namespace detail
594 
596 
597 // The number of characters to store in the basic_memory_buffer object itself
598 // to avoid dynamic memory allocation.
599 enum { inline_buffer_size = 500 };
600 
601 /**
602  \rst
603  A dynamically growing memory buffer for trivially copyable/constructible types
604  with the first ``SIZE`` elements stored in the object itself.
605 
606  You can use the ```memory_buffer`` type alias for ``char`` instead.
607 
608  **Example**::
609 
610  fmt::memory_buffer out;
611  format_to(out, "The answer is {}.", 42);
612 
613  This will append the following output to the ``out`` object:
614 
615  .. code-block:: none
616 
617  The answer is 42.
618 
619  The output can be converted to an ``std::string`` with ``to_string(out)``.
620  \endrst
621  */
622 template <typename T, size_t SIZE = inline_buffer_size,
623  typename Allocator = std::allocator<T>>
624 class basic_memory_buffer final : public detail::buffer<T> {
625  private:
626  T store_[SIZE];
627 
628  // Don't inherit from Allocator avoid generating type_info for it.
629  Allocator alloc_;
630 
631  // Deallocate memory allocated by the buffer.
632  void deallocate() {
633  T* data = this->data();
634  if (data != store_) alloc_.deallocate(data, this->capacity());
635  }
636 
637  protected:
638  void grow(size_t size) final FMT_OVERRIDE;
639 
640  public:
641  using value_type = T;
642  using const_reference = const T&;
643 
644  explicit basic_memory_buffer(const Allocator& alloc = Allocator())
645  : alloc_(alloc) {
646  this->set(store_, SIZE);
647  }
648  ~basic_memory_buffer() { deallocate(); }
649 
650  private:
651  // Move data from other to this buffer.
652  void move(basic_memory_buffer& other) {
653  alloc_ = std::move(other.alloc_);
654  T* data = other.data();
655  size_t size = other.size(), capacity = other.capacity();
656  if (data == other.store_) {
657  this->set(store_, capacity);
658  std::uninitialized_copy(other.store_, other.store_ + size,
659  detail::make_checked(store_, capacity));
660  } else {
661  this->set(data, capacity);
662  // Set pointer to the inline array so that delete is not called
663  // when deallocating.
664  other.set(other.store_, 0);
665  }
666  this->resize(size);
667  }
668 
669  public:
670  /**
671  \rst
672  Constructs a :class:`fmt::basic_memory_buffer` object moving the content
673  of the other object to it.
674  \endrst
675  */
677 
678  /**
679  \rst
680  Moves the content of the other ``basic_memory_buffer`` object to this one.
681  \endrst
682  */
684  -> basic_memory_buffer& {
685  FMT_ASSERT(this != &other, "");
686  deallocate();
687  move(other);
688  return *this;
689  }
690 
691  // Returns a copy of the allocator associated with this buffer.
692  auto get_allocator() const -> Allocator { return alloc_; }
693 
694  /**
695  Resizes the buffer to contain *count* elements. If T is a POD type new
696  elements may not be initialized.
697  */
698  void resize(size_t count) { this->try_resize(count); }
699 
700  /** Increases the buffer capacity to *new_capacity*. */
701  void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
702 
703  // Directly append data into the buffer
704  using detail::buffer<T>::append;
705  template <typename ContiguousRange>
706  void append(const ContiguousRange& range) {
707  append(range.data(), range.data() + range.size());
708  }
709 };
710 
711 template <typename T, size_t SIZE, typename Allocator>
713 #ifdef FMT_FUZZ
714  if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much");
715 #endif
716  const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
717  size_t old_capacity = this->capacity();
718  size_t new_capacity = old_capacity + old_capacity / 2;
719  if (size > new_capacity)
720  new_capacity = size;
721  else if (new_capacity > max_size)
722  new_capacity = size > max_size ? size : max_size;
723  T* old_data = this->data();
724  T* new_data =
725  std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
726  // The following code doesn't throw, so the raw pointer above doesn't leak.
727  std::uninitialized_copy(old_data, old_data + this->size(),
728  detail::make_checked(new_data, new_capacity));
729  this->set(new_data, new_capacity);
730  // deallocate must not throw according to the standard, but even if it does,
731  // the buffer already uses the new storage and will deallocate it in
732  // destructor.
733  if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
734 }
735 
737 
738 template <typename T, size_t SIZE, typename Allocator>
739 struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
740 };
741 
742 namespace detail {
743 FMT_API void print(std::FILE*, string_view);
744 }
745 
746 /** A formatting error such as invalid format string. */
748 class FMT_API format_error : public std::runtime_error {
749  public:
750  explicit format_error(const char* message) : std::runtime_error(message) {}
752  : std::runtime_error(message) {}
753  format_error(const format_error&) = default;
754  format_error& operator=(const format_error&) = default;
755  format_error(format_error&&) = default;
756  format_error& operator=(format_error&&) = default;
758 };
759 
760 /**
761  \rst
762  Constructs a `~fmt::format_arg_store` object that contains references
763  to arguments and can be implicitly converted to `~fmt::format_args`.
764  If ``fmt`` is a compile-time string then `make_args_checked` checks
765  its validity at compile time.
766  \endrst
767  */
768 template <typename... Args, typename S, typename Char = char_t<S>>
770  const remove_reference_t<Args>&... args)
772  static_assert(
773  detail::count<(
774  std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
775  std::is_reference<Args>::value)...>() == 0,
776  "passing views as lvalues is disallowed");
777  detail::check_format_string<Args...>(fmt);
778  return {args...};
779 }
780 
781 // compile-time support
782 namespace detail_exported {
783 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
784 template <typename Char, size_t N> struct fixed_string {
785  constexpr fixed_string(const Char (&str)[N]) {
786  detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
787  str + N, data);
788  }
789  Char data[N]{};
790 };
791 #endif
792 
793 // Converts a compile-time string to basic_string_view.
794 template <typename Char, size_t N>
795 constexpr auto compile_string_to_view(const Char (&s)[N])
797  // Remove trailing NUL character if needed. Won't be present if this is used
798  // with a raw character array (i.e. not defined as a string).
799  return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
800 }
801 template <typename Char>
802 constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
804  return {s.data(), s.size()};
805 }
806 } // namespace detail_exported
807 
809 
810 inline void throw_format_error(const char* message) {
811  FMT_THROW(format_error(message));
812 }
813 
814 template <typename T> struct is_integral : std::is_integral<T> {};
815 template <> struct is_integral<int128_t> : std::true_type {};
816 template <> struct is_integral<uint128_t> : std::true_type {};
817 
818 template <typename T>
819 using is_signed =
822 
823 // Returns true if value is negative, false otherwise.
824 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
827  return value < 0;
828 }
830 FMT_CONSTEXPR auto is_negative(T) -> bool {
831  return false;
832 }
833 
839 }
840 
841 // Smallest of uint32_t, uint64_t, uint128_t that is large enough to
842 // represent all values of an integral type T.
843 template <typename T>
844 using uint32_or_64_or_128_t =
846  uint32_t,
847  conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
848 template <typename T>
850 
851 #define FMT_POWERS_OF_10(factor) \
852  factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
853  (factor)*1000000, (factor)*10000000, (factor)*100000000, \
854  (factor)*1000000000
855 
856 // Static data is placed in this class template for the header-only config.
857 template <typename T = void> struct basic_data {
858  // log10(2) = 0x0.4d104d427de7fbcc...
859  static const uint64_t log10_2_significand = 0x4d104d427de7fbcc;
860 
861  // GCC generates slightly better code for pairs than chars.
862  FMT_API static constexpr const char digits[][2] = {
863  {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
864  {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
865  {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
866  {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'},
867  {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
868  {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'},
869  {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'},
870  {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'},
871  {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'},
872  {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
873  {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'},
874  {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'},
875  {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'},
876  {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'},
877  {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
878  {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'},
879  {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
880 
881  FMT_API static constexpr const char hex_digits[] = "0123456789abcdef";
882  FMT_API static constexpr const char signs[] = {0, '-', '+', ' '};
883  FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
884  0x1000000u | ' '};
885  FMT_API static constexpr const char left_padding_shifts[] = {31, 31, 0, 1, 0};
886  FMT_API static constexpr const char right_padding_shifts[] = {0, 31, 0, 1, 0};
887 };
888 
889 #ifdef FMT_SHARED
890 // Required for -flto, -fivisibility=hidden and -shared to work
891 extern template struct basic_data<void>;
892 #endif
893 
894 // This is a struct rather than an alias to avoid shadowing warnings in gcc.
895 struct data : basic_data<> {};
896 
897 template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
898  int count = 1;
899  for (;;) {
900  // Integer division is slow so do it for a group of four digits instead
901  // of for every digit. The idea comes from the talk by Alexandrescu
902  // "Three Optimization Tips for C++". See speed-test for a comparison.
903  if (n < 10) return count;
904  if (n < 100) return count + 1;
905  if (n < 1000) return count + 2;
906  if (n < 10000) return count + 3;
907  n /= 10000u;
908  count += 4;
909  }
910 }
911 #if FMT_USE_INT128
912 FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int {
913  return count_digits_fallback(n);
914 }
915 #endif
916 
917 // Returns the number of decimal digits in n. Leading zeros are not counted
918 // except for n == 0 in which case count_digits returns 1.
919 FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
920 #ifdef FMT_BUILTIN_CLZLL
921  if (!is_constant_evaluated()) {
922  // https://github.com/fmtlib/format-benchmark/blob/master/digits10
923  // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
924  constexpr uint16_t bsr2log10[] = {
925  1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
926  6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
927  10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
928  15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
929  auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
930  constexpr const uint64_t zero_or_powers_of_10[] = {
931  0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
932  10000000000000000000ULL};
933  return t - (n < zero_or_powers_of_10[t]);
934  }
935 #endif
936  return count_digits_fallback(n);
937 }
938 
939 // Counts the number of digits in n. BITS = log2(radix).
940 template <int BITS, typename UInt>
941 FMT_CONSTEXPR auto count_digits(UInt n) -> int {
942 #ifdef FMT_BUILTIN_CLZ
943  if (num_bits<UInt>() == 32)
944  return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
945 #endif
946  int num_digits = 0;
947  do {
948  ++num_digits;
949  } while ((n >>= BITS) != 0);
950  return num_digits;
951 }
952 
953 template <> auto count_digits<4>(detail::fallback_uintptr n) -> int;
954 
955 // It is a separate function rather than a part of count_digits to workaround
956 // the lack of static constexpr in constexpr functions.
958  // An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
959  // This increments the upper 32 bits (log10(T) - 1) when >= T is added.
960 #define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
961  static constexpr uint64_t table[] = {
962  FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
963  FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
964  FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
965  FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
966  FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
967  FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
968  FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
969  FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
970  FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
971  FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
972  FMT_INC(1000000000), FMT_INC(1000000000) // 4B
973  };
974  return table[n];
975 }
976 
977 // Optional version of count_digits for better performance on 32-bit platforms.
978 FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
979 #ifdef FMT_BUILTIN_CLZ
980  if (!is_constant_evaluated()) {
981  auto inc = count_digits_inc(FMT_BUILTIN_CLZ(n | 1) ^ 31);
982  return static_cast<int>((n + inc) >> 32);
983  }
984 #endif
985  return count_digits_fallback(n);
986 }
987 
988 template <typename Int> constexpr auto digits10() FMT_NOEXCEPT -> int {
990 }
991 template <> constexpr auto digits10<int128_t>() FMT_NOEXCEPT -> int {
992  return 38;
993 }
994 template <> constexpr auto digits10<uint128_t>() FMT_NOEXCEPT -> int {
995  return 38;
996 }
997 
998 template <typename Char> struct thousands_sep_result {
1001 };
1002 
1003 template <typename Char>
1005 template <typename Char>
1007  auto result = thousands_sep_impl<char>(loc);
1008  return {result.grouping, Char(result.thousands_sep)};
1009 }
1010 template <>
1012  return thousands_sep_impl<wchar_t>(loc);
1013 }
1014 
1015 template <typename Char>
1016 FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1017 template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1018  return Char(decimal_point_impl<char>(loc));
1019 }
1020 template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1021  return decimal_point_impl<wchar_t>(loc);
1022 }
1023 
1024 // Compares two characters for equality.
1025 template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1026  return lhs[0] == rhs[0] && lhs[1] == rhs[1];
1027 }
1028 inline auto equal2(const char* lhs, const char* rhs) -> bool {
1029  return memcmp(lhs, rhs, 2) == 0;
1030 }
1031 
1032 // Copies two characters from src to dst.
1033 template <typename Char> void copy2(Char* dst, const char* src) {
1034  *dst++ = static_cast<Char>(*src++);
1035  *dst = static_cast<Char>(*src);
1036 }
1037 FMT_INLINE void copy2(char* dst, const char* src) { memcpy(dst, src, 2); }
1038 
1039 template <typename Iterator> struct format_decimal_result {
1040  Iterator begin;
1041  Iterator end;
1042 };
1043 
1044 // Formats a decimal unsigned integer value writing into out pointing to a
1045 // buffer of specified size. The caller must ensure that the buffer is large
1046 // enough.
1047 template <typename Char, typename UInt>
1048 FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1050  FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1051  out += size;
1052  Char* end = out;
1053  if (is_constant_evaluated()) {
1054  while (value >= 10) {
1055  *--out = static_cast<Char>('0' + value % 10);
1056  value /= 10;
1057  }
1058  *--out = static_cast<Char>('0' + value);
1059  return {out, end};
1060  }
1061  while (value >= 100) {
1062  // Integer division is slow so do it for a group of two digits instead
1063  // of for every digit. The idea comes from the talk by Alexandrescu
1064  // "Three Optimization Tips for C++". See speed-test for a comparison.
1065  out -= 2;
1066  copy2(out, data::digits[value % 100]);
1067  value /= 100;
1068  }
1069  if (value < 10) {
1070  *--out = static_cast<Char>('0' + value);
1071  return {out, end};
1072  }
1073  out -= 2;
1074  copy2(out, data::digits[value]);
1075  return {out, end};
1076 }
1077 
1078 template <typename Char, typename UInt, typename Iterator,
1079  FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
1080 inline auto format_decimal(Iterator out, UInt value, int size)
1082  // Buffer is large enough to hold all digits (digits10 + 1).
1083  Char buffer[digits10<UInt>() + 1];
1084  auto end = format_decimal(buffer, value, size).end;
1085  return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1086 }
1087 
1088 template <unsigned BASE_BITS, typename Char, typename UInt>
1089 FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1090  bool upper = false) -> Char* {
1091  buffer += num_digits;
1092  Char* end = buffer;
1093  do {
1094  const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits;
1095  unsigned digit = (value & ((1 << BASE_BITS) - 1));
1096  *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1097  : digits[digit]);
1098  } while ((value >>= BASE_BITS) != 0);
1099  return end;
1100 }
1101 
1102 template <unsigned BASE_BITS, typename Char>
1103 auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits,
1104  bool = false) -> Char* {
1105  auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
1106  int start = (num_digits + char_digits - 1) / char_digits - 1;
1107  if (int start_digits = num_digits % char_digits) {
1108  unsigned value = n.value[start--];
1109  buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
1110  }
1111  for (; start >= 0; --start) {
1112  unsigned value = n.value[start];
1113  buffer += char_digits;
1114  auto p = buffer;
1115  for (int i = 0; i < char_digits; ++i) {
1116  unsigned digit = (value & ((1 << BASE_BITS) - 1));
1117  *--p = static_cast<Char>(data::hex_digits[digit]);
1118  value >>= BASE_BITS;
1119  }
1120  }
1121  return buffer;
1122 }
1123 
1124 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1125 inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
1126  -> It {
1127  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1128  format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1129  return out;
1130  }
1131  // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1132  char buffer[num_bits<UInt>() / BASE_BITS + 1];
1133  format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1134  return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1135 }
1136 
1137 // A converter from UTF-8 to UTF-16.
1139  private:
1141 
1142  public:
1143  FMT_API explicit utf8_to_utf16(string_view s);
1144  operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1145  auto size() const -> size_t { return buffer_.size() - 1; }
1146  auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1147  auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1148 };
1149 
1150 namespace dragonbox {
1151 
1152 // Type-specific information that Dragonbox uses.
1153 template <class T> struct float_info;
1154 
1155 template <> struct float_info<float> {
1156  using carrier_uint = uint32_t;
1157  static const int significand_bits = 23;
1158  static const int exponent_bits = 8;
1159  static const int min_exponent = -126;
1160  static const int max_exponent = 127;
1161  static const int exponent_bias = -127;
1162  static const int decimal_digits = 9;
1163  static const int kappa = 1;
1164  static const int big_divisor = 100;
1165  static const int small_divisor = 10;
1166  static const int min_k = -31;
1167  static const int max_k = 46;
1168  static const int cache_bits = 64;
1169  static const int divisibility_check_by_5_threshold = 39;
1170  static const int case_fc_pm_half_lower_threshold = -1;
1171  static const int case_fc_pm_half_upper_threshold = 6;
1172  static const int case_fc_lower_threshold = -2;
1173  static const int case_fc_upper_threshold = 6;
1174  static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1175  static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1176  static const int shorter_interval_tie_lower_threshold = -35;
1177  static const int shorter_interval_tie_upper_threshold = -35;
1178  static const int max_trailing_zeros = 7;
1179 };
1180 
1181 template <> struct float_info<double> {
1182  using carrier_uint = uint64_t;
1183  static const int significand_bits = 52;
1184  static const int exponent_bits = 11;
1185  static const int min_exponent = -1022;
1186  static const int max_exponent = 1023;
1187  static const int exponent_bias = -1023;
1188  static const int decimal_digits = 17;
1189  static const int kappa = 2;
1190  static const int big_divisor = 1000;
1191  static const int small_divisor = 100;
1192  static const int min_k = -292;
1193  static const int max_k = 326;
1194  static const int cache_bits = 128;
1195  static const int divisibility_check_by_5_threshold = 86;
1196  static const int case_fc_pm_half_lower_threshold = -2;
1197  static const int case_fc_pm_half_upper_threshold = 9;
1198  static const int case_fc_lower_threshold = -4;
1199  static const int case_fc_upper_threshold = 9;
1200  static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1201  static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1202  static const int shorter_interval_tie_lower_threshold = -77;
1203  static const int shorter_interval_tie_upper_threshold = -77;
1204  static const int max_trailing_zeros = 16;
1205 };
1206 
1207 template <typename T> struct decimal_fp {
1211 };
1212 
1213 template <typename T>
1215 } // namespace dragonbox
1216 
1217 template <typename T>
1218 constexpr auto exponent_mask() ->
1221  return ((uint(1) << dragonbox::float_info<T>::exponent_bits) - 1)
1223 }
1224 
1225 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1226 template <typename Char, typename It>
1227 auto write_exponent(int exp, It it) -> It {
1228  FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1229  if (exp < 0) {
1230  *it++ = static_cast<Char>('-');
1231  exp = -exp;
1232  } else {
1233  *it++ = static_cast<Char>('+');
1234  }
1235  if (exp >= 100) {
1236  const char* top = data::digits[exp / 100];
1237  if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1238  *it++ = static_cast<Char>(top[1]);
1239  exp %= 100;
1240  }
1241  const char* d = data::digits[exp];
1242  *it++ = static_cast<Char>(d[0]);
1243  *it++ = static_cast<Char>(d[1]);
1244  return it;
1245 }
1246 
1247 template <typename T>
1248 auto format_float(T value, int precision, float_specs specs, buffer<char>& buf)
1249  -> int;
1250 
1251 // Formats a floating-point number with snprintf.
1252 template <typename T>
1253 auto snprintf_float(T value, int precision, float_specs specs,
1254  buffer<char>& buf) -> int;
1255 
1256 template <typename T> auto promote_float(T value) -> T { return value; }
1257 inline auto promote_float(float value) -> double {
1258  return static_cast<double>(value);
1259 }
1260 
1261 template <typename OutputIt, typename Char>
1262 FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1263  const fill_t<Char>& fill) -> OutputIt {
1264  auto fill_size = fill.size();
1265  if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1266  auto data = fill.data();
1267  for (size_t i = 0; i < n; ++i)
1268  it = copy_str<Char>(data, data + fill_size, it);
1269  return it;
1270 }
1271 
1272 // Writes the output of f, padded according to format specifications in specs.
1273 // size: output size in code units.
1274 // width: output display width in (terminal) column positions.
1275 template <align::type align = align::left, typename OutputIt, typename Char,
1276  typename F>
1277 FMT_CONSTEXPR auto write_padded(OutputIt out,
1278  const basic_format_specs<Char>& specs,
1279  size_t size, size_t width, F&& f) -> OutputIt {
1280  static_assert(align == align::left || align == align::right, "");
1281  unsigned spec_width = to_unsigned(specs.width);
1282  size_t padding = spec_width > width ? spec_width - width : 0;
1283  auto* shifts = align == align::left ? data::left_padding_shifts
1285  size_t left_padding = padding >> shifts[specs.align];
1286  size_t right_padding = padding - left_padding;
1287  auto it = reserve(out, size + padding * specs.fill.size());
1288  if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1289  it = f(it);
1290  if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1291  return base_iterator(out, it);
1292 }
1293 
1294 template <align::type align = align::left, typename OutputIt, typename Char,
1295  typename F>
1296 constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs,
1297  size_t size, F&& f) -> OutputIt {
1298  return write_padded<align>(out, specs, size, size, f);
1299 }
1300 
1301 template <align::type align = align::left, typename Char, typename OutputIt>
1303  const basic_format_specs<Char>& specs)
1304  -> OutputIt {
1305  return write_padded<align>(
1306  out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1307  const char* data = bytes.data();
1308  return copy_str<Char>(data, data + bytes.size(), it);
1309  });
1310 }
1311 
1312 template <typename Char, typename OutputIt, typename UIntPtr>
1313 auto write_ptr(OutputIt out, UIntPtr value,
1314  const basic_format_specs<Char>* specs) -> OutputIt {
1315  int num_digits = count_digits<4>(value);
1316  auto size = to_unsigned(num_digits) + size_t(2);
1317  auto write = [=](reserve_iterator<OutputIt> it) {
1318  *it++ = static_cast<Char>('0');
1319  *it++ = static_cast<Char>('x');
1320  return format_uint<4, Char>(it, value, num_digits);
1321  };
1322  return specs ? write_padded<align::right>(out, *specs, size, write)
1323  : base_iterator(out, write(reserve(out, size)));
1324 }
1325 
1326 template <typename Char, typename OutputIt>
1327 FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1328  const basic_format_specs<Char>& specs)
1329  -> OutputIt {
1330  return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1331  *it++ = value;
1332  return it;
1333  });
1334 }
1335 template <typename Char, typename OutputIt>
1336 FMT_CONSTEXPR auto write(OutputIt out, Char value,
1337  const basic_format_specs<Char>& specs,
1338  locale_ref loc = {}) -> OutputIt {
1339  return check_char_specs(specs)
1340  ? write_char(out, value, specs)
1341  : write(out, static_cast<int>(value), specs, loc);
1342 }
1343 
1344 // Data for write_int that doesn't depend on output iterator type. It is used to
1345 // avoid template code bloat.
1346 template <typename Char> struct write_int_data {
1347  size_t size;
1348  size_t padding;
1349 
1350  FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1351  const basic_format_specs<Char>& specs)
1352  : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1353  if (specs.align == align::numeric) {
1354  auto width = to_unsigned(specs.width);
1355  if (width > size) {
1356  padding = width - size;
1357  size = width;
1358  }
1359  } else if (specs.precision > num_digits) {
1360  size = (prefix >> 24) + to_unsigned(specs.precision);
1361  padding = to_unsigned(specs.precision - num_digits);
1362  }
1363  }
1364 };
1365 
1366 // Writes an integer in the format
1367 // <left-padding><prefix><numeric-padding><digits><right-padding>
1368 // where <digits> are written by write_digits(it).
1369 // prefix contains chars in three lower bytes and the size in the fourth byte.
1370 template <typename OutputIt, typename Char, typename W>
1371 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1372  unsigned prefix,
1373  const basic_format_specs<Char>& specs,
1374  W write_digits) -> OutputIt {
1375  // Slightly faster check for specs.width == 0 && specs.precision == -1.
1376  if ((specs.width | (specs.precision + 1)) == 0) {
1377  auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1378  if (prefix != 0) {
1379  for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1380  *it++ = static_cast<Char>(p & 0xff);
1381  }
1382  return base_iterator(out, write_digits(it));
1383  }
1384  auto data = write_int_data<Char>(num_digits, prefix, specs);
1385  return write_padded<align::right>(
1386  out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
1387  for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1388  *it++ = static_cast<Char>(p & 0xff);
1389  it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
1390  return write_digits(it);
1391  });
1392 }
1393 
1394 template <typename OutputIt, typename UInt, typename Char>
1395 auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
1396  const basic_format_specs<Char>& specs, locale_ref loc)
1397  -> bool {
1398  static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
1399  const auto sep_size = 1;
1400  auto ts = thousands_sep<Char>(loc);
1401  if (!ts.thousands_sep) return false;
1402  int num_digits = count_digits(value);
1403  int size = num_digits, n = num_digits;
1404  const std::string& groups = ts.grouping;
1405  std::string::const_iterator group = groups.cbegin();
1406  while (group != groups.cend() && n > *group && *group > 0 &&
1407  *group != max_value<char>()) {
1408  size += sep_size;
1409  n -= *group;
1410  ++group;
1411  }
1412  if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back());
1413  char digits[40];
1414  format_decimal(digits, value, num_digits);
1416  if (prefix != 0) ++size;
1417  const auto usize = to_unsigned(size);
1418  buffer.resize(usize);
1419  basic_string_view<Char> s(&ts.thousands_sep, sep_size);
1420  // Index of a decimal digit with the least significant digit having index 0.
1421  int digit_index = 0;
1422  group = groups.cbegin();
1423  auto p = buffer.data() + size - 1;
1424  for (int i = num_digits - 1; i > 0; --i) {
1425  *p-- = static_cast<Char>(digits[i]);
1426  if (*group <= 0 || ++digit_index % *group != 0 ||
1427  *group == max_value<char>())
1428  continue;
1429  if (group + 1 != groups.cend()) {
1430  digit_index = 0;
1431  ++group;
1432  }
1433  std::uninitialized_copy(s.data(), s.data() + s.size(),
1434  make_checked(p, s.size()));
1435  p -= s.size();
1436  }
1437  *p-- = static_cast<Char>(*digits);
1438  if (prefix != 0) *p = static_cast<Char>(prefix);
1439  auto data = buffer.data();
1440  out = write_padded<align::right>(
1441  out, specs, usize, usize, [=](reserve_iterator<OutputIt> it) {
1442  return copy_str<Char>(data, data + size, it);
1443  });
1444  return true;
1445 }
1446 
1447 FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
1448  prefix |= prefix != 0 ? value << 8 : value;
1449  prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
1450 }
1451 
1452 template <typename UInt> struct write_int_arg {
1454  unsigned prefix;
1455 };
1456 
1457 template <typename T>
1460  auto prefix = 0u;
1461  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
1462  if (is_negative(value)) {
1463  prefix = 0x01000000 | '-';
1464  abs_value = 0 - abs_value;
1465  } else {
1466  prefix = data::prefixes[sign];
1467  }
1468  return {abs_value, prefix};
1469 }
1470 
1471 template <typename Char, typename OutputIt, typename T>
1473  const basic_format_specs<Char>& specs,
1474  locale_ref loc) -> OutputIt {
1475  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
1476  auto abs_value = arg.abs_value;
1477  auto prefix = arg.prefix;
1478  auto utype = static_cast<unsigned>(specs.type);
1479  switch (specs.type) {
1480  case 0:
1481  case 'd': {
1482  if (specs.localized &&
1483  write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value),
1484  prefix, specs, loc)) {
1485  return out;
1486  }
1487  auto num_digits = count_digits(abs_value);
1488  return write_int(
1489  out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
1490  return format_decimal<Char>(it, abs_value, num_digits).end;
1491  });
1492  }
1493  case 'x':
1494  case 'X': {
1495  if (specs.alt) prefix_append(prefix, (utype << 8) | '0');
1496  bool upper = specs.type != 'x';
1497  int num_digits = count_digits<4>(abs_value);
1498  return write_int(
1499  out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
1500  return format_uint<4, Char>(it, abs_value, num_digits, upper);
1501  });
1502  }
1503  case 'b':
1504  case 'B': {
1505  if (specs.alt) prefix_append(prefix, (utype << 8) | '0');
1506  int num_digits = count_digits<1>(abs_value);
1507  return write_int(out, num_digits, prefix, specs,
1508  [=](reserve_iterator<OutputIt> it) {
1509  return format_uint<1, Char>(it, abs_value, num_digits);
1510  });
1511  }
1512  case 'o': {
1513  int num_digits = count_digits<3>(abs_value);
1514  if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
1515  // Octal prefix '0' is counted as a digit, so only add it if precision
1516  // is not greater than the number of digits.
1517  prefix_append(prefix, '0');
1518  }
1519  return write_int(out, num_digits, prefix, specs,
1520  [=](reserve_iterator<OutputIt> it) {
1521  return format_uint<3, Char>(it, abs_value, num_digits);
1522  });
1523  }
1524  case 'c':
1525  return write_char(out, static_cast<Char>(abs_value), specs);
1526  default:
1527  FMT_THROW(format_error("invalid type specifier"));
1528  }
1529  return out;
1530 }
1531 template <typename Char, typename OutputIt, typename T,
1534  std::is_same<OutputIt, buffer_appender<Char>>::value)>
1535 FMT_CONSTEXPR auto write(OutputIt out, T value,
1536  const basic_format_specs<Char>& specs, locale_ref loc)
1537  -> OutputIt {
1538  return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
1539 }
1540 // An inlined version of write used in format string compilation.
1541 template <typename Char, typename OutputIt, typename T,
1544  !std::is_same<OutputIt, buffer_appender<Char>>::value)>
1545 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
1546  const basic_format_specs<Char>& specs,
1547  locale_ref loc) -> OutputIt {
1548  return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
1549 }
1550 
1551 template <typename Char, typename OutputIt>
1553  const basic_format_specs<Char>& specs) -> OutputIt {
1554  auto data = s.data();
1555  auto size = s.size();
1556  if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
1557  size = code_point_index(s, to_unsigned(specs.precision));
1558  auto width =
1559  specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0;
1560  return write_padded(out, specs, size, width,
1561  [=](reserve_iterator<OutputIt> it) {
1562  return copy_str<Char>(data, data + size, it);
1563  });
1564 }
1565 template <typename Char, typename OutputIt>
1566 FMT_CONSTEXPR auto write(OutputIt out,
1568  const basic_format_specs<Char>& specs, locale_ref)
1569  -> OutputIt {
1570  return write(out, s, specs);
1571 }
1572 template <typename Char, typename OutputIt>
1573 FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
1574  const basic_format_specs<Char>& specs, locale_ref)
1575  -> OutputIt {
1576  return check_cstring_type_spec(specs.type)
1577  ? write(out, basic_string_view<Char>(s), specs, {})
1578  : write_ptr<Char>(out, to_uintptr(s), &specs);
1579 }
1580 
1581 template <typename Char, typename OutputIt>
1582 auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs<Char> specs,
1583  const float_specs& fspecs) -> OutputIt {
1584  auto str =
1585  isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan");
1586  constexpr size_t str_size = 3;
1587  auto sign = fspecs.sign;
1588  auto size = str_size + (sign ? 1 : 0);
1589  // Replace '0'-padding with space for non-finite values.
1590  const bool is_zero_fill =
1591  specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
1592  if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
1593  return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
1594  if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1595  return copy_str<Char>(str, str + str_size, it);
1596  });
1597 }
1598 
1599 // A decimal floating-point number significand * pow(10, exp).
1601  const char* significand;
1604 };
1605 
1606 inline auto get_significand_size(const big_decimal_fp& fp) -> int {
1607  return fp.significand_size;
1608 }
1609 template <typename T>
1610 inline auto get_significand_size(const dragonbox::decimal_fp<T>& fp) -> int {
1611  return count_digits(fp.significand);
1612 }
1613 
1614 template <typename Char, typename OutputIt>
1615 inline auto write_significand(OutputIt out, const char* significand,
1616  int& significand_size) -> OutputIt {
1617  return copy_str<Char>(significand, significand + significand_size, out);
1618 }
1619 template <typename Char, typename OutputIt, typename UInt>
1620 inline auto write_significand(OutputIt out, UInt significand,
1621  int significand_size) -> OutputIt {
1622  return format_decimal<Char>(out, significand, significand_size).end;
1623 }
1624 
1625 template <typename Char, typename UInt,
1627 inline auto write_significand(Char* out, UInt significand, int significand_size,
1628  int integral_size, Char decimal_point) -> Char* {
1629  if (!decimal_point)
1630  return format_decimal(out, significand, significand_size).end;
1631  auto end = format_decimal(out + 1, significand, significand_size).end;
1632  if (integral_size == 1) {
1633  out[0] = out[1];
1634  } else {
1635  std::uninitialized_copy_n(out + 1, integral_size,
1636  make_checked(out, to_unsigned(integral_size)));
1637  }
1638  out[integral_size] = decimal_point;
1639  return end;
1640 }
1641 
1642 template <typename OutputIt, typename UInt, typename Char,
1643  FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
1644 inline auto write_significand(OutputIt out, UInt significand,
1645  int significand_size, int integral_size,
1646  Char decimal_point) -> OutputIt {
1647  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
1648  Char buffer[digits10<UInt>() + 2];
1649  auto end = write_significand(buffer, significand, significand_size,
1650  integral_size, decimal_point);
1651  return detail::copy_str_noinline<Char>(buffer, end, out);
1652 }
1653 
1654 template <typename OutputIt, typename Char>
1655 inline auto write_significand(OutputIt out, const char* significand,
1656  int significand_size, int integral_size,
1657  Char decimal_point) -> OutputIt {
1658  out = detail::copy_str_noinline<Char>(significand,
1659  significand + integral_size, out);
1660  if (!decimal_point) return out;
1661  *out++ = decimal_point;
1662  return detail::copy_str_noinline<Char>(significand + integral_size,
1663  significand + significand_size, out);
1664 }
1665 
1666 template <typename OutputIt, typename DecimalFP, typename Char>
1667 auto write_float(OutputIt out, const DecimalFP& fp,
1668  const basic_format_specs<Char>& specs, float_specs fspecs,
1669  Char decimal_point) -> OutputIt {
1670  auto significand = fp.significand;
1671  int significand_size = get_significand_size(fp);
1672  static const Char zero = static_cast<Char>('0');
1673  auto sign = fspecs.sign;
1674  size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
1675  using iterator = reserve_iterator<OutputIt>;
1676 
1677  int output_exp = fp.exponent + significand_size - 1;
1678  auto use_exp_format = [=]() {
1679  if (fspecs.format == float_format::exp) return true;
1680  if (fspecs.format != float_format::general) return false;
1681  // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
1682  // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
1683  const int exp_lower = -4, exp_upper = 16;
1684  return output_exp < exp_lower ||
1685  output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
1686  };
1687  if (use_exp_format()) {
1688  int num_zeros = 0;
1689  if (fspecs.showpoint) {
1690  num_zeros = fspecs.precision - significand_size;
1691  if (num_zeros < 0) num_zeros = 0;
1692  size += to_unsigned(num_zeros);
1693  } else if (significand_size == 1) {
1694  decimal_point = Char();
1695  }
1696  auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
1697  int exp_digits = 2;
1698  if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
1699 
1700  size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
1701  char exp_char = fspecs.upper ? 'E' : 'e';
1702  auto write = [=](iterator it) {
1703  if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1704  // Insert a decimal point after the first digit and add an exponent.
1705  it = write_significand(it, significand, significand_size, 1,
1706  decimal_point);
1707  if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
1708  *it++ = static_cast<Char>(exp_char);
1709  return write_exponent<Char>(output_exp, it);
1710  };
1711  return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
1712  : base_iterator(out, write(reserve(out, size)));
1713  }
1714 
1715  int exp = fp.exponent + significand_size;
1716  if (fp.exponent >= 0) {
1717  // 1234e5 -> 123400000[.0+]
1718  size += to_unsigned(fp.exponent);
1719  int num_zeros = fspecs.precision - exp;
1720 #ifdef FMT_FUZZ
1721  if (num_zeros > 5000)
1722  throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
1723 #endif
1724  if (fspecs.showpoint) {
1725  if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1;
1726  if (num_zeros > 0) size += to_unsigned(num_zeros) + 1;
1727  }
1728  return write_padded<align::right>(out, specs, size, [&](iterator it) {
1729  if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1730  it = write_significand<Char>(it, significand, significand_size);
1731  it = detail::fill_n(it, fp.exponent, zero);
1732  if (!fspecs.showpoint) return it;
1733  *it++ = decimal_point;
1734  return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
1735  });
1736  } else if (exp > 0) {
1737  // 1234e-2 -> 12.34[0+]
1738  int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
1739  size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
1740  return write_padded<align::right>(out, specs, size, [&](iterator it) {
1741  if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1742  it = write_significand(it, significand, significand_size, exp,
1743  decimal_point);
1744  return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
1745  });
1746  }
1747  // 1234e-6 -> 0.001234
1748  int num_zeros = -exp;
1749  if (significand_size == 0 && fspecs.precision >= 0 &&
1750  fspecs.precision < num_zeros) {
1751  num_zeros = fspecs.precision;
1752  }
1753  bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
1754  size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
1755  return write_padded<align::right>(out, specs, size, [&](iterator it) {
1756  if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1757  *it++ = zero;
1758  if (!pointy) return it;
1759  *it++ = decimal_point;
1760  it = detail::fill_n(it, num_zeros, zero);
1761  return write_significand<Char>(it, significand, significand_size);
1762  });
1763 }
1764 
1765 template <typename Char, typename OutputIt, typename T,
1767 auto write(OutputIt out, T value, basic_format_specs<Char> specs,
1768  locale_ref loc = {}) -> OutputIt {
1769  if (const_check(!is_supported_floating_point(value))) return out;
1770  float_specs fspecs = parse_float_type_spec(specs);
1771  fspecs.sign = specs.sign;
1772  if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
1773  fspecs.sign = sign::minus;
1774  value = -value;
1775  } else if (fspecs.sign == sign::minus) {
1776  fspecs.sign = sign::none;
1777  }
1778 
1779  if (!std::isfinite(value))
1780  return write_nonfinite(out, std::isinf(value), specs, fspecs);
1781 
1782  if (specs.align == align::numeric && fspecs.sign) {
1783  auto it = reserve(out, 1);
1784  *it++ = static_cast<Char>(data::signs[fspecs.sign]);
1785  out = base_iterator(out, it);
1786  fspecs.sign = sign::none;
1787  if (specs.width != 0) --specs.width;
1788  }
1789 
1791  if (fspecs.format == float_format::hex) {
1792  if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]);
1793  snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
1794  return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
1795  specs);
1796  }
1797  int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
1798  if (fspecs.format == float_format::exp) {
1799  if (precision == max_value<int>())
1800  FMT_THROW(format_error("number is too big"));
1801  else
1802  ++precision;
1803  }
1804  if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
1805  fspecs.use_grisu = is_fast_float<T>();
1806  int exp = format_float(promote_float(value), precision, fspecs, buffer);
1807  fspecs.precision = precision;
1808  Char point =
1809  fspecs.locale ? decimal_point<Char>(loc) : static_cast<Char>('.');
1810  auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
1811  return write_float(out, fp, specs, fspecs, point);
1812 }
1813 
1814 template <typename Char, typename OutputIt, typename T,
1816 auto write(OutputIt out, T value) -> OutputIt {
1817  if (const_check(!is_supported_floating_point(value))) return out;
1818 
1819  using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
1821  auto bits = bit_cast<uint>(value);
1822 
1823  auto fspecs = float_specs();
1824  auto sign_bit = bits & (uint(1) << (num_bits<uint>() - 1));
1825  if (sign_bit != 0) {
1826  fspecs.sign = sign::minus;
1827  value = -value;
1828  }
1829 
1830  static const auto specs = basic_format_specs<Char>();
1831  uint mask = exponent_mask<floaty>();
1832  if ((bits & mask) == mask)
1833  return write_nonfinite(out, std::isinf(value), specs, fspecs);
1834 
1835  auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
1836  return write_float(out, dec, specs, fspecs, static_cast<Char>('.'));
1837 }
1838 
1839 template <typename Char, typename OutputIt, typename T,
1842 inline auto write(OutputIt out, T value) -> OutputIt {
1843  return write(out, value, basic_format_specs<Char>());
1844 }
1845 
1846 template <typename Char, typename OutputIt>
1847 auto write(OutputIt out, monostate, basic_format_specs<Char> = {},
1848  locale_ref = {}) -> OutputIt {
1849  FMT_ASSERT(false, "");
1850  return out;
1851 }
1852 
1853 template <typename Char, typename OutputIt>
1855  -> OutputIt {
1856  auto it = reserve(out, value.size());
1857  it = copy_str_noinline<Char>(value.begin(), value.end(), it);
1858  return base_iterator(out, it);
1859 }
1860 
1861 template <typename Char, typename OutputIt, typename T,
1863 constexpr auto write(OutputIt out, const T& value) -> OutputIt {
1864  return write<Char>(out, to_string_view(value));
1865 }
1866 
1867 template <typename Char, typename OutputIt, typename T,
1871 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
1872  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
1873  bool negative = is_negative(value);
1874  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
1875  if (negative) abs_value = ~abs_value + 1;
1876  int num_digits = count_digits(abs_value);
1877  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
1878  auto it = reserve(out, size);
1879  if (auto ptr = to_pointer<Char>(it, size)) {
1880  if (negative) *ptr++ = static_cast<Char>('-');
1881  format_decimal<Char>(ptr, abs_value, num_digits);
1882  return out;
1883  }
1884  if (negative) *it++ = static_cast<Char>('-');
1885  it = format_decimal<Char>(it, abs_value, num_digits).end;
1886  return base_iterator(out, it);
1887 }
1888 
1889 // FMT_ENABLE_IF() condition separated to workaround MSVC bug
1890 template <
1891  typename Char, typename OutputIt, typename T,
1892  bool check =
1896  FMT_ENABLE_IF(check)>
1897 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
1898  return write<Char>(
1899  out, static_cast<typename std::underlying_type<T>::type>(value));
1900 }
1901 
1902 template <typename Char, typename OutputIt, typename T,
1904 FMT_CONSTEXPR auto write(OutputIt out, T value,
1905  const basic_format_specs<Char>& specs = {},
1906  locale_ref = {}) -> OutputIt {
1907  return specs.type && specs.type != 's'
1908  ? write(out, value ? 1 : 0, specs, {})
1909  : write_bytes(out, value ? "true" : "false", specs);
1910 }
1911 
1912 template <typename Char, typename OutputIt>
1913 FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
1914  auto it = reserve(out, 1);
1915  *it++ = value;
1916  return base_iterator(out, it);
1917 }
1918 
1919 template <typename Char, typename OutputIt>
1920 FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
1921  -> OutputIt {
1922  if (!value) {
1923  FMT_THROW(format_error("string pointer is null"));
1924  } else {
1925  auto length = std::char_traits<Char>::length(value);
1926  out = write(out, basic_string_view<Char>(value, length));
1927  }
1928  return out;
1929 }
1930 
1931 template <typename Char, typename OutputIt, typename T,
1933 auto write(OutputIt out, const T* value,
1934  const basic_format_specs<Char>& specs = {}, locale_ref = {})
1935  -> OutputIt {
1937  return write_ptr<Char>(out, to_uintptr(value), &specs);
1938 }
1939 
1940 template <typename Char, typename OutputIt, typename T>
1941 FMT_CONSTEXPR auto write(OutputIt out, const T& value) ->
1942  typename std::enable_if<
1945  OutputIt>::type {
1946  using context_type = basic_format_context<OutputIt, Char>;
1947  using formatter_type =
1949  typename context_type::template formatter_type<T>,
1951  context_type ctx(out, {}, {});
1952  return formatter_type().format(value, ctx);
1953 }
1954 
1955 // An argument visitor that formats the argument and writes it via the output
1956 // iterator. It's a class and not a generic lambda for compatibility with C++11.
1957 template <typename Char> struct default_arg_formatter {
1960 
1964 
1965  template <typename T> auto operator()(T value) -> iterator {
1966  return write<Char>(out, value);
1967  }
1969  basic_format_parse_context<Char> parse_ctx({});
1970  context format_ctx(out, args, loc);
1971  h.format(parse_ctx, format_ctx);
1972  return format_ctx.out();
1973  }
1974 };
1975 
1976 template <typename Char> struct arg_formatter {
1979 
1983 
1984  template <typename T>
1986  return detail::write(out, value, specs, locale);
1987  }
1989  // User-defined types are handled separately because they require access
1990  // to the parse context.
1991  return out;
1992  }
1993 };
1994 
1995 template <typename Char> struct custom_formatter {
1998 
2000  typename basic_format_arg<buffer_context<Char>>::handle h) const {
2001  h.format(parse_ctx, ctx);
2002  }
2003  template <typename T> void operator()(T) const {}
2004 };
2005 
2006 template <typename T>
2007 using is_integer =
2011 
2012 template <typename ErrorHandler> class width_checker {
2013  public:
2014  explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
2015 
2017  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
2018  if (is_negative(value)) handler_.on_error("negative width");
2019  return static_cast<unsigned long long>(value);
2020  }
2021 
2023  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
2024  handler_.on_error("width is not integer");
2025  return 0;
2026  }
2027 
2028  private:
2029  ErrorHandler& handler_;
2030 };
2031 
2032 template <typename ErrorHandler> class precision_checker {
2033  public:
2034  explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
2035 
2037  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
2038  if (is_negative(value)) handler_.on_error("negative precision");
2039  return static_cast<unsigned long long>(value);
2040  }
2041 
2043  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
2044  handler_.on_error("precision is not integer");
2045  return 0;
2046  }
2047 
2048  private:
2049  ErrorHandler& handler_;
2050 };
2051 
2052 template <template <typename> class Handler, typename FormatArg,
2053  typename ErrorHandler>
2054 FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int {
2055  unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
2056  if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
2057  return static_cast<int>(value);
2058 }
2059 
2060 template <typename Context, typename ID>
2061 FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) ->
2062  typename Context::format_arg {
2063  auto arg = ctx.arg(id);
2064  if (!arg) ctx.on_error("argument not found");
2065  return arg;
2066 }
2067 
2068 // The standard format specifier handler with checking.
2069 template <typename Char> class specs_handler : public specs_setter<Char> {
2070  private:
2071  basic_format_parse_context<Char>& parse_context_;
2072  buffer_context<Char>& context_;
2073 
2074  // This is only needed for compatibility with gcc 4.4.
2076 
2078  return detail::get_arg(context_, parse_context_.next_arg_id());
2079  }
2080 
2081  FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg {
2082  parse_context_.check_arg_id(arg_id);
2083  return detail::get_arg(context_, arg_id);
2084  }
2085 
2087  parse_context_.check_arg_id(arg_id);
2088  return detail::get_arg(context_, arg_id);
2089  }
2090 
2091  public:
2094  buffer_context<Char>& ctx)
2095  : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
2096 
2097  template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2098  this->specs_.width = get_dynamic_spec<width_checker>(
2099  get_arg(arg_id), context_.error_handler());
2100  }
2101 
2102  template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2103  this->specs_.precision = get_dynamic_spec<precision_checker>(
2104  get_arg(arg_id), context_.error_handler());
2105  }
2106 
2107  void on_error(const char* message) { context_.on_error(message); }
2108 };
2109 
2110 template <template <typename> class Handler, typename Context>
2113  Context& ctx) {
2114  switch (ref.kind) {
2115  case arg_id_kind::none:
2116  break;
2117  case arg_id_kind::index:
2118  value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
2119  ctx.error_handler());
2120  break;
2121  case arg_id_kind::name:
2122  value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
2123  ctx.error_handler());
2124  break;
2125  }
2126 }
2127 
2128 #define FMT_STRING_IMPL(s, base, explicit) \
2129  [] { \
2130  /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
2131  /* Use a macro-like name to avoid shadowing warnings. */ \
2132  struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
2133  using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
2134  FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
2135  operator fmt::basic_string_view<char_type>() const { \
2136  return fmt::detail_exported::compile_string_to_view<char_type>(s); \
2137  } \
2138  }; \
2139  return FMT_COMPILE_STRING(); \
2140  }()
2141 
2142 /**
2143  \rst
2144  Constructs a compile-time format string from a string literal *s*.
2145 
2146  **Example**::
2147 
2148  // A compile-time error because 'd' is an invalid specifier for strings.
2149  std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
2150  \endrst
2151  */
2152 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
2153 
2154 #if FMT_USE_USER_DEFINED_LITERALS
2155 template <typename Char> struct udl_formatter {
2157 
2158  template <typename... T>
2159  auto operator()(T&&... args) const -> std::basic_string<Char> {
2160  return vformat(str, fmt::make_args_checked<T...>(str, args...));
2161  }
2162 };
2163 
2164 # if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2165 template <typename T, typename Char, size_t N,
2166  fmt::detail_exported::fixed_string<Char, N> Str>
2167 struct statically_named_arg : view {
2168  static constexpr auto name = Str.data;
2169 
2170  const T& value;
2171  statically_named_arg(const T& v) : value(v) {}
2172 };
2173 
2174 template <typename T, typename Char, size_t N,
2175  fmt::detail_exported::fixed_string<Char, N> Str>
2176 struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
2177 
2178 template <typename T, typename Char, size_t N,
2179  fmt::detail_exported::fixed_string<Char, N> Str>
2180 struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
2181  : std::true_type {};
2182 
2183 template <typename Char, size_t N,
2184  fmt::detail_exported::fixed_string<Char, N> Str>
2185 struct udl_arg {
2186  template <typename T> auto operator=(T&& value) const {
2187  return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
2188  }
2189 };
2190 # else
2191 template <typename Char> struct udl_arg {
2192  const Char* str;
2193 
2194  template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
2195  return {str, std::forward<T>(value)};
2196  }
2197 };
2198 # endif
2199 #endif // FMT_USE_USER_DEFINED_LITERALS
2200 
2201 template <typename Locale, typename Char>
2202 auto vformat(const Locale& loc, basic_string_view<Char> format_str,
2206  detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
2207  return {buffer.data(), buffer.size()};
2208 }
2209 
2210 using format_func = void (*)(detail::buffer<char>&, int, const char*);
2211 
2212 FMT_API void format_error_code(buffer<char>& out, int error_code,
2214 
2215 FMT_API void report_error(format_func func, int error_code,
2216  const char* message) FMT_NOEXCEPT;
2218 
2219 FMT_API auto vsystem_error(int error_code, string_view format_str,
2221 
2222 /**
2223  \rst
2224  Constructs :class:`std::system_error` with a message formatted with
2225  ``fmt::format(fmt, args...)``.
2226  *error_code* is a system error code as given by ``errno``.
2227 
2228  **Example**::
2229 
2230  // This throws std::system_error with the description
2231  // cannot open file 'madeup': No such file or directory
2232  // or similar (system message may vary).
2233  const char* filename = "madeup";
2234  std::FILE* file = std::fopen(filename, "r");
2235  if (!file)
2236  throw fmt::system_error(errno, "cannot open file '{}'", filename);
2237  \endrst
2238 */
2239 template <typename... T>
2240 auto system_error(int error_code, format_string<T...> fmt, T&&... args)
2241  -> std::system_error {
2242  return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
2243 }
2244 
2245 /**
2246  \rst
2247  Formats an error message for an error returned by an operating system or a
2248  language runtime, for example a file opening error, and writes it to *out*.
2249  The format is the same as the one used by ``std::system_error(ec, message)``
2250  where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
2251  It is implementation-defined but normally looks like:
2252 
2253  .. parsed-literal::
2254  *<message>*: *<system-message>*
2255 
2256  where *<message>* is the passed message and *<system-message>* is the system
2257  message corresponding to the error code.
2258  *error_code* is a system error code as given by ``errno``.
2259  \endrst
2260  */
2261 FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
2262  const char* message) FMT_NOEXCEPT;
2263 
2264 // Reports a system error without throwing an exception.
2265 // Can be used to report errors from destructors.
2266 FMT_API void report_system_error(int error_code,
2267  const char* message) FMT_NOEXCEPT;
2268 
2269 /** Fast integer formatter. */
2270 class format_int {
2271  private:
2272  // Buffer should be large enough to hold all digits (digits10 + 1),
2273  // a sign and a null character.
2274  enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
2275  mutable char buffer_[buffer_size];
2276  char* str_;
2277 
2278  template <typename UInt> auto format_unsigned(UInt value) -> char* {
2279  auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
2280  return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
2281  }
2282 
2283  template <typename Int> auto format_signed(Int value) -> char* {
2284  auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
2285  bool negative = value < 0;
2286  if (negative) abs_value = 0 - abs_value;
2287  auto begin = format_unsigned(abs_value);
2288  if (negative) *--begin = '-';
2289  return begin;
2290  }
2291 
2292  public:
2293  explicit format_int(int value) : str_(format_signed(value)) {}
2294  explicit format_int(long value) : str_(format_signed(value)) {}
2295  explicit format_int(long long value) : str_(format_signed(value)) {}
2296  explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
2297  explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
2298  explicit format_int(unsigned long long value)
2299  : str_(format_unsigned(value)) {}
2300 
2301  /** Returns the number of characters written to the output buffer. */
2302  auto size() const -> size_t {
2303  return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
2304  }
2305 
2306  /**
2307  Returns a pointer to the output buffer content. No terminating null
2308  character is appended.
2309  */
2310  auto data() const -> const char* { return str_; }
2311 
2312  /**
2313  Returns a pointer to the output buffer content with terminating null
2314  character appended.
2315  */
2316  auto c_str() const -> const char* {
2317  buffer_[buffer_size - 1] = '\0';
2318  return str_;
2319  }
2320 
2321  /**
2322  \rst
2323  Returns the content of the output buffer as an ``std::string``.
2324  \endrst
2325  */
2326  auto str() const -> std::string { return std::string(str_, size()); }
2327 };
2328 
2329 template <typename T, typename Char>
2330 template <typename FormatContext>
2332 formatter<T, Char,
2334  detail::type::custom_type>>::format(const T& val,
2335  FormatContext& ctx)
2336  const -> decltype(ctx.out()) {
2337  if (specs_.width_ref.kind != detail::arg_id_kind::none ||
2338  specs_.precision_ref.kind != detail::arg_id_kind::none) {
2339  auto specs = specs_;
2340  detail::handle_dynamic_spec<detail::width_checker>(specs.width,
2341  specs.width_ref, ctx);
2342  detail::handle_dynamic_spec<detail::precision_checker>(
2343  specs.precision, specs.precision_ref, ctx);
2344  return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
2345  }
2346  return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
2347 }
2348 
2349 #define FMT_FORMAT_AS(Type, Base) \
2350  template <typename Char> \
2351  struct formatter<Type, Char> : formatter<Base, Char> { \
2352  template <typename FormatContext> \
2353  auto format(Type const& val, FormatContext& ctx) const \
2354  -> decltype(ctx.out()) { \
2355  return formatter<Base, Char>::format(static_cast<Base>(val), ctx); \
2356  } \
2357  }
2358 
2359 FMT_FORMAT_AS(signed char, int);
2360 FMT_FORMAT_AS(unsigned char, unsigned);
2361 FMT_FORMAT_AS(short, int);
2362 FMT_FORMAT_AS(unsigned short, unsigned);
2363 FMT_FORMAT_AS(long, long long);
2364 FMT_FORMAT_AS(unsigned long, unsigned long long);
2365 FMT_FORMAT_AS(Char*, const Char*);
2367 FMT_FORMAT_AS(std::nullptr_t, const void*);
2368 FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
2369 
2370 template <typename Char>
2372  template <typename FormatContext>
2373  auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) {
2375  }
2376 };
2377 
2378 template <typename Char, size_t N>
2379 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
2380  template <typename FormatContext>
2381  FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const
2382  -> decltype(ctx.out()) {
2383  return formatter<basic_string_view<Char>, Char>::format(val, ctx);
2384  }
2385 };
2386 
2387 // A formatter for types known only at run time such as variant alternatives.
2388 //
2389 // Usage:
2390 // using variant = std::variant<int, std::string>;
2391 // template <>
2392 // struct formatter<variant>: dynamic_formatter<> {
2393 // auto format(const variant& v, format_context& ctx) {
2394 // return visit([&](const auto& val) {
2395 // return dynamic_formatter<>::format(val, ctx);
2396 // }, v);
2397 // }
2398 // };
2399 template <typename Char = char> class dynamic_formatter {
2400  private:
2401  detail::dynamic_format_specs<Char> specs_;
2402  const Char* format_str_;
2403 
2404  struct null_handler : detail::error_handler {
2405  void on_align(align_t) {}
2406  void on_sign(sign_t) {}
2407  void on_hash() {}
2408  };
2409 
2410  template <typename Context> void handle_specs(Context& ctx) {
2411  detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
2412  specs_.width_ref, ctx);
2413  detail::handle_dynamic_spec<detail::precision_checker>(
2414  specs_.precision, specs_.precision_ref, ctx);
2415  }
2416 
2417  public:
2418  template <typename ParseContext>
2419  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2420  format_str_ = ctx.begin();
2421  // Checks are deferred to formatting time when the argument type is known.
2422  detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
2423  return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
2424  }
2425 
2426  template <typename T, typename FormatContext>
2427  auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
2428  handle_specs(ctx);
2429  detail::specs_checker<null_handler> checker(
2431  checker.on_align(specs_.align);
2432  if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
2433  if (specs_.alt) checker.on_hash();
2434  if (specs_.precision >= 0) checker.end_precision();
2435  return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
2436  }
2437 };
2438 
2439 /**
2440  \rst
2441  Converts ``p`` to ``const void*`` for pointer formatting.
2442 
2443  **Example**::
2444 
2445  auto s = fmt::format("{}", fmt::ptr(p));
2446  \endrst
2447  */
2448 template <typename T> auto ptr(T p) -> const void* {
2449  static_assert(std::is_pointer<T>::value, "");
2450  return detail::bit_cast<const void*>(p);
2451 }
2452 template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* {
2453  return p.get();
2454 }
2455 template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
2456  return p.get();
2457 }
2458 
2459 class bytes {
2460  private:
2461  string_view data_;
2462  friend struct formatter<bytes>;
2463 
2464  public:
2465  explicit bytes(string_view data) : data_(data) {}
2466 };
2467 
2468 template <> struct formatter<bytes> {
2469  private:
2470  detail::dynamic_format_specs<char> specs_;
2471 
2472  public:
2473  template <typename ParseContext>
2474  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2475  using handler_type = detail::dynamic_specs_handler<ParseContext>;
2476  detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
2477  detail::type::string_type);
2478  auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
2479  detail::check_string_type_spec(specs_.type, ctx.error_handler());
2480  return it;
2481  }
2482 
2483  template <typename FormatContext>
2484  auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
2485  detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
2486  specs_.width_ref, ctx);
2487  detail::handle_dynamic_spec<detail::precision_checker>(
2488  specs_.precision, specs_.precision_ref, ctx);
2489  return detail::write_bytes(ctx.out(), b.data_, specs_);
2490  }
2491 };
2492 
2493 template <typename It, typename Sentinel, typename Char = char>
2494 struct join_view : detail::view {
2495  It begin;
2496  Sentinel end;
2498 
2500  : begin(b), end(e), sep(s) {}
2501 };
2502 
2503 template <typename It, typename Sentinel, typename Char>
2505 
2506 template <typename It, typename Sentinel, typename Char>
2507 struct formatter<join_view<It, Sentinel, Char>, Char> {
2508  private:
2509  using value_type = typename std::iterator_traits<It>::value_type;
2510  using context = buffer_context<Char>;
2511  using mapper = detail::arg_mapper<context>;
2512 
2514  static auto map(const T& value) -> const T& {
2515  return value;
2516  }
2518  static auto map(const T& value) -> decltype(mapper().map(value)) {
2519  return mapper().map(value);
2520  }
2521 
2522  using formatter_type =
2524  formatter<remove_cvref_t<decltype(map(
2525  std::declval<const value_type&>()))>,
2526  Char>,
2527  detail::fallback_formatter<value_type, Char>>;
2528 
2529  formatter_type value_formatter_;
2530 
2531  public:
2532  template <typename ParseContext>
2533  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2534  return value_formatter_.parse(ctx);
2535  }
2536 
2537  template <typename FormatContext>
2538  auto format(const join_view<It, Sentinel, Char>& value, FormatContext& ctx)
2539  -> decltype(ctx.out()) {
2540  auto it = value.begin;
2541  auto out = ctx.out();
2542  if (it != value.end) {
2543  out = value_formatter_.format(map(*it++), ctx);
2544  while (it != value.end) {
2545  out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
2546  ctx.advance_to(out);
2547  out = value_formatter_.format(map(*it++), ctx);
2548  }
2549  }
2550  return out;
2551  }
2552 };
2553 
2554 /**
2555  Returns an object that formats the iterator range `[begin, end)` with
2556  elements separated by `sep`.
2557  */
2558 template <typename It, typename Sentinel>
2559 auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
2560  return {begin, end, sep};
2561 }
2562 
2563 /**
2564  \rst
2565  Returns an object that formats `range` with elements separated by `sep`.
2566 
2567  **Example**::
2568 
2569  std::vector<int> v = {1, 2, 3};
2570  fmt::print("{}", fmt::join(v, ", "));
2571  // Output: "1, 2, 3"
2572 
2573  ``fmt::join`` applies passed format specifiers to the range elements::
2574 
2575  fmt::print("{:02}", fmt::join(v, ", "));
2576  // Output: "01, 02, 03"
2577  \endrst
2578  */
2579 template <typename Range>
2580 auto join(Range&& range, string_view sep)
2582  return join(std::begin(range), std::end(range), sep);
2583 }
2584 
2585 /**
2586  \rst
2587  Converts *value* to ``std::string`` using the default format for type *T*.
2588 
2589  **Example**::
2590 
2591  #include <fmt/format.h>
2592 
2593  std::string answer = fmt::to_string(42);
2594  \endrst
2595  */
2597 inline auto to_string(const T& value) -> std::string {
2598  auto result = std::string();
2599  detail::write<char>(std::back_inserter(result), value);
2600  return result;
2601 }
2602 
2604 inline auto to_string(T value) -> std::string {
2605  // The buffer should be large enough to store the number including the sign
2606  // or "false" for bool.
2607  constexpr int max_size = detail::digits10<T>() + 2;
2608  char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
2609  char* begin = buffer;
2610  return std::string(begin, detail::write<char>(begin, value));
2611 }
2612 
2613 template <typename Char, size_t SIZE>
2616  auto size = buf.size();
2617  detail::assume(size < std::basic_string<Char>().max_size());
2618  return std::basic_string<Char>(buf.data(), size);
2619 }
2620 
2622 
2623 template <typename Char>
2626  locale_ref loc) {
2627  // workaround for msvc bug regarding name-lookup in module
2628  // link names into function scope
2629  using detail::arg_formatter;
2631  using detail::custom_formatter;
2632  using detail::default_arg_formatter;
2633  using detail::get_arg;
2634  using detail::locale_ref;
2636  using detail::specs_checker;
2637  using detail::specs_handler;
2638  using detail::to_unsigned;
2639  using detail::type;
2640  using detail::write;
2641  auto out = buffer_appender<Char>(buf);
2642  if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
2643  auto arg = args.get(0);
2644  if (!arg) error_handler().on_error("argument not found");
2646  return;
2647  }
2648 
2649  struct format_handler : error_handler {
2650  basic_format_parse_context<Char> parse_context;
2651  buffer_context<Char> context;
2652 
2653  format_handler(buffer_appender<Char> out, basic_string_view<Char> str,
2655  : parse_context(str), context(out, args, loc) {}
2656 
2657  void on_text(const Char* begin, const Char* end) {
2658  auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
2659  context.advance_to(write<Char>(context.out(), text));
2660  }
2661 
2662  FMT_CONSTEXPR auto on_arg_id() -> int {
2663  return parse_context.next_arg_id();
2664  }
2665  FMT_CONSTEXPR auto on_arg_id(int id) -> int {
2666  return parse_context.check_arg_id(id), id;
2667  }
2668  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
2669  int arg_id = context.arg_id(id);
2670  if (arg_id < 0) on_error("argument not found");
2671  return arg_id;
2672  }
2673 
2674  FMT_INLINE void on_replacement_field(int id, const Char*) {
2675  auto arg = get_arg(context, id);
2676  context.advance_to(visit_format_arg(
2677  default_arg_formatter<Char>{context.out(), context.args(),
2678  context.locale()},
2679  arg));
2680  }
2681 
2682  auto on_format_specs(int id, const Char* begin, const Char* end)
2683  -> const Char* {
2684  auto arg = get_arg(context, id);
2685  if (arg.type() == type::custom_type) {
2686  parse_context.advance_to(parse_context.begin() +
2687  (begin - &*parse_context.begin()));
2688  visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
2689  return parse_context.begin();
2690  }
2691  auto specs = basic_format_specs<Char>();
2693  specs_handler<Char>(specs, parse_context, context), arg.type());
2694  begin = parse_format_specs(begin, end, handler);
2695  if (begin == end || *begin != '}')
2696  on_error("missing '}' in format string");
2697  auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
2698  context.advance_to(visit_format_arg(f, arg));
2699  return begin;
2700  }
2701  };
2702  detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
2703 }
2704 
2705 #ifndef FMT_HEADER_ONLY
2706 extern template void vformat_to(detail::buffer<char>&, string_view,
2708  detail::locale_ref);
2709 
2710 extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
2712 extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
2714 extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
2715 extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
2716 extern template auto format_float<double>(double value, int precision,
2717  float_specs specs, buffer<char>& buf)
2718  -> int;
2719 extern template auto format_float<long double>(long double value, int precision,
2720  float_specs specs,
2721  buffer<char>& buf) -> int;
2722 void snprintf_float(float, int, float_specs, buffer<char>&) = delete;
2723 extern template auto snprintf_float<double>(double value, int precision,
2724  float_specs specs,
2725  buffer<char>& buf) -> int;
2726 extern template auto snprintf_float<long double>(long double value,
2727  int precision,
2728  float_specs specs,
2729  buffer<char>& buf) -> int;
2730 #endif // FMT_HEADER_ONLY
2731 
2733 inline namespace literals {
2734 /**
2735  \rst
2736  User-defined literal equivalent of :func:`fmt::arg`.
2737 
2738  **Example**::
2739 
2740  using namespace fmt::literals;
2741  fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
2742  \endrst
2743  */
2744 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2745 template <detail_exported::fixed_string Str>
2746 constexpr auto operator""_a()
2747  -> detail::udl_arg<remove_cvref_t<decltype(Str.data[0])>,
2748  sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> {
2749  return {};
2750 }
2751 #else
2752 constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> {
2753  return {s};
2754 }
2755 #endif
2756 
2757 /**
2758  \rst
2759  User-defined literal equivalent of :func:`fmt::format`.
2760 
2761  **Example**::
2762 
2763  using namespace fmt::literals;
2764  std::string message = "The answer is {}"_format(42);
2765  \endrst
2766  */
2767 constexpr auto operator"" _format(const char* s, size_t n)
2768  -> detail::udl_formatter<char> {
2769  return {{s, n}};
2770 }
2771 } // namespace literals
2772 
2774 inline auto vformat(const Locale& loc, string_view fmt, format_args args)
2775  -> std::string {
2776  return detail::vformat(loc, fmt, args);
2777 }
2778 
2779 template <typename Locale, typename... T,
2781 inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
2782  -> std::string {
2783  return vformat(loc, string_view(fmt), fmt::make_format_args(args...));
2784 }
2785 
2786 template <typename... T, size_t SIZE, typename Allocator>
2788  format_string<T...> fmt, T&&... args)
2789  -> appender {
2791  return appender(buf);
2792 }
2793 
2794 template <typename OutputIt, typename Locale,
2797 auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
2798  format_args args) -> OutputIt {
2799  using detail::get_buffer;
2800  auto&& buf = get_buffer<char>(out);
2801  detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
2802  return detail::get_iterator(buf);
2803 }
2804 
2805 template <typename OutputIt, typename Locale, typename... T,
2808 FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
2809  format_string<T...> fmt, T&&... args) -> OutputIt {
2810  return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
2811 }
2812 
2815 
2816 #ifdef FMT_DEPRECATED_INCLUDE_XCHAR
2817 # include "xchar.h"
2818 #endif
2819 
2820 #ifdef FMT_HEADER_ONLY
2821 # define FMT_FUNC inline
2822 # include "format-inl.h"
2823 #else
2824 # define FMT_FUNC
2825 #endif
2826 
2827 #endif // FMT_FORMAT_H_
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:405
constexpr auto num_bits< int128_t >() -> int
Definition: format.h:310
#define FMT_MODULE_EXPORT_END
Definition: core.h:242
constexpr auto max_value() -> T
Definition: format.h:303
basic_string_view< Char > name
Definition: core.h:1955
auto data() FMT_NOEXCEPT-> T *
Definition: core.h:808
#define FMT_ENABLE_IF(...)
Definition: core.h:341
auto count_digits< 4 >(detail::fallback_uintptr n) -> int
Definition: format-inl.h:140
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result< Char >
Definition: format-inl.h:107
auto make_checked(T *p, size_t) -> T *
Definition: format.h:347
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
Definition: format.h:2034
constexpr auto digits10() FMT_NOEXCEPT-> int
Definition: format.h:988
FMT_INLINE void check_format_string(const S &)
Definition: core.h:601
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
static FMT_API constexpr const char hex_digits[]
Definition: format.h:881
static FMT_API constexpr const unsigned prefixes[4]
Definition: format.h:883
std::string upper(string_view a)
Return an all-upper case version of a (locale-independent).
Definition: strutil.h:402
bool_constant< std::numeric_limits< T >::is_iec559 &&sizeof(T)<=sizeof(double)> is_fast_float
Definition: format.h:569
basic_format_args< context > args
Definition: format.h:1962
typename float_info< T >::carrier_uint significand_type
Definition: format.h:1208
FMT_BEGIN_DETAIL_NAMESPACE constexpr FMT_INLINE auto is_constant_evaluated() FMT_NOEXCEPT-> bool
Definition: core.h:346
auto size() const -> size_t
Definition: format.h:2302
auto to_string(const T &value) -> std::string
Definition: format.h:2597
template FMT_API auto thousands_sep_impl< char >(locale_ref) -> thousands_sep_result< char >
GLenum GLint * range
Definition: glcorearb.h:1925
auto format(bytes b, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:2484
FMT_CONSTEXPR20 auto format_decimal(Char *out, UInt value, int size) -> format_decimal_result< Char * >
Definition: format.h:1048
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler) -> const Char *
Definition: core.h:2288
auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:2427
auto c_str() const -> const char *
Definition: format.h:2316
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition: core.h:243
#define FMT_DEPRECATED
Definition: format.h:120
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:2419
FMT_INLINE uint64_t count_digits_inc(int n)
Definition: format.h:957
bool locale
Definition: core.h:2533
static FMT_API constexpr const char signs[]
Definition: format.h:882
void reserve(size_t new_capacity)
Definition: format.h:701
#define FMT_END_DETAIL_NAMESPACE
Definition: core.h:244
void
Definition: png.h:1083
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128
GLboolean * data
Definition: glcorearb.h:131
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1629
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
Definition: core.h:2597
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:322
static FMT_API constexpr const char digits[][2]
Definition: format.h:862
const GLdouble * v
Definition: glcorearb.h:837
GLuint start
Definition: glcorearb.h:475
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
#define FMT_CONSTEXPR20
Definition: format.h:254
GLsizei const GLfloat * value
Definition: glcorearb.h:824
auto system_error(int error_code, format_string< T...> fmt, T &&...args) -> std::system_error
Definition: format.h:2240
locale_ref locale
Definition: format.h:1982
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
Definition: format.h:2010
constexpr auto num_bits() -> int
Definition: format.h:306
decltype(std::begin(std::declval< T & >())) iterator_t
Definition: format.h:326
basic_format_parse_context< Char > & parse_ctx
Definition: format.h:1996
buffer_appender< Char > iterator
Definition: format.h:1958
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition: core.h:115
Definition: core.h:1968
char8_type
Definition: format.h:425
constexpr auto const_check(T value) -> T
Definition: core.h:355
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:2474
GLdouble s
Definition: glad.h:3009
void on_error(const char *message)
Definition: format.h:2107
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T >>> buffer_appender
Definition: core.h:956
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
fallback_uintptr uintptr_t
Definition: format.h:295
bool binary32
Definition: core.h:2534
auto c_str() const -> const wchar_t *
Definition: format.h:1146
void append(const ContiguousRange &range)
Definition: format.h:706
decltype(std::end(std::declval< T & >())) sentinel_t
Definition: format.h:327
auto format_float(T value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format-inl.h:2335
conditional_t< num_bits< T >()<=64, uint64_t, uint128_t > uint64_or_128_t
Definition: format.h:849
auto operator()(typename basic_format_arg< context >::handle h) -> iterator
Definition: format.h:1968
union arg_ref::value val
constexpr auto digits10< int128_t >() FMT_NOEXCEPT-> int
Definition: format.h:991
conditional_t< num_bits< T >()<=32 &&!FMT_REDUCE_INT_INSTANTIATIONS, uint32_t, conditional_t< num_bits< T >()<=64, uint64_t, uint128_t >> uint32_or_64_or_128_t
Definition: format.h:847
template auto format_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf) -> int
ImageBuf OIIO_API checker(int width, int height, int depth, cspan< float > color1, cspan< float > color2, int xoffset, int yoffset, int zoffset, ROI roi, int nthreads=0)
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, unsigned prefix, const basic_format_specs< Char > &specs, W write_digits) -> OutputIt
Definition: format.h:1371
**But if you need a result
Definition: thread.h:613
FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign) -> write_int_arg< uint32_or_64_or_128_t< T >>
Definition: format.h:1458
auto write_int_localized(OutputIt &out, UInt value, unsigned prefix, const basic_format_specs< Char > &specs, locale_ref loc) -> bool
Definition: format.h:1395
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
Definition: format.h:821
typename std::remove_cv< remove_reference_t< T >>::type remove_cvref_t
Definition: core.h:327
auto format(const join_view< It, Sentinel, Char > &value, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:2538
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
Definition: format.h:408
align_t align
Definition: core.h:1912
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> reserve_iterator
Definition: format.h:379
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
PUGIXML_CHAR char_t
Definition: pugixml.hpp:125
constexpr auto size() const -> size_t
Definition: core.h:477
GLuint buffer
Definition: glcorearb.h:660
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
Definition: format.h:551
FMT_API auto to_decimal(T x) FMT_NOEXCEPT-> decimal_fp< T >
Definition: format-inl.h:2080
FMT_CONSTEXPR void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
Definition: format.h:2111
fallback_uintptr(const void *p)
Definition: format.h:281
uint64 value_type
Definition: GA_PrimCompat.h:29
FMT_INLINE auto make_args_checked(const S &fmt, const remove_reference_t< Args > &...args) -> format_arg_store< buffer_context< Char >, remove_reference_t< Args >...>
Definition: format.h:769
void operator()(T) const
Definition: format.h:2003
int significand_size
Definition: format.h:1602
arg_id_kind kind
Definition: core.h:1949
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1262
FMT_CONSTEXPR auto count_digits_fallback(T n) -> int
Definition: format.h:897
constexpr const_pointer data() const noexcept
Definition: string_view.h:170
#define FMT_END_NAMESPACE
Definition: core.h:229
FMT_CONSTEXPR auto write_padded(OutputIt out, const basic_format_specs< Char > &specs, size_t size, size_t width, F &&f) -> OutputIt
Definition: format.h:1277
#define FMT_THROW(x)
Definition: format.h:93
template auto snprintf_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf) -> int
#define FMT_REDUCE_INT_INSTANTIATIONS
Definition: format.h:148
significand_type significand
Definition: format.h:1209
#define FMT_USE_DOUBLE
Definition: core.h:198
UInt abs_value
Definition: format.h:1453
FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator
Definition: format.h:1985
basic_string_view< char > string_view
Definition: core.h:522
< returns > If no error
Definition: snippets.dox:2
#define FMT_INLINE
Definition: core.h:208
#define FMT_CLASS_API
Definition: core.h:255
constexpr size_type size() const noexcept
Definition: string_view.h:150
auto decimal_point(locale_ref loc) -> Char
Definition: format.h:1017
__attribute__((visibility("default")))
format_int(unsigned long value)
Definition: format.h:2297
auto get_data(std::basic_string< Char > &s) -> Char *
Definition: format.h:331
void try_reserve(size_t new_capacity)
Definition: core.h:827
format_error(const std::string &message)
Definition: format.h:751
auto get_iterator(Buffer &buf) -> decltype(buf.out())
Definition: core.h:965
void copy2(Char *dst, const char *src)
Definition: format.h:1033
GLdouble n
Definition: glcorearb.h:2008
FMT_API auto decimal_point_impl(locale_ref loc) -> Char
Definition: format-inl.h:113
GLfloat f
Definition: glcorearb.h:1926
auto base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >) -> std::back_insert_iterator< Container >
Definition: format.h:394
constexpr auto digits10< uint128_t >() FMT_NOEXCEPT-> int
Definition: format.h:994
auto format(const Locale &loc, format_string< T...> fmt, T &&...args) -> std::string
Definition: format.h:2781
auto str() const -> std::wstring
Definition: format.h:1147
constexpr auto data() const -> const Char *
Definition: core.h:474
class OCIOEXPORT Context
auto promote_float(T value) -> T
Definition: format.h:1256
const wchar_t & const_reference
Definition: format.h:642
auto get_allocator() const -> Allocator
Definition: format.h:692
Definition: core.h:760
Definition: core.h:1935
It begin
Definition: format.h:2495
int128_t
Definition: core.h:395
FMT_BEGIN_DETAIL_NAMESPACE void vformat_to(buffer< Char > &buf, basic_string_view< Char > fmt, basic_format_args< buffer_context< type_identity_t< Char >>> args, locale_ref loc)
Definition: format.h:2624
GLint ref
Definition: glcorearb.h:124
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:545
OIIO_FORCEINLINE OIIO_HOSTDEVICE OUT_TYPE bit_cast(const IN_TYPE &in)
Definition: fmath.h:754
buffer_appender< Char > iterator
Definition: format.h:1977
auto size() const -> size_t
Definition: format.h:1145
format_error(const char *message)
Definition: format.h:750
#define FMT_USE_FLOAT
Definition: core.h:195
FMT_CONSTEXPR auto format_uint(Char *buffer, UInt value, int num_digits, bool upper=false) -> Char *
Definition: format.h:1089
GLuint GLuint end
Definition: glcorearb.h:475
auto snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format-inl.h:2398
FMT_FUNC void print(std::FILE *f, string_view text)
Definition: format-inl.h:2579
auto operator()(T value) -> iterator
Definition: format.h:1965
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition: format.h:2499
void void_t
Definition: core.h:1512
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
FMT_DEPRECATED auto format_to(basic_memory_buffer< char, SIZE, Allocator > &buf, format_string< T...> fmt, T &&...args) -> appender
Definition: format.h:2787
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:325
GLint GLuint mask
Definition: glcorearb.h:124
type
Definition: core.h:1870
FMT_CONSTEXPR auto write(OutputIt out, Char value, const basic_format_specs< Char > &specs, locale_ref loc={}) -> OutputIt
Definition: format.h:1336
static FMT_API constexpr const char left_padding_shifts[]
Definition: format.h:885
format_int(long long value)
Definition: format.h:2295
#define FMT_ICC_VERSION
Definition: format.h:51
constexpr auto base_iterator(Iterator, Iterator it) -> Iterator
Definition: format.h:401
#define FMT_API
Definition: core.h:263
format_int(unsigned long long value)
Definition: format.h:2298
FMT_MSC_WARNING(suppress:4566) const expr unsigned char micro[]
auto capacity() const FMT_NOEXCEPT-> size_t
Definition: core.h:805
FMT_BEGIN_DETAIL_NAMESPACE auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition: core.h:727
GLuint id
Definition: glcorearb.h:655
void try_resize(size_t count)
Definition: core.h:818
detail::fill_t< Char > fill
Definition: core.h:1916
#define FMT_USE_LONG_DOUBLE
Definition: core.h:201
auto compute_width(basic_string_view< char8_type > s) -> size_t
Definition: format.h:545
auto write_significand(OutputIt out, const char *significand, int &significand_size) -> OutputIt
Definition: format.h:1615
bool use_grisu
Definition: core.h:2535
GLuint const GLchar * name
Definition: glcorearb.h:786
FMT_CONSTEXPR auto utf8_decode(const char *s, uint32_t *c, int *e) -> const char *
Definition: format.h:451
IMATH_HOSTDEVICE constexpr int sign(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:33
auto get_significand_size(const big_decimal_fp &fp) -> int
Definition: format.h:1606
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:2533
sign_t sign
Definition: core.h:2531
std::wstring OIIO_UTIL_API utf8_to_utf16(string_view utf8str) noexcept
int precision
Definition: core.h:2529
auto to_uintptr(const void *p) -> fallback_uintptr
Definition: format.h:296
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: format.h:2097
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
constexpr auto make_format_args(const Args &...args) -> format_arg_store< Context, Args...>
Definition: core.h:1719
GLint GLenum GLint x
Definition: glcorearb.h:409
FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition: format.h:429
FMT_CONSTEXPR auto write_char(OutputIt out, Char value, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1327
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
FMT_NORETURN FMT_API void on_error(const char *message)
Definition: format-inl.h:2553
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
Definition: core.h:960
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const basic_format_specs< Char > &specs)
Definition: format.h:1350
GLdouble t
Definition: glad.h:2397
auto operator()(typename basic_format_arg< context >::handle) -> iterator
Definition: format.h:1988
FMT_CONSTEXPR specs_handler(basic_format_specs< Char > &specs, basic_format_parse_context< Char > &parse_ctx, buffer_context< Char > &ctx)
Definition: format.h:2092
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
Definition: format.h:357
std::string grouping
Definition: format.h:999
constexpr auto num_bits< fallback_uintptr >() -> int
Definition: format.h:312
GLint j
Definition: glad.h:2733
auto equal2(const Char *lhs, const char *rhs) -> bool
Definition: format.h:1025
FMT_BEGIN_DETAIL_NAMESPACE void throw_format_error(const char *message)
Definition: format.h:810
FMT_INLINE void assume(bool condition)
Definition: format.h:317
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
void(*)(detail::buffer< char > &, int, const char *) format_func
Definition: format.h:2210
GLenum GLenum dst
Definition: glcorearb.h:1793
basic_string_view< Char > sep
Definition: format.h:2497
auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs< Char > specs, const float_specs &fspecs) -> OutputIt
Definition: format.h:1582
GLenum func
Definition: glcorearb.h:783
#define FMT_CONSTEXPR
Definition: core.h:98
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1302
auto bit_cast(const Source &source) -> Dest
Definition: format.h:261
#define FMT_INC(T)
auto str() const -> std::string
Definition: format.h:2326
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
Definition: format.h:2014
auto write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs) -> OutputIt
Definition: format.h:1313
typename type_identity< T >::type type_identity_t
Definition: core.h:329
auto write_float(OutputIt out, const DecimalFP &fp, const basic_format_specs< Char > &specs, float_specs fspecs, Char decimal_point) -> OutputIt
Definition: format.h:1667
constexpr auto num_bits< uint128_t >() -> int
Definition: format.h:311
Sentinel end
Definition: format.h:2496
auto data() const -> const char *
Definition: format.h:2310
auto code_point_index(basic_string_view< char8_type > s, size_t n) -> size_t
Definition: format.h:557
format_int(int value)
Definition: format.h:2293
static FMT_API constexpr const char right_padding_shifts[]
Definition: format.h:886
buffer_context< Char > & ctx
Definition: format.h:1997
FMT_API void format_system_error(detail::buffer< char > &out, int error_code, const char *message) FMT_NOEXCEPT
Definition: format-inl.h:2542
uint128_t
Definition: core.h:396
FMT_CONSTEXPR auto is_negative(T value) -> bool
Definition: format.h:826
auto ptr(T p) -> const void *
Definition: format.h:2448
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
constexpr auto exponent_mask() -> typename dragonbox::float_info< T >::carrier_uint
Definition: format.h:1218
constexpr auto to_pointer(OutputIt, size_t) -> T *
Definition: format.h:382
auto thousands_sep(locale_ref loc) -> thousands_sep_result< Char >
Definition: format.h:1006
GA_API const UT_StringHolder N
FMT_CONSTEXPR auto code_point_length(const Char *begin) -> int
Definition: core.h:2075
FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t
Definition: format.h:835
basic_memory_buffer(basic_memory_buffer &&other) FMT_NOEXCEPT
Definition: format.h:676
auto vformat(const Locale &loc, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args) -> std::basic_string< Char >
Definition: format.h:2202
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
Definition: core.h:1458
FMT_CONSTEXPR void prefix_append(unsigned &prefix, unsigned value)
Definition: format.h:1447
format_int(unsigned value)
Definition: format.h:2296
**If you just want to fire and args
Definition: thread.h:609
bytes(string_view data)
Definition: format.h:2465
GLint GLsizei width
Definition: glcorearb.h:103
#define FMT_MSC_DEFAULT
Definition: format.h:75
GLdouble GLdouble GLdouble top
Definition: glad.h:2817
unsigned prefix
Definition: format.h:1454
Definition: core.h:982
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: format.h:2102
#define SIZE
Definition: simple.C:41
void resize(size_t count)
Definition: format.h:698
#define FMT_NOEXCEPT
Definition: core.h:153
FMT_CONSTEXPR20 auto count_digits(uint64_t n) -> int
Definition: format.h:919
FMT_API void report_error(format_func func, int error_code, const char *message) FMT_NOEXCEPT
Definition: format-inl.h:79
#define FMT_FORMAT_AS(Type, Base)
Definition: format.h:2349
const basic_format_specs< Char > & specs
Definition: format.h:1981
#define FMT_CLANG_VERSION
Definition: core.h:24
Definition: core.h:1131
basic_memory_buffer(const Allocator &alloc=Allocator())
Definition: format.h:644
FMT_CONSTEXPR auto check_cstring_type_spec(Char spec, ErrorHandler &&eh={}) -> bool
Definition: core.h:2584
FMT_CONSTEXPR auto get_arg(Context &ctx, ID id) -> typename Context::format_arg
Definition: format.h:2061
void operator()(typename basic_format_arg< buffer_context< Char >>::handle h) const
Definition: format.h:1999
#define FMT_ASSERT(condition, message)
Definition: core.h:365
size_t padding
Definition: format.h:1348
GLboolean r
Definition: glcorearb.h:1222
#define FMT_BEGIN_NAMESPACE
Definition: core.h:234
#define const
Definition: zconf.h:214
template auto format_float< double >(double value, int precision, float_specs specs, buffer< char > &buf) -> int
auto compute_width(basic_string_view< Char > s) -> size_t
Definition: format.h:508
iterator out
Definition: format.h:1980
#define FMT_POWERS_OF_10(factor)
Definition: format.h:851
FMT_END_DETAIL_NAMESPACE FMT_API auto vsystem_error(int error_code, string_view format_str, format_args args) -> std::system_error
Definition: format-inl.h:132
Definition: core.h:1883
void append(const U *begin, const U *end)
Definition: format.h:577
auto write_exponent(int exp, It it) -> It
Definition: format.h:1227
constexpr auto compile_string_to_view(detail::std_string_view< Char > s) -> basic_string_view< Char >
Definition: format.h:802
#define FMT_OVERRIDE
Definition: core.h:123
auto size() const FMT_NOEXCEPT-> size_t
Definition: core.h:802
FMT_API void report_system_error(int error_code, const char *message) FMT_NOEXCEPT
Definition: format-inl.h:2557
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f)
Definition: format.h:484
constexpr auto reserve(Iterator &it, size_t) -> Iterator &
Definition: format.h:373
locale_ref loc
Definition: format.h:1963
ImageBuf OIIO_API zero(ROI roi, int nthreads=0)
#define FMT_MODULE_EXPORT_BEGIN
Definition: core.h:241
type
Definition: core.h:1059
void grow(size_t size) final FMT_OVERRIDE
Definition: format.h:712
auto is_big_endian() -> bool
Definition: format.h:268
unsigned int uint
Definition: SYS_Types.h:45
std::integral_constant< bool, B > bool_constant
Definition: core.h:323
#define FMT_NOINLINE
Definition: format.h:69
PXR_NAMESPACE_OPEN_SCOPE typedef unsigned char uchar
Definition: inttypes.h:58
float_format format
Definition: core.h:2530
const char * significand
Definition: format.h:1601
auto format(void *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:2373
FMT_API void format_error_code(buffer< char > &out, int error_code, string_view message) FMT_NOEXCEPT
Definition: format-inl.h:56
unsigned char uchar
Definition: SYS_Types.h:42
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> float_specs
Definition: core.h:2540
type
Definition: core.h:1874
FMT_CONSTEXPR auto format(const Char *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:2381
GLint GLsizei count
Definition: glcorearb.h:405
Definition: format.h:895
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
Definition: core.h:2592
Definition: format.h:2459
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Definition: format.h:2559
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition: core.h:2509
T * checked_ptr
Definition: format.h:346
auto operator=(basic_memory_buffer &&other) FMT_NOEXCEPT-> basic_memory_buffer &
Definition: format.h:683
size_t size
Definition: format.h:1347
template auto snprintf_float< double >(double value, int precision, float_specs specs, buffer< char > &buf) -> int
FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int
Definition: format.h:2054
format_int(long value)
Definition: format.h:2294
GLenum src
Definition: glcorearb.h:1793
template FMT_API auto thousands_sep_impl< wchar_t >(locale_ref) -> thousands_sep_result< wchar_t >
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:483