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