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