blob: 1bb24a529687c561c8750c63bc72f57e1b8ddbfa [file] [log] [blame]
Thomas Psota6bf79382019-09-16 16:42:15 +02001/*
2 Formatting library for C++
3
4 Copyright (c) 2012 - present, Victor Zverovich
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef FMT_FORMAT_H_
29#define FMT_FORMAT_H_
30
31#include <algorithm>
32#include <cassert>
33#include <cmath>
34#include <cstring>
35#include <limits>
36#include <memory>
37#include <stdexcept>
38#include <stdint.h>
39
40#ifdef __clang__
41# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
42#else
43# define FMT_CLANG_VERSION 0
44#endif
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#include "core.h"
61
62#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION
63# pragma GCC diagnostic push
64
65// Disable the warning about declaration shadowing because it affects too
66// many valid cases.
67# pragma GCC diagnostic ignored "-Wshadow"
68
69// Disable the warning about nonliteral format strings because we construct
70// them dynamically when falling back to snprintf for FP formatting.
71# pragma GCC diagnostic ignored "-Wformat-nonliteral"
72#endif
73
74# if FMT_CLANG_VERSION
75# pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
76# endif
77
78#ifdef _SECURE_SCL
79# define FMT_SECURE_SCL _SECURE_SCL
80#else
81# define FMT_SECURE_SCL 0
82#endif
83
84#if FMT_SECURE_SCL
85# include <iterator>
86#endif
87
88#ifdef __has_builtin
89# define FMT_HAS_BUILTIN(x) __has_builtin(x)
90#else
91# define FMT_HAS_BUILTIN(x) 0
92#endif
93
94#ifdef __GNUC_LIBSTD__
95# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
96#endif
97
98#ifndef FMT_THROW
99# if FMT_EXCEPTIONS
100# if FMT_MSC_VER
101FMT_BEGIN_NAMESPACE
102namespace internal {
103template <typename Exception>
104inline void do_throw(const Exception &x) {
105 // Silence unreachable code warnings in MSVC because these are nearly
106 // impossible to fix in a generic code.
107 volatile bool b = true;
108 if (b)
109 throw x;
110}
111}
112FMT_END_NAMESPACE
113# define FMT_THROW(x) fmt::internal::do_throw(x)
114# else
115# define FMT_THROW(x) throw x
116# endif
117# else
118# define FMT_THROW(x) do { static_cast<void>(sizeof(x)); assert(false); } while(false);
119# endif
120#endif
121
122#ifndef FMT_USE_USER_DEFINED_LITERALS
123// For Intel's compiler and NVIDIA's compiler both it and the system gcc/msc
124// must support UDLs.
125# if (FMT_HAS_FEATURE(cxx_user_literals) || \
126 FMT_GCC_VERSION >= 407 || FMT_MSC_VER >= 1900) && \
127 (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || \
128 FMT_ICC_VERSION >= 1500 || FMT_CUDA_VERSION >= 700)
129# define FMT_USE_USER_DEFINED_LITERALS 1
130# else
131# define FMT_USE_USER_DEFINED_LITERALS 0
132# endif
133#endif
134
135// EDG C++ Front End based compilers (icc, nvcc) do not currently support UDL
136// templates.
137#if FMT_USE_USER_DEFINED_LITERALS && \
138 FMT_ICC_VERSION == 0 && \
139 FMT_CUDA_VERSION == 0 && \
140 ((FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L) || \
141 (defined(FMT_CLANG_VERSION) && FMT_CLANG_VERSION >= 304))
142# define FMT_UDL_TEMPLATE 1
143#else
144# define FMT_UDL_TEMPLATE 0
145#endif
146
147#ifndef FMT_USE_EXTERN_TEMPLATES
148# ifndef FMT_HEADER_ONLY
149# define FMT_USE_EXTERN_TEMPLATES \
150 ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \
151 (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
152# else
153# define FMT_USE_EXTERN_TEMPLATES 0
154# endif
155#endif
156
157#if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \
158 FMT_MSC_VER >= 1600
159# define FMT_USE_TRAILING_RETURN 1
160#else
161# define FMT_USE_TRAILING_RETURN 0
162#endif
163
164#ifndef FMT_USE_GRISU
165# define FMT_USE_GRISU 0
166//# define FMT_USE_GRISU std::numeric_limits<double>::is_iec559
167#endif
168
169// __builtin_clz is broken in clang with Microsoft CodeGen:
170// https://github.com/fmtlib/fmt/issues/519
171#ifndef _MSC_VER
172# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
173# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
174# endif
175
176# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
177# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
178# endif
179#endif
180
181// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
182// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
183// MSVC intrinsics if the clz and clzll builtins are not available.
184#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
185# include <intrin.h> // _BitScanReverse, _BitScanReverse64
186
187FMT_BEGIN_NAMESPACE
188namespace internal {
189// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
190# ifndef __clang__
191# pragma intrinsic(_BitScanReverse)
192# endif
193inline uint32_t clz(uint32_t x) {
194 unsigned long r = 0;
195 _BitScanReverse(&r, x);
196
197 assert(x != 0);
198 // Static analysis complains about using uninitialized data
199 // "r", but the only way that can happen is if "x" is 0,
200 // which the callers guarantee to not happen.
201# pragma warning(suppress: 6102)
202 return 31 - r;
203}
204# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
205
206# if defined(_WIN64) && !defined(__clang__)
207# pragma intrinsic(_BitScanReverse64)
208# endif
209
210inline uint32_t clzll(uint64_t x) {
211 unsigned long r = 0;
212# ifdef _WIN64
213 _BitScanReverse64(&r, x);
214# else
215 // Scan the high 32 bits.
216 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
217 return 63 - (r + 32);
218
219 // Scan the low 32 bits.
220 _BitScanReverse(&r, static_cast<uint32_t>(x));
221# endif
222
223 assert(x != 0);
224 // Static analysis complains about using uninitialized data
225 // "r", but the only way that can happen is if "x" is 0,
226 // which the callers guarantee to not happen.
227# pragma warning(suppress: 6102)
228 return 63 - r;
229}
230# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
231}
232FMT_END_NAMESPACE
233#endif
234
235FMT_BEGIN_NAMESPACE
236namespace internal {
237
238// An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't produce
239// undefined behavior (e.g. due to type aliasing).
240// Example: uint64_t d = bit_cast<uint64_t>(2.718);
241template <typename Dest, typename Source>
242inline Dest bit_cast(const Source& source) {
243 static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
244 Dest dest;
245 std::memcpy(&dest, &source, sizeof(dest));
246 return dest;
247}
248
249// An implementation of begin and end for pre-C++11 compilers such as gcc 4.
250template <typename C>
251FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin()) {
252 return c.begin();
253}
254template <typename T, std::size_t N>
255FMT_CONSTEXPR T *begin(T (&array)[N]) FMT_NOEXCEPT { return array; }
256template <typename C>
257FMT_CONSTEXPR auto end(const C &c) -> decltype(c.end()) { return c.end(); }
258template <typename T, std::size_t N>
259FMT_CONSTEXPR T *end(T (&array)[N]) FMT_NOEXCEPT { return array + N; }
260
261// For std::result_of in gcc 4.4.
262template <typename Result>
263struct function {
264 template <typename T>
265 struct result { typedef Result type; };
266};
267
268struct dummy_int {
269 int data[2];
270 operator int() const { return 0; }
271};
272typedef std::numeric_limits<internal::dummy_int> fputil;
273
274// Dummy implementations of system functions called if the latter are not
275// available.
276inline dummy_int isinf(...) { return dummy_int(); }
277inline dummy_int _finite(...) { return dummy_int(); }
278inline dummy_int isnan(...) { return dummy_int(); }
279inline dummy_int _isnan(...) { return dummy_int(); }
280
281template <typename Allocator>
282typename Allocator::value_type *allocate(Allocator& alloc, std::size_t n) {
283#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
284 return std::allocator_traits<Allocator>::allocate(alloc, n);
285#else
286 return alloc.allocate(n);
287#endif
288}
289
290// A helper function to suppress bogus "conditional expression is constant"
291// warnings.
292template <typename T>
293inline T const_check(T value) { return value; }
294} // namespace internal
295FMT_END_NAMESPACE
296
297namespace std {
298// Standard permits specialization of std::numeric_limits. This specialization
299// is used to resolve ambiguity between isinf and std::isinf in glibc:
300// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
301// and the same for isnan.
302template <>
303class numeric_limits<fmt::internal::dummy_int> :
304 public std::numeric_limits<int> {
305 public:
306 // Portable version of isinf.
307 template <typename T>
308 static bool isinfinity(T x) {
309 using namespace fmt::internal;
310 // The resolution "priority" is:
311 // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
312 if (const_check(sizeof(isinf(x)) != sizeof(fmt::internal::dummy_int)))
313 return isinf(x) != 0;
314 return !_finite(static_cast<double>(x));
315 }
316
317 // Portable version of isnan.
318 template <typename T>
319 static bool isnotanumber(T x) {
320 using namespace fmt::internal;
321 if (const_check(sizeof(isnan(x)) != sizeof(fmt::internal::dummy_int)))
322 return isnan(x) != 0;
323 return _isnan(static_cast<double>(x)) != 0;
324 }
325};
326} // namespace std
327
328FMT_BEGIN_NAMESPACE
329template <typename Range>
330class basic_writer;
331
332template <typename OutputIt, typename T = typename OutputIt::value_type>
333class output_range {
334 private:
335 OutputIt it_;
336
337 // Unused yet.
338 typedef void sentinel;
339 sentinel end() const;
340
341 public:
342 typedef OutputIt iterator;
343 typedef T value_type;
344
345 explicit output_range(OutputIt it): it_(it) {}
346 OutputIt begin() const { return it_; }
347};
348
349// A range where begin() returns back_insert_iterator.
350template <typename Container>
351class back_insert_range:
352 public output_range<std::back_insert_iterator<Container>> {
353 typedef output_range<std::back_insert_iterator<Container>> base;
354 public:
355 typedef typename Container::value_type value_type;
356
357 back_insert_range(Container &c): base(std::back_inserter(c)) {}
358 back_insert_range(typename base::iterator it): base(it) {}
359};
360
361typedef basic_writer<back_insert_range<internal::buffer>> writer;
362typedef basic_writer<back_insert_range<internal::wbuffer>> wwriter;
363
364/** A formatting error such as invalid format string. */
365class format_error : public std::runtime_error {
366 public:
367 explicit format_error(const char *message)
368 : std::runtime_error(message) {}
369
370 explicit format_error(const std::string &message)
371 : std::runtime_error(message) {}
372};
373
374namespace internal {
375
376#if FMT_SECURE_SCL
377template <typename T>
378struct checked { typedef stdext::checked_array_iterator<T*> type; };
379
380// Make a checked iterator to avoid warnings on MSVC.
381template <typename T>
382inline stdext::checked_array_iterator<T*> make_checked(T *p, std::size_t size) {
383 return {p, size};
384}
385#else
386template <typename T>
387struct checked { typedef T *type; };
388template <typename T>
389inline T *make_checked(T *p, std::size_t) { return p; }
390#endif
391
392template <typename T>
393template <typename U>
394void basic_buffer<T>::append(const U *begin, const U *end) {
395 std::size_t new_size = size_ + internal::to_unsigned(end - begin);
396 reserve(new_size);
397 std::uninitialized_copy(begin, end,
398 internal::make_checked(ptr_, capacity_) + size_);
399 size_ = new_size;
400}
401} // namespace internal
402
403// C++20 feature test, since r346892 Clang considers char8_t a fundamental
404// type in this mode. If this is the case __cpp_char8_t will be defined.
405#if !defined(__cpp_char8_t)
406// A UTF-8 code unit type.
407enum char8_t: unsigned char {};
408#endif
409
410// A UTF-8 string view.
411class u8string_view : public basic_string_view<char8_t> {
412 public:
413 typedef char8_t char_type;
414
415 u8string_view(const char *s):
416 basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s)) {}
417 u8string_view(const char *s, size_t count) FMT_NOEXCEPT:
418 basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s), count) {}
419};
420
421#if FMT_USE_USER_DEFINED_LITERALS
422inline namespace literals {
423inline u8string_view operator"" _u(const char *s, std::size_t n) {
424 return {s, n};
425}
426}
427#endif
428
429// The number of characters to store in the basic_memory_buffer object itself
430// to avoid dynamic memory allocation.
431enum { inline_buffer_size = 500 };
432
433/**
434 \rst
435 A dynamically growing memory buffer for trivially copyable/constructible types
436 with the first ``SIZE`` elements stored in the object itself.
437
438 You can use one of the following typedefs for common character types:
439
440 +----------------+------------------------------+
441 | Type | Definition |
442 +================+==============================+
443 | memory_buffer | basic_memory_buffer<char> |
444 +----------------+------------------------------+
445 | wmemory_buffer | basic_memory_buffer<wchar_t> |
446 +----------------+------------------------------+
447
448 **Example**::
449
450 fmt::memory_buffer out;
451 format_to(out, "The answer is {}.", 42);
452
453 This will append the following output to the ``out`` object:
454
455 .. code-block:: none
456
457 The answer is 42.
458
459 The output can be converted to an ``std::string`` with ``to_string(out)``.
460 \endrst
461 */
462template <typename T, std::size_t SIZE = inline_buffer_size,
463 typename Allocator = std::allocator<T> >
464class basic_memory_buffer: private Allocator, public internal::basic_buffer<T> {
465 private:
466 T store_[SIZE];
467
468 // Deallocate memory allocated by the buffer.
469 void deallocate() {
470 T* data = this->data();
471 if (data != store_) Allocator::deallocate(data, this->capacity());
472 }
473
474 protected:
475 void grow(std::size_t size) FMT_OVERRIDE;
476
477 public:
478 typedef T value_type;
479 typedef const T &const_reference;
480
481 explicit basic_memory_buffer(const Allocator &alloc = Allocator())
482 : Allocator(alloc) {
483 this->set(store_, SIZE);
484 }
485 ~basic_memory_buffer() { deallocate(); }
486
487 private:
488 // Move data from other to this buffer.
489 void move(basic_memory_buffer &other) {
490 Allocator &this_alloc = *this, &other_alloc = other;
491 this_alloc = std::move(other_alloc);
492 T* data = other.data();
493 std::size_t size = other.size(), capacity = other.capacity();
494 if (data == other.store_) {
495 this->set(store_, capacity);
496 std::uninitialized_copy(other.store_, other.store_ + size,
497 internal::make_checked(store_, capacity));
498 } else {
499 this->set(data, capacity);
500 // Set pointer to the inline array so that delete is not called
501 // when deallocating.
502 other.set(other.store_, 0);
503 }
504 this->resize(size);
505 }
506
507 public:
508 /**
509 \rst
510 Constructs a :class:`fmt::basic_memory_buffer` object moving the content
511 of the other object to it.
512 \endrst
513 */
514 basic_memory_buffer(basic_memory_buffer &&other) {
515 move(other);
516 }
517
518 /**
519 \rst
520 Moves the content of the other ``basic_memory_buffer`` object to this one.
521 \endrst
522 */
523 basic_memory_buffer &operator=(basic_memory_buffer &&other) {
524 assert(this != &other);
525 deallocate();
526 move(other);
527 return *this;
528 }
529
530 // Returns a copy of the allocator associated with this buffer.
531 Allocator get_allocator() const { return *this; }
532};
533
534template <typename T, std::size_t SIZE, typename Allocator>
535void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) {
536 std::size_t old_capacity = this->capacity();
537 std::size_t new_capacity = old_capacity + old_capacity / 2;
538 if (size > new_capacity)
539 new_capacity = size;
540 T *old_data = this->data();
541 T *new_data = internal::allocate<Allocator>(*this, new_capacity);
542 // The following code doesn't throw, so the raw pointer above doesn't leak.
543 std::uninitialized_copy(old_data, old_data + this->size(),
544 internal::make_checked(new_data, new_capacity));
545 this->set(new_data, new_capacity);
546 // deallocate must not throw according to the standard, but even if it does,
547 // the buffer already uses the new storage and will deallocate it in
548 // destructor.
549 if (old_data != store_)
550 Allocator::deallocate(old_data, old_capacity);
551}
552
553typedef basic_memory_buffer<char> memory_buffer;
554typedef basic_memory_buffer<wchar_t> wmemory_buffer;
555
556namespace internal {
557
558template <typename Char>
559struct char_traits;
560
561template <>
562struct char_traits<char> {
563 // Formats a floating-point number.
564 template <typename T>
565 FMT_API static int format_float(char *buffer, std::size_t size,
566 const char *format, int precision, T value);
567};
568
569template <>
570struct char_traits<wchar_t> {
571 template <typename T>
572 FMT_API static int format_float(wchar_t *buffer, std::size_t size,
573 const wchar_t *format, int precision, T value);
574};
575
576#if FMT_USE_EXTERN_TEMPLATES
577extern template int char_traits<char>::format_float<double>(
578 char *buffer, std::size_t size, const char* format, int precision,
579 double value);
580extern template int char_traits<char>::format_float<long double>(
581 char *buffer, std::size_t size, const char* format, int precision,
582 long double value);
583
584extern template int char_traits<wchar_t>::format_float<double>(
585 wchar_t *buffer, std::size_t size, const wchar_t* format, int precision,
586 double value);
587extern template int char_traits<wchar_t>::format_float<long double>(
588 wchar_t *buffer, std::size_t size, const wchar_t* format, int precision,
589 long double value);
590#endif
591
592template <typename Container>
593inline typename std::enable_if<
594 is_contiguous<Container>::value,
595 typename checked<typename Container::value_type>::type>::type
596 reserve(std::back_insert_iterator<Container> &it, std::size_t n) {
597 Container &c = internal::get_container(it);
598 std::size_t size = c.size();
599 c.resize(size + n);
600 return make_checked(&c[size], n);
601}
602
603template <typename Iterator>
604inline Iterator &reserve(Iterator &it, std::size_t) { return it; }
605
606template <typename Char>
607class null_terminating_iterator;
608
609template <typename Char>
610FMT_CONSTEXPR_DECL const Char *pointer_from(null_terminating_iterator<Char> it);
611
612// An output iterator that counts the number of objects written to it and
613// discards them.
614template <typename T>
615class counting_iterator {
616 private:
617 std::size_t count_;
618 mutable T blackhole_;
619
620 public:
621 typedef std::output_iterator_tag iterator_category;
622 typedef T value_type;
623 typedef std::ptrdiff_t difference_type;
624 typedef T* pointer;
625 typedef T& reference;
626 typedef counting_iterator _Unchecked_type; // Mark iterator as checked.
627
628 counting_iterator(): count_(0) {}
629
630 std::size_t count() const { return count_; }
631
632 counting_iterator& operator++() {
633 ++count_;
634 return *this;
635 }
636
637 counting_iterator operator++(int) {
638 auto it = *this;
639 ++*this;
640 return it;
641 }
642
643 T &operator*() const { return blackhole_; }
644};
645
646template <typename OutputIt>
647class truncating_iterator_base {
648 protected:
649 OutputIt out_;
650 std::size_t limit_;
651 std::size_t count_;
652
653 truncating_iterator_base(OutputIt out, std::size_t limit)
654 : out_(out), limit_(limit), count_(0) {}
655
656 public:
657 typedef std::output_iterator_tag iterator_category;
658 typedef void difference_type;
659 typedef void pointer;
660 typedef void reference;
661 typedef truncating_iterator_base _Unchecked_type; // Mark iterator as checked.
662
663 OutputIt base() const { return out_; }
664 std::size_t count() const { return count_; }
665};
666
667// An output iterator that truncates the output and counts the number of objects
668// written to it.
669template <typename OutputIt, typename Enable = typename std::is_void<
670 typename std::iterator_traits<OutputIt>::value_type>::type>
671class truncating_iterator;
672
673template <typename OutputIt>
674class truncating_iterator<OutputIt, std::false_type>:
675 public truncating_iterator_base<OutputIt> {
676 typedef std::iterator_traits<OutputIt> traits;
677
678 mutable typename traits::value_type blackhole_;
679
680 public:
681 typedef typename traits::value_type value_type;
682
683 truncating_iterator(OutputIt out, std::size_t limit)
684 : truncating_iterator_base<OutputIt>(out, limit) {}
685
686 truncating_iterator& operator++() {
687 if (this->count_++ < this->limit_)
688 ++this->out_;
689 return *this;
690 }
691
692 truncating_iterator operator++(int) {
693 auto it = *this;
694 ++*this;
695 return it;
696 }
697
698 value_type& operator*() const {
699 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
700 }
701};
702
703template <typename OutputIt>
704class truncating_iterator<OutputIt, std::true_type>:
705 public truncating_iterator_base<OutputIt> {
706 public:
707 typedef typename OutputIt::container_type::value_type value_type;
708
709 truncating_iterator(OutputIt out, std::size_t limit)
710 : truncating_iterator_base<OutputIt>(out, limit) {}
711
712 truncating_iterator& operator=(value_type val) {
713 if (this->count_++ < this->limit_)
714 this->out_ = val;
715 return *this;
716 }
717
718 truncating_iterator& operator++() { return *this; }
719 truncating_iterator& operator++(int) { return *this; }
720 truncating_iterator& operator*() { return *this; }
721};
722
723// Returns true if value is negative, false otherwise.
724// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
725template <typename T>
726FMT_CONSTEXPR typename std::enable_if<
727 std::numeric_limits<T>::is_signed, bool>::type is_negative(T value) {
728 return value < 0;
729}
730template <typename T>
731FMT_CONSTEXPR typename std::enable_if<
732 !std::numeric_limits<T>::is_signed, bool>::type is_negative(T) {
733 return false;
734}
735
736template <typename T>
737struct int_traits {
738 // Smallest of uint32_t and uint64_t that is large enough to represent
739 // all values of T.
740 typedef typename std::conditional<
741 std::numeric_limits<T>::digits <= 32, uint32_t, uint64_t>::type main_type;
742};
743
744// Static data is placed in this class template to allow header-only
745// configuration.
746template <typename T = void>
747struct FMT_API basic_data {
748 static const uint32_t POWERS_OF_10_32[];
749 static const uint32_t ZERO_OR_POWERS_OF_10_32[];
750 static const uint64_t ZERO_OR_POWERS_OF_10_64[];
751 static const uint64_t POW10_SIGNIFICANDS[];
752 static const int16_t POW10_EXPONENTS[];
753 static const char DIGITS[];
754 static const char FOREGROUND_COLOR[];
755 static const char BACKGROUND_COLOR[];
756 static const char RESET_COLOR[];
757 static const wchar_t WRESET_COLOR[];
758};
759
760#if FMT_USE_EXTERN_TEMPLATES
761extern template struct basic_data<void>;
762#endif
763
764typedef basic_data<> data;
765
766#ifdef FMT_BUILTIN_CLZLL
767// Returns the number of decimal digits in n. Leading zeros are not counted
768// except for n == 0 in which case count_digits returns 1.
769inline int count_digits(uint64_t n) {
770 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
771 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
772 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
773 return t - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1;
774}
775#else
776// Fallback version of count_digits used when __builtin_clz is not available.
777inline int count_digits(uint64_t n) {
778 int count = 1;
779 for (;;) {
780 // Integer division is slow so do it for a group of four digits instead
781 // of for every digit. The idea comes from the talk by Alexandrescu
782 // "Three Optimization Tips for C++". See speed-test for a comparison.
783 if (n < 10) return count;
784 if (n < 100) return count + 1;
785 if (n < 1000) return count + 2;
786 if (n < 10000) return count + 3;
787 n /= 10000u;
788 count += 4;
789 }
790}
791#endif
792
793template <typename Char>
794inline size_t count_code_points(basic_string_view<Char> s) { return s.size(); }
795
796// Counts the number of code points in a UTF-8 string.
797FMT_API size_t count_code_points(basic_string_view<char8_t> s);
798
799inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); }
800
801template <typename InputIt, typename OutChar>
802struct needs_conversion: std::integral_constant<bool,
803 std::is_same<
804 typename std::iterator_traits<InputIt>::value_type, char>::value &&
805 std::is_same<OutChar, char8_t>::value> {};
806
807template <typename OutChar, typename InputIt, typename OutputIt>
808typename std::enable_if<
809 !needs_conversion<InputIt, OutChar>::value, OutputIt>::type
810 copy_str(InputIt begin, InputIt end, OutputIt it) {
811 return std::copy(begin, end, it);
812}
813
814template <typename OutChar, typename InputIt, typename OutputIt>
815typename std::enable_if<
816 needs_conversion<InputIt, OutChar>::value, OutputIt>::type
817 copy_str(InputIt begin, InputIt end, OutputIt it) {
818 return std::transform(begin, end, it, to_char8_t);
819}
820
821#if FMT_HAS_CPP_ATTRIBUTE(always_inline)
822# define FMT_ALWAYS_INLINE __attribute__((always_inline))
823#else
824# define FMT_ALWAYS_INLINE
825#endif
826
827template <typename Handler>
828inline char *lg(uint32_t n, Handler h) FMT_ALWAYS_INLINE;
829
830// Computes g = floor(log10(n)) and calls h.on<g>(n);
831template <typename Handler>
832inline char *lg(uint32_t n, Handler h) {
833 return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n)
834 : n < 1000000
835 ? n < 10000 ? n < 1000 ? h.template on<2>(n)
836 : h.template on<3>(n)
837 : n < 100000 ? h.template on<4>(n)
838 : h.template on<5>(n)
839 : n < 100000000 ? n < 10000000 ? h.template on<6>(n)
840 : h.template on<7>(n)
841 : n < 1000000000 ? h.template on<8>(n)
842 : h.template on<9>(n);
843}
844
845// An lg handler that formats a decimal number.
846// Usage: lg(n, decimal_formatter(buffer));
847class decimal_formatter {
848 private:
849 char *buffer_;
850
851 void write_pair(unsigned N, uint32_t index) {
852 std::memcpy(buffer_ + N, data::DIGITS + index * 2, 2);
853 }
854
855 public:
856 explicit decimal_formatter(char *buf) : buffer_(buf) {}
857
858 template <unsigned N> char *on(uint32_t u) {
859 if (N == 0) {
860 *buffer_ = static_cast<char>(u) + '0';
861 } else if (N == 1) {
862 write_pair(0, u);
863 } else {
864 // The idea of using 4.32 fixed-point numbers is based on
865 // https://github.com/jeaiii/itoa
866 unsigned n = N - 1;
867 unsigned a = n / 5 * n * 53 / 16;
868 uint64_t t = ((1ULL << (32 + a)) /
869 data::ZERO_OR_POWERS_OF_10_32[n] + 1 - n / 9);
870 t = ((t * u) >> a) + n / 5 * 4;
871 write_pair(0, t >> 32);
872 for (unsigned i = 2; i < N; i += 2) {
873 t = 100ULL * static_cast<uint32_t>(t);
874 write_pair(i, t >> 32);
875 }
876 if (N % 2 == 0) {
877 buffer_[N] = static_cast<char>(
878 (10ULL * static_cast<uint32_t>(t)) >> 32) + '0';
879 }
880 }
881 return buffer_ += N + 1;
882 }
883};
884
885// An lg handler that formats a decimal number with a terminating null.
886class decimal_formatter_null : public decimal_formatter {
887 public:
888 explicit decimal_formatter_null(char *buf) : decimal_formatter(buf) {}
889
890 template <unsigned N> char *on(uint32_t u) {
891 char *buf = decimal_formatter::on<N>(u);
892 *buf = '\0';
893 return buf;
894 }
895};
896
897#ifdef FMT_BUILTIN_CLZ
898// Optional version of count_digits for better performance on 32-bit platforms.
899inline int count_digits(uint32_t n) {
900 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
901 return t - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1;
902}
903#endif
904
905// A functor that doesn't add a thousands separator.
906struct no_thousands_sep {
907 typedef char char_type;
908
909 template <typename Char>
910 void operator()(Char *) {}
911
912 enum { size = 0 };
913};
914
915// A functor that adds a thousands separator.
916template <typename Char>
917class add_thousands_sep {
918 private:
919 basic_string_view<Char> sep_;
920
921 // Index of a decimal digit with the least significant digit having index 0.
922 unsigned digit_index_;
923
924 public:
925 typedef Char char_type;
926
927 explicit add_thousands_sep(basic_string_view<Char> sep)
928 : sep_(sep), digit_index_(0) {}
929
930 void operator()(Char *&buffer) {
931 if (++digit_index_ % 3 != 0)
932 return;
933 buffer -= sep_.size();
934 std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
935 internal::make_checked(buffer, sep_.size()));
936 }
937
938 enum { size = 1 };
939};
940
941template <typename Char>
942FMT_API Char thousands_sep_impl(locale_ref loc);
943
944template <typename Char>
945inline Char thousands_sep(locale_ref loc) {
946 return Char(thousands_sep_impl<char>(loc));
947}
948
949template <>
950inline wchar_t thousands_sep(locale_ref loc) {
951 return thousands_sep_impl<wchar_t>(loc);
952}
953
954// Formats a decimal unsigned integer value writing into buffer.
955// thousands_sep is a functor that is called after writing each char to
956// add a thousands separator if necessary.
957template <typename UInt, typename Char, typename ThousandsSep>
958inline Char *format_decimal(Char *buffer, UInt value, int num_digits,
959 ThousandsSep thousands_sep) {
960 FMT_ASSERT(num_digits >= 0, "invalid digit count");
961 buffer += num_digits;
962 Char *end = buffer;
963 while (value >= 100) {
964 // Integer division is slow so do it for a group of two digits instead
965 // of for every digit. The idea comes from the talk by Alexandrescu
966 // "Three Optimization Tips for C++". See speed-test for a comparison.
967 unsigned index = static_cast<unsigned>((value % 100) * 2);
968 value /= 100;
969 *--buffer = static_cast<Char>(data::DIGITS[index + 1]);
970 thousands_sep(buffer);
971 *--buffer = static_cast<Char>(data::DIGITS[index]);
972 thousands_sep(buffer);
973 }
974 if (value < 10) {
975 *--buffer = static_cast<Char>('0' + value);
976 return end;
977 }
978 unsigned index = static_cast<unsigned>(value * 2);
979 *--buffer = static_cast<Char>(data::DIGITS[index + 1]);
980 thousands_sep(buffer);
981 *--buffer = static_cast<Char>(data::DIGITS[index]);
982 return end;
983}
984
985template <typename OutChar, typename UInt, typename Iterator,
986 typename ThousandsSep>
987inline Iterator format_decimal(
988 Iterator out, UInt value, int num_digits, ThousandsSep sep) {
989 FMT_ASSERT(num_digits >= 0, "invalid digit count");
990 typedef typename ThousandsSep::char_type char_type;
991 // Buffer should be large enough to hold all digits (<= digits10 + 1).
992 enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
993 FMT_ASSERT(ThousandsSep::size <= 1, "invalid separator");
994 char_type buffer[max_size + max_size / 3];
995 auto end = format_decimal(buffer, value, num_digits, sep);
996 return internal::copy_str<OutChar>(buffer, end, out);
997}
998
999template <typename OutChar, typename It, typename UInt>
1000inline It format_decimal(It out, UInt value, int num_digits) {
1001 return format_decimal<OutChar>(out, value, num_digits, no_thousands_sep());
1002}
1003
1004template <unsigned BASE_BITS, typename Char, typename UInt>
1005inline Char *format_uint(Char *buffer, UInt value, int num_digits,
1006 bool upper = false) {
1007 buffer += num_digits;
1008 Char *end = buffer;
1009 do {
1010 const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1011 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1012 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1013 : digits[digit]);
1014 } while ((value >>= BASE_BITS) != 0);
1015 return end;
1016}
1017
1018template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1019inline It format_uint(It out, UInt value, int num_digits,
1020 bool upper = false) {
1021 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1)
1022 // and null.
1023 char buffer[std::numeric_limits<UInt>::digits / BASE_BITS + 2];
1024 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1025 return internal::copy_str<Char>(buffer, buffer + num_digits, out);
1026}
1027
1028#ifndef _WIN32
1029# define FMT_USE_WINDOWS_H 0
1030#elif !defined(FMT_USE_WINDOWS_H)
1031# define FMT_USE_WINDOWS_H 1
1032#endif
1033
1034// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
1035// All the functionality that relies on it will be disabled too.
1036#if FMT_USE_WINDOWS_H
1037// A converter from UTF-8 to UTF-16.
1038// It is only provided for Windows since other systems support UTF-8 natively.
1039class utf8_to_utf16 {
1040 private:
1041 wmemory_buffer buffer_;
1042
1043 public:
1044 FMT_API explicit utf8_to_utf16(string_view s);
1045 operator wstring_view() const { return wstring_view(&buffer_[0], size()); }
1046 size_t size() const { return buffer_.size() - 1; }
1047 const wchar_t *c_str() const { return &buffer_[0]; }
1048 std::wstring str() const { return std::wstring(&buffer_[0], size()); }
1049};
1050
1051// A converter from UTF-16 to UTF-8.
1052// It is only provided for Windows since other systems support UTF-8 natively.
1053class utf16_to_utf8 {
1054 private:
1055 memory_buffer buffer_;
1056
1057 public:
1058 utf16_to_utf8() {}
1059 FMT_API explicit utf16_to_utf8(wstring_view s);
1060 operator string_view() const { return string_view(&buffer_[0], size()); }
1061 size_t size() const { return buffer_.size() - 1; }
1062 const char *c_str() const { return &buffer_[0]; }
1063 std::string str() const { return std::string(&buffer_[0], size()); }
1064
1065 // Performs conversion returning a system error code instead of
1066 // throwing exception on conversion error. This method may still throw
1067 // in case of memory allocation error.
1068 FMT_API int convert(wstring_view s);
1069};
1070
1071FMT_API void format_windows_error(fmt::internal::buffer &out, int error_code,
1072 fmt::string_view message) FMT_NOEXCEPT;
1073#endif
1074
1075template <typename T = void>
1076struct null {};
1077} // namespace internal
1078
1079enum alignment {
1080 ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
1081};
1082
1083// Flags.
1084enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8 };
1085
1086// An alignment specifier.
1087struct align_spec {
1088 unsigned width_;
1089 // Fill is always wchar_t and cast to char if necessary to avoid having
1090 // two specialization of AlignSpec and its subclasses.
1091 wchar_t fill_;
1092 alignment align_;
1093
1094 FMT_CONSTEXPR align_spec() : width_(0), fill_(' '), align_(ALIGN_DEFAULT) {}
1095 FMT_CONSTEXPR unsigned width() const { return width_; }
1096 FMT_CONSTEXPR wchar_t fill() const { return fill_; }
1097 FMT_CONSTEXPR alignment align() const { return align_; }
1098};
1099
1100struct core_format_specs {
1101 int precision;
1102 uint_least8_t flags;
1103 char type;
1104
1105 FMT_CONSTEXPR core_format_specs() : precision(-1), flags(0), type(0) {}
1106 FMT_CONSTEXPR bool has(unsigned f) const { return (flags & f) != 0; }
1107};
1108
1109// Format specifiers.
1110template <typename Char>
1111struct basic_format_specs : align_spec, core_format_specs {
1112 FMT_CONSTEXPR basic_format_specs() {}
1113};
1114
1115typedef basic_format_specs<char> format_specs;
1116
1117template <typename Char, typename ErrorHandler>
1118FMT_CONSTEXPR unsigned basic_parse_context<Char, ErrorHandler>::next_arg_id() {
1119 if (next_arg_id_ >= 0)
1120 return internal::to_unsigned(next_arg_id_++);
1121 on_error("cannot switch from manual to automatic argument indexing");
1122 return 0;
1123}
1124
1125namespace internal {
1126
1127// Formats value using Grisu2 algorithm:
1128// https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
1129template <typename Double>
1130FMT_API typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
1131 grisu2_format(Double value, buffer &buf, core_format_specs);
1132template <typename Double>
1133inline typename std::enable_if<sizeof(Double) != sizeof(uint64_t), bool>::type
1134 grisu2_format(Double, buffer &, core_format_specs) { return false; }
1135
1136template <typename Double>
1137void sprintf_format(Double, internal::buffer &, core_format_specs);
1138
1139template <typename Handler>
1140FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler) {
1141 switch (spec) {
1142 case 0: case 'd':
1143 handler.on_dec();
1144 break;
1145 case 'x': case 'X':
1146 handler.on_hex();
1147 break;
1148 case 'b': case 'B':
1149 handler.on_bin();
1150 break;
1151 case 'o':
1152 handler.on_oct();
1153 break;
1154 case 'n':
1155 handler.on_num();
1156 break;
1157 default:
1158 handler.on_error();
1159 }
1160}
1161
1162template <typename Handler>
1163FMT_CONSTEXPR void handle_float_type_spec(char spec, Handler &&handler) {
1164 switch (spec) {
1165 case 0: case 'g': case 'G':
1166 handler.on_general();
1167 break;
1168 case 'e': case 'E':
1169 handler.on_exp();
1170 break;
1171 case 'f': case 'F':
1172 handler.on_fixed();
1173 break;
1174 case 'a': case 'A':
1175 handler.on_hex();
1176 break;
1177 default:
1178 handler.on_error();
1179 break;
1180 }
1181}
1182
1183template <typename Char, typename Handler>
1184FMT_CONSTEXPR void handle_char_specs(
1185 const basic_format_specs<Char> *specs, Handler &&handler) {
1186 if (!specs) return handler.on_char();
1187 if (specs->type && specs->type != 'c') return handler.on_int();
1188 if (specs->align() == ALIGN_NUMERIC || specs->flags != 0)
1189 handler.on_error("invalid format specifier for char");
1190 handler.on_char();
1191}
1192
1193template <typename Char, typename Handler>
1194FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler) {
1195 if (spec == 0 || spec == 's')
1196 handler.on_string();
1197 else if (spec == 'p')
1198 handler.on_pointer();
1199 else
1200 handler.on_error("invalid type specifier");
1201}
1202
1203template <typename Char, typename ErrorHandler>
1204FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh) {
1205 if (spec != 0 && spec != 's')
1206 eh.on_error("invalid type specifier");
1207}
1208
1209template <typename Char, typename ErrorHandler>
1210FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh) {
1211 if (spec != 0 && spec != 'p')
1212 eh.on_error("invalid type specifier");
1213}
1214
1215template <typename ErrorHandler>
1216class int_type_checker : private ErrorHandler {
1217 public:
1218 FMT_CONSTEXPR explicit int_type_checker(ErrorHandler eh) : ErrorHandler(eh) {}
1219
1220 FMT_CONSTEXPR void on_dec() {}
1221 FMT_CONSTEXPR void on_hex() {}
1222 FMT_CONSTEXPR void on_bin() {}
1223 FMT_CONSTEXPR void on_oct() {}
1224 FMT_CONSTEXPR void on_num() {}
1225
1226 FMT_CONSTEXPR void on_error() {
1227 ErrorHandler::on_error("invalid type specifier");
1228 }
1229};
1230
1231template <typename ErrorHandler>
1232class float_type_checker : private ErrorHandler {
1233 public:
1234 FMT_CONSTEXPR explicit float_type_checker(ErrorHandler eh)
1235 : ErrorHandler(eh) {}
1236
1237 FMT_CONSTEXPR void on_general() {}
1238 FMT_CONSTEXPR void on_exp() {}
1239 FMT_CONSTEXPR void on_fixed() {}
1240 FMT_CONSTEXPR void on_hex() {}
1241
1242 FMT_CONSTEXPR void on_error() {
1243 ErrorHandler::on_error("invalid type specifier");
1244 }
1245};
1246
1247template <typename ErrorHandler>
1248class char_specs_checker : public ErrorHandler {
1249 private:
1250 char type_;
1251
1252 public:
1253 FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
1254 : ErrorHandler(eh), type_(type) {}
1255
1256 FMT_CONSTEXPR void on_int() {
1257 handle_int_type_spec(type_, int_type_checker<ErrorHandler>(*this));
1258 }
1259 FMT_CONSTEXPR void on_char() {}
1260};
1261
1262template <typename ErrorHandler>
1263class cstring_type_checker : public ErrorHandler {
1264 public:
1265 FMT_CONSTEXPR explicit cstring_type_checker(ErrorHandler eh)
1266 : ErrorHandler(eh) {}
1267
1268 FMT_CONSTEXPR void on_string() {}
1269 FMT_CONSTEXPR void on_pointer() {}
1270};
1271
1272template <typename Context>
1273void arg_map<Context>::init(const basic_format_args<Context> &args) {
1274 if (map_)
1275 return;
1276 map_ = new entry[args.max_size()];
1277 if (args.is_packed()) {
1278 for (unsigned i = 0;/*nothing*/; ++i) {
1279 internal::type arg_type = args.type(i);
1280 switch (arg_type) {
1281 case internal::none_type:
1282 return;
1283 case internal::named_arg_type:
1284 push_back(args.values_[i]);
1285 break;
1286 default:
1287 break; // Do nothing.
1288 }
1289 }
1290 }
1291 for (unsigned i = 0; ; ++i) {
1292 switch (args.args_[i].type_) {
1293 case internal::none_type:
1294 return;
1295 case internal::named_arg_type:
1296 push_back(args.args_[i].value_);
1297 break;
1298 default:
1299 break; // Do nothing.
1300 }
1301 }
1302}
1303
1304template <typename Range>
1305class arg_formatter_base {
1306 public:
1307 typedef typename Range::value_type char_type;
1308 typedef decltype(internal::declval<Range>().begin()) iterator;
1309 typedef basic_format_specs<char_type> format_specs;
1310
1311 private:
1312 typedef basic_writer<Range> writer_type;
1313 writer_type writer_;
1314 format_specs *specs_;
1315
1316 struct char_writer {
1317 char_type value;
1318
1319 size_t size() const { return 1; }
1320 size_t width() const { return 1; }
1321
1322 template <typename It>
1323 void operator()(It &&it) const { *it++ = value; }
1324 };
1325
1326 void write_char(char_type value) {
1327 if (specs_)
1328 writer_.write_padded(*specs_, char_writer{value});
1329 else
1330 writer_.write(value);
1331 }
1332
1333 void write_pointer(const void *p) {
1334 format_specs specs = specs_ ? *specs_ : format_specs();
1335 specs.flags = HASH_FLAG;
1336 specs.type = 'x';
1337 writer_.write_int(reinterpret_cast<uintptr_t>(p), specs);
1338 }
1339
1340 protected:
1341 writer_type &writer() { return writer_; }
1342 format_specs *spec() { return specs_; }
1343 iterator out() { return writer_.out(); }
1344
1345 void write(bool value) {
1346 string_view sv(value ? "true" : "false");
1347 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1348 }
1349
1350 void write(const char_type *value) {
1351 if (!value)
1352 FMT_THROW(format_error("string pointer is null"));
1353 auto length = std::char_traits<char_type>::length(value);
1354 basic_string_view<char_type> sv(value, length);
1355 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1356 }
1357
1358 public:
1359 arg_formatter_base(Range r, format_specs *s, locale_ref loc)
1360 : writer_(r, loc), specs_(s) {}
1361
1362 iterator operator()(monostate) {
1363 FMT_ASSERT(false, "invalid argument type");
1364 return out();
1365 }
1366
1367 template <typename T>
1368 typename std::enable_if<
1369 std::is_integral<T>::value || std::is_same<T, char_type>::value,
1370 iterator>::type operator()(T value) {
1371 // MSVC2013 fails to compile separate overloads for bool and char_type so
1372 // use std::is_same instead.
1373 if (std::is_same<T, bool>::value) {
1374 if (specs_ && specs_->type)
1375 return (*this)(value ? 1 : 0);
1376 write(value != 0);
1377 } else if (std::is_same<T, char_type>::value) {
1378 internal::handle_char_specs(
1379 specs_, char_spec_handler(*this, static_cast<char_type>(value)));
1380 } else {
1381 specs_ ? writer_.write_int(value, *specs_) : writer_.write(value);
1382 }
1383 return out();
1384 }
1385
1386 template <typename T>
1387 typename std::enable_if<std::is_floating_point<T>::value, iterator>::type
1388 operator()(T value) {
1389 writer_.write_double(value, specs_ ? *specs_ : format_specs());
1390 return out();
1391 }
1392
1393 struct char_spec_handler : internal::error_handler {
1394 arg_formatter_base &formatter;
1395 char_type value;
1396
1397 char_spec_handler(arg_formatter_base& f, char_type val)
1398 : formatter(f), value(val) {}
1399
1400 void on_int() {
1401 if (formatter.specs_)
1402 formatter.writer_.write_int(value, *formatter.specs_);
1403 else
1404 formatter.writer_.write(value);
1405 }
1406 void on_char() { formatter.write_char(value); }
1407 };
1408
1409 struct cstring_spec_handler : internal::error_handler {
1410 arg_formatter_base &formatter;
1411 const char_type *value;
1412
1413 cstring_spec_handler(arg_formatter_base &f, const char_type *val)
1414 : formatter(f), value(val) {}
1415
1416 void on_string() { formatter.write(value); }
1417 void on_pointer() { formatter.write_pointer(value); }
1418 };
1419
1420 iterator operator()(const char_type *value) {
1421 if (!specs_) return write(value), out();
1422 internal::handle_cstring_type_spec(
1423 specs_->type, cstring_spec_handler(*this, value));
1424 return out();
1425 }
1426
1427 iterator operator()(basic_string_view<char_type> value) {
1428 if (specs_) {
1429 internal::check_string_type_spec(
1430 specs_->type, internal::error_handler());
1431 writer_.write(value, *specs_);
1432 } else {
1433 writer_.write(value);
1434 }
1435 return out();
1436 }
1437
1438 iterator operator()(const void *value) {
1439 if (specs_)
1440 check_pointer_type_spec(specs_->type, internal::error_handler());
1441 write_pointer(value);
1442 return out();
1443 }
1444};
1445
1446template <typename Char>
1447FMT_CONSTEXPR bool is_name_start(Char c) {
1448 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
1449}
1450
1451// Parses the range [begin, end) as an unsigned integer. This function assumes
1452// that the range is non-empty and the first character is a digit.
1453template <typename Char, typename ErrorHandler>
1454FMT_CONSTEXPR unsigned parse_nonnegative_int(
1455 const Char *&begin, const Char *end, ErrorHandler &&eh) {
1456 assert(begin != end && '0' <= *begin && *begin <= '9');
1457 if (*begin == '0') {
1458 ++begin;
1459 return 0;
1460 }
1461 unsigned value = 0;
1462 // Convert to unsigned to prevent a warning.
1463 unsigned max_int = (std::numeric_limits<int>::max)();
1464 unsigned big = max_int / 10;
1465 do {
1466 // Check for overflow.
1467 if (value > big) {
1468 value = max_int + 1;
1469 break;
1470 }
1471 value = value * 10 + unsigned(*begin - '0');
1472 ++begin;
1473 } while (begin != end && '0' <= *begin && *begin <= '9');
1474 if (value > max_int)
1475 eh.on_error("number is too big");
1476 return value;
1477}
1478
1479template <typename Char, typename Context>
1480class custom_formatter: public function<bool> {
1481 private:
1482 Context &ctx_;
1483
1484 public:
1485 explicit custom_formatter(Context &ctx): ctx_(ctx) {}
1486
1487 bool operator()(typename basic_format_arg<Context>::handle h) const {
1488 h.format(ctx_);
1489 return true;
1490 }
1491
1492 template <typename T>
1493 bool operator()(T) const { return false; }
1494};
1495
1496template <typename T>
1497struct is_integer {
1498 enum {
1499 value = std::is_integral<T>::value && !std::is_same<T, bool>::value &&
1500 !std::is_same<T, char>::value && !std::is_same<T, wchar_t>::value
1501 };
1502};
1503
1504template <typename ErrorHandler>
1505class width_checker: public function<unsigned long long> {
1506 public:
1507 explicit FMT_CONSTEXPR width_checker(ErrorHandler &eh) : handler_(eh) {}
1508
1509 template <typename T>
1510 FMT_CONSTEXPR
1511 typename std::enable_if<
1512 is_integer<T>::value, unsigned long long>::type operator()(T value) {
1513 if (is_negative(value))
1514 handler_.on_error("negative width");
1515 return static_cast<unsigned long long>(value);
1516 }
1517
1518 template <typename T>
1519 FMT_CONSTEXPR typename std::enable_if<
1520 !is_integer<T>::value, unsigned long long>::type operator()(T) {
1521 handler_.on_error("width is not integer");
1522 return 0;
1523 }
1524
1525 private:
1526 ErrorHandler &handler_;
1527};
1528
1529template <typename ErrorHandler>
1530class precision_checker: public function<unsigned long long> {
1531 public:
1532 explicit FMT_CONSTEXPR precision_checker(ErrorHandler &eh) : handler_(eh) {}
1533
1534 template <typename T>
1535 FMT_CONSTEXPR typename std::enable_if<
1536 is_integer<T>::value, unsigned long long>::type operator()(T value) {
1537 if (is_negative(value))
1538 handler_.on_error("negative precision");
1539 return static_cast<unsigned long long>(value);
1540 }
1541
1542 template <typename T>
1543 FMT_CONSTEXPR typename std::enable_if<
1544 !is_integer<T>::value, unsigned long long>::type operator()(T) {
1545 handler_.on_error("precision is not integer");
1546 return 0;
1547 }
1548
1549 private:
1550 ErrorHandler &handler_;
1551};
1552
1553// A format specifier handler that sets fields in basic_format_specs.
1554template <typename Char>
1555class specs_setter {
1556 public:
1557 explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char> &specs):
1558 specs_(specs) {}
1559
1560 FMT_CONSTEXPR specs_setter(const specs_setter &other): specs_(other.specs_) {}
1561
1562 FMT_CONSTEXPR void on_align(alignment align) { specs_.align_ = align; }
1563 FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill_ = fill; }
1564 FMT_CONSTEXPR void on_plus() { specs_.flags |= SIGN_FLAG | PLUS_FLAG; }
1565 FMT_CONSTEXPR void on_minus() { specs_.flags |= MINUS_FLAG; }
1566 FMT_CONSTEXPR void on_space() { specs_.flags |= SIGN_FLAG; }
1567 FMT_CONSTEXPR void on_hash() { specs_.flags |= HASH_FLAG; }
1568
1569 FMT_CONSTEXPR void on_zero() {
1570 specs_.align_ = ALIGN_NUMERIC;
1571 specs_.fill_ = '0';
1572 }
1573
1574 FMT_CONSTEXPR void on_width(unsigned width) { specs_.width_ = width; }
1575 FMT_CONSTEXPR void on_precision(unsigned precision) {
1576 specs_.precision = static_cast<int>(precision);
1577 }
1578 FMT_CONSTEXPR void end_precision() {}
1579
1580 FMT_CONSTEXPR void on_type(Char type) {
1581 specs_.type = static_cast<char>(type);
1582 }
1583
1584 protected:
1585 basic_format_specs<Char> &specs_;
1586};
1587
1588// A format specifier handler that checks if specifiers are consistent with the
1589// argument type.
1590template <typename Handler>
1591class specs_checker : public Handler {
1592 public:
1593 FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type)
1594 : Handler(handler), arg_type_(arg_type) {}
1595
1596 FMT_CONSTEXPR specs_checker(const specs_checker &other)
1597 : Handler(other), arg_type_(other.arg_type_) {}
1598
1599 FMT_CONSTEXPR void on_align(alignment align) {
1600 if (align == ALIGN_NUMERIC)
1601 require_numeric_argument();
1602 Handler::on_align(align);
1603 }
1604
1605 FMT_CONSTEXPR void on_plus() {
1606 check_sign();
1607 Handler::on_plus();
1608 }
1609
1610 FMT_CONSTEXPR void on_minus() {
1611 check_sign();
1612 Handler::on_minus();
1613 }
1614
1615 FMT_CONSTEXPR void on_space() {
1616 check_sign();
1617 Handler::on_space();
1618 }
1619
1620 FMT_CONSTEXPR void on_hash() {
1621 require_numeric_argument();
1622 Handler::on_hash();
1623 }
1624
1625 FMT_CONSTEXPR void on_zero() {
1626 require_numeric_argument();
1627 Handler::on_zero();
1628 }
1629
1630 FMT_CONSTEXPR void end_precision() {
1631 if (is_integral(arg_type_) || arg_type_ == pointer_type)
1632 this->on_error("precision not allowed for this argument type");
1633 }
1634
1635 private:
1636 FMT_CONSTEXPR void require_numeric_argument() {
1637 if (!is_arithmetic(arg_type_))
1638 this->on_error("format specifier requires numeric argument");
1639 }
1640
1641 FMT_CONSTEXPR void check_sign() {
1642 require_numeric_argument();
1643 if (is_integral(arg_type_) && arg_type_ != int_type &&
1644 arg_type_ != long_long_type && arg_type_ != internal::char_type) {
1645 this->on_error("format specifier requires signed argument");
1646 }
1647 }
1648
1649 internal::type arg_type_;
1650};
1651
1652template <template <typename> class Handler, typename T,
1653 typename Context, typename ErrorHandler>
1654FMT_CONSTEXPR void set_dynamic_spec(
1655 T &value, basic_format_arg<Context> arg, ErrorHandler eh) {
1656 unsigned long long big_value =
1657 visit_format_arg(Handler<ErrorHandler>(eh), arg);
1658 if (big_value > to_unsigned((std::numeric_limits<int>::max)()))
1659 eh.on_error("number is too big");
1660 value = static_cast<T>(big_value);
1661}
1662
1663struct auto_id {};
1664
1665// The standard format specifier handler with checking.
1666template <typename Context>
1667class specs_handler: public specs_setter<typename Context::char_type> {
1668 public:
1669 typedef typename Context::char_type char_type;
1670
1671 FMT_CONSTEXPR specs_handler(
1672 basic_format_specs<char_type> &specs, Context &ctx)
1673 : specs_setter<char_type>(specs), context_(ctx) {}
1674
1675 template <typename Id>
1676 FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
1677 set_dynamic_spec<width_checker>(
1678 this->specs_.width_, get_arg(arg_id), context_.error_handler());
1679 }
1680
1681 template <typename Id>
1682 FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
1683 set_dynamic_spec<precision_checker>(
1684 this->specs_.precision, get_arg(arg_id), context_.error_handler());
1685 }
1686
1687 void on_error(const char *message) {
1688 context_.on_error(message);
1689 }
1690
1691 private:
1692 FMT_CONSTEXPR basic_format_arg<Context> get_arg(auto_id) {
1693 return context_.next_arg();
1694 }
1695
1696 template <typename Id>
1697 FMT_CONSTEXPR basic_format_arg<Context> get_arg(Id arg_id) {
1698 context_.parse_context().check_arg_id(arg_id);
1699 return context_.get_arg(arg_id);
1700 }
1701
1702 Context &context_;
1703};
1704
1705// An argument reference.
1706template <typename Char>
1707struct arg_ref {
1708 enum Kind { NONE, INDEX, NAME };
1709
1710 FMT_CONSTEXPR arg_ref() : kind(NONE), index(0) {}
1711 FMT_CONSTEXPR explicit arg_ref(unsigned index) : kind(INDEX), index(index) {}
1712 explicit arg_ref(basic_string_view<Char> nm) : kind(NAME) {
1713 name = {nm.data(), nm.size()};
1714 }
1715
1716 FMT_CONSTEXPR arg_ref &operator=(unsigned idx) {
1717 kind = INDEX;
1718 index = idx;
1719 return *this;
1720 }
1721
1722 Kind kind;
1723 union {
1724 unsigned index;
1725 string_value<Char> name; // This is not string_view because of gcc 4.4.
1726 };
1727};
1728
1729// Format specifiers with width and precision resolved at formatting rather
1730// than parsing time to allow re-using the same parsed specifiers with
1731// differents sets of arguments (precompilation of format strings).
1732template <typename Char>
1733struct dynamic_format_specs : basic_format_specs<Char> {
1734 arg_ref<Char> width_ref;
1735 arg_ref<Char> precision_ref;
1736};
1737
1738// Format spec handler that saves references to arguments representing dynamic
1739// width and precision to be resolved at formatting time.
1740template <typename ParseContext>
1741class dynamic_specs_handler :
1742 public specs_setter<typename ParseContext::char_type> {
1743 public:
1744 typedef typename ParseContext::char_type char_type;
1745
1746 FMT_CONSTEXPR dynamic_specs_handler(
1747 dynamic_format_specs<char_type> &specs, ParseContext &ctx)
1748 : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
1749
1750 FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
1751 : specs_setter<char_type>(other),
1752 specs_(other.specs_), context_(other.context_) {}
1753
1754 template <typename Id>
1755 FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
1756 specs_.width_ref = make_arg_ref(arg_id);
1757 }
1758
1759 template <typename Id>
1760 FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
1761 specs_.precision_ref = make_arg_ref(arg_id);
1762 }
1763
1764 FMT_CONSTEXPR void on_error(const char *message) {
1765 context_.on_error(message);
1766 }
1767
1768 private:
1769 typedef arg_ref<char_type> arg_ref_type;
1770
1771 template <typename Id>
1772 FMT_CONSTEXPR arg_ref_type make_arg_ref(Id arg_id) {
1773 context_.check_arg_id(arg_id);
1774 return arg_ref_type(arg_id);
1775 }
1776
1777 FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id) {
1778 return arg_ref_type(context_.next_arg_id());
1779 }
1780
1781 dynamic_format_specs<char_type> &specs_;
1782 ParseContext &context_;
1783};
1784
1785template <typename Char, typename IDHandler>
1786FMT_CONSTEXPR const Char *parse_arg_id(
1787 const Char *begin, const Char *end, IDHandler &&handler) {
1788 assert(begin != end);
1789 Char c = *begin;
1790 if (c == '}' || c == ':')
1791 return handler(), begin;
1792 if (c >= '0' && c <= '9') {
1793 unsigned index = parse_nonnegative_int(begin, end, handler);
1794 if (begin == end || (*begin != '}' && *begin != ':'))
1795 return handler.on_error("invalid format string"), begin;
1796 handler(index);
1797 return begin;
1798 }
1799 if (!is_name_start(c))
1800 return handler.on_error("invalid format string"), begin;
1801 auto it = begin;
1802 do {
1803 ++it;
1804 } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
1805 handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
1806 return it;
1807}
1808
1809// Adapts SpecHandler to IDHandler API for dynamic width.
1810template <typename SpecHandler, typename Char>
1811struct width_adapter {
1812 explicit FMT_CONSTEXPR width_adapter(SpecHandler &h) : handler(h) {}
1813
1814 FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
1815 FMT_CONSTEXPR void operator()(unsigned id) { handler.on_dynamic_width(id); }
1816 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
1817 handler.on_dynamic_width(id);
1818 }
1819
1820 FMT_CONSTEXPR void on_error(const char *message) {
1821 handler.on_error(message);
1822 }
1823
1824 SpecHandler &handler;
1825};
1826
1827// Adapts SpecHandler to IDHandler API for dynamic precision.
1828template <typename SpecHandler, typename Char>
1829struct precision_adapter {
1830 explicit FMT_CONSTEXPR precision_adapter(SpecHandler &h) : handler(h) {}
1831
1832 FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
1833 FMT_CONSTEXPR void operator()(unsigned id) {
1834 handler.on_dynamic_precision(id);
1835 }
1836 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
1837 handler.on_dynamic_precision(id);
1838 }
1839
1840 FMT_CONSTEXPR void on_error(const char *message) { handler.on_error(message); }
1841
1842 SpecHandler &handler;
1843};
1844
1845// Parses fill and alignment.
1846template <typename Char, typename Handler>
1847FMT_CONSTEXPR const Char *parse_align(
1848 const Char *begin, const Char *end, Handler &&handler) {
1849 FMT_ASSERT(begin != end, "");
1850 alignment align = ALIGN_DEFAULT;
1851 int i = 0;
1852 if (begin + 1 != end) ++i;
1853 do {
1854 switch (static_cast<char>(begin[i])) {
1855 case '<':
1856 align = ALIGN_LEFT;
1857 break;
1858 case '>':
1859 align = ALIGN_RIGHT;
1860 break;
1861 case '=':
1862 align = ALIGN_NUMERIC;
1863 break;
1864 case '^':
1865 align = ALIGN_CENTER;
1866 break;
1867 }
1868 if (align != ALIGN_DEFAULT) {
1869 if (i > 0) {
1870 auto c = *begin;
1871 if (c == '{')
1872 return handler.on_error("invalid fill character '{'"), begin;
1873 begin += 2;
1874 handler.on_fill(c);
1875 } else ++begin;
1876 handler.on_align(align);
1877 break;
1878 }
1879 } while (i-- > 0);
1880 return begin;
1881}
1882
1883template <typename Char, typename Handler>
1884FMT_CONSTEXPR const Char *parse_width(
1885 const Char *begin, const Char *end, Handler &&handler) {
1886 FMT_ASSERT(begin != end, "");
1887 if ('0' <= *begin && *begin <= '9') {
1888 handler.on_width(parse_nonnegative_int(begin, end, handler));
1889 } else if (*begin == '{') {
1890 ++begin;
1891 if (begin != end)
1892 begin = parse_arg_id(begin, end, width_adapter<Handler, Char>(handler));
1893 if (begin == end || *begin != '}')
1894 return handler.on_error("invalid format string"), begin;
1895 ++begin;
1896 }
1897 return begin;
1898}
1899
1900// Parses standard format specifiers and sends notifications about parsed
1901// components to handler.
1902template <typename Char, typename SpecHandler>
1903FMT_CONSTEXPR const Char *parse_format_specs(
1904 const Char *begin, const Char *end, SpecHandler &&handler) {
1905 if (begin == end || *begin == '}')
1906 return begin;
1907
1908 begin = parse_align(begin, end, handler);
1909 if (begin == end) return begin;
1910
1911 // Parse sign.
1912 switch (static_cast<char>(*begin)) {
1913 case '+':
1914 handler.on_plus();
1915 ++begin;
1916 break;
1917 case '-':
1918 handler.on_minus();
1919 ++begin;
1920 break;
1921 case ' ':
1922 handler.on_space();
1923 ++begin;
1924 break;
1925 }
1926 if (begin == end) return begin;
1927
1928 if (*begin == '#') {
1929 handler.on_hash();
1930 if (++begin == end) return begin;
1931 }
1932
1933 // Parse zero flag.
1934 if (*begin == '0') {
1935 handler.on_zero();
1936 if (++begin == end) return begin;
1937 }
1938
1939 begin = parse_width(begin, end, handler);
1940 if (begin == end) return begin;
1941
1942 // Parse precision.
1943 if (*begin == '.') {
1944 ++begin;
1945 auto c = begin != end ? *begin : 0;
1946 if ('0' <= c && c <= '9') {
1947 handler.on_precision(parse_nonnegative_int(begin, end, handler));
1948 } else if (c == '{') {
1949 ++begin;
1950 if (begin != end) {
1951 begin = parse_arg_id(
1952 begin, end, precision_adapter<SpecHandler, Char>(handler));
1953 }
1954 if (begin == end || *begin++ != '}')
1955 return handler.on_error("invalid format string"), begin;
1956 } else {
1957 return handler.on_error("missing precision specifier"), begin;
1958 }
1959 handler.end_precision();
1960 }
1961
1962 // Parse type.
1963 if (begin != end && *begin != '}')
1964 handler.on_type(*begin++);
1965 return begin;
1966}
1967
1968// Return the result via the out param to workaround gcc bug 77539.
1969template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
1970FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out) {
1971 for (out = first; out != last; ++out) {
1972 if (*out == value)
1973 return true;
1974 }
1975 return false;
1976}
1977
1978template <>
1979inline bool find<false, char>(
1980 const char *first, const char *last, char value, const char *&out) {
1981 out = static_cast<const char*>(std::memchr(first, value, internal::to_unsigned(last - first)));
1982 return out != FMT_NULL;
1983}
1984
1985template <typename Handler, typename Char>
1986struct id_adapter {
1987 FMT_CONSTEXPR void operator()() { handler.on_arg_id(); }
1988 FMT_CONSTEXPR void operator()(unsigned id) { handler.on_arg_id(id); }
1989 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
1990 handler.on_arg_id(id);
1991 }
1992 FMT_CONSTEXPR void on_error(const char *message) {
1993 handler.on_error(message);
1994 }
1995 Handler &handler;
1996};
1997
1998template <bool IS_CONSTEXPR, typename Char, typename Handler>
1999FMT_CONSTEXPR void parse_format_string(
2000 basic_string_view<Char> format_str, Handler &&handler) {
2001 struct writer {
2002 FMT_CONSTEXPR void operator()(const Char *begin, const Char *end) {
2003 if (begin == end) return;
2004 for (;;) {
2005 const Char *p = FMT_NULL;
2006 if (!find<IS_CONSTEXPR>(begin, end, '}', p))
2007 return handler_.on_text(begin, end);
2008 ++p;
2009 if (p == end || *p != '}')
2010 return handler_.on_error("unmatched '}' in format string");
2011 handler_.on_text(begin, p);
2012 begin = p + 1;
2013 }
2014 }
2015 Handler &handler_;
2016 } write{handler};
2017 auto begin = format_str.data();
2018 auto end = begin + format_str.size();
2019 while (begin != end) {
2020 // Doing two passes with memchr (one for '{' and another for '}') is up to
2021 // 2.5x faster than the naive one-pass implementation on big format strings.
2022 const Char *p = begin;
2023 if (*begin != '{' && !find<IS_CONSTEXPR>(begin, end, '{', p))
2024 return write(begin, end);
2025 write(begin, p);
2026 ++p;
2027 if (p == end)
2028 return handler.on_error("invalid format string");
2029 if (static_cast<char>(*p) == '}') {
2030 handler.on_arg_id();
2031 handler.on_replacement_field(p);
2032 } else if (*p == '{') {
2033 handler.on_text(p, p + 1);
2034 } else {
2035 p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler});
2036 Char c = p != end ? *p : Char();
2037 if (c == '}') {
2038 handler.on_replacement_field(p);
2039 } else if (c == ':') {
2040 p = handler.on_format_specs(p + 1, end);
2041 if (p == end || *p != '}')
2042 return handler.on_error("unknown format specifier");
2043 } else {
2044 return handler.on_error("missing '}' in format string");
2045 }
2046 }
2047 begin = p + 1;
2048 }
2049}
2050
2051template <typename T, typename ParseContext>
2052FMT_CONSTEXPR const typename ParseContext::char_type *
2053 parse_format_specs(ParseContext &ctx) {
2054 // GCC 7.2 requires initializer.
2055 formatter<T, typename ParseContext::char_type> f{};
2056 return f.parse(ctx);
2057}
2058
2059template <typename Char, typename ErrorHandler, typename... Args>
2060class format_string_checker {
2061 public:
2062 explicit FMT_CONSTEXPR format_string_checker(
2063 basic_string_view<Char> format_str, ErrorHandler eh)
2064 : arg_id_((std::numeric_limits<unsigned>::max)()), context_(format_str, eh),
2065 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2066
2067 FMT_CONSTEXPR void on_text(const Char *, const Char *) {}
2068
2069 FMT_CONSTEXPR void on_arg_id() {
2070 arg_id_ = context_.next_arg_id();
2071 check_arg_id();
2072 }
2073 FMT_CONSTEXPR void on_arg_id(unsigned id) {
2074 arg_id_ = id;
2075 context_.check_arg_id(id);
2076 check_arg_id();
2077 }
2078 FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) {}
2079
2080 FMT_CONSTEXPR void on_replacement_field(const Char *) {}
2081
2082 FMT_CONSTEXPR const Char *on_format_specs(const Char *begin, const Char *) {
2083 context_.advance_to(begin);
2084 return arg_id_ < NUM_ARGS ?
2085 parse_funcs_[arg_id_](context_) : begin;
2086 }
2087
2088 FMT_CONSTEXPR void on_error(const char *message) {
2089 context_.on_error(message);
2090 }
2091
2092 private:
2093 typedef basic_parse_context<Char, ErrorHandler> parse_context_type;
2094 enum { NUM_ARGS = sizeof...(Args) };
2095
2096 FMT_CONSTEXPR void check_arg_id() {
2097 if (arg_id_ >= NUM_ARGS)
2098 context_.on_error("argument index out of range");
2099 }
2100
2101 // Format specifier parsing function.
2102 typedef const Char *(*parse_func)(parse_context_type &);
2103
2104 unsigned arg_id_;
2105 parse_context_type context_;
2106 parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
2107};
2108
2109template <typename Char, typename ErrorHandler, typename... Args>
2110FMT_CONSTEXPR bool do_check_format_string(
2111 basic_string_view<Char> s, ErrorHandler eh = ErrorHandler()) {
2112 format_string_checker<Char, ErrorHandler, Args...> checker(s, eh);
2113 parse_format_string<true>(s, checker);
2114 return true;
2115}
2116
2117template <typename... Args, typename S>
2118typename std::enable_if<is_compile_string<S>::value>::type
2119 check_format_string(S format_str) {
2120 typedef typename S::char_type char_t;
2121 FMT_CONSTEXPR_DECL bool invalid_format = internal::do_check_format_string<
2122 char_t, internal::error_handler, Args...>(to_string_view(format_str));
2123 (void)invalid_format;
2124}
2125
2126// Specifies whether to format T using the standard formatter.
2127// It is not possible to use get_type in formatter specialization directly
2128// because of a bug in MSVC.
2129template <typename Context, typename T>
2130struct format_type :
2131 std::integral_constant<bool, get_type<Context, T>::value != custom_type> {};
2132
2133template <template <typename> class Handler, typename Spec, typename Context>
2134void handle_dynamic_spec(
2135 Spec &value, arg_ref<typename Context::char_type> ref, Context &ctx) {
2136 typedef typename Context::char_type char_type;
2137 switch (ref.kind) {
2138 case arg_ref<char_type>::NONE:
2139 break;
2140 case arg_ref<char_type>::INDEX:
2141 internal::set_dynamic_spec<Handler>(
2142 value, ctx.get_arg(ref.index), ctx.error_handler());
2143 break;
2144 case arg_ref<char_type>::NAME:
2145 internal::set_dynamic_spec<Handler>(
2146 value, ctx.get_arg({ref.name.value, ref.name.size}),
2147 ctx.error_handler());
2148 break;
2149 }
2150}
2151} // namespace internal
2152
2153/** The default argument formatter. */
2154template <typename Range>
2155class arg_formatter:
2156 public internal::function<
2157 typename internal::arg_formatter_base<Range>::iterator>,
2158 public internal::arg_formatter_base<Range> {
2159 private:
2160 typedef typename Range::value_type char_type;
2161 typedef internal::arg_formatter_base<Range> base;
2162 typedef basic_format_context<typename base::iterator, char_type> context_type;
2163
2164 context_type &ctx_;
2165
2166 public:
2167 typedef Range range;
2168 typedef typename base::iterator iterator;
2169 typedef typename base::format_specs format_specs;
2170
2171 /**
2172 \rst
2173 Constructs an argument formatter object.
2174 *ctx* is a reference to the formatting context,
2175 *spec* contains format specifier information for standard argument types.
2176 \endrst
2177 */
2178 explicit arg_formatter(context_type &ctx, format_specs *spec = FMT_NULL)
2179 : base(Range(ctx.out()), spec, ctx.locale()), ctx_(ctx) {}
2180
2181 // Deprecated.
2182 arg_formatter(context_type &ctx, format_specs &spec)
2183 : base(Range(ctx.out()), &spec), ctx_(ctx) {}
2184
2185 using base::operator();
2186
2187 /** Formats an argument of a user-defined type. */
2188 iterator operator()(typename basic_format_arg<context_type>::handle handle) {
2189 handle.format(ctx_);
2190 return this->out();
2191 }
2192};
2193
2194/**
2195 An error returned by an operating system or a language runtime,
2196 for example a file opening error.
2197*/
2198class system_error : public std::runtime_error {
2199 private:
2200 FMT_API void init(int err_code, string_view format_str, format_args args);
2201
2202 protected:
2203 int error_code_;
2204
2205 system_error() : std::runtime_error("") {}
2206
2207 public:
2208 /**
2209 \rst
2210 Constructs a :class:`fmt::system_error` object with a description
2211 formatted with `fmt::format_system_error`. *message* and additional
2212 arguments passed into the constructor are formatted similarly to
2213 `fmt::format`.
2214
2215 **Example**::
2216
2217 // This throws a system_error with the description
2218 // cannot open file 'madeup': No such file or directory
2219 // or similar (system message may vary).
2220 const char *filename = "madeup";
2221 std::FILE *file = std::fopen(filename, "r");
2222 if (!file)
2223 throw fmt::system_error(errno, "cannot open file '{}'", filename);
2224 \endrst
2225 */
2226 template <typename... Args>
2227 system_error(int error_code, string_view message, const Args &... args)
2228 : std::runtime_error("") {
2229 init(error_code, message, make_format_args(args...));
2230 }
2231
2232 int error_code() const { return error_code_; }
2233};
2234
2235/**
2236 \rst
2237 Formats an error returned by an operating system or a language runtime,
2238 for example a file opening error, and writes it to *out* in the following
2239 form:
2240
2241 .. parsed-literal::
2242 *<message>*: *<system-message>*
2243
2244 where *<message>* is the passed message and *<system-message>* is
2245 the system message corresponding to the error code.
2246 *error_code* is a system error code as given by ``errno``.
2247 If *error_code* is not a valid error code such as -1, the system message
2248 may look like "Unknown error -1" and is platform-dependent.
2249 \endrst
2250 */
2251FMT_API void format_system_error(internal::buffer &out, int error_code,
2252 fmt::string_view message) FMT_NOEXCEPT;
2253
2254/**
2255 This template provides operations for formatting and writing data into a
2256 character range.
2257 */
2258template <typename Range>
2259class basic_writer {
2260 public:
2261 typedef typename Range::value_type char_type;
2262 typedef decltype(internal::declval<Range>().begin()) iterator;
2263 typedef basic_format_specs<char_type> format_specs;
2264
2265 private:
2266 iterator out_; // Output iterator.
2267 internal::locale_ref locale_;
2268
2269 // Attempts to reserve space for n extra characters in the output range.
2270 // Returns a pointer to the reserved range or a reference to out_.
2271 auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) {
2272 return internal::reserve(out_, n);
2273 }
2274
2275 // Writes a value in the format
2276 // <left-padding><value><right-padding>
2277 // where <value> is written by f(it).
2278 template <typename F>
2279 void write_padded(const align_spec &spec, F &&f) {
2280 unsigned width = spec.width(); // User-perceived width (in code points).
2281 size_t size = f.size(); // The number of code units.
2282 size_t num_code_points = width != 0 ? f.width() : size;
2283 if (width <= num_code_points)
2284 return f(reserve(size));
2285 auto &&it = reserve(width + (size - num_code_points));
2286 char_type fill = static_cast<char_type>(spec.fill());
2287 std::size_t padding = width - num_code_points;
2288 if (spec.align() == ALIGN_RIGHT) {
2289 it = std::fill_n(it, padding, fill);
2290 f(it);
2291 } else if (spec.align() == ALIGN_CENTER) {
2292 std::size_t left_padding = padding / 2;
2293 it = std::fill_n(it, left_padding, fill);
2294 f(it);
2295 it = std::fill_n(it, padding - left_padding, fill);
2296 } else {
2297 f(it);
2298 it = std::fill_n(it, padding, fill);
2299 }
2300 }
2301
2302 template <typename F>
2303 struct padded_int_writer {
2304 size_t size_;
2305 string_view prefix;
2306 char_type fill;
2307 std::size_t padding;
2308 F f;
2309
2310 size_t size() const { return size_; }
2311 size_t width() const { return size_; }
2312
2313 template <typename It>
2314 void operator()(It &&it) const {
2315 if (prefix.size() != 0)
2316 it = internal::copy_str<char_type>(prefix.begin(), prefix.end(), it);
2317 it = std::fill_n(it, padding, fill);
2318 f(it);
2319 }
2320 };
2321
2322 // Writes an integer in the format
2323 // <left-padding><prefix><numeric-padding><digits><right-padding>
2324 // where <digits> are written by f(it).
2325 template <typename Spec, typename F>
2326 void write_int(int num_digits, string_view prefix,
2327 const Spec &spec, F f) {
2328 std::size_t size = prefix.size() + internal::to_unsigned(num_digits);
2329 char_type fill = static_cast<char_type>(spec.fill());
2330 std::size_t padding = 0;
2331 if (spec.align() == ALIGN_NUMERIC) {
2332 if (spec.width() > size) {
2333 padding = spec.width() - size;
2334 size = spec.width();
2335 }
2336 } else if (spec.precision > num_digits) {
2337 size = prefix.size() + internal::to_unsigned(spec.precision);
2338 padding = internal::to_unsigned(spec.precision - num_digits);
2339 fill = static_cast<char_type>('0');
2340 }
2341 align_spec as = spec;
2342 if (spec.align() == ALIGN_DEFAULT)
2343 as.align_ = ALIGN_RIGHT;
2344 write_padded(as, padded_int_writer<F>{size, prefix, fill, padding, f});
2345 }
2346
2347 // Writes a decimal integer.
2348 template <typename Int>
2349 void write_decimal(Int value) {
2350 typedef typename internal::int_traits<Int>::main_type main_type;
2351 main_type abs_value = static_cast<main_type>(value);
2352 bool is_negative = internal::is_negative(value);
2353 if (is_negative)
2354 abs_value = 0 - abs_value;
2355 int num_digits = internal::count_digits(abs_value);
2356 auto &&it = reserve((is_negative ? 1 : 0) + static_cast<size_t>(num_digits));
2357 if (is_negative)
2358 *it++ = static_cast<char_type>('-');
2359 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2360 }
2361
2362 // The handle_int_type_spec handler that writes an integer.
2363 template <typename Int, typename Spec>
2364 struct int_writer {
2365 typedef typename internal::int_traits<Int>::main_type unsigned_type;
2366
2367 basic_writer<Range> &writer;
2368 const Spec &spec;
2369 unsigned_type abs_value;
2370 char prefix[4];
2371 unsigned prefix_size;
2372
2373 string_view get_prefix() const { return string_view(prefix, prefix_size); }
2374
2375 // Counts the number of digits in abs_value. BITS = log2(radix).
2376 template <unsigned BITS>
2377 int count_digits() const {
2378 unsigned_type n = abs_value;
2379 int num_digits = 0;
2380 do {
2381 ++num_digits;
2382 } while ((n >>= BITS) != 0);
2383 return num_digits;
2384 }
2385
2386 int_writer(basic_writer<Range> &w, Int value, const Spec &s)
2387 : writer(w), spec(s), abs_value(static_cast<unsigned_type>(value)),
2388 prefix_size(0) {
2389 if (internal::is_negative(value)) {
2390 prefix[0] = '-';
2391 ++prefix_size;
2392 abs_value = 0 - abs_value;
2393 } else if (spec.has(SIGN_FLAG)) {
2394 prefix[0] = spec.has(PLUS_FLAG) ? '+' : ' ';
2395 ++prefix_size;
2396 }
2397 }
2398
2399 struct dec_writer {
2400 unsigned_type abs_value;
2401 int num_digits;
2402
2403 template <typename It>
2404 void operator()(It &&it) const {
2405 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2406 }
2407 };
2408
2409 void on_dec() {
2410 int num_digits = internal::count_digits(abs_value);
2411 writer.write_int(num_digits, get_prefix(), spec,
2412 dec_writer{abs_value, num_digits});
2413 }
2414
2415 struct hex_writer {
2416 int_writer &self;
2417 int num_digits;
2418
2419 template <typename It>
2420 void operator()(It &&it) const {
2421 it = internal::format_uint<4, char_type>(
2422 it, self.abs_value, num_digits, self.spec.type != 'x');
2423 }
2424 };
2425
2426 void on_hex() {
2427 if (spec.has(HASH_FLAG)) {
2428 prefix[prefix_size++] = '0';
2429 prefix[prefix_size++] = static_cast<char>(spec.type);
2430 }
2431 int num_digits = count_digits<4>();
2432 writer.write_int(num_digits, get_prefix(), spec,
2433 hex_writer{*this, num_digits});
2434 }
2435
2436 template <int BITS>
2437 struct bin_writer {
2438 unsigned_type abs_value;
2439 int num_digits;
2440
2441 template <typename It>
2442 void operator()(It &&it) const {
2443 it = internal::format_uint<BITS, char_type>(it, abs_value, num_digits);
2444 }
2445 };
2446
2447 void on_bin() {
2448 if (spec.has(HASH_FLAG)) {
2449 prefix[prefix_size++] = '0';
2450 prefix[prefix_size++] = static_cast<char>(spec.type);
2451 }
2452 int num_digits = count_digits<1>();
2453 writer.write_int(num_digits, get_prefix(), spec,
2454 bin_writer<1>{abs_value, num_digits});
2455 }
2456
2457 void on_oct() {
2458 int num_digits = count_digits<3>();
2459 if (spec.has(HASH_FLAG) &&
2460 spec.precision <= num_digits) {
2461 // Octal prefix '0' is counted as a digit, so only add it if precision
2462 // is not greater than the number of digits.
2463 prefix[prefix_size++] = '0';
2464 }
2465 writer.write_int(num_digits, get_prefix(), spec,
2466 bin_writer<3>{abs_value, num_digits});
2467 }
2468
2469 enum { SEP_SIZE = 1 };
2470
2471 struct num_writer {
2472 unsigned_type abs_value;
2473 int size;
2474 char_type sep;
2475
2476 template <typename It>
2477 void operator()(It &&it) const {
2478 basic_string_view<char_type> s(&sep, SEP_SIZE);
2479 it = internal::format_decimal<char_type>(
2480 it, abs_value, size, internal::add_thousands_sep<char_type>(s));
2481 }
2482 };
2483
2484 void on_num() {
2485 int num_digits = internal::count_digits(abs_value);
2486 char_type sep = internal::thousands_sep<char_type>(writer.locale_);
2487 int size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
2488 writer.write_int(size, get_prefix(), spec,
2489 num_writer{abs_value, size, sep});
2490 }
2491
2492 void on_error() {
2493 FMT_THROW(format_error("invalid type specifier"));
2494 }
2495 };
2496
2497 // Writes a formatted integer.
2498 template <typename T, typename Spec>
2499 void write_int(T value, const Spec &spec) {
2500 internal::handle_int_type_spec(spec.type,
2501 int_writer<T, Spec>(*this, value, spec));
2502 }
2503
2504 enum {INF_SIZE = 3}; // This is an enum to workaround a bug in MSVC.
2505
2506 struct inf_or_nan_writer {
2507 char sign;
2508 const char *str;
2509
2510 size_t size() const {
2511 return static_cast<std::size_t>(INF_SIZE + (sign ? 1 : 0));
2512 }
2513 size_t width() const { return size(); }
2514
2515 template <typename It>
2516 void operator()(It &&it) const {
2517 if (sign)
2518 *it++ = static_cast<char_type>(sign);
2519 it = internal::copy_str<char_type>(
2520 str, str + static_cast<std::size_t>(INF_SIZE), it);
2521 }
2522 };
2523
2524 struct double_writer {
2525 size_t n;
2526 char sign;
2527 internal::buffer &buffer;
2528
2529 size_t size() const { return buffer.size() + (sign ? 1 : 0); }
2530 size_t width() const { return size(); }
2531
2532 template <typename It>
2533 void operator()(It &&it) {
2534 if (sign) {
2535 *it++ = static_cast<char_type>(sign);
2536 --n;
2537 }
2538 it = internal::copy_str<char_type>(buffer.begin(), buffer.end(), it);
2539 }
2540 };
2541
2542 // Formats a floating-point number (double or long double).
2543 template <typename T>
2544 void write_double(T value, const format_specs &spec);
2545
2546 template <typename Char>
2547 struct str_writer {
2548 const Char *s;
2549 size_t size_;
2550
2551 size_t size() const { return size_; }
2552 size_t width() const {
2553 return internal::count_code_points(basic_string_view<Char>(s, size_));
2554 }
2555
2556 template <typename It>
2557 void operator()(It &&it) const {
2558 it = internal::copy_str<char_type>(s, s + size_, it);
2559 }
2560 };
2561
2562 template <typename Char>
2563 friend class internal::arg_formatter_base;
2564
2565 public:
2566 /** Constructs a ``basic_writer`` object. */
2567 explicit basic_writer(
2568 Range out, internal::locale_ref loc = internal::locale_ref())
2569 : out_(out.begin()), locale_(loc) {}
2570
2571 iterator out() const { return out_; }
2572
2573 void write(int value) { write_decimal(value); }
2574 void write(long value) { write_decimal(value); }
2575 void write(long long value) { write_decimal(value); }
2576
2577 void write(unsigned value) { write_decimal(value); }
2578 void write(unsigned long value) { write_decimal(value); }
2579 void write(unsigned long long value) { write_decimal(value); }
2580
2581 /**
2582 \rst
2583 Formats *value* and writes it to the buffer.
2584 \endrst
2585 */
2586 template <typename T, typename FormatSpec, typename... FormatSpecs>
2587 typename std::enable_if<std::is_integral<T>::value, void>::type
2588 write(T value, FormatSpec spec, FormatSpecs... specs) {
2589 format_specs s(spec, specs...);
2590 s.align_ = ALIGN_RIGHT;
2591 write_int(value, s);
2592 }
2593
2594 void write(double value) {
2595 write_double(value, format_specs());
2596 }
2597
2598 /**
2599 \rst
2600 Formats *value* using the general format for floating-point numbers
2601 (``'g'``) and writes it to the buffer.
2602 \endrst
2603 */
2604 void write(long double value) {
2605 write_double(value, format_specs());
2606 }
2607
2608 /** Writes a character to the buffer. */
2609 void write(char value) {
2610 *reserve(1) = value;
2611 }
2612 void write(wchar_t value) {
2613 static_assert(std::is_same<char_type, wchar_t>::value, ""