DIY 3.0 data-parallel out-of-core C++ library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List

All Classes Namespaces Functions Typedefs Groups Pages
format.h
1 /*
2 Formatting library for C++
3
4 Copyright (c) 2012 - 2016, 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 #define FMT_HEADER_ONLY // Added by diy for header-only usage
32
33 #include <cassert>
34 #include <clocale>
35 #include <cmath>
36 #include <cstdio>
37 #include <cstring>
38 #include <limits>
39 #include <memory>
40 #include <stdexcept>
41 #include <string>
42 #include <vector>
43 #include <utility>
44
45 #ifdef _SECURE_SCL
46 # define FMT_SECURE_SCL _SECURE_SCL
47 #else
48 # define FMT_SECURE_SCL 0
49 #endif
50
51 #if FMT_SECURE_SCL
52 # include <iterator>
53 #endif
54
55 #if defined(_MSC_VER) && _MSC_VER <= 1500
56 typedef unsigned __int32 uint32_t;
57 typedef unsigned __int64 uint64_t;
58 typedef __int64 intmax_t;
59 #else
60 #include <stdint.h>
61 #endif
62
63 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
64 # ifdef FMT_EXPORT
65 # define FMT_API __declspec(dllexport)
66 # elif defined(FMT_SHARED)
67 # define FMT_API __declspec(dllimport)
68 # endif
69 #endif
70 #ifndef FMT_API
71 # define FMT_API
72 #endif
73
74 #ifdef __GNUC__
75 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
76 # define FMT_GCC_EXTENSION __extension__
77 # if FMT_GCC_VERSION >= 406
78 # pragma GCC diagnostic push
79 // Disable the warning about "long long" which is sometimes reported even
80 // when using __extension__.
81 # pragma GCC diagnostic ignored "-Wlong-long"
82 // Disable the warning about declaration shadowing because it affects too
83 // many valid cases.
84 # pragma GCC diagnostic ignored "-Wshadow"
85 // Disable the warning about implicit conversions that may change the sign of
86 // an integer; silencing it otherwise would require many explicit casts.
87 # pragma GCC diagnostic ignored "-Wsign-conversion"
88 # endif
89 # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
90 # define FMT_HAS_GXX_CXX11 1
91 # endif
92 #else
93 # define FMT_GCC_EXTENSION
94 #endif
95
96 #if defined(__INTEL_COMPILER)
97 # define FMT_ICC_VERSION __INTEL_COMPILER
98 #elif defined(__ICL)
99 # define FMT_ICC_VERSION __ICL
100 #endif
101
102 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
103 # pragma clang diagnostic push
104 # pragma clang diagnostic ignored "-Wdocumentation"
105 #endif
106
107 #ifdef __GNUC_LIBSTD__
108 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
109 #endif
110
111 #ifdef __has_feature
112 # define FMT_HAS_FEATURE(x) __has_feature(x)
113 #else
114 # define FMT_HAS_FEATURE(x) 0
115 #endif
116
117 #ifdef __has_builtin
118 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
119 #else
120 # define FMT_HAS_BUILTIN(x) 0
121 #endif
122
123 #ifdef __has_cpp_attribute
124 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
125 #else
126 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
127 #endif
128
129 #ifndef FMT_USE_VARIADIC_TEMPLATES
130 // Variadic templates are available in GCC since version 4.4
131 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
132 // since version 2013.
133 # define FMT_USE_VARIADIC_TEMPLATES \
134 (FMT_HAS_FEATURE(cxx_variadic_templates) || \
135 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800)
136 #endif
137
138 #ifndef FMT_USE_RVALUE_REFERENCES
139 // Don't use rvalue references when compiling with clang and an old libstdc++
140 // as the latter doesn't provide std::move.
141 # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
142 # define FMT_USE_RVALUE_REFERENCES 0
143 # else
144 # define FMT_USE_RVALUE_REFERENCES \
145 (FMT_HAS_FEATURE(cxx_rvalue_references) || \
146 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600)
147 # endif
148 #endif
149
150 #if FMT_USE_RVALUE_REFERENCES
151 # include <utility> // for std::move
152 #endif
153
154 // Check if exceptions are disabled.
155 #if defined(__GNUC__) && !defined(__EXCEPTIONS)
156 # define FMT_EXCEPTIONS 0
157 #endif
158 #if defined(_MSC_VER) && !_HAS_EXCEPTIONS
159 # define FMT_EXCEPTIONS 0
160 #endif
161 #ifndef FMT_EXCEPTIONS
162 # define FMT_EXCEPTIONS 1
163 #endif
164
165 #ifndef FMT_THROW
166 # if FMT_EXCEPTIONS
167 # define FMT_THROW(x) throw x
168 # else
169 # define FMT_THROW(x) assert(false)
170 # endif
171 #endif
172
173 // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
174 #ifndef FMT_USE_NOEXCEPT
175 # define FMT_USE_NOEXCEPT 0
176 #endif
177
178 #ifndef FMT_NOEXCEPT
179 # if FMT_EXCEPTIONS
180 # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
181 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
182 _MSC_VER >= 1900
183 # define FMT_NOEXCEPT noexcept
184 # else
185 # define FMT_NOEXCEPT throw()
186 # endif
187 # else
188 # define FMT_NOEXCEPT
189 # endif
190 #endif
191
192 // A macro to disallow the copy constructor and operator= functions
193 // This should be used in the private: declarations for a class
194 #ifndef FMT_USE_DELETED_FUNCTIONS
195 # define FMT_USE_DELETED_FUNCTIONS 0
196 #endif
197
198 #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \
199 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800
200 # define FMT_DELETED_OR_UNDEFINED = delete
201 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
202 TypeName(const TypeName&) = delete; \
203 TypeName& operator=(const TypeName&) = delete
204 #else
205 # define FMT_DELETED_OR_UNDEFINED
206 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
207 TypeName(const TypeName&); \
208 TypeName& operator=(const TypeName&)
209 #endif
210
211 #ifndef FMT_USE_USER_DEFINED_LITERALS
212 // All compilers which support UDLs also support variadic templates. This
213 // makes the fmt::literals implementation easier. However, an explicit check
214 // for variadic templates is added here just in case.
215 // For Intel's compiler both it and the system gcc/msc must support UDLs.
216 # define FMT_USE_USER_DEFINED_LITERALS \
217 FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
218 (FMT_HAS_FEATURE(cxx_user_literals) || \
219 (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) && \
220 (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
221 #endif
222
223 #ifndef FMT_ASSERT
224 # define FMT_ASSERT(condition, message) assert((condition) && message)
225 #endif
226
227
228 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
229 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
230 #endif
231
232 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
233 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
234 #endif
235
236 // Some compilers masquerade as both MSVC and GCC-likes or
237 // otherwise support __builtin_clz and __builtin_clzll, so
238 // only define FMT_BUILTIN_CLZ using the MSVC intrinsics
239 // if the clz and clzll builtins are not available.
240 #if defined(_MSC_VER) && !defined(FMT_BUILTIN_CLZLL)
241 # include <intrin.h> // _BitScanReverse, _BitScanReverse64
242
243 namespace fmt {
244 namespace internal {
245 # pragma intrinsic(_BitScanReverse)
246 inline uint32_t clz(uint32_t x) {
247 unsigned long r = 0;
248 _BitScanReverse(&r, x);
249
250 assert(x != 0);
251 // Static analysis complains about using uninitialized data
252 // "r", but the only way that can happen is if "x" is 0,
253 // which the callers guarantee to not happen.
254 # pragma warning(suppress: 6102)
255 return 31 - r;
256 }
257 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
258
259 # ifdef _WIN64
260 # pragma intrinsic(_BitScanReverse64)
261 # endif
262
263 inline uint32_t clzll(uint64_t x) {
264 unsigned long r = 0;
265 # ifdef _WIN64
266 _BitScanReverse64(&r, x);
267 # else
268 // Scan the high 32 bits.
269 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
270 return 63 - (r + 32);
271
272 // Scan the low 32 bits.
273 _BitScanReverse(&r, static_cast<uint32_t>(x));
274 # endif
275
276 assert(x != 0);
277 // Static analysis complains about using uninitialized data
278 // "r", but the only way that can happen is if "x" is 0,
279 // which the callers guarantee to not happen.
280 # pragma warning(suppress: 6102)
281 return 63 - r;
282 }
283 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
284 }
285 }
286 #endif
287
288 namespace fmt {
289 namespace internal {
290 struct DummyInt {
291 int data[2];
292 operator int() const { return 0; }
293 };
294 typedef std::numeric_limits<fmt::internal::DummyInt> FPUtil;
295
296 // Dummy implementations of system functions such as signbit and ecvt called
297 // if the latter are not available.
298 inline DummyInt signbit(...) { return DummyInt(); }
299 inline DummyInt _ecvt_s(...) { return DummyInt(); }
300 inline DummyInt isinf(...) { return DummyInt(); }
301 inline DummyInt _finite(...) { return DummyInt(); }
302 inline DummyInt isnan(...) { return DummyInt(); }
303 inline DummyInt _isnan(...) { return DummyInt(); }
304
305 // A helper function to suppress bogus "conditional expression is constant"
306 // warnings.
307 template <typename T>
308 inline T check(T value) { return value; }
309 }
310 } // namespace fmt
311
312 namespace std {
313 // Standard permits specialization of std::numeric_limits. This specialization
314 // is used to resolve ambiguity between isinf and std::isinf in glibc:
315 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
316 // and the same for isnan and signbit.
317 template <>
318 class numeric_limits<fmt::internal::DummyInt> :
319 public std::numeric_limits<int> {
320 public:
321 // Portable version of isinf.
322 template <typename T>
323 static bool isinfinity(T x) {
324 using namespace fmt::internal;
325 // The resolution "priority" is:
326 // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
327 if (check(sizeof(isinf(x)) == sizeof(bool) ||
328 sizeof(isinf(x)) == sizeof(int))) {
329 return isinf(x) != 0;
330 }
331 return !_finite(static_cast<double>(x));
332 }
333
334 // Portable version of isnan.
335 template <typename T>
336 static bool isnotanumber(T x) {
337 using namespace fmt::internal;
338 if (check(sizeof(isnan(x)) == sizeof(bool) ||
339 sizeof(isnan(x)) == sizeof(int))) {
340 return isnan(x) != 0;
341 }
342 return _isnan(static_cast<double>(x)) != 0;
343 }
344
345 // Portable version of signbit.
346 static bool isnegative(double x) {
347 using namespace fmt::internal;
348 if (check(sizeof(signbit(x)) == sizeof(int)))
349 return signbit(x) != 0;
350 if (x < 0) return true;
351 if (!isnotanumber(x)) return false;
352 int dec = 0, sign = 0;
353 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
354 _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
355 return sign != 0;
356 }
357 };
358 } // namespace std
359
360 namespace fmt {
361
362 // Fix the warning about long long on older versions of GCC
363 // that don't support the diagnostic pragma.
364 FMT_GCC_EXTENSION typedef long long LongLong;
365 FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
366
367 #if FMT_USE_RVALUE_REFERENCES
368 using std::move;
369 #endif
370
371 template <typename Char>
372 class BasicWriter;
373
374 typedef BasicWriter<char> Writer;
375 typedef BasicWriter<wchar_t> WWriter;
376
377 template <typename Char>
378 class ArgFormatter;
379
380 template <typename CharType,
381 typename ArgFormatter = fmt::ArgFormatter<CharType> >
382 class BasicFormatter;
383
408 template <typename Char>
409 class BasicStringRef {
410 private:
411 const Char *data_;
412 std::size_t size_;
413
414 public:
416 BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {}
417
424 BasicStringRef(const Char *s)
425 : data_(s), size_(std::char_traits<Char>::length(s)) {}
426
432 BasicStringRef(const std::basic_string<Char> &s)
433 : data_(s.c_str()), size_(s.size()) {}
434
440 std::basic_string<Char> to_string() const {
441 return std::basic_string<Char>(data_, size_);
442 }
443
445 const Char *data() const { return data_; }
446
448 std::size_t size() const { return size_; }
449
450 // Lexicographically compare this string reference to other.
451 int compare(BasicStringRef other) const {
452 std::size_t size = size_ < other.size_ ? size_ : other.size_;
453 int result = std::char_traits<Char>::compare(data_, other.data_, size);
454 if (result == 0)
455 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
456 return result;
457 }
458
459 friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
460 return lhs.compare(rhs) == 0;
461 }
462 friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
463 return lhs.compare(rhs) != 0;
464 }
465 friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) {
466 return lhs.compare(rhs) < 0;
467 }
468 friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) {
469 return lhs.compare(rhs) <= 0;
470 }
471 friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) {
472 return lhs.compare(rhs) > 0;
473 }
474 friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) {
475 return lhs.compare(rhs) >= 0;
476 }
477 };
478
479 typedef BasicStringRef<char> StringRef;
480 typedef BasicStringRef<wchar_t> WStringRef;
481
507 template <typename Char>
508 class BasicCStringRef {
509 private:
510 const Char *data_;
511
512 public:
514 BasicCStringRef(const Char *s) : data_(s) {}
515
521 BasicCStringRef(const std::basic_string<Char> &s) : data_(s.c_str()) {}
522
524 const Char *c_str() const { return data_; }
525 };
526
527 typedef BasicCStringRef<char> CStringRef;
528 typedef BasicCStringRef<wchar_t> WCStringRef;
529
533 class FormatError : public std::runtime_error {
534 public:
535 explicit FormatError(CStringRef message)
536 : std::runtime_error(message.c_str()) {}
537 };
538
539 namespace internal {
540
541 // MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
542 template <typename T>
543 struct MakeUnsigned { typedef T Type; };
544
545 #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
546 template <> \
547 struct MakeUnsigned<T> { typedef U Type; }
548
549 FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
550 FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
551 FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
552 FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
553 FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
554 FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
555
556 // Casts nonnegative integer to unsigned.
557 template <typename Int>
558 inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
559 FMT_ASSERT(value >= 0, "negative value");
560 return static_cast<typename MakeUnsigned<Int>::Type>(value);
561 }
562
563 // The number of characters to store in the MemoryBuffer object itself
564 // to avoid dynamic memory allocation.
565 enum { INLINE_BUFFER_SIZE = 500 };
566
567 #if FMT_SECURE_SCL
568 // Use checked iterator to avoid warnings on MSVC.
569 template <typename T>
570 inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
571 return stdext::checked_array_iterator<T*>(ptr, size);
572 }
573 #else
574 template <typename T>
575 inline T *make_ptr(T *ptr, std::size_t) { return ptr; }
576 #endif
577 } // namespace internal
578
584 template <typename T>
585 class Buffer {
586 private:
587 FMT_DISALLOW_COPY_AND_ASSIGN(Buffer);
588
589 protected:
590 T *ptr_;
591 std::size_t size_;
592 std::size_t capacity_;
593
594 Buffer(T *ptr = 0, std::size_t capacity = 0)
595 : ptr_(ptr), size_(0), capacity_(capacity) {}
596
603 virtual void grow(std::size_t size) = 0;
604
605 public:
606 virtual ~Buffer() {}
607
609 std::size_t size() const { return size_; }
610
612 std::size_t capacity() const { return capacity_; }
613
617 void resize(std::size_t new_size) {
618 if (new_size > capacity_)
619 grow(new_size);
620 size_ = new_size;
621 }
622
628 void reserve(std::size_t capacity) {
629 if (capacity > capacity_)
630 grow(capacity);
631 }
632
633 void clear() FMT_NOEXCEPT { size_ = 0; }
634
635 void push_back(const T &value) {
636 if (size_ == capacity_)
637 grow(size_ + 1);
638 ptr_[size_++] = value;
639 }
640
642 template <typename U>
643 void append(const U *begin, const U *end);
644
645 T &operator[](std::size_t index) { return ptr_[index]; }
646 const T &operator[](std::size_t index) const { return ptr_[index]; }
647 };
648
649 template <typename T>
650 template <typename U>
651 void Buffer<T>::append(const U *begin, const U *end) {
652 std::size_t new_size = size_ + internal::to_unsigned(end - begin);
653 if (new_size > capacity_)
654 grow(new_size);
655 std::uninitialized_copy(begin, end,
656 internal::make_ptr(ptr_, capacity_) + size_);
657 size_ = new_size;
658 }
659
660 namespace internal {
661
662 // A memory buffer for trivially copyable/constructible types with the first SIZE
663 // elements stored in the object itself.
664 template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
665 class MemoryBuffer : private Allocator, public Buffer<T> {
666 private:
667 T data_[SIZE];
668
669 // Deallocate memory allocated by the buffer.
670 void deallocate() {
671 if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
672 }
673
674 protected:
675 void grow(std::size_t size);
676
677 public:
678 explicit MemoryBuffer(const Allocator &alloc = Allocator())
679 : Allocator(alloc), Buffer<T>(data_, SIZE) {}
680 ~MemoryBuffer() { deallocate(); }
681
682 #if FMT_USE_RVALUE_REFERENCES
683 private:
684 // Move data from other to this buffer.
685 void move(MemoryBuffer &other) {
686 Allocator &this_alloc = *this, &other_alloc = other;
687 this_alloc = std::move(other_alloc);
688 this->size_ = other.size_;
689 this->capacity_ = other.capacity_;
690 if (other.ptr_ == other.data_) {
691 this->ptr_ = data_;
692 std::uninitialized_copy(other.data_, other.data_ + this->size_,
693 make_ptr(data_, this->capacity_));
694 } else {
695 this->ptr_ = other.ptr_;
696 // Set pointer to the inline array so that delete is not called
697 // when deallocating.
698 other.ptr_ = other.data_;
699 }
700 }
701
702 public:
703 MemoryBuffer(MemoryBuffer &&other) {
704 move(other);
705 }
706
707 MemoryBuffer &operator=(MemoryBuffer &&other) {
708 assert(this != &other);
709 deallocate();
710 move(other);
711 return *this;
712 }
713 #endif
714
715 // Returns a copy of the allocator associated with this buffer.
716 Allocator get_allocator() const { return *this; }
717 };
718
719 template <typename T, std::size_t SIZE, typename Allocator>
720 void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
721 std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
722 if (size > new_capacity)
723 new_capacity = size;
724 T *new_ptr = this->allocate(new_capacity);
725 // The following code doesn't throw, so the raw pointer above doesn't leak.
726 std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
727 make_ptr(new_ptr, new_capacity));
728 std::size_t old_capacity = this->capacity_;
729 T *old_ptr = this->ptr_;
730 this->capacity_ = new_capacity;
731 this->ptr_ = new_ptr;
732 // deallocate may throw (at least in principle), but it doesn't matter since
733 // the buffer already uses the new storage and will deallocate it in case
734 // of exception.
735 if (old_ptr != data_)
736 Allocator::deallocate(old_ptr, old_capacity);
737 }
738
739 // A fixed-size buffer.
740 template <typename Char>
741 class FixedBuffer : public fmt::Buffer<Char> {
742 public:
743 FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
744
745 protected:
746 FMT_API void grow(std::size_t size);
747 };
748
749 template <typename Char>
750 class BasicCharTraits {
751 public:
752 #if FMT_SECURE_SCL
753 typedef stdext::checked_array_iterator<Char*> CharPtr;
754 #else
755 typedef Char *CharPtr;
756 #endif
757 static Char cast(int value) { return static_cast<Char>(value); }
758 };
759
760 template <typename Char>
761 class CharTraits;
762
763 template <>
764 class CharTraits<char> : public BasicCharTraits<char> {
765 private:
766 // Conversion from wchar_t to char is not allowed.
767 static char convert(wchar_t);
768
769 public:
770 static char convert(char value) { return value; }
771
772 // Formats a floating-point number.
773 template <typename T>
774 FMT_API static int format_float(char *buffer, std::size_t size,
775 const char *format, unsigned width, int precision, T value);
776 };
777
778 template <>
779 class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
780 public:
781 static wchar_t convert(char value) { return value; }
782 static wchar_t convert(wchar_t value) { return value; }
783
784 template <typename T>
785 FMT_API static int format_float(wchar_t *buffer, std::size_t size,
786 const wchar_t *format, unsigned width, int precision, T value);
787 };
788
789 // Checks if a number is negative - used to avoid warnings.
790 template <bool IsSigned>
791 struct SignChecker {
792 template <typename T>
793 static bool is_negative(T value) { return value < 0; }
794 };
795
796 template <>
797 struct SignChecker<false> {
798 template <typename T>
799 static bool is_negative(T) { return false; }
800 };
801
802 // Returns true if value is negative, false otherwise.
803 // Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
804 template <typename T>
805 inline bool is_negative(T value) {
806 return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value);
807 }
808
809 // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
810 template <bool FitsIn32Bits>
811 struct TypeSelector { typedef uint32_t Type; };
812
813 template <>
814 struct TypeSelector<false> { typedef uint64_t Type; };
815
816 template <typename T>
817 struct IntTraits {
818 // Smallest of uint32_t and uint64_t that is large enough to represent
819 // all values of T.
820 typedef typename
821 TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
822 };
823
824 FMT_API void report_unknown_type(char code, const char *type);
825
826 // Static data is placed in this class template to allow header-only
827 // configuration.
828 template <typename T = void>
829 struct FMT_API BasicData {
830 static const uint32_t POWERS_OF_10_32[];
831 static const uint64_t POWERS_OF_10_64[];
832 static const char DIGITS[];
833 };
834
835 typedef BasicData<> Data;
836
837 #ifdef FMT_BUILTIN_CLZLL
838 // Returns the number of decimal digits in n. Leading zeros are not counted
839 // except for n == 0 in which case count_digits returns 1.
840 inline unsigned count_digits(uint64_t n) {
841 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
842 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
843 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
844 return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
845 }
846 #else
847 // Fallback version of count_digits used when __builtin_clz is not available.
848 inline unsigned count_digits(uint64_t n) {
849 unsigned count = 1;
850 for (;;) {
851 // Integer division is slow so do it for a group of four digits instead
852 // of for every digit. The idea comes from the talk by Alexandrescu
853 // "Three Optimization Tips for C++". See speed-test for a comparison.
854 if (n < 10) return count;
855 if (n < 100) return count + 1;
856 if (n < 1000) return count + 2;
857 if (n < 10000) return count + 3;
858 n /= 10000u;
859 count += 4;
860 }
861 }
862 #endif
863
864 #ifdef FMT_BUILTIN_CLZ
865 // Optional version of count_digits for better performance on 32-bit platforms.
866 inline unsigned count_digits(uint32_t n) {
867 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
868 return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
869 }
870 #endif
871
872 // A functor that doesn't add a thousands separator.
873 struct NoThousandsSep {
874 template <typename Char>
875 void operator()(Char *) {}
876 };
877
878 // A functor that adds a thousands separator.
879 class ThousandsSep {
880 private:
881 fmt::StringRef sep_;
882
883 // Index of a decimal digit with the least significant digit having index 0.
884 unsigned digit_index_;
885
886 public:
887 explicit ThousandsSep(fmt::StringRef sep) : sep_(sep), digit_index_(0) {}
888
889 template <typename Char>
890 void operator()(Char *&buffer) {
891 if (++digit_index_ % 3 != 0)
892 return;
893 buffer -= sep_.size();
894 std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
895 internal::make_ptr(buffer, sep_.size()));
896 }
897 };
898
899 // Formats a decimal unsigned integer value writing into buffer.
900 // thousands_sep is a functor that is called after writing each char to
901 // add a thousands separator if necessary.
902 template <typename UInt, typename Char, typename ThousandsSep>
903 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
904 ThousandsSep thousands_sep) {
905 buffer += num_digits;
906 while (value >= 100) {
907 // Integer division is slow so do it for a group of two digits instead
908 // of for every digit. The idea comes from the talk by Alexandrescu
909 // "Three Optimization Tips for C++". See speed-test for a comparison.
910 unsigned index = static_cast<unsigned>((value % 100) * 2);
911 value /= 100;
912 *--buffer = Data::DIGITS[index + 1];
913 thousands_sep(buffer);
914 *--buffer = Data::DIGITS[index];
915 thousands_sep(buffer);
916 }
917 if (value < 10) {
918 *--buffer = static_cast<char>('0' + value);
919 return;
920 }
921 unsigned index = static_cast<unsigned>(value * 2);
922 *--buffer = Data::DIGITS[index + 1];
923 *--buffer = Data::DIGITS[index];
924 }
925
926 template <typename UInt, typename Char>
927 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
928 return format_decimal(buffer, value, num_digits, NoThousandsSep());
929 }
930
931 #ifndef _WIN32
932 # define FMT_USE_WINDOWS_H 0
933 #elif !defined(FMT_USE_WINDOWS_H)
934 # define FMT_USE_WINDOWS_H 1
935 #endif
936
937 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
938 // All the functionality that relies on it will be disabled too.
939 #if FMT_USE_WINDOWS_H
940 // A converter from UTF-8 to UTF-16.
941 // It is only provided for Windows since other systems support UTF-8 natively.
942 class UTF8ToUTF16 {
943 private:
944 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
945
946 public:
947 FMT_API explicit UTF8ToUTF16(StringRef s);
948 operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
949 size_t size() const { return buffer_.size() - 1; }
950 const wchar_t *c_str() const { return &buffer_[0]; }
951 std::wstring str() const { return std::wstring(&buffer_[0], size()); }
952 };
953
954 // A converter from UTF-16 to UTF-8.
955 // It is only provided for Windows since other systems support UTF-8 natively.
956 class UTF16ToUTF8 {
957 private:
958 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_;
959
960 public:
961 UTF16ToUTF8() {}
962 FMT_API explicit UTF16ToUTF8(WStringRef s);
963 operator StringRef() const { return StringRef(&buffer_[0], size()); }
964 size_t size() const { return buffer_.size() - 1; }
965 const char *c_str() const { return &buffer_[0]; }
966 std::string str() const { return std::string(&buffer_[0], size()); }
967
968 // Performs conversion returning a system error code instead of
969 // throwing exception on conversion error. This method may still throw
970 // in case of memory allocation error.
971 FMT_API int convert(WStringRef s);
972 };
973
974 FMT_API void format_windows_error(fmt::Writer &out, int error_code,
975 fmt::StringRef message) FMT_NOEXCEPT;
976 #endif
977
978 FMT_API void format_system_error(fmt::Writer &out, int error_code,
979 fmt::StringRef message) FMT_NOEXCEPT;
980
981 // A formatting argument value.
982 struct Value {
983 template <typename Char>
984 struct StringValue {
985 const Char *value;
986 std::size_t size;
987 };
988
989 typedef void (*FormatFunc)(
990 void *formatter, const void *arg, void *format_str_ptr);
991
992 struct CustomValue {
993 const void *value;
994 FormatFunc format;
995 };
996
997 union {
998 int int_value;
999 unsigned uint_value;
1000 LongLong long_long_value;
1001 ULongLong ulong_long_value;
1002 double double_value;
1003 long double long_double_value;
1004 const void *pointer;
1005 StringValue<char> string;
1006 StringValue<signed char> sstring;
1007 StringValue<unsigned char> ustring;
1008 StringValue<wchar_t> wstring;
1009 CustomValue custom;
1010 };
1011
1012 enum Type {
1013 NONE, NAMED_ARG,
1014 // Integer types should go first,
1015 INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
1016 // followed by floating-point types.
1017 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
1018 CSTRING, STRING, WSTRING, POINTER, CUSTOM
1019 };
1020 };
1021
1022 // A formatting argument. It is a trivially copyable/constructible type to
1023 // allow storage in internal::MemoryBuffer.
1024 struct Arg : Value {
1025 Type type;
1026 };
1027
1028 template <typename Char>
1029 struct NamedArg;
1030
1031 template <typename T = void>
1032 struct Null {};
1033
1034 // A helper class template to enable or disable overloads taking wide
1035 // characters and strings in MakeValue.
1036 template <typename T, typename Char>
1037 struct WCharHelper {
1038 typedef Null<T> Supported;
1039 typedef T Unsupported;
1040 };
1041
1042 template <typename T>
1043 struct WCharHelper<T, wchar_t> {
1044 typedef T Supported;
1045 typedef Null<T> Unsupported;
1046 };
1047
1048 typedef char Yes[1];
1049 typedef char No[2];
1050
1051 template <typename T>
1052 T &get();
1053
1054 // These are non-members to workaround an overload resolution bug in bcc32.
1055 Yes &convert(fmt::ULongLong);
1056 No &convert(...);
1057
1058 template<typename T, bool ENABLE_CONVERSION>
1059 struct ConvertToIntImpl {
1060 enum { value = ENABLE_CONVERSION };
1061 };
1062
1063 template<typename T, bool ENABLE_CONVERSION>
1064 struct ConvertToIntImpl2 {
1065 enum { value = false };
1066 };
1067
1068 template<typename T>
1069 struct ConvertToIntImpl2<T, true> {
1070 enum {
1071 // Don't convert numeric types.
1072 value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value
1073 };
1074 };
1075
1076 template<typename T>
1077 struct ConvertToInt {
1078 enum { enable_conversion = sizeof(convert(get<T>())) == sizeof(Yes) };
1079 enum { value = ConvertToIntImpl2<T, enable_conversion>::value };
1080 };
1081
1082 #define FMT_DISABLE_CONVERSION_TO_INT(Type) \
1083 template <> \
1084 struct ConvertToInt<Type> { enum { value = 0 }; }
1085
1086 // Silence warnings about convering float to int.
1087 FMT_DISABLE_CONVERSION_TO_INT(float);
1088 FMT_DISABLE_CONVERSION_TO_INT(double);
1089 FMT_DISABLE_CONVERSION_TO_INT(long double);
1090
1091 template<bool B, class T = void>
1092 struct EnableIf {};
1093
1094 template<class T>
1095 struct EnableIf<true, T> { typedef T type; };
1096
1097 template<bool B, class T, class F>
1098 struct Conditional { typedef T type; };
1099
1100 template<class T, class F>
1101 struct Conditional<false, T, F> { typedef F type; };
1102
1103 // For bcc32 which doesn't understand ! in template arguments.
1104 template<bool>
1105 struct Not { enum { value = 0 }; };
1106
1107 template<>
1108 struct Not<false> { enum { value = 1 }; };
1109
1110 // Makes an Arg object from any type.
1111 template <typename Formatter>
1112 class MakeValue : public Arg {
1113 public:
1114 typedef typename Formatter::Char Char;
1115
1116 private:
1117 // The following two methods are private to disallow formatting of
1118 // arbitrary pointers. If you want to output a pointer cast it to
1119 // "void *" or "const void *". In particular, this forbids formatting
1120 // of "[const] volatile char *" which is printed as bool by iostreams.
1121 // Do not implement!
1122 template <typename T>
1123 MakeValue(const T *value);
1124 template <typename T>
1125 MakeValue(T *value);
1126
1127 // The following methods are private to disallow formatting of wide
1128 // characters and strings into narrow strings as in
1129 // fmt::format("{}", L"test");
1130 // To fix this, use a wide format string: fmt::format(L"{}", L"test").
1131 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1132 MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported);
1133 #endif
1134 MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
1135 MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
1136 MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
1137 MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
1138
1139 void set_string(StringRef str) {
1140 string.value = str.data();
1141 string.size = str.size();
1142 }
1143
1144 void set_string(WStringRef str) {
1145 wstring.value = str.data();
1146 wstring.size = str.size();
1147 }
1148
1149 // Formats an argument of a custom type, such as a user-defined class.
1150 template <typename T>
1151 static void format_custom_arg(
1152 void *formatter, const void *arg, void *format_str_ptr) {
1153 format(*static_cast<Formatter*>(formatter),
1154 *static_cast<const Char**>(format_str_ptr),
1155 *static_cast<const T*>(arg));
1156 }
1157
1158 public:
1159 MakeValue() {}
1160
1161 #define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
1162 MakeValue(Type value) { field = rhs; } \
1163 static uint64_t type(Type) { return Arg::TYPE; }
1164
1165 #define FMT_MAKE_VALUE(Type, field, TYPE) \
1166 FMT_MAKE_VALUE_(Type, field, TYPE, value)
1167
1168 FMT_MAKE_VALUE(bool, int_value, BOOL)
1169 FMT_MAKE_VALUE(short, int_value, INT)
1170 FMT_MAKE_VALUE(unsigned short, uint_value, UINT)
1171 FMT_MAKE_VALUE(int, int_value, INT)
1172 FMT_MAKE_VALUE(unsigned, uint_value, UINT)
1173
1174 MakeValue(long value) {
1175 // To minimize the number of types we need to deal with, long is
1176 // translated either to int or to long long depending on its size.
1177 if (check(sizeof(long) == sizeof(int)))
1178 int_value = static_cast<int>(value);
1179 else
1180 long_long_value = value;
1181 }
1182 static uint64_t type(long) {
1183 return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG;
1184 }
1185
1186 MakeValue(unsigned long value) {
1187 if (check(sizeof(unsigned long) == sizeof(unsigned)))
1188 uint_value = static_cast<unsigned>(value);
1189 else
1190 ulong_long_value = value;
1191 }
1192 static uint64_t type(unsigned long) {
1193 return sizeof(unsigned long) == sizeof(unsigned) ?
1194 Arg::UINT : Arg::ULONG_LONG;
1195 }
1196
1197 FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG)
1198 FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG)
1199 FMT_MAKE_VALUE(float, double_value, DOUBLE)
1200 FMT_MAKE_VALUE(double, double_value, DOUBLE)
1201 FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE)
1202 FMT_MAKE_VALUE(signed char, int_value, INT)
1203 FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
1204 FMT_MAKE_VALUE(char, int_value, CHAR)
1205
1206 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1207 MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) {
1208 int_value = value;
1209 }
1210 static uint64_t type(wchar_t) { return Arg::CHAR; }
1211 #endif
1212
1213 #define FMT_MAKE_STR_VALUE(Type, TYPE) \
1214 MakeValue(Type value) { set_string(value); } \
1215 static uint64_t type(Type) { return Arg::TYPE; }
1216
1217 FMT_MAKE_VALUE(char *, string.value, CSTRING)
1218 FMT_MAKE_VALUE(const char *, string.value, CSTRING)
1219 FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING)
1220 FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING)
1221 FMT_MAKE_STR_VALUE(const std::string &, STRING)
1222 FMT_MAKE_STR_VALUE(StringRef, STRING)
1223 FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
1224
1225 #define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
1226 MakeValue(typename WCharHelper<Type, Char>::Supported value) { \
1227 set_string(value); \
1228 } \
1229 static uint64_t type(Type) { return Arg::TYPE; }
1230
1231 FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
1232 FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
1233 FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING)
1234 FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
1235
1236 FMT_MAKE_VALUE(void *, pointer, POINTER)
1237 FMT_MAKE_VALUE(const void *, pointer, POINTER)
1238
1239 template <typename T>
1240 MakeValue(const T &value,
1241 typename EnableIf<Not<
1242 ConvertToInt<T>::value>::value, int>::type = 0) {
1243 custom.value = &value;
1244 custom.format = &format_custom_arg<T>;
1245 }
1246
1247 template <typename T>
1248 MakeValue(const T &value,
1249 typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
1250 int_value = value;
1251 }
1252
1253 template <typename T>
1254 static uint64_t type(const T &) {
1255 return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM;
1256 }
1257
1258 // Additional template param `Char_` is needed here because make_type always
1259 // uses char.
1260 template <typename Char_>
1261 MakeValue(const NamedArg<Char_> &value) { pointer = &value; }
1262
1263 template <typename Char_>
1264 static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
1265 };
1266
1267 template <typename Formatter>
1268 class MakeArg : public Arg {
1269 public:
1270 MakeArg() {
1271 type = Arg::NONE;
1272 }
1273
1274 template <typename T>
1275 MakeArg(const T &value)
1276 : Arg(MakeValue<Formatter>(value)) {
1277 type = static_cast<Arg::Type>(MakeValue<Formatter>::type(value));
1278 }
1279 };
1280
1281 template <typename Char>
1282 struct NamedArg : Arg {
1283 BasicStringRef<Char> name;
1284
1285 template <typename T>
1286 NamedArg(BasicStringRef<Char> argname, const T &value)
1287 : Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
1288 };
1289
1290 class RuntimeError : public std::runtime_error {
1291 protected:
1292 RuntimeError() : std::runtime_error("") {}
1293 };
1294
1295 template <typename Char>
1296 class PrintfArgFormatter;
1297
1298 template <typename Char>
1299 class ArgMap;
1300 } // namespace internal
1301
1303 class ArgList {
1304 private:
1305 // To reduce compiled code size per formatting function call, types of first
1306 // MAX_PACKED_ARGS arguments are passed in the types_ field.
1307 uint64_t types_;
1308 union {
1309 // If the number of arguments is less than MAX_PACKED_ARGS, the argument
1310 // values are stored in values_, otherwise they are stored in args_.
1311 // This is done to reduce compiled code size as storing larger objects
1312 // may require more code (at least on x86-64) even if the same amount of
1313 // data is actually copied to stack. It saves ~10% on the bloat test.
1314 const internal::Value *values_;
1315 const internal::Arg *args_;
1316 };
1317
1318 internal::Arg::Type type(unsigned index) const {
1319 unsigned shift = index * 4;
1320 uint64_t mask = 0xf;
1321 return static_cast<internal::Arg::Type>(
1322 (types_ & (mask << shift)) >> shift);
1323 }
1324
1325 template <typename Char>
1326 friend class internal::ArgMap;
1327
1328 public:
1329 // Maximum number of arguments with packed types.
1330 enum { MAX_PACKED_ARGS = 16 };
1331
1332 ArgList() : types_(0) {}
1333
1334 ArgList(ULongLong types, const internal::Value *values)
1335 : types_(types), values_(values) {}
1336 ArgList(ULongLong types, const internal::Arg *args)
1337 : types_(types), args_(args) {}
1338
1340 internal::Arg operator[](unsigned index) const {
1341 using internal::Arg;
1342 Arg arg;
1343 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1344 if (index < MAX_PACKED_ARGS) {
1345 Arg::Type arg_type = type(index);
1346 internal::Value &val = arg;
1347 if (arg_type != Arg::NONE)
1348 val = use_values ? values_[index] : args_[index];
1349 arg.type = arg_type;
1350 return arg;
1351 }
1352 if (use_values) {
1353 // The index is greater than the number of arguments that can be stored
1354 // in values, so return a "none" argument.
1355 arg.type = Arg::NONE;
1356 return arg;
1357 }
1358 for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1359 if (args_[i].type == Arg::NONE)
1360 return args_[i];
1361 }
1362 return args_[index];
1363 }
1364 };
1365
1366 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
1367
1392 template <typename Impl, typename Result>
1393 class ArgVisitor {
1394 private:
1395 typedef internal::Arg Arg;
1396
1397 public:
1398 void report_unhandled_arg() {}
1399
1400 Result visit_unhandled_arg() {
1401 FMT_DISPATCH(report_unhandled_arg());
1402 return Result();
1403 }
1404
1406 Result visit_int(int value) {
1407 return FMT_DISPATCH(visit_any_int(value));
1408 }
1409
1411 Result visit_long_long(LongLong value) {
1412 return FMT_DISPATCH(visit_any_int(value));
1413 }
1414
1416 Result visit_uint(unsigned value) {
1417 return FMT_DISPATCH(visit_any_int(value));
1418 }
1419
1421 Result visit_ulong_long(ULongLong value) {
1422 return FMT_DISPATCH(visit_any_int(value));
1423 }
1424
1426 Result visit_bool(bool value) {
1427 return FMT_DISPATCH(visit_any_int(value));
1428 }
1429
1431 Result visit_char(int value) {
1432 return FMT_DISPATCH(visit_any_int(value));
1433 }
1434
1436 template <typename T>
1437 Result visit_any_int(T) {
1438 return FMT_DISPATCH(visit_unhandled_arg());
1439 }
1440
1442 Result visit_double(double value) {
1443 return FMT_DISPATCH(visit_any_double(value));
1444 }
1445
1447 Result visit_long_double(long double value) {
1448 return FMT_DISPATCH(visit_any_double(value));
1449 }
1450
1452 template <typename T>
1453 Result visit_any_double(T) {
1454 return FMT_DISPATCH(visit_unhandled_arg());
1455 }
1456
1458 Result visit_cstring(const char *) {
1459 return FMT_DISPATCH(visit_unhandled_arg());
1460 }
1461
1463 Result visit_string(Arg::StringValue<char>) {
1464 return FMT_DISPATCH(visit_unhandled_arg());
1465 }
1466
1468 Result visit_wstring(Arg::StringValue<wchar_t>) {
1469 return FMT_DISPATCH(visit_unhandled_arg());
1470 }
1471
1473 Result visit_pointer(const void *) {
1474 return FMT_DISPATCH(visit_unhandled_arg());
1475 }
1476
1478 Result visit_custom(Arg::CustomValue) {
1479 return FMT_DISPATCH(visit_unhandled_arg());
1480 }
1481
1490 Result visit(const Arg &arg) {
1491 switch (arg.type) {
1492 default:
1493 FMT_ASSERT(false, "invalid argument type");
1494 return Result();
1495 case Arg::INT:
1496 return FMT_DISPATCH(visit_int(arg.int_value));
1497 case Arg::UINT:
1498 return FMT_DISPATCH(visit_uint(arg.uint_value));
1499 case Arg::LONG_LONG:
1500 return FMT_DISPATCH(visit_long_long(arg.long_long_value));
1501 case Arg::ULONG_LONG:
1502 return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
1503 case Arg::BOOL:
1504 return FMT_DISPATCH(visit_bool(arg.int_value != 0));
1505 case Arg::CHAR:
1506 return FMT_DISPATCH(visit_char(arg.int_value));
1507 case Arg::DOUBLE:
1508 return FMT_DISPATCH(visit_double(arg.double_value));
1509 case Arg::LONG_DOUBLE:
1510 return FMT_DISPATCH(visit_long_double(arg.long_double_value));
1511 case Arg::CSTRING:
1512 return FMT_DISPATCH(visit_cstring(arg.string.value));
1513 case Arg::STRING:
1514 return FMT_DISPATCH(visit_string(arg.string));
1515 case Arg::WSTRING:
1516 return FMT_DISPATCH(visit_wstring(arg.wstring));
1517 case Arg::POINTER:
1518 return FMT_DISPATCH(visit_pointer(arg.pointer));
1519 case Arg::CUSTOM:
1520 return FMT_DISPATCH(visit_custom(arg.custom));
1521 }
1522 }
1523 };
1524
1525 enum Alignment {
1526 ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
1527 };
1528
1529 // Flags.
1530 enum {
1531 SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8,
1532 CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
1533 };
1534
1535 // An empty format specifier.
1536 struct EmptySpec {};
1537
1538 // A type specifier.
1539 template <char TYPE>
1540 struct TypeSpec : EmptySpec {
1541 Alignment align() const { return ALIGN_DEFAULT; }
1542 unsigned width() const { return 0; }
1543 int precision() const { return -1; }
1544 bool flag(unsigned) const { return false; }
1545 char type() const { return TYPE; }
1546 char fill() const { return ' '; }
1547 };
1548
1549 // A width specifier.
1550 struct WidthSpec {
1551 unsigned width_;
1552 // Fill is always wchar_t and cast to char if necessary to avoid having
1553 // two specialization of WidthSpec and its subclasses.
1554 wchar_t fill_;
1555
1556 WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {}
1557
1558 unsigned width() const { return width_; }
1559 wchar_t fill() const { return fill_; }
1560 };
1561
1562 // An alignment specifier.
1563 struct AlignSpec : WidthSpec {
1564 Alignment align_;
1565
1566 AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT)
1567 : WidthSpec(width, fill), align_(align) {}
1568
1569 Alignment align() const { return align_; }
1570
1571 int precision() const { return -1; }
1572 };
1573
1574 // An alignment and type specifier.
1575 template <char TYPE>
1576 struct AlignTypeSpec : AlignSpec {
1577 AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {}
1578
1579 bool flag(unsigned) const { return false; }
1580 char type() const { return TYPE; }
1581 };
1582
1583 // A full format specifier.
1584 struct FormatSpec : AlignSpec {
1585 unsigned flags_;
1586 int precision_;
1587 char type_;
1588
1589 FormatSpec(
1590 unsigned width = 0, char type = 0, wchar_t fill = ' ')
1591 : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1592
1593 bool flag(unsigned f) const { return (flags_ & f) != 0; }
1594 int precision() const { return precision_; }
1595 char type() const { return type_; }
1596 };
1597
1598 // An integer format specifier.
1599 template <typename T, typename SpecT = TypeSpec<0>, typename Char = char>
1600 class IntFormatSpec : public SpecT {
1601 private:
1602 T value_;
1603
1604 public:
1605 IntFormatSpec(T val, const SpecT &spec = SpecT())
1606 : SpecT(spec), value_(val) {}
1607
1608 T value() const { return value_; }
1609 };
1610
1611 // A string format specifier.
1612 template <typename Char>
1613 class StrFormatSpec : public AlignSpec {
1614 private:
1615 const Char *str_;
1616
1617 public:
1618 template <typename FillChar>
1619 StrFormatSpec(const Char *str, unsigned width, FillChar fill)
1620 : AlignSpec(width, fill), str_(str) {
1621 internal::CharTraits<Char>::convert(FillChar());
1622 }
1623
1624 const Char *str() const { return str_; }
1625 };
1626
1630 IntFormatSpec<int, TypeSpec<'b'> > bin(int value);
1631
1635 IntFormatSpec<int, TypeSpec<'o'> > oct(int value);
1636
1641 IntFormatSpec<int, TypeSpec<'x'> > hex(int value);
1642
1647 IntFormatSpec<int, TypeSpec<'X'> > hexu(int value);
1648
1663 template <char TYPE_CODE, typename Char>
1664 IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
1665 int value, unsigned width, Char fill = ' ');
1666
1667 #define FMT_DEFINE_INT_FORMATTERS(TYPE) \
1668 inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
1669 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
1670 } \
1671 \
1672 inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
1673 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
1674 } \
1675 \
1676 inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
1677 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
1678 } \
1679 \
1680 inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
1681 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
1682 } \
1683 \
1684 template <char TYPE_CODE> \
1685 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
1686 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
1687 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
1688 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
1689 } \
1690 \
1691 /* For compatibility with older compilers we provide two overloads for pad, */ \
1692 /* one that takes a fill character and one that doesn't. In the future this */ \
1693 /* can be replaced with one overload making the template argument Char */ \
1694 /* default to char (C++11). */ \
1695 template <char TYPE_CODE, typename Char> \
1696 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
1697 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \
1698 unsigned width, Char fill) { \
1699 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
1700 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
1701 } \
1702 \
1703 inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
1704 TYPE value, unsigned width) { \
1705 return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
1706 value, AlignTypeSpec<0>(width, ' ')); \
1707 } \
1708 \
1709 template <typename Char> \
1710 inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
1711 TYPE value, unsigned width, Char fill) { \
1712 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
1713 value, AlignTypeSpec<0>(width, fill)); \
1714 }
1715
1716 FMT_DEFINE_INT_FORMATTERS(int)
1717 FMT_DEFINE_INT_FORMATTERS(long)
1718 FMT_DEFINE_INT_FORMATTERS(unsigned)
1719 FMT_DEFINE_INT_FORMATTERS(unsigned long)
1720 FMT_DEFINE_INT_FORMATTERS(LongLong)
1721 FMT_DEFINE_INT_FORMATTERS(ULongLong)
1722
1735 template <typename Char>
1736 inline StrFormatSpec<Char> pad(
1737 const Char *str, unsigned width, Char fill = ' ') {
1738 return StrFormatSpec<Char>(str, width, fill);
1739 }
1740
1741 inline StrFormatSpec<wchar_t> pad(
1742 const wchar_t *str, unsigned width, char fill = ' ') {
1743 return StrFormatSpec<wchar_t>(str, width, fill);
1744 }
1745
1746 namespace internal {
1747
1748 template <typename Char>
1749 class ArgMap {
1750 private:
1751 typedef std::vector<
1752 std::pair<fmt::BasicStringRef<Char>, internal::Arg> > MapType;
1753 typedef typename MapType::value_type Pair;
1754
1755 MapType map_;
1756
1757 public:
1758 FMT_API void init(const ArgList &args);
1759
1760 const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
1761 // The list is unsorted, so just return the first matching name.
1762 for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
1763 it != end; ++it) {
1764 if (it->first == name)
1765 return &it->second;
1766 }
1767 return 0;
1768 }
1769 };
1770
1771 template <typename Impl, typename Char>
1772 class ArgFormatterBase : public ArgVisitor<Impl, void> {
1773 private:
1774 BasicWriter<Char> &writer_;
1775 FormatSpec &spec_;
1776
1777 FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
1778
1779 void write_pointer(const void *p) {
1780 spec_.flags_ = HASH_FLAG;
1781 spec_.type_ = 'x';
1782 writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
1783 }
1784
1785 protected:
1786 BasicWriter<Char> &writer() { return writer_; }
1787 FormatSpec &spec() { return spec_; }
1788
1789 void write(bool value) {
1790 const char *str_value = value ? "true" : "false";
1791 Arg::StringValue<char> str = { str_value, std::strlen(str_value) };
1792 writer_.write_str(str, spec_);
1793 }
1794
1795 void write(const char *value) {
1796 Arg::StringValue<char> str = {value, value != 0 ? std::strlen(value) : 0};
1797 writer_.write_str(str, spec_);
1798 }
1799
1800 public:
1801 ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s)
1802 : writer_(w), spec_(s) {}
1803
1804 template <typename T>
1805 void visit_any_int(T value) { writer_.write_int(value, spec_); }
1806
1807 template <typename T>
1808 void visit_any_double(T value) { writer_.write_double(value, spec_); }
1809
1810 void visit_bool(bool value) {
1811 if (spec_.type_)
1812 return visit_any_int(value);
1813 write(value);
1814 }
1815
1816 void visit_char(int value) {
1817 if (spec_.type_ && spec_.type_ != 'c') {
1818 spec_.flags_ |= CHAR_FLAG;
1819 writer_.write_int(value, spec_);
1820 return;
1821 }
1822 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
1823 FMT_THROW(FormatError("invalid format specifier for char"));
1824 typedef typename BasicWriter<Char>::CharPtr CharPtr;
1825 Char fill = internal::CharTraits<Char>::cast(spec_.fill());
1826 CharPtr out = CharPtr();
1827 const unsigned CHAR_WIDTH = 1;
1828 if (spec_.width_ > CHAR_WIDTH) {
1829 out = writer_.grow_buffer(spec_.width_);
1830 if (spec_.align_ == ALIGN_RIGHT) {
1831 std::uninitialized_fill_n(out, spec_.width_ - CHAR_WIDTH, fill);
1832 out += spec_.width_ - CHAR_WIDTH;
1833 } else if (spec_.align_ == ALIGN_CENTER) {
1834 out = writer_.fill_padding(out, spec_.width_,
1835 internal::check(CHAR_WIDTH), fill);
1836 } else {
1837 std::uninitialized_fill_n(out + CHAR_WIDTH,
1838 spec_.width_ - CHAR_WIDTH, fill);
1839 }
1840 } else {
1841 out = writer_.grow_buffer(CHAR_WIDTH);
1842 }
1843 *out = internal::CharTraits<Char>::cast(value);
1844 }
1845
1846 void visit_cstring(const char *value) {
1847 if (spec_.type_ == 'p')
1848 return write_pointer(value);
1849 write(value);
1850 }
1851
1852 void visit_string(Arg::StringValue<char> value) {
1853 writer_.write_str(value, spec_);
1854 }
1855
1856 using ArgVisitor<Impl, void>::visit_wstring;
1857
1858 void visit_wstring(Arg::StringValue<Char> value) {
1859 writer_.write_str(value, spec_);
1860 }
1861
1862 void visit_pointer(const void *value) {
1863 if (spec_.type_ && spec_.type_ != 'p')
1864 report_unknown_type(spec_.type_, "pointer");
1865 write_pointer(value);
1866 }
1867 };
1868
1869 class FormatterBase {
1870 private:
1871 ArgList args_;
1872 int next_arg_index_;
1873
1874 // Returns the argument with specified index.
1875 FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
1876
1877 protected:
1878 const ArgList &args() const { return args_; }
1879
1880 explicit FormatterBase(const ArgList &args) {
1881 args_ = args;
1882 next_arg_index_ = 0;
1883 }
1884
1885 // Returns the next argument.
1886 Arg next_arg(const char *&error) {
1887 if (next_arg_index_ >= 0)
1888 return do_get_arg(internal::to_unsigned(next_arg_index_++), error);
1889 error = "cannot switch from manual to automatic argument indexing";
1890 return Arg();
1891 }
1892
1893 // Checks if manual indexing is used and returns the argument with
1894 // specified index.
1895 Arg get_arg(unsigned arg_index, const char *&error) {
1896 return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
1897 }
1898
1899 bool check_no_auto_index(const char *&error) {
1900 if (next_arg_index_ > 0) {
1901 error = "cannot switch from automatic to manual argument indexing";
1902 return false;
1903 }
1904 next_arg_index_ = -1;
1905 return true;
1906 }
1907
1908 template <typename Char>
1909 void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
1910 if (start != end)
1911 w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
1912 }
1913 };
1914
1915 // A printf formatter.
1916 template <typename Char>
1917 class PrintfFormatter : private FormatterBase {
1918 private:
1919 void parse_flags(FormatSpec &spec, const Char *&s);
1920
1921 // Returns the argument with specified index or, if arg_index is equal
1922 // to the maximum unsigned value, the next argument.
1923 Arg get_arg(const Char *s,
1924 unsigned arg_index = (std::numeric_limits<unsigned>::max)());
1925
1926 // Parses argument index, flags and width and returns the argument index.
1927 unsigned parse_header(const Char *&s, FormatSpec &spec);
1928
1929 public:
1930 explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {}
1931 FMT_API void format(BasicWriter<Char> &writer,
1932 BasicCStringRef<Char> format_str);
1933 };
1934 } // namespace internal
1935
1953 template <typename Impl, typename Char>
1954 class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
1955 private:
1956 BasicFormatter<Char, Impl> &formatter_;
1957 const Char *format_;
1958
1959 public:
1968 BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
1969 FormatSpec &spec, const Char *fmt)
1970 : internal::ArgFormatterBase<Impl, Char>(formatter.writer(), spec),
1971 formatter_(formatter), format_(fmt) {}
1972
1974 void visit_custom(internal::Arg::CustomValue c) {
1975 c.format(&formatter_, c.value, &format_);
1976 }
1977 };
1978
1980 template <typename Char>
1981 class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
1982 public:
1984 ArgFormatter(BasicFormatter<Char> &formatter,
1985 FormatSpec &spec, const Char *fmt)
1986 : BasicArgFormatter<ArgFormatter<Char>, Char>(formatter, spec, fmt) {}
1987 };
1988
1990 template <typename CharType, typename ArgFormatter>
1991 class BasicFormatter : private internal::FormatterBase {
1992 public:
1994 typedef CharType Char;
1995
1996 private:
1997 BasicWriter<Char> &writer_;
1998 internal::ArgMap<Char> map_;
1999
2000 FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter);
2001
2002 using internal::FormatterBase::get_arg;
2003
2004 // Checks if manual indexing is used and returns the argument with
2005 // specified name.
2006 internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error);
2007
2008 // Parses argument index and returns corresponding argument.
2009 internal::Arg parse_arg_index(const Char *&s);
2010
2011 // Parses argument name and returns corresponding argument.
2012 internal::Arg parse_arg_name(const Char *&s);
2013
2014 public:
2022 BasicFormatter(const ArgList &args, BasicWriter<Char> &w)
2023 : internal::FormatterBase(args), writer_(w) {}
2024
2026 BasicWriter<Char> &writer() { return writer_; }
2027
2029 void format(BasicCStringRef<Char> format_str);
2030
2031 // Formats a single argument and advances format_str, a format string pointer.
2032 const Char *format(const Char *&format_str, const internal::Arg &arg);
2033 };
2034
2035 // Generates a comma-separated list with results of applying f to
2036 // numbers 0..n-1.
2037 # define FMT_GEN(n, f) FMT_GEN##n(f)
2038 # define FMT_GEN1(f) f(0)
2039 # define FMT_GEN2(f) FMT_GEN1(f), f(1)
2040 # define FMT_GEN3(f) FMT_GEN2(f), f(2)
2041 # define FMT_GEN4(f) FMT_GEN3(f), f(3)
2042 # define FMT_GEN5(f) FMT_GEN4(f), f(4)
2043 # define FMT_GEN6(f) FMT_GEN5(f), f(5)
2044 # define FMT_GEN7(f) FMT_GEN6(f), f(6)
2045 # define FMT_GEN8(f) FMT_GEN7(f), f(7)
2046 # define FMT_GEN9(f) FMT_GEN8(f), f(8)
2047 # define FMT_GEN10(f) FMT_GEN9(f), f(9)
2048 # define FMT_GEN11(f) FMT_GEN10(f), f(10)
2049 # define FMT_GEN12(f) FMT_GEN11(f), f(11)
2050 # define FMT_GEN13(f) FMT_GEN12(f), f(12)
2051 # define FMT_GEN14(f) FMT_GEN13(f), f(13)
2052 # define FMT_GEN15(f) FMT_GEN14(f), f(14)
2053
2054 namespace internal {
2055 inline uint64_t make_type() { return 0; }
2056
2057 template <typename T>
2058 inline uint64_t make_type(const T &arg) {
2059 return MakeValue< BasicFormatter<char> >::type(arg);
2060 }
2061
2062 template <unsigned N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
2063 struct ArgArray;
2064
2065 template <unsigned N>
2066 struct ArgArray<N, true/*IsPacked*/> {
2067 typedef Value Type[N > 0 ? N : 1];
2068
2069 template <typename Formatter, typename T>
2070 static Value make(const T &value) {
2071 #ifdef __clang__
2072 Value result = MakeValue<Formatter>(value);
2073 // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
2074 // https://github.com/fmtlib/fmt/issues/276
2075 (void)result.custom.format;
2076 return result;
2077 #else
2078 return MakeValue<Formatter>(value);
2079 #endif
2080 }
2081 };
2082
2083 template <unsigned N>
2084 struct ArgArray<N, false/*IsPacked*/> {
2085 typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
2086
2087 template <typename Formatter, typename T>
2088 static Arg make(const T &value) { return MakeArg<Formatter>(value); }
2089 };
2090
2091 #if FMT_USE_VARIADIC_TEMPLATES
2092 template <typename Arg, typename... Args>
2093 inline uint64_t make_type(const Arg &first, const Args & ... tail) {
2094 return make_type(first) | (make_type(tail...) << 4);
2095 }
2096
2097 #else
2098
2099 struct ArgType {
2100 uint64_t type;
2101
2102 ArgType() : type(0) {}
2103
2104 template <typename T>
2105 ArgType(const T &arg) : type(make_type(arg)) {}
2106 };
2107
2108 # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
2109
2110 inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
2111 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
2112 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
2113 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
2114 (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
2115 }
2116 #endif
2117 } // namespace internal
2118
2119 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
2120 # define FMT_MAKE_ARG_TYPE(n) T##n
2121 # define FMT_MAKE_ARG(n) const T##n &v##n
2122 # define FMT_ASSIGN_char(n) \
2123 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
2124 # define FMT_ASSIGN_wchar_t(n) \
2125 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
2126
2127 #if FMT_USE_VARIADIC_TEMPLATES
2128 // Defines a variadic function returning void.
2129 # define FMT_VARIADIC_VOID(func, arg_type) \
2130 template <typename... Args> \
2131 void func(arg_type arg0, const Args & ... args) { \
2132 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2133 typename ArgArray::Type array{ \
2134 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2135 func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2136 }
2137
2138 // Defines a variadic constructor.
2139 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2140 template <typename... Args> \
2141 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
2142 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2143 typename ArgArray::Type array{ \
2144 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2145 func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2146 }
2147
2148 #else
2149
2150 # define FMT_MAKE_REF(n) \
2151 fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
2152 # define FMT_MAKE_REF2(n) v##n
2153
2154 // Defines a wrapper for a function taking one argument of type arg_type
2155 // and n additional arguments of arbitrary types.
2156 # define FMT_WRAP1(func, arg_type, n) \
2157 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2158 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2159 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2160 func(arg1, fmt::ArgList( \
2161 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2162 }
2163
2164 // Emulates a variadic function returning void on a pre-C++11 compiler.
2165 # define FMT_VARIADIC_VOID(func, arg_type) \
2166 inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \
2167 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \
2168 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \
2169 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \
2170 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \
2171 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
2172
2173 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
2174 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2175 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2176 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2177 func(arg0, arg1, fmt::ArgList( \
2178 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2179 }
2180
2181 // Emulates a variadic constructor on a pre-C++11 compiler.
2182 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2183 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \
2184 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \
2185 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \
2186 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \
2187 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \
2188 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \
2189 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \
2190 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \
2191 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \
2192 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
2193 #endif
2194
2195 // Generates a comma-separated list with results of applying f to pairs
2196 // (argument, index).
2197 #define FMT_FOR_EACH1(f, x0) f(x0, 0)
2198 #define FMT_FOR_EACH2(f, x0, x1) \
2199 FMT_FOR_EACH1(f, x0), f(x1, 1)
2200 #define FMT_FOR_EACH3(f, x0, x1, x2) \
2201 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
2202 #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
2203 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
2204 #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
2205 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
2206 #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
2207 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
2208 #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
2209 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
2210 #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
2211 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
2212 #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
2213 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
2214 #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
2215 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
2216
2221 class SystemError : public internal::RuntimeError {
2222 private:
2223 void init(int err_code, CStringRef format_str, ArgList args);
2224
2225 protected:
2226 int error_code_;
2227
2228 typedef char Char; // For FMT_VARIADIC_CTOR.
2229
2230 SystemError() {}
2231
2232 public:
2258 SystemError(int error_code, CStringRef message) {
2259 init(error_code, message, ArgList());
2260 }
2261 FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
2262
2263 int error_code() const { return error_code_; }
2264 };
2265
2284 template <typename Char>
2285 class BasicWriter {
2286 private:
2287 // Output buffer.
2288 Buffer<Char> &buffer_;
2289
2290 FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter);
2291
2292 typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
2293
2294 #if FMT_SECURE_SCL
2295 // Returns pointer value.
2296 static Char *get(CharPtr p) { return p.base(); }
2297 #else
2298 static Char *get(Char *p) { return p; }
2299 #endif
2300
2301 // Fills the padding around the content and returns the pointer to the
2302 // content area.
2303 static CharPtr fill_padding(CharPtr buffer,
2304 unsigned total_size, std::size_t content_size, wchar_t fill);
2305
2306 // Grows the buffer by n characters and returns a pointer to the newly
2307 // allocated area.
2308 CharPtr grow_buffer(std::size_t n) {
2309 std::size_t size = buffer_.size();
2310 buffer_.resize(size + n);
2311 return internal::make_ptr(&buffer_[size], n);
2312 }
2313
2314 // Writes an unsigned decimal integer.
2315 template <typename UInt>
2316 Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) {
2317 unsigned num_digits = internal::count_digits(value);
2318 Char *ptr = get(grow_buffer(prefix_size + num_digits));
2319 internal::format_decimal(ptr + prefix_size, value, num_digits);
2320 return ptr;
2321 }
2322
2323 // Writes a decimal integer.
2324 template <typename Int>
2325 void write_decimal(Int value) {
2326 typedef typename internal::IntTraits<Int>::MainType MainType;
2327 MainType abs_value = static_cast<MainType>(value);
2328 if (internal::is_negative(value)) {
2329 abs_value = 0 - abs_value;
2330 *write_unsigned_decimal(abs_value, 1) = '-';
2331 } else {
2332 write_unsigned_decimal(abs_value, 0);
2333 }
2334 }
2335
2336 // Prepare a buffer for integer formatting.
2337 CharPtr prepare_int_buffer(unsigned num_digits,
2338 const EmptySpec &, const char *prefix, unsigned prefix_size) {
2339 unsigned size = prefix_size + num_digits;
2340 CharPtr p = grow_buffer(size);
2341 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2342 return p + size - 1;
2343 }
2344
2345 template <typename Spec>
2346 CharPtr prepare_int_buffer(unsigned num_digits,
2347 const Spec &spec, const char *prefix, unsigned prefix_size);
2348
2349 // Formats an integer.
2350 template <typename T, typename Spec>
2351 void write_int(T value, Spec spec);
2352
2353 // Formats a floating-point number (double or long double).
2354 template <typename T>
2355 void write_double(T value, const FormatSpec &spec);
2356
2357 // Writes a formatted string.
2358 template <typename StrChar>
2359 CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
2360
2361 template <typename StrChar>
2362 void write_str(const internal::Arg::StringValue<StrChar> &str,
2363 const FormatSpec &spec);
2364
2365 // This following methods are private to disallow writing wide characters
2366 // and strings to a char stream. If you want to print a wide string as a
2367 // pointer as std::ostream does, cast it to const void*.
2368 // Do not implement!
2369 void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported);
2370 void operator<<(
2371 typename internal::WCharHelper<const wchar_t *, Char>::Unsupported);
2372
2373 // Appends floating-point length specifier to the format string.
2374 // The second argument is only used for overload resolution.
2375 void append_float_length(Char *&format_ptr, long double) {
2376 *format_ptr++ = 'L';
2377 }
2378
2379 template<typename T>
2380 void append_float_length(Char *&, T) {}
2381
2382 template <typename Impl, typename Char_>
2383 friend class internal::ArgFormatterBase;
2384
2385 friend class internal::PrintfArgFormatter<Char>;
2386
2387 protected:
2391 explicit BasicWriter(Buffer<Char> &b) : buffer_(b) {}
2392
2393 public:
2399 virtual ~BasicWriter() {}
2400
2404 std::size_t size() const { return buffer_.size(); }
2405
2410 const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
2411
2416 const Char *c_str() const {
2417 std::size_t size = buffer_.size();
2418 buffer_.reserve(size + 1);
2419 buffer_[size] = '\0';
2420 return &buffer_[0];
2421 }
2422
2428 std::basic_string<Char> str() const {
2429 return std::basic_string<Char>(&buffer_[0], buffer_.size());
2430 }
2431
2457 void write(BasicCStringRef<Char> format, ArgList args) {
2458 BasicFormatter<Char>(args, *this).format(format);
2459 }
2460 FMT_VARIADIC_VOID(write, BasicCStringRef<Char>)
2461
2462 BasicWriter &operator<<(int value) {
2463 write_decimal(value);
2464 return *this;
2465 }
2466 BasicWriter &operator<<(unsigned value) {
2467 return *this << IntFormatSpec<unsigned>(value);
2468 }
2469 BasicWriter &operator<<(long value) {
2470 write_decimal(value);
2471 return *this;
2472 }
2473 BasicWriter &operator<<(unsigned long value) {
2474 return *this << IntFormatSpec<unsigned long>(value);
2475 }
2476 BasicWriter &operator<<(LongLong value) {
2477 write_decimal(value);
2478 return *this;
2479 }
2480
2486 BasicWriter &operator<<(ULongLong value) {
2487 return *this << IntFormatSpec<ULongLong>(value);
2488 }
2489
2490 BasicWriter &operator<<(double value) {
2491 write_double(value, FormatSpec());
2492 return *this;
2493 }
2494
2501 BasicWriter &operator<<(long double value) {
2502 write_double(value, FormatSpec());
2503 return *this;
2504 }
2505
2509 BasicWriter &operator<<(char value) {
2510 buffer_.push_back(value);
2511 return *this;
2512 }
2513
2514 BasicWriter &operator<<(
2515 typename internal::WCharHelper<wchar_t, Char>::Supported value) {
2516 buffer_.push_back(value);
2517 return *this;
2518 }
2519
2525 BasicWriter &operator<<(fmt::BasicStringRef<Char> value) {
2526 const Char *str = value.data();
2527 buffer_.append(str, str + value.size());
2528 return *this;
2529 }
2530
2531 BasicWriter &operator<<(
2532 typename internal::WCharHelper<StringRef, Char>::Supported value) {
2533 const char *str = value.data();
2534 buffer_.append(str, str + value.size());
2535 return *this;
2536 }
2537
2538 template <typename T, typename Spec, typename FillChar>
2539 BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) {
2540 internal::CharTraits<Char>::convert(FillChar());
2541 write_int(spec.value(), spec);
2542 return *this;
2543 }
2544
2545 template <typename StrChar>
2546 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) {
2547 const StrChar *s = spec.str();
2548 write_str(s, std::char_traits<Char>::length(s), spec);
2549 return *this;
2550 }
2551
2552 void clear() FMT_NOEXCEPT { buffer_.clear(); }
2553
2554 Buffer<Char> &buffer() FMT_NOEXCEPT { return buffer_; }
2555 };
2556
2557 template <typename Char>
2558 template <typename StrChar>
2559 typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
2560 const StrChar *s, std::size_t size, const AlignSpec &spec) {
2561 CharPtr out = CharPtr();
2562 if (spec.width() > size) {
2563 out = grow_buffer(spec.width());
2564 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2565 if (spec.align() == ALIGN_RIGHT) {
2566 std::uninitialized_fill_n(out, spec.width() - size, fill);
2567 out += spec.width() - size;
2568 } else if (spec.align() == ALIGN_CENTER) {
2569 out = fill_padding(out, spec.width(), size, fill);
2570 } else {
2571 std::uninitialized_fill_n(out + size, spec.width() - size, fill);
2572 }
2573 } else {
2574 out = grow_buffer(size);
2575 }
2576 std::uninitialized_copy(s, s + size, out);
2577 return out;
2578 }
2579
2580 template <typename Char>
2581 template <typename StrChar>
2582 void BasicWriter<Char>::write_str(
2583 const internal::Arg::StringValue<StrChar> &s, const FormatSpec &spec) {
2584 // Check if StrChar is convertible to Char.
2585 internal::CharTraits<Char>::convert(StrChar());
2586 if (spec.type_ && spec.type_ != 's')
2587 internal::report_unknown_type(spec.type_, "string");
2588 const StrChar *str_value = s.value;
2589 std::size_t str_size = s.size;
2590 if (str_size == 0) {
2591 if (!str_value) {
2592 FMT_THROW(FormatError("string pointer is null"));
2593 return;
2594 }
2595 }
2596 std::size_t precision = static_cast<std::size_t>(spec.precision_);
2597 if (spec.precision_ >= 0 && precision < str_size)
2598 str_size = precision;
2599 write_str(str_value, str_size, spec);
2600 }
2601
2602 template <typename Char>
2603 typename BasicWriter<Char>::CharPtr
2604 BasicWriter<Char>::fill_padding(
2605 CharPtr buffer, unsigned total_size,
2606 std::size_t content_size, wchar_t fill) {
2607 std::size_t padding = total_size - content_size;
2608 std::size_t left_padding = padding / 2;
2609 Char fill_char = internal::CharTraits<Char>::cast(fill);
2610 std::uninitialized_fill_n(buffer, left_padding, fill_char);
2611 buffer += left_padding;
2612 CharPtr content = buffer;
2613 std::uninitialized_fill_n(buffer + content_size,
2614 padding - left_padding, fill_char);
2615 return content;
2616 }
2617
2618 template <typename Char>
2619 template <typename Spec>
2620 typename BasicWriter<Char>::CharPtr
2621 BasicWriter<Char>::prepare_int_buffer(
2622 unsigned num_digits, const Spec &spec,
2623 const char *prefix, unsigned prefix_size) {
2624 unsigned width = spec.width();
2625 Alignment align = spec.align();
2626 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2627 if (spec.precision() > static_cast<int>(num_digits)) {
2628 // Octal prefix '0' is counted as a digit, so ignore it if precision
2629 // is specified.
2630 if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
2631 --prefix_size;
2632 unsigned number_size =
2633 prefix_size + internal::to_unsigned(spec.precision());
2634 AlignSpec subspec(number_size, '0', ALIGN_NUMERIC);
2635 if (number_size >= width)
2636 return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
2637 buffer_.reserve(width);
2638 unsigned fill_size = width - number_size;
2639 if (align != ALIGN_LEFT) {
2640 CharPtr p = grow_buffer(fill_size);
2641 std::uninitialized_fill(p, p + fill_size, fill);
2642 }
2643 CharPtr result = prepare_int_buffer(
2644 num_digits, subspec, prefix, prefix_size);
2645 if (align == ALIGN_LEFT) {
2646 CharPtr p = grow_buffer(fill_size);
2647 std::uninitialized_fill(p, p + fill_size, fill);
2648 }
2649 return result;
2650 }
2651 unsigned size = prefix_size + num_digits;
2652 if (width <= size) {
2653 CharPtr p = grow_buffer(size);
2654 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2655 return p + size - 1;
2656 }
2657 CharPtr p = grow_buffer(width);
2658 CharPtr end = p + width;
2659 if (align == ALIGN_LEFT) {
2660 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2661 p += size;
2662 std::uninitialized_fill(p, end, fill);
2663 } else if (align == ALIGN_CENTER) {
2664 p = fill_padding(p, width, size, fill);
2665 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2666 p += size;
2667 } else {
2668 if (align == ALIGN_NUMERIC) {
2669 if (prefix_size != 0) {
2670 p = std::uninitialized_copy(prefix, prefix + prefix_size, p);
2671 size -= prefix_size;
2672 }
2673 } else {
2674 std::uninitialized_copy(prefix, prefix + prefix_size, end - size);
2675 }
2676 std::uninitialized_fill(p, end - size, fill);
2677 p = end;
2678 }
2679 return p - 1;
2680 }
2681
2682 template <typename Char>
2683 template <typename T, typename Spec>
2684 void BasicWriter<Char>::write_int(T value, Spec spec) {
2685 unsigned prefix_size = 0;
2686 typedef typename internal::IntTraits<T>::MainType UnsignedType;
2687 UnsignedType abs_value = static_cast<UnsignedType>(value);
2688 char prefix[4] = "";
2689 if (internal::is_negative(value)) {
2690 prefix[0] = '-';
2691 ++prefix_size;
2692 abs_value = 0 - abs_value;
2693 } else if (spec.flag(SIGN_FLAG)) {
2694 prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' ';
2695 ++prefix_size;
2696 }
2697 switch (spec.type()) {
2698 case 0: case 'd': {
2699 unsigned num_digits = internal::count_digits(abs_value);
2700 CharPtr p = prepare_int_buffer(num_digits, spec, prefix, prefix_size) + 1;
2701 internal::format_decimal(get(p), abs_value, 0);
2702 break;
2703 }
2704 case 'x': case 'X': {
2705 UnsignedType n = abs_value;
2706 if (spec.flag(HASH_FLAG)) {
2707 prefix[prefix_size++] = '0';
2708 prefix[prefix_size++] = spec.type();
2709 }
2710 unsigned num_digits = 0;
2711 do {
2712 ++num_digits;
2713 } while ((n >>= 4) != 0);
2714 Char *p = get(prepare_int_buffer(
2715 num_digits, spec, prefix, prefix_size));
2716 n = abs_value;
2717 const char *digits = spec.type() == 'x' ?
2718 "0123456789abcdef" : "0123456789ABCDEF";
2719 do {
2720 *p-- = digits[n & 0xf];
2721 } while ((n >>= 4) != 0);
2722 break;
2723 }
2724 case 'b': case 'B': {
2725 UnsignedType n = abs_value;
2726 if (spec.flag(HASH_FLAG)) {
2727 prefix[prefix_size++] = '0';
2728 prefix[prefix_size++] = spec.type();
2729 }
2730 unsigned num_digits = 0;
2731 do {
2732 ++num_digits;
2733 } while ((n >>= 1) != 0);
2734 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2735 n = abs_value;
2736 do {
2737 *p-- = static_cast<Char>('0' + (n & 1));
2738 } while ((n >>= 1) != 0);
2739 break;
2740 }
2741 case 'o': {
2742 UnsignedType n = abs_value;
2743 if (spec.flag(HASH_FLAG))
2744 prefix[prefix_size++] = '0';
2745 unsigned num_digits = 0;
2746 do {
2747 ++num_digits;
2748 } while ((n >>= 3) != 0);
2749 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2750 n = abs_value;
2751 do {
2752 *p-- = static_cast<Char>('0' + (n & 7));
2753 } while ((n >>= 3) != 0);
2754 break;
2755 }
2756 case 'n': {
2757 unsigned num_digits = internal::count_digits(abs_value);
2758 fmt::StringRef sep = std::localeconv()->thousands_sep;
2759 unsigned size = static_cast<unsigned>(
2760 num_digits + sep.size() * (num_digits - 1) / 3);
2761 CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1;
2762 internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep));
2763 break;
2764 }
2765 default:
2766 internal::report_unknown_type(
2767 spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer");
2768 break;
2769 }
2770 }
2771
2772 template <typename Char>
2773 template <typename T>
2774 void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
2775 // Check type.
2776 char type = spec.type();
2777 bool upper = false;
2778 switch (type) {
2779 case 0:
2780 type = 'g';
2781 break;
2782 case 'e': case 'f': case 'g': case 'a':
2783 break;
2784 case 'F':
2785 #ifdef _MSC_VER
2786 // MSVC's printf doesn't support 'F'.
2787 type = 'f';
2788 #endif
2789 // Fall through.
2790 case 'E': case 'G': case 'A':
2791 upper = true;
2792 break;
2793 default:
2794 internal::report_unknown_type(type, "double");
2795 break;
2796 }
2797
2798 char sign = 0;
2799 // Use isnegative instead of value < 0 because the latter is always
2800 // false for NaN.
2801 if (internal::FPUtil::isnegative(static_cast<double>(value))) {
2802 sign = '-';
2803 value = -value;
2804 } else if (spec.flag(SIGN_FLAG)) {
2805 sign = spec.flag(PLUS_FLAG) ? '+' : ' ';
2806 }
2807
2808 if (internal::FPUtil::isnotanumber(value)) {
2809 // Format NaN ourselves because sprintf's output is not consistent
2810 // across platforms.
2811 std::size_t nan_size = 4;
2812 const char *nan = upper ? " NAN" : " nan";
2813 if (!sign) {
2814 --nan_size;
2815 ++nan;
2816 }
2817 CharPtr out = write_str(nan, nan_size, spec);
2818 if (sign)
2819 *out = sign;
2820 return;
2821 }
2822
2823 if (internal::FPUtil::isinfinity(value)) {
2824 // Format infinity ourselves because sprintf's output is not consistent
2825 // across platforms.
2826 std::size_t inf_size = 4;
2827 const char *inf = upper ? " INF" : " inf";
2828 if (!sign) {
2829 --inf_size;
2830 ++inf;
2831 }
2832 CharPtr out = write_str(inf, inf_size, spec);
2833 if (sign)
2834 *out = sign;
2835 return;
2836 }
2837
2838 std::size_t offset = buffer_.size();
2839 unsigned width = spec.width();
2840 if (sign) {
2841 buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u));
2842 if (width > 0)
2843 --width;
2844 ++offset;
2845 }
2846
2847 // Build format string.
2848 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
2849 Char format[MAX_FORMAT_SIZE];
2850 Char *format_ptr = format;
2851 *format_ptr++ = '%';
2852 unsigned width_for_sprintf = width;
2853 if (spec.flag(HASH_FLAG))
2854 *format_ptr++ = '#';
2855 if (spec.align() == ALIGN_CENTER) {
2856 width_for_sprintf = 0;
2857 } else {
2858 if (spec.align() == ALIGN_LEFT)
2859 *format_ptr++ = '-';
2860 if (width != 0)
2861 *format_ptr++ = '*';
2862 }
2863 if (spec.precision() >= 0) {
2864 *format_ptr++ = '.';
2865 *format_ptr++ = '*';
2866 }
2867
2868 append_float_length(format_ptr, value);
2869 *format_ptr++ = type;
2870 *format_ptr = '\0';
2871
2872 // Format using snprintf.
2873 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2874 unsigned n = 0;
2875 Char *start = 0;
2876 for (;;) {
2877 std::size_t buffer_size = buffer_.capacity() - offset;
2878 #ifdef _MSC_VER
2879 // MSVC's vsnprintf_s doesn't work with zero size, so reserve
2880 // space for at least one extra character to make the size non-zero.
2881 // Note that the buffer's capacity will increase by more than 1.
2882 if (buffer_size == 0) {
2883 buffer_.reserve(offset + 1);
2884 buffer_size = buffer_.capacity() - offset;
2885 }
2886 #endif
2887 start = &buffer_[offset];
2888 int result = internal::CharTraits<Char>::format_float(
2889 start, buffer_size, format, width_for_sprintf, spec.precision(), value);
2890 if (result >= 0) {
2891 n = internal::to_unsigned(result);
2892 if (offset + n < buffer_.capacity())
2893 break; // The buffer is large enough - continue with formatting.
2894 buffer_.reserve(offset + n + 1);
2895 } else {
2896 // If result is negative we ask to increase the capacity by at least 1,
2897 // but as std::vector, the buffer grows exponentially.
2898 buffer_.reserve(buffer_.capacity() + 1);
2899 }
2900 }
2901 if (sign) {
2902 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
2903 *start != ' ') {
2904 *(start - 1) = sign;
2905 sign = 0;
2906 } else {
2907 *(start - 1) = fill;
2908 }
2909 ++n;
2910 }
2911 if (spec.align() == ALIGN_CENTER && spec.width() > n) {
2912 width = spec.width();
2913 CharPtr p = grow_buffer(width);
2914 std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
2915 fill_padding(p, spec.width(), n, fill);
2916 return;
2917 }
2918 if (spec.fill() != ' ' || sign) {
2919 while (*start == ' ')
2920 *start++ = fill;
2921 if (sign)
2922 *(start - 1) = sign;
2923 }
2924 grow_buffer(n);
2925 }
2926
2961 template <typename Char, typename Allocator = std::allocator<Char> >
2962 class BasicMemoryWriter : public BasicWriter<Char> {
2963 private:
2964 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
2965
2966 public:
2967 explicit BasicMemoryWriter(const Allocator& alloc = Allocator())
2968 : BasicWriter<Char>(buffer_), buffer_(alloc) {}
2969
2970 #if FMT_USE_RVALUE_REFERENCES
2971
2977 BasicMemoryWriter(BasicMemoryWriter &&other)
2978 : BasicWriter<Char>(buffer_), buffer_(std::move(other.buffer_)) {
2979 }
2980
2986 BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
2987 buffer_ = std::move(other.buffer_);
2988 return *this;
2989 }
2990 #endif
2991 };
2992
2993 typedef BasicMemoryWriter<char> MemoryWriter;
2994 typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
2995
3016 template <typename Char>
3017 class BasicArrayWriter : public BasicWriter<Char> {
3018 private:
3019 internal::FixedBuffer<Char> buffer_;
3020
3021 public:
3028 BasicArrayWriter(Char *array, std::size_t size)
3029 : BasicWriter<Char>(buffer_), buffer_(array, size) {}
3030
3037 template <std::size_t SIZE>
3038 explicit BasicArrayWriter(Char (&array)[SIZE])
3039 : BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
3040 };
3041
3042 typedef BasicArrayWriter<char> ArrayWriter;
3043 typedef BasicArrayWriter<wchar_t> WArrayWriter;
3044
3045 // Reports a system error without throwing an exception.
3046 // Can be used to report errors from destructors.
3047 FMT_API void report_system_error(int error_code,
3048 StringRef message) FMT_NOEXCEPT;
3049
3050 #if FMT_USE_WINDOWS_H
3051
3053 class WindowsError : public SystemError {
3054 private:
3055 FMT_API void init(int error_code, CStringRef format_str, ArgList args);
3056
3057 public:
3086 WindowsError(int error_code, CStringRef message) {
3087 init(error_code, message, ArgList());
3088 }
3089 FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef)
3090 };
3091
3092 // Reports a Windows error without throwing an exception.
3093 // Can be used to report errors from destructors.
3094 FMT_API void report_windows_error(int error_code,
3095 StringRef message) FMT_NOEXCEPT;
3096
3097 #endif
3098
3099 enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
3100
3107 FMT_API void print_colored(Color c, CStringRef format, ArgList args);
3108
3118 inline std::string format(CStringRef format_str, ArgList args) {
3119 MemoryWriter w;
3120 w.write(format_str, args);
3121 return w.str();
3122 }
3123
3124 inline std::wstring format(WCStringRef format_str, ArgList args) {
3125 WMemoryWriter w;
3126 w.write(format_str, args);
3127 return w.str();
3128 }
3129
3139 FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
3140
3150 FMT_API void print(CStringRef format_str, ArgList args);
3151
3152 template <typename Char>
3153 void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
3154 internal::PrintfFormatter<Char>(args).format(w, format);
3155 }
3156
3166 inline std::string sprintf(CStringRef format, ArgList args) {
3167 MemoryWriter w;
3168 printf(w, format, args);
3169 return w.str();
3170 }
3171
3172 inline std::wstring sprintf(WCStringRef format, ArgList args) {
3173 WMemoryWriter w;
3174 printf(w, format, args);
3175 return w.str();
3176 }
3177
3187 FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
3188
3198 inline int printf(CStringRef format, ArgList args) {
3199 return fprintf(stdout, format, args);
3200 }
3201
3205 class FormatInt {
3206 private:
3207 // Buffer should be large enough to hold all digits (digits10 + 1),
3208 // a sign and a null character.
3209 enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3};
3210 mutable char buffer_[BUFFER_SIZE];
3211 char *str_;
3212
3213 // Formats value in reverse and returns the number of digits.
3214 char *format_decimal(ULongLong value) {
3215 char *buffer_end = buffer_ + BUFFER_SIZE - 1;
3216 while (value >= 100) {
3217 // Integer division is slow so do it for a group of two digits instead
3218 // of for every digit. The idea comes from the talk by Alexandrescu
3219 // "Three Optimization Tips for C++". See speed-test for a comparison.
3220 unsigned index = static_cast<unsigned>((value % 100) * 2);
3221 value /= 100;
3222 *--buffer_end = internal::Data::DIGITS[index + 1];
3223 *--buffer_end = internal::Data::DIGITS[index];
3224 }
3225 if (value < 10) {
3226 *--buffer_end = static_cast<char>('0' + value);
3227 return buffer_end;
3228 }
3229 unsigned index = static_cast<unsigned>(value * 2);
3230 *--buffer_end = internal::Data::DIGITS[index + 1];
3231 *--buffer_end = internal::Data::DIGITS[index];
3232 return buffer_end;
3233 }
3234
3235 void FormatSigned(LongLong value) {
3236 ULongLong abs_value = static_cast<ULongLong>(value);
3237 bool negative = value < 0;
3238 if (negative)
3239 abs_value = 0 - abs_value;
3240 str_ = format_decimal(abs_value);
3241 if (negative)
3242 *--str_ = '-';
3243 }
3244
3245 public:
3246 explicit FormatInt(int value) { FormatSigned(value); }
3247 explicit FormatInt(long value) { FormatSigned(value); }
3248 explicit FormatInt(LongLong value) { FormatSigned(value); }
3249 explicit FormatInt(unsigned value) : str_(format_decimal(value)) {}
3250 explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
3251 explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
3252
3254 std::size_t size() const {
3255 return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
3256 }
3257
3262 const char *data() const { return str_; }
3263
3268 const char *c_str() const {
3269 buffer_[BUFFER_SIZE - 1] = '\0';
3270 return str_;
3271 }
3272
3278 std::string str() const { return std::string(str_, size()); }
3279 };
3280
3281 // Formats a decimal integer value writing into buffer and returns
3282 // a pointer to the end of the formatted string. This function doesn't
3283 // write a terminating null character.
3284 template <typename T>
3285 inline void format_decimal(char *&buffer, T value) {
3286 typedef typename internal::IntTraits<T>::MainType MainType;
3287 MainType abs_value = static_cast<MainType>(value);
3288 if (internal::is_negative(value)) {
3289 *buffer++ = '-';
3290 abs_value = 0 - abs_value;
3291 }
3292 if (abs_value < 100) {
3293 if (abs_value < 10) {
3294 *buffer++ = static_cast<char>('0' + abs_value);
3295 return;
3296 }
3297 unsigned index = static_cast<unsigned>(abs_value * 2);
3298 *buffer++ = internal::Data::DIGITS[index];
3299 *buffer++ = internal::Data::DIGITS[index + 1];
3300 return;
3301 }
3302 unsigned num_digits = internal::count_digits(abs_value);
3303 internal::format_decimal(buffer, abs_value, num_digits);
3304 buffer += num_digits;
3305 }
3306
3317 template <typename T>
3318 inline internal::NamedArg<char> arg(StringRef name, const T &arg) {
3319 return internal::NamedArg<char>(name, arg);
3320 }
3321
3322 template <typename T>
3323 inline internal::NamedArg<wchar_t> arg(WStringRef name, const T &arg) {
3324 return internal::NamedArg<wchar_t>(name, arg);
3325 }
3326
3327 // The following two functions are deleted intentionally to disable
3328 // nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``.
3329 template <typename Char>
3330 void arg(StringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3331 template <typename Char>
3332 void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3333 }
3334
3335 #if FMT_GCC_VERSION
3336 // Use the system_header pragma to suppress warnings about variadic macros
3337 // because suppressing -Wvariadic-macros with the diagnostic pragma doesn't
3338 // work. It is used at the end because we want to suppress as little warnings
3339 // as possible.
3340 # pragma GCC system_header
3341 #endif
3342
3343 // This is used to work around VC++ bugs in handling variadic macros.
3344 #define FMT_EXPAND(args) args
3345
3346 // Returns the number of arguments.
3347 // Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s.
3348 #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
3349 #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
3350 #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3351 #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
3352
3353 #define FMT_CONCAT(a, b) a##b
3354 #define FMT_FOR_EACH_(N, f, ...) \
3355 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
3356 #define FMT_FOR_EACH(f, ...) \
3357 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
3358
3359 #define FMT_ADD_ARG_NAME(type, index) type arg##index
3360 #define FMT_GET_ARG_NAME(type, index) arg##index
3361
3362 #if FMT_USE_VARIADIC_TEMPLATES
3363 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3364 template <typename... Args> \
3365 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3366 const Args & ... args) { \
3367 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
3368 typename ArgArray::Type array{ \
3369 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
3370 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
3371 fmt::ArgList(fmt::internal::make_type(args...), array)); \
3372 }
3373 #else
3374 // Defines a wrapper for a function taking __VA_ARGS__ arguments
3375 // and n additional arguments of arbitrary types.
3376 # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
3377 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
3378 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3379 FMT_GEN(n, FMT_MAKE_ARG)) { \
3380 fmt::internal::ArgArray<n>::Type arr; \
3381 FMT_GEN(n, FMT_ASSIGN_##Char); \
3382 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
3383 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
3384 }
3385
3386 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3387 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
3388 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
3389 } \
3390 FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
3391 FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
3392 FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
3393 FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
3394 FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
3395 FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
3396 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
3397 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
3398 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
3399 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
3400 FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
3401 FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
3402 FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
3403 FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
3404 FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
3405 #endif // FMT_USE_VARIADIC_TEMPLATES
3406
3434 #define FMT_VARIADIC(ReturnType, func, ...) \
3435 FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
3436
3437 #define FMT_VARIADIC_W(ReturnType, func, ...) \
3438 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
3439
3440 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
3441
3442 #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
3443
3458 #define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
3459
3460 #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
3461
3462 namespace fmt {
3463 FMT_VARIADIC(std::string, format, CStringRef)
3464 FMT_VARIADIC_W(std::wstring, format, WCStringRef)
3465 FMT_VARIADIC(void, print, CStringRef)
3466 FMT_VARIADIC(void, print, std::FILE *, CStringRef)
3467
3468 FMT_VARIADIC(void, print_colored, Color, CStringRef)
3469 FMT_VARIADIC(std::string, sprintf, CStringRef)
3470 FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
3471 FMT_VARIADIC(int, printf, CStringRef)
3472 FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
3473
3474 namespace internal {
3475 template <typename Char>
3476 inline bool is_name_start(Char c) {
3477 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
3478 }
3479
3480 // Parses an unsigned integer advancing s to the end of the parsed input.
3481 // This function assumes that the first character of s is a digit.
3482 template <typename Char>
3483 unsigned parse_nonnegative_int(const Char *&s) {
3484 assert('0' <= *s && *s <= '9');
3485 unsigned value = 0;
3486 do {
3487 unsigned new_value = value * 10 + (*s++ - '0');
3488 // Check if value wrapped around.
3489 if (new_value < value) {
3490 value = (std::numeric_limits<unsigned>::max)();
3491 break;
3492 }
3493 value = new_value;
3494 } while ('0' <= *s && *s <= '9');
3495 // Convert to unsigned to prevent a warning.
3496 unsigned max_int = (std::numeric_limits<int>::max)();
3497 if (value > max_int)
3498 FMT_THROW(FormatError("number is too big"));
3499 return value;
3500 }
3501
3502 inline void require_numeric_argument(const Arg &arg, char spec) {
3503 if (arg.type > Arg::LAST_NUMERIC_TYPE) {
3504 std::string message =
3505 fmt::format("format specifier '{}' requires numeric argument", spec);
3506 FMT_THROW(fmt::FormatError(message));
3507 }
3508 }
3509
3510 template <typename Char>
3511 void check_sign(const Char *&s, const Arg &arg) {
3512 char sign = static_cast<char>(*s);
3513 require_numeric_argument(arg, sign);
3514 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) {
3515 FMT_THROW(FormatError(fmt::format(
3516 "format specifier '{}' requires signed argument", sign)));
3517 }
3518 ++s;
3519 }
3520 } // namespace internal
3521
3522 template <typename Char, typename AF>
3523 inline internal::Arg BasicFormatter<Char, AF>::get_arg(
3524 BasicStringRef<Char> arg_name, const char *&error) {
3525 if (check_no_auto_index(error)) {
3526 map_.init(args());
3527 const internal::Arg *arg = map_.find(arg_name);
3528 if (arg)
3529 return *arg;
3530 error = "argument not found";
3531 }
3532 return internal::Arg();
3533 }
3534
3535 template <typename Char, typename AF>
3536 inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s) {
3537 const char *error = 0;
3538 internal::Arg arg = *s < '0' || *s > '9' ?
3539 next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
3540 if (error) {
3541 FMT_THROW(FormatError(
3542 *s != '}' && *s != ':' ? "invalid format string" : error));
3543 }
3544 return arg;
3545 }
3546
3547 template <typename Char, typename AF>
3548 inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s) {
3549 assert(internal::is_name_start(*s));
3550 const Char *start = s;
3551 Char c;
3552 do {
3553 c = *++s;
3554 } while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
3555 const char *error = 0;
3556 internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
3557 if (error)
3558 FMT_THROW(FormatError(error));
3559 return arg;
3560 }
3561
3562 template <typename Char, typename ArgFormatter>
3563 const Char *BasicFormatter<Char, ArgFormatter>::format(
3564 const Char *&format_str, const internal::Arg &arg) {
3565 using internal::Arg;
3566 const Char *s = format_str;
3567 FormatSpec spec;
3568 if (*s == ':') {
3569 if (arg.type == Arg::CUSTOM) {
3570 arg.custom.format(this, arg.custom.value, &s);
3571 return s;
3572 }
3573 ++s;
3574 // Parse fill and alignment.
3575 if (Char c = *s) {
3576 const Char *p = s + 1;
3577 spec.align_ = ALIGN_DEFAULT;
3578 do {
3579 switch (*p) {
3580 case '<':
3581 spec.align_ = ALIGN_LEFT;
3582 break;
3583 case '>':
3584 spec.align_ = ALIGN_RIGHT;
3585 break;
3586 case '=':
3587 spec.align_ = ALIGN_NUMERIC;
3588 break;
3589 case '^':
3590 spec.align_ = ALIGN_CENTER;
3591 break;
3592 }
3593 if (spec.align_ != ALIGN_DEFAULT) {
3594 if (p != s) {
3595 if (c == '}') break;
3596 if (c == '{')
3597 FMT_THROW(FormatError("invalid fill character '{'"));
3598 s += 2;
3599 spec.fill_ = c;
3600 } else ++s;
3601 if (spec.align_ == ALIGN_NUMERIC)
3602 require_numeric_argument(arg, '=');
3603 break;
3604 }
3605 } while (--p >= s);
3606 }
3607
3608 // Parse sign.
3609 switch (*s) {
3610 case '+':
3611 check_sign(s, arg);
3612 spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
3613 break;
3614 case '-':
3615 check_sign(s, arg);
3616 spec.flags_ |= MINUS_FLAG;
3617 break;
3618 case ' ':
3619 check_sign(s, arg);
3620 spec.flags_ |= SIGN_FLAG;
3621 break;
3622 }
3623
3624 if (*s == '#') {
3625 require_numeric_argument(arg, '#');
3626 spec.flags_ |= HASH_FLAG;
3627 ++s;
3628 }
3629
3630 // Parse zero flag.
3631 if (*s == '0') {
3632 require_numeric_argument(arg, '0');
3633 spec.align_ = ALIGN_NUMERIC;
3634 spec.fill_ = '0';
3635 ++s;
3636 }
3637
3638 // Parse width.
3639 if ('0' <= *s && *s <= '9') {
3640 spec.width_ = internal::parse_nonnegative_int(s);
3641 } else if (*s == '{') {
3642 ++s;
3643 Arg width_arg = internal::is_name_start(*s) ?
3644 parse_arg_name(s) : parse_arg_index(s);
3645 if (*s++ != '}')
3646 FMT_THROW(FormatError("invalid format string"));
3647 ULongLong value = 0;
3648 switch (width_arg.type) {
3649 case Arg::INT:
3650 if (width_arg.int_value < 0)
3651 FMT_THROW(FormatError("negative width"));
3652 value = width_arg.int_value;
3653 break;
3654 case Arg::UINT:
3655 value = width_arg.uint_value;
3656 break;
3657 case Arg::LONG_LONG:
3658 if (width_arg.long_long_value < 0)
3659 FMT_THROW(FormatError("negative width"));
3660 value = width_arg.long_long_value;
3661 break;
3662 case Arg::ULONG_LONG:
3663 value = width_arg.ulong_long_value;
3664 break;
3665 default:
3666 FMT_THROW(FormatError("width is not integer"));
3667 }
3668 if (value > (std::numeric_limits<int>::max)())
3669 FMT_THROW(FormatError("number is too big"));
3670 spec.width_ = static_cast<int>(value);
3671 }
3672
3673 // Parse precision.
3674 if (*s == '.') {
3675 ++s;
3676 spec.precision_ = 0;
3677 if ('0' <= *s && *s <= '9') {
3678 spec.precision_ = internal::parse_nonnegative_int(s);
3679 } else if (*s == '{') {
3680 ++s;
3681 Arg precision_arg = internal::is_name_start(*s) ?
3682 parse_arg_name(s) : parse_arg_index(s);
3683 if (*s++ != '}')
3684 FMT_THROW(FormatError("invalid format string"));
3685 ULongLong value = 0;
3686 switch (precision_arg.type) {
3687 case Arg::INT:
3688 if (precision_arg.int_value < 0)
3689 FMT_THROW(FormatError("negative precision"));
3690 value = precision_arg.int_value;
3691 break;
3692 case Arg::UINT:
3693 value = precision_arg.uint_value;
3694 break;
3695 case Arg::LONG_LONG:
3696 if (precision_arg.long_long_value < 0)
3697 FMT_THROW(FormatError("negative precision"));
3698 value = precision_arg.long_long_value;
3699 break;
3700 case Arg::ULONG_LONG:
3701 value = precision_arg.ulong_long_value;
3702 break;
3703 default:
3704 FMT_THROW(FormatError("precision is not integer"));
3705 }
3706 if (value > (std::numeric_limits<int>::max)())
3707 FMT_THROW(FormatError("number is too big"));
3708 spec.precision_ = static_cast<int>(value);
3709 } else {
3710 FMT_THROW(FormatError("missing precision specifier"));
3711 }
3712 if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
3713 FMT_THROW(FormatError(
3714 fmt::format("precision not allowed in {} format specifier",
3715 arg.type == Arg::POINTER ? "pointer" : "integer")));
3716 }
3717 }
3718
3719 // Parse type.
3720 if (*s != '}' && *s)
3721 spec.type_ = static_cast<char>(*s++);
3722 }
3723
3724 if (*s++ != '}')
3725 FMT_THROW(FormatError("missing '}' in format string"));
3726
3727 // Format argument.
3728 ArgFormatter(*this, spec, s - 1).visit(arg);
3729 return s;
3730 }
3731
3732 template <typename Char, typename AF>
3733 void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
3734 const Char *s = format_str.c_str();
3735 const Char *start = s;
3736 while (*s) {
3737 Char c = *s++;
3738 if (c != '{' && c != '}') continue;
3739 if (*s == c) {
3740 write(writer_, start, s);
3741 start = ++s;
3742 continue;
3743 }
3744 if (c == '}')
3745 FMT_THROW(FormatError("unmatched '}' in format string"));
3746 write(writer_, start, s - 1);
3747 internal::Arg arg = internal::is_name_start(*s) ?
3748 parse_arg_name(s) : parse_arg_index(s);
3749 start = s = format(s, arg);
3750 }
3751 write(writer_, start, s);
3752 }
3753 } // namespace fmt
3754
3755 #if FMT_USE_USER_DEFINED_LITERALS
3756 namespace fmt {
3757 namespace internal {
3758
3759 template <typename Char>
3760 struct UdlFormat {
3761 const Char *str;
3762
3763 template <typename... Args>
3764 auto operator()(Args && ... args) const
3765 -> decltype(format(str, std::forward<Args>(args)...)) {
3766 return format(str, std::forward<Args>(args)...);
3767 }
3768 };
3769
3770 template <typename Char>
3771 struct UdlArg {
3772 const Char *str;
3773
3774 template <typename T>
3775 NamedArg<Char> operator=(T &&value) const {
3776 return {str, std::forward<T>(value)};
3777 }
3778 };
3779
3780 } // namespace internal
3781
3782 inline namespace literals {
3783
3794 inline internal::UdlFormat<char>
3795 operator"" _format(const char *s, std::size_t) { return {s}; }
3796 inline internal::UdlFormat<wchar_t>
3797 operator"" _format(const wchar_t *s, std::size_t) { return {s}; }
3798
3809 inline internal::UdlArg<char>
3810 operator"" _a(const char *s, std::size_t) { return {s}; }
3811 inline internal::UdlArg<wchar_t>
3812 operator"" _a(const wchar_t *s, std::size_t) { return {s}; }
3813
3814 } // inline namespace literals
3815 } // namespace fmt
3816 #endif // FMT_USE_USER_DEFINED_LITERALS
3817
3818 // Restore warnings.
3819 #if FMT_GCC_VERSION >= 406
3820 # pragma GCC diagnostic pop
3821 #endif
3822
3823 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
3824 # pragma clang diagnostic pop
3825 #endif
3826
3827 #ifdef FMT_HEADER_ONLY
3828 # define FMT_FUNC inline
3829 # include "format.cc"
3830 #else
3831 # define FMT_FUNC
3832 #endif
3833
3834 #endif // FMT_FORMAT_H_
fmt::internal::Value
Definition: format.h:982
fmt::FormatInt::size
std::size_t size() const
Definition: format.h:3254
fmt::BasicFormatter::writer
BasicWriter< Char > & writer()
Definition: format.h:2026
fmt::FormatSpec
Definition: format.h:1584
fmt::ArgVisitor::visit_custom
Result visit_custom(Arg::CustomValue)
Definition: format.h:1478
fmt::BasicArgFormatter::BasicArgFormatter
BasicArgFormatter(BasicFormatter< Char, Impl > &formatter, FormatSpec &spec, const Char *fmt)
Definition: format.h:1968
fmt::BasicStringRef::size
std::size_t size() const
Definition: format.h:448
fmt::internal::ConvertToIntImpl
Definition: format.h:1059
fmt::BasicCStringRef::BasicCStringRef
BasicCStringRef(const Char *s)
Definition: format.h:514
fmt::ArgVisitor::visit_string
Result visit_string(Arg::StringValue< char >)
Definition: format.h:1463
fmt::ArgVisitor::visit_pointer
Result visit_pointer(const void *)
Definition: format.h:1473
fmt::internal::WCharHelper
Definition: format.h:1037
fmt::BasicWriter::operator<<
BasicWriter & operator<<(long double value)
Definition: format.h:2501
fmt::IntFormatSpec
Definition: format.h:1600
fmt::ArgList
Definition: format.h:1303
fmt::internal::ArgArray
Definition: format.h:2063
fmt::ArgVisitor::visit_uint
Result visit_uint(unsigned value)
Definition: format.h:1416
fmt::BasicCStringRef::BasicCStringRef
BasicCStringRef(const std::basic_string< Char > &s)
Definition: format.h:521
fmt::BasicCStringRef
Definition: format.h:508
fmt::FormatInt
Definition: format.h:3205
fmt::ArgVisitor::visit_bool
Result visit_bool(bool value)
Definition: format.h:1426
fmt::internal::IntTraits
Definition: format.h:817
fmt::internal::MakeArg
Definition: format.h:1268
fmt::internal::DummyInt
Definition: format.h:290
fmt::internal::SignChecker
Definition: format.h:791
fmt::BasicWriter::data
const Char * data() const FMT_NOEXCEPT
Definition: format.h:2410
fmt::ArgVisitor::visit_ulong_long
Result visit_ulong_long(ULongLong value)
Definition: format.h:1421
fmt::ArgVisitor::visit_any_int
Result visit_any_int(T)
Definition: format.h:1437
fmt::SystemError::SystemError
SystemError(int error_code, CStringRef message)
Definition: format.h:2258
fmt::BasicWriter::c_str
const Char * c_str() const
Definition: format.h:2416
fmt::ArgVisitor::visit_long_long
Result visit_long_long(LongLong value)
Definition: format.h:1411
fmt::internal::Value::CustomValue
Definition: format.h:992
fmt::BasicFormatter::Char
CharType Char
Definition: format.h:1994
fmt::internal::Arg
Definition: format.h:1024
fmt::ArgVisitor::visit_any_double
Result visit_any_double(T)
Definition: format.h:1453
fmt::AlignTypeSpec
Definition: format.h:1576
fmt::ArgVisitor
Definition: format.h:1393
fmt::FormatInt::data
const char * data() const
Definition: format.h:3262
fmt::BasicCStringRef::c_str
const Char * c_str() const
Definition: format.h:524
fmt::Buffer
Definition: format.h:585
fmt::ArgList::operator[]
internal::Arg operator[](unsigned index) const
Definition: format.h:1340
fmt::BasicArrayWriter
Definition: format.h:3017
fmt::internal::NoThousandsSep
Definition: format.h:873
fmt::BasicStringRef::data
const Char * data() const
Definition: format.h:445
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const Char *s)
Definition: format.h:424
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const std::basic_string< Char > &s)
Definition: format.h:432
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const Char *s, std::size_t size)
Definition: format.h:416
fmt::ArgVisitor::visit_wstring
Result visit_wstring(Arg::StringValue< wchar_t >)
Definition: format.h:1468
fmt::ArgVisitor::visit_double
Result visit_double(double value)
Definition: format.h:1442
fmt::ArgVisitor::visit_long_double
Result visit_long_double(long double value)
Definition: format.h:1447
fmt::BasicWriter::write
void write(BasicCStringRef< Char > format, ArgList args)
Definition: format.h:2457
fmt::ArgVisitor::visit_char
Result visit_char(int value)
Definition: format.h:1431
fmt::internal::Value::StringValue
Definition: format.h:984
fmt::BasicArrayWriter::BasicArrayWriter
BasicArrayWriter(Char(&array)[SIZE])
Definition: format.h:3038
fmt::FormatInt::c_str
const char * c_str() const
Definition: format.h:3268
fmt::BasicFormatter::BasicFormatter
BasicFormatter(const ArgList &args, BasicWriter< Char > &w)
Definition: format.h:2022
fmt::internal::FormatterBase
Definition: format.h:1869
fmt::internal::PrintfArgFormatter
Definition: format.cc:363
fmt::BasicFormatter
Definition: format.h:382
fmt::Buffer::reserve
void reserve(std::size_t capacity)
Definition: format.h:628
fmt::internal::ConvertToIntImpl2
Definition: format.h:1064
fmt::internal::EnableIf
Definition: format.h:1092
fmt::internal::FixedBuffer
Definition: format.h:741
fmt::internal::RuntimeError
Definition: format.h:1290
fmt::internal::BasicCharTraits
Definition: format.h:750
fmt::AlignSpec
Definition: format.h:1563
fmt::internal::ArgFormatterBase
Definition: format.h:1772
fmt::internal::MemoryBuffer
Definition: format.h:665
fmt::BasicWriter::operator<<
BasicWriter & operator<<(char value)
Definition: format.h:2509
fmt::TypeSpec
Definition: format.h:1540
fmt::internal::ThousandsSep
Definition: format.h:879
fmt::internal::NamedArg
Definition: format.h:1029
fmt::ArgFormatter::ArgFormatter
ArgFormatter(BasicFormatter< Char > &formatter, FormatSpec &spec, const Char *fmt)
Definition: format.h:1984
fmt::ArgVisitor::visit_int
Result visit_int(int value)
Definition: format.h:1406
std::numeric_limits< fmt::internal::DummyInt >
Definition: format.h:318
fmt::BasicMemoryWriter
Definition: format.h:2962
fmt::EmptySpec
Definition: format.h:1536
fmt::internal::ArgMap
Definition: format.h:1299
fmt::internal::CharTraits
Definition: format.h:761
fmt::ArgVisitor::visit_cstring
Result visit_cstring(const char *)
Definition: format.h:1458
fmt::Buffer::capacity
std::size_t capacity() const
Definition: format.h:612
fmt::Buffer::resize
void resize(std::size_t new_size)
Definition: format.h:617
fmt::BasicWriter::operator<<
BasicWriter & operator<<(ULongLong value)
Definition: format.h:2486
fmt::FormatError
Definition: format.h:533
fmt::internal::BasicData
Definition: format.h:829
fmt::BasicArgFormatter::visit_custom
void visit_custom(internal::Arg::CustomValue c)
Definition: format.h:1974
fmt::ArgVisitor::visit
Result visit(const Arg &arg)
Definition: format.h:1490
fmt::BasicStringRef
Definition: format.h:409
fmt::internal::Not
Definition: format.h:1105
fmt::internal::TypeSelector
Definition: format.h:811
fmt::BasicWriter::BasicWriter
BasicWriter(Buffer< Char > &b)
Definition: format.h:2391
fmt::Buffer::size
std::size_t size() const
Definition: format.h:609
fmt::ArgFormatter
Definition: format.h:378
fmt::BasicArrayWriter::BasicArrayWriter
BasicArrayWriter(Char *array, std::size_t size)
Definition: format.h:3028
fmt::internal::ArgType
Definition: format.h:2099
fmt::SystemError
Definition: format.h:2221
fmt::internal::MakeUnsigned
Definition: format.h:543
fmt::internal::Conditional
Definition: format.h:1098
fmt::BasicArgFormatter
Definition: format.h:1954
fmt::internal::Null
Definition: format.h:1032
fmt::BasicWriter::~BasicWriter
virtual ~BasicWriter()
Definition: format.h:2399
fmt::BasicWriter::str
std::basic_string< Char > str() const
Definition: format.h:2428
fmt::internal::ConvertToInt
Definition: format.h:1077
fmt::BasicWriter
Definition: format.h:372
fmt::BasicStringRef::to_string
std::basic_string< Char > to_string() const
Definition: format.h:440
fmt::internal::PrintfFormatter
Definition: format.h:1917
fmt::internal::MakeValue
Definition: format.h:1112
fmt::WidthSpec
Definition: format.h:1550
fmt::StrFormatSpec
Definition: format.h:1613
fmt::FormatInt::str
std::string str() const
Definition: format.h:3278
fmt::BasicWriter::size
std::size_t size() const
Definition: format.h:2404