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