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> // for std::pair
44
45 // The fmt library version in the form major * 10000 + minor * 100 + patch.
46 #define FMT_VERSION 40000
47
48 #ifdef _SECURE_SCL
49 # define FMT_SECURE_SCL _SECURE_SCL
50 #else
51 # define FMT_SECURE_SCL 0
52 #endif
53
54 #if FMT_SECURE_SCL
55 # include <iterator>
56 #endif
57
58 #ifdef _MSC_VER
59 # define FMT_MSC_VER _MSC_VER
60 #else
61 # define FMT_MSC_VER 0
62 #endif
63
64 #if FMT_MSC_VER && FMT_MSC_VER <= 1500
65 typedef unsigned __int32 uint32_t;
66 typedef unsigned __int64 uint64_t;
67 typedef __int64 intmax_t;
68 #else
69 #include <stdint.h>
70 #endif
71
72 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
73 # ifdef FMT_EXPORT
74 # define FMT_API __declspec(dllexport)
75 # elif defined(FMT_SHARED)
76 # define FMT_API __declspec(dllimport)
77 # endif
78 #endif
79 #ifndef FMT_API
80 # define FMT_API
81 #endif
82
83 #ifdef __GNUC__
84 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
85 # define FMT_GCC_EXTENSION __extension__
86 # if FMT_GCC_VERSION >= 406
87 # pragma GCC diagnostic push
88 // Disable the warning about "long long" which is sometimes reported even
89 // when using __extension__.
90 # pragma GCC diagnostic ignored "-Wlong-long"
91 // Disable the warning about declaration shadowing because it affects too
92 // many valid cases.
93 # pragma GCC diagnostic ignored "-Wshadow"
94 // Disable the warning about implicit conversions that may change the sign of
95 // an integer; silencing it otherwise would require many explicit casts.
96 # pragma GCC diagnostic ignored "-Wsign-conversion"
97 # endif
98 # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
99 # define FMT_HAS_GXX_CXX11 1
100 # endif
101 #else
102 # define FMT_GCC_EXTENSION
103 #endif
104
105 #if defined(__INTEL_COMPILER)
106 # define FMT_ICC_VERSION __INTEL_COMPILER
107 #elif defined(__ICL)
108 # define FMT_ICC_VERSION __ICL
109 #endif
110
111 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
112 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
113 # pragma clang diagnostic push
114 # pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
115 # pragma clang diagnostic ignored "-Wpadded"
116 #endif
117
118 #ifdef __GNUC_LIBSTD__
119 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
120 #endif
121
122 #ifdef __has_feature
123 # define FMT_HAS_FEATURE(x) __has_feature(x)
124 #else
125 # define FMT_HAS_FEATURE(x) 0
126 #endif
127
128 #ifdef __has_builtin
129 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
130 #else
131 # define FMT_HAS_BUILTIN(x) 0
132 #endif
133
134 #ifdef __has_cpp_attribute
135 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
136 #else
137 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
138 #endif
139
140 #ifndef FMT_USE_VARIADIC_TEMPLATES
141 // Variadic templates are available in GCC since version 4.4
142 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
143 // since version 2013.
144 # define FMT_USE_VARIADIC_TEMPLATES \
145 (FMT_HAS_FEATURE(cxx_variadic_templates) || \
146 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800)
147 #endif
148
149 #ifndef FMT_USE_RVALUE_REFERENCES
150 // Don't use rvalue references when compiling with clang and an old libstdc++
151 // as the latter doesn't provide std::move.
152 # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
153 # define FMT_USE_RVALUE_REFERENCES 0
154 # else
155 # define FMT_USE_RVALUE_REFERENCES \
156 (FMT_HAS_FEATURE(cxx_rvalue_references) || \
157 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600)
158 # endif
159 #endif
160
161 // Check if exceptions are disabled.
162 #if defined(__GNUC__) && !defined(__EXCEPTIONS)
163 # define FMT_EXCEPTIONS 0
164 #endif
165 #if FMT_MSC_VER && !_HAS_EXCEPTIONS
166 # define FMT_EXCEPTIONS 0
167 #endif
168 #ifndef FMT_EXCEPTIONS
169 # define FMT_EXCEPTIONS 1
170 #endif
171
172 #ifndef FMT_THROW
173 # if FMT_EXCEPTIONS
174 # define FMT_THROW(x) throw x
175 # else
176 # define FMT_THROW(x) assert(false)
177 # endif
178 #endif
179
180 // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
181 #ifndef FMT_USE_NOEXCEPT
182 # define FMT_USE_NOEXCEPT 0
183 #endif
184
185 #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
186 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
187 FMT_MSC_VER >= 1900
188 # define FMT_DETECTED_NOEXCEPT noexcept
189 #else
190 # define FMT_DETECTED_NOEXCEPT throw()
191 #endif
192
193 #ifndef FMT_NOEXCEPT
194 # if FMT_EXCEPTIONS
195 # define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
196 # else
197 # define FMT_NOEXCEPT
198 # endif
199 #endif
200
201 // This is needed because GCC still uses throw() in its headers when exceptions
202 // are disabled.
203 #if FMT_GCC_VERSION
204 # define FMT_DTOR_NOEXCEPT FMT_DETECTED_NOEXCEPT
205 #else
206 # define FMT_DTOR_NOEXCEPT FMT_NOEXCEPT
207 #endif
208
209 #ifndef FMT_OVERRIDE
210 # if (defined(FMT_USE_OVERRIDE) && FMT_USE_OVERRIDE) || FMT_HAS_FEATURE(cxx_override) || \
211 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
212 FMT_MSC_VER >= 1900
213 # define FMT_OVERRIDE override
214 # else
215 # define FMT_OVERRIDE
216 # endif
217 #endif
218
219 #ifndef FMT_NULL
220 # if FMT_HAS_FEATURE(cxx_nullptr) || \
221 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
222 FMT_MSC_VER >= 1600
223 # define FMT_NULL nullptr
224 # else
225 # define FMT_NULL NULL
226 # endif
227 #endif
228
229 // A macro to disallow the copy constructor and operator= functions
230 // This should be used in the private: declarations for a class
231 #ifndef FMT_USE_DELETED_FUNCTIONS
232 # define FMT_USE_DELETED_FUNCTIONS 0
233 #endif
234
235 #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \
236 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
237 # define FMT_DELETED_OR_UNDEFINED = delete
238 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
239 TypeName(const TypeName&) = delete; \
240 TypeName& operator=(const TypeName&) = delete
241 #else
242 # define FMT_DELETED_OR_UNDEFINED
243 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
244 TypeName(const TypeName&); \
245 TypeName& operator=(const TypeName&)
246 #endif
247
248 #ifndef FMT_USE_DEFAULTED_FUNCTIONS
249 # define FMT_USE_DEFAULTED_FUNCTIONS 0
250 #endif
251
252 #ifndef FMT_DEFAULTED_COPY_CTOR
253 # if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) || \
254 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
255 # define FMT_DEFAULTED_COPY_CTOR(TypeName) \
256 TypeName(const TypeName&) = default;
257 # else
258 # define FMT_DEFAULTED_COPY_CTOR(TypeName)
259 # endif
260 #endif
261
262 #ifndef FMT_USE_USER_DEFINED_LITERALS
263 // All compilers which support UDLs also support variadic templates. This
264 // makes the fmt::literals implementation easier. However, an explicit check
265 // for variadic templates is added here just in case.
266 // For Intel's compiler both it and the system gcc/msc must support UDLs.
267 # define FMT_USE_USER_DEFINED_LITERALS \
268 FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
269 (FMT_HAS_FEATURE(cxx_user_literals) || \
270 (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \
271 (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
272 #endif
273
274 #ifndef FMT_USE_EXTERN_TEMPLATES
275 # define FMT_USE_EXTERN_TEMPLATES \
276 (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
277 #endif
278
279 #ifdef FMT_HEADER_ONLY
280 // If header only do not use extern templates.
281 # undef FMT_USE_EXTERN_TEMPLATES
282 # define FMT_USE_EXTERN_TEMPLATES 0
283 #endif
284
285 #ifndef FMT_ASSERT
286 # define FMT_ASSERT(condition, message) assert((condition) && message)
287 #endif
288
289 // __builtin_clz is broken in clang with Microsoft CodeGen:
290 // https://github.com/fmtlib/fmt/issues/519
291 #ifndef _MSC_VER
292 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
293 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
294 # endif
295
296 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
297 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
298 # endif
299 #endif
300
301 // Some compilers masquerade as both MSVC and GCC-likes or
302 // otherwise support __builtin_clz and __builtin_clzll, so
303 // only define FMT_BUILTIN_CLZ using the MSVC intrinsics
304 // if the clz and clzll builtins are not available.
305 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
306 # include <intrin.h> // _BitScanReverse, _BitScanReverse64
307
308 namespace fmt {
309 namespace internal {
310 # pragma intrinsic(_BitScanReverse)
311 inline uint32_t clz(uint32_t x) {
312 unsigned long r = 0;
313 _BitScanReverse(&r, x);
314
315 assert(x != 0);
316 // Static analysis complains about using uninitialized data
317 // "r", but the only way that can happen is if "x" is 0,
318 // which the callers guarantee to not happen.
319 # pragma warning(suppress: 6102)
320 return 31 - r;
321 }
322 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
323
324 # ifdef _WIN64
325 # pragma intrinsic(_BitScanReverse64)
326 # endif
327
328 inline uint32_t clzll(uint64_t x) {
329 unsigned long r = 0;
330 # ifdef _WIN64
331 _BitScanReverse64(&r, x);
332 # else
333 // Scan the high 32 bits.
334 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
335 return 63 - (r + 32);
336
337 // Scan the low 32 bits.
338 _BitScanReverse(&r, static_cast<uint32_t>(x));
339 # endif
340
341 assert(x != 0);
342 // Static analysis complains about using uninitialized data
343 // "r", but the only way that can happen is if "x" is 0,
344 // which the callers guarantee to not happen.
345 # pragma warning(suppress: 6102)
346 return 63 - r;
347 }
348 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
349 }
350 }
351 #endif
352
353 namespace fmt {
354 namespace internal {
355 struct DummyInt {
356 int data[2];
357 operator int() const { return 0; }
358 };
359 typedef std::numeric_limits<fmt::internal::DummyInt> FPUtil;
360
361 // Dummy implementations of system functions such as signbit and ecvt called
362 // if the latter are not available.
363 inline DummyInt signbit(...) { return DummyInt(); }
364 inline DummyInt _ecvt_s(...) { return DummyInt(); }
365 inline DummyInt isinf(...) { return DummyInt(); }
366 inline DummyInt _finite(...) { return DummyInt(); }
367 inline DummyInt isnan(...) { return DummyInt(); }
368 inline DummyInt _isnan(...) { return DummyInt(); }
369
370 // A helper function to suppress bogus "conditional expression is constant"
371 // warnings.
372 template <typename T>
373 inline T const_check(T value) { return value; }
374 }
375 } // namespace fmt
376
377 namespace std {
378 // Standard permits specialization of std::numeric_limits. This specialization
379 // is used to resolve ambiguity between isinf and std::isinf in glibc:
380 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
381 // and the same for isnan and signbit.
382 template <>
383 class numeric_limits<fmt::internal::DummyInt> :
384 public std::numeric_limits<int> {
385 public:
386 // Portable version of isinf.
387 template <typename T>
388 static bool isinfinity(T x) {
389 using namespace fmt::internal;
390 // The resolution "priority" is:
391 // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
392 if (const_check(sizeof(isinf(x)) == sizeof(bool) ||
393 sizeof(isinf(x)) == sizeof(int))) {
394 return isinf(x) != 0;
395 }
396 return !_finite(static_cast<double>(x));
397 }
398
399 // Portable version of isnan.
400 template <typename T>
401 static bool isnotanumber(T x) {
402 using namespace fmt::internal;
403 if (const_check(sizeof(isnan(x)) == sizeof(bool) ||
404 sizeof(isnan(x)) == sizeof(int))) {
405 return isnan(x) != 0;
406 }
407 return _isnan(static_cast<double>(x)) != 0;
408 }
409
410 // Portable version of signbit.
411 static bool isnegative(double x) {
412 using namespace fmt::internal;
413 if (const_check(sizeof(signbit(x)) == sizeof(bool) ||
414 sizeof(signbit(x)) == sizeof(int))) {
415 return signbit(x) != 0;
416 }
417 if (x < 0) return true;
418 if (!isnotanumber(x)) return false;
419 int dec = 0, sign = 0;
420 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
421 _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
422 return sign != 0;
423 }
424 };
425 } // namespace std
426
427 namespace fmt {
428
429 // Fix the warning about long long on older versions of GCC
430 // that don't support the diagnostic pragma.
431 FMT_GCC_EXTENSION typedef long long LongLong;
432 FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
433
434 #if FMT_USE_RVALUE_REFERENCES
435 using std::move;
436 #endif
437
438 template <typename Char>
439 class BasicWriter;
440
441 typedef BasicWriter<char> Writer;
442 typedef BasicWriter<wchar_t> WWriter;
443
444 template <typename Char>
445 class ArgFormatter;
446
447 struct FormatSpec;
448
449 template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
450 class BasicPrintfArgFormatter;
451
452 template <typename CharType,
453 typename ArgFormatter = fmt::ArgFormatter<CharType> >
454 class BasicFormatter;
455
481 template <typename Char>
482 class BasicStringRef {
483 private:
484 const Char *data_;
485 std::size_t size_;
486
487 public:
489 BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {}
490
497 BasicStringRef(const Char *s)
498 : data_(s), size_(std::char_traits<Char>::length(s)) {}
499
505 template <typename Allocator>
506 BasicStringRef(
507 const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
508 : data_(s.c_str()), size_(s.size()) {}
509
515 std::basic_string<Char> to_string() const {
516 return std::basic_string<Char>(data_, size_);
517 }
518
520 const Char *data() const { return data_; }
521
523 std::size_t size() const { return size_; }
524
525 // Lexicographically compare this string reference to other.
526 int compare(BasicStringRef other) const {
527 std::size_t size = size_ < other.size_ ? size_ : other.size_;
528 int result = std::char_traits<Char>::compare(data_, other.data_, size);
529 if (result == 0)
530 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
531 return result;
532 }
533
534 friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
535 return lhs.compare(rhs) == 0;
536 }
537 friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
538 return lhs.compare(rhs) != 0;
539 }
540 friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) {
541 return lhs.compare(rhs) < 0;
542 }
543 friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) {
544 return lhs.compare(rhs) <= 0;
545 }
546 friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) {
547 return lhs.compare(rhs) > 0;
548 }
549 friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) {
550 return lhs.compare(rhs) >= 0;
551 }
552 };
553
554 typedef BasicStringRef<char> StringRef;
555 typedef BasicStringRef<wchar_t> WStringRef;
556
582 template <typename Char>
583 class BasicCStringRef {
584 private:
585 const Char *data_;
586
587 public:
589 BasicCStringRef(const Char *s) : data_(s) {}
590
596 template <typename Allocator>
597 BasicCStringRef(
598 const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
599 : data_(s.c_str()) {}
600
602 const Char *c_str() const { return data_; }
603 };
604
605 typedef BasicCStringRef<char> CStringRef;
606 typedef BasicCStringRef<wchar_t> WCStringRef;
607
609 class FormatError : public std::runtime_error {
610 public:
611 explicit FormatError(CStringRef message)
612 : std::runtime_error(message.c_str()) {}
613 FormatError(const FormatError &ferr) : std::runtime_error(ferr) {}
614 FMT_API ~FormatError() FMT_DTOR_NOEXCEPT;
615 };
616
617 namespace internal {
618
619 // MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
620 template <typename T>
621 struct MakeUnsigned { typedef T Type; };
622
623 #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
624 template <> \
625 struct MakeUnsigned<T> { typedef U Type; }
626
627 FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
628 FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
629 FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
630 FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
631 FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
632 FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
633
634 // Casts nonnegative integer to unsigned.
635 template <typename Int>
636 inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
637 FMT_ASSERT(value >= 0, "negative value");
638 return static_cast<typename MakeUnsigned<Int>::Type>(value);
639 }
640
641 // The number of characters to store in the MemoryBuffer object itself
642 // to avoid dynamic memory allocation.
643 enum { INLINE_BUFFER_SIZE = 500 };
644
645 #if FMT_SECURE_SCL
646 // Use checked iterator to avoid warnings on MSVC.
647 template <typename T>
648 inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
649 return stdext::checked_array_iterator<T*>(ptr, size);
650 }
651 #else
652 template <typename T>
653 inline T *make_ptr(T *ptr, std::size_t) { return ptr; }
654 #endif
655 } // namespace internal
656
662 template <typename T>
663 class Buffer {
664 private:
665 FMT_DISALLOW_COPY_AND_ASSIGN(Buffer);
666
667 protected:
668 T *ptr_;
669 std::size_t size_;
670 std::size_t capacity_;
671
672 Buffer(T *ptr = FMT_NULL, std::size_t capacity = 0)
673 : ptr_(ptr), size_(0), capacity_(capacity) {}
674
681 virtual void grow(std::size_t size) = 0;
682
683 public:
684 virtual ~Buffer() {}
685
687 std::size_t size() const { return size_; }
688
690 std::size_t capacity() const { return capacity_; }
691
695 void resize(std::size_t new_size) {
696 if (new_size > capacity_)
697 grow(new_size);
698 size_ = new_size;
699 }
700
706 void reserve(std::size_t capacity) {
707 if (capacity > capacity_)
708 grow(capacity);
709 }
710
711 void clear() FMT_NOEXCEPT { size_ = 0; }
712
713 void push_back(const T &value) {
714 if (size_ == capacity_)
715 grow(size_ + 1);
716 ptr_[size_++] = value;
717 }
718
720 template <typename U>
721 void append(const U *begin, const U *end);
722
723 T &operator[](std::size_t index) { return ptr_[index]; }
724 const T &operator[](std::size_t index) const { return ptr_[index]; }
725 };
726
727 template <typename T>
728 template <typename U>
729 void Buffer<T>::append(const U *begin, const U *end) {
730 FMT_ASSERT(end >= begin, "negative value");
731 std::size_t new_size = size_ + (end - begin);
732 if (new_size > capacity_)
733 grow(new_size);
734 std::uninitialized_copy(begin, end,
735 internal::make_ptr(ptr_, capacity_) + size_);
736 size_ = new_size;
737 }
738
739 namespace internal {
740
741 // A memory buffer for trivially copyable/constructible types with the first
742 // SIZE elements stored in the object itself.
743 template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
744 class MemoryBuffer : private Allocator, public Buffer<T> {
745 private:
746 T data_[SIZE];
747
748 // Deallocate memory allocated by the buffer.
749 void deallocate() {
750 if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
751 }
752
753 protected:
754 void grow(std::size_t size) FMT_OVERRIDE;
755
756 public:
757 explicit MemoryBuffer(const Allocator &alloc = Allocator())
758 : Allocator(alloc), Buffer<T>(data_, SIZE) {}
759 ~MemoryBuffer() { deallocate(); }
760
761 #if FMT_USE_RVALUE_REFERENCES
762 private:
763 // Move data from other to this buffer.
764 void move(MemoryBuffer &other) {
765 Allocator &this_alloc = *this, &other_alloc = other;
766 this_alloc = std::move(other_alloc);
767 this->size_ = other.size_;
768 this->capacity_ = other.capacity_;
769 if (other.ptr_ == other.data_) {
770 this->ptr_ = data_;
771 std::uninitialized_copy(other.data_, other.data_ + this->size_,
772 make_ptr(data_, this->capacity_));
773 } else {
774 this->ptr_ = other.ptr_;
775 // Set pointer to the inline array so that delete is not called
776 // when deallocating.
777 other.ptr_ = other.data_;
778 }
779 }
780
781 public:
782 MemoryBuffer(MemoryBuffer &&other) {
783 move(other);
784 }
785
786 MemoryBuffer &operator=(MemoryBuffer &&other) {
787 assert(this != &other);
788 deallocate();
789 move(other);
790 return *this;
791 }
792 #endif
793
794 // Returns a copy of the allocator associated with this buffer.
795 Allocator get_allocator() const { return *this; }
796 };
797
798 template <typename T, std::size_t SIZE, typename Allocator>
799 void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
800 std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
801 if (size > new_capacity)
802 new_capacity = size;
803 T *new_ptr = this->allocate(new_capacity, FMT_NULL);
804 // The following code doesn't throw, so the raw pointer above doesn't leak.
805 std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
806 make_ptr(new_ptr, new_capacity));
807 std::size_t old_capacity = this->capacity_;
808 T *old_ptr = this->ptr_;
809 this->capacity_ = new_capacity;
810 this->ptr_ = new_ptr;
811 // deallocate may throw (at least in principle), but it doesn't matter since
812 // the buffer already uses the new storage and will deallocate it in case
813 // of exception.
814 if (old_ptr != data_)
815 Allocator::deallocate(old_ptr, old_capacity);
816 }
817
818 // A fixed-size buffer.
819 template <typename Char>
820 class FixedBuffer : public fmt::Buffer<Char> {
821 public:
822 FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
823
824 protected:
825 FMT_API void grow(std::size_t size) FMT_OVERRIDE;
826 };
827
828 template <typename Char>
829 class BasicCharTraits {
830 public:
831 #if FMT_SECURE_SCL
832 typedef stdext::checked_array_iterator<Char*> CharPtr;
833 #else
834 typedef Char *CharPtr;
835 #endif
836 static Char cast(int value) { return static_cast<Char>(value); }
837 };
838
839 template <typename Char>
840 class CharTraits;
841
842 template <>
843 class CharTraits<char> : public BasicCharTraits<char> {
844 private:
845 // Conversion from wchar_t to char is not allowed.
846 static char convert(wchar_t);
847
848 public:
849 static char convert(char value) { return value; }
850
851 // Formats a floating-point number.
852 template <typename T>
853 FMT_API static int format_float(char *buffer, std::size_t size,
854 const char *format, unsigned width, int precision, T value);
855 };
856
857 #if FMT_USE_EXTERN_TEMPLATES
858 extern template int CharTraits<char>::format_float<double>
859 (char *buffer, std::size_t size,
860 const char* format, unsigned width, int precision, double value);
861 extern template int CharTraits<char>::format_float<long double>
862 (char *buffer, std::size_t size,
863 const char* format, unsigned width, int precision, long double value);
864 #endif
865
866 template <>
867 class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
868 public:
869 static wchar_t convert(char value) { return value; }
870 static wchar_t convert(wchar_t value) { return value; }
871
872 template <typename T>
873 FMT_API static int format_float(wchar_t *buffer, std::size_t size,
874 const wchar_t *format, unsigned width, int precision, T value);
875 };
876
877 #if FMT_USE_EXTERN_TEMPLATES
878 extern template int CharTraits<wchar_t>::format_float<double>
879 (wchar_t *buffer, std::size_t size,
880 const wchar_t* format, unsigned width, int precision, double value);
881 extern template int CharTraits<wchar_t>::format_float<long double>
882 (wchar_t *buffer, std::size_t size,
883 const wchar_t* format, unsigned width, int precision, long double value);
884 #endif
885
886 // Checks if a number is negative - used to avoid warnings.
887 template <bool IsSigned>
888 struct SignChecker {
889 template <typename T>
890 static bool is_negative(T value) { return value < 0; }
891 };
892
893 template <>
894 struct SignChecker<false> {
895 template <typename T>
896 static bool is_negative(T) { return false; }
897 };
898
899 // Returns true if value is negative, false otherwise.
900 // Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
901 template <typename T>
902 inline bool is_negative(T value) {
903 return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value);
904 }
905
906 // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
907 template <bool FitsIn32Bits>
908 struct TypeSelector { typedef uint32_t Type; };
909
910 template <>
911 struct TypeSelector<false> { typedef uint64_t Type; };
912
913 template <typename T>
914 struct IntTraits {
915 // Smallest of uint32_t and uint64_t that is large enough to represent
916 // all values of T.
917 typedef typename
918 TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
919 };
920
921 FMT_API void report_unknown_type(char code, const char *type);
922
923 // Static data is placed in this class template to allow header-only
924 // configuration.
925 template <typename T = void>
926 struct FMT_API BasicData {
927 static const uint32_t POWERS_OF_10_32[];
928 static const uint64_t POWERS_OF_10_64[];
929 static const char DIGITS[];
930 };
931
932 #if FMT_USE_EXTERN_TEMPLATES
933 extern template struct BasicData<void>;
934 #endif
935
936 typedef BasicData<> Data;
937
938 #ifdef FMT_BUILTIN_CLZLL
939 // Returns the number of decimal digits in n. Leading zeros are not counted
940 // except for n == 0 in which case count_digits returns 1.
941 inline unsigned count_digits(uint64_t n) {
942 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
943 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
944 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
945 return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
946 }
947 #else
948 // Fallback version of count_digits used when __builtin_clz is not available.
949 inline unsigned count_digits(uint64_t n) {
950 unsigned count = 1;
951 for (;;) {
952 // Integer division is slow so do it for a group of four digits instead
953 // of for every digit. The idea comes from the talk by Alexandrescu
954 // "Three Optimization Tips for C++". See speed-test for a comparison.
955 if (n < 10) return count;
956 if (n < 100) return count + 1;
957 if (n < 1000) return count + 2;
958 if (n < 10000) return count + 3;
959 n /= 10000u;
960 count += 4;
961 }
962 }
963 #endif
964
965 #ifdef FMT_BUILTIN_CLZ
966 // Optional version of count_digits for better performance on 32-bit platforms.
967 inline unsigned count_digits(uint32_t n) {
968 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
969 return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
970 }
971 #endif
972
973 // A functor that doesn't add a thousands separator.
974 struct NoThousandsSep {
975 template <typename Char>
976 void operator()(Char *) {}
977 };
978
979 // A functor that adds a thousands separator.
980 class ThousandsSep {
981 private:
982 fmt::StringRef sep_;
983
984 // Index of a decimal digit with the least significant digit having index 0.
985 unsigned digit_index_;
986
987 public:
988 explicit ThousandsSep(fmt::StringRef sep) : sep_(sep), digit_index_(0) {}
989
990 template <typename Char>
991 void operator()(Char *&buffer) {
992 if (++digit_index_ % 3 != 0)
993 return;
994 buffer -= sep_.size();
995 std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
996 internal::make_ptr(buffer, sep_.size()));
997 }
998 };
999
1000 // Formats a decimal unsigned integer value writing into buffer.
1001 // thousands_sep is a functor that is called after writing each char to
1002 // add a thousands separator if necessary.
1003 template <typename UInt, typename Char, typename ThousandsSep>
1004 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
1005 ThousandsSep thousands_sep) {
1006 buffer += num_digits;
1007 while (value >= 100) {
1008 // Integer division is slow so do it for a group of two digits instead
1009 // of for every digit. The idea comes from the talk by Alexandrescu
1010 // "Three Optimization Tips for C++". See speed-test for a comparison.
1011 unsigned index = static_cast<unsigned>((value % 100) * 2);
1012 value /= 100;
1013 *--buffer = Data::DIGITS[index + 1];
1014 thousands_sep(buffer);
1015 *--buffer = Data::DIGITS[index];
1016 thousands_sep(buffer);
1017 }
1018 if (value < 10) {
1019 *--buffer = static_cast<char>('0' + value);
1020 return;
1021 }
1022 unsigned index = static_cast<unsigned>(value * 2);
1023 *--buffer = Data::DIGITS[index + 1];
1024 thousands_sep(buffer);
1025 *--buffer = Data::DIGITS[index];
1026 }
1027
1028 template <typename UInt, typename Char>
1029 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
1030 format_decimal(buffer, value, num_digits, NoThousandsSep());
1031 return;
1032 }
1033
1034 #ifndef _WIN32
1035 # define FMT_USE_WINDOWS_H 0
1036 #elif !defined(FMT_USE_WINDOWS_H)
1037 # define FMT_USE_WINDOWS_H 1
1038 #endif
1039
1040 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
1041 // All the functionality that relies on it will be disabled too.
1042 #if FMT_USE_WINDOWS_H
1043 // A converter from UTF-8 to UTF-16.
1044 // It is only provided for Windows since other systems support UTF-8 natively.
1045 class UTF8ToUTF16 {
1046 private:
1047 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
1048
1049 public:
1050 FMT_API explicit UTF8ToUTF16(StringRef s);
1051 operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
1052 size_t size() const { return buffer_.size() - 1; }
1053 const wchar_t *c_str() const { return &buffer_[0]; }
1054 std::wstring str() const { return std::wstring(&buffer_[0], size()); }
1055 };
1056
1057 // A converter from UTF-16 to UTF-8.
1058 // It is only provided for Windows since other systems support UTF-8 natively.
1059 class UTF16ToUTF8 {
1060 private:
1061 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_;
1062
1063 public:
1064 UTF16ToUTF8() {}
1065 FMT_API explicit UTF16ToUTF8(WStringRef s);
1066 operator StringRef() const { return StringRef(&buffer_[0], size()); }
1067 size_t size() const { return buffer_.size() - 1; }
1068 const char *c_str() const { return &buffer_[0]; }
1069 std::string str() const { return std::string(&buffer_[0], size()); }
1070
1071 // Performs conversion returning a system error code instead of
1072 // throwing exception on conversion error. This method may still throw
1073 // in case of memory allocation error.
1074 FMT_API int convert(WStringRef s);
1075 };
1076
1077 FMT_API void format_windows_error(fmt::Writer &out, int error_code,
1078 fmt::StringRef message) FMT_NOEXCEPT;
1079 #endif
1080
1081 // A formatting argument value.
1082 struct Value {
1083 template <typename Char>
1084 struct StringValue {
1085 const Char *value;
1086 std::size_t size;
1087 };
1088
1089 typedef void (*FormatFunc)(
1090 void *formatter, const void *arg, void *format_str_ptr);
1091
1092 struct CustomValue {
1093 const void *value;
1094 FormatFunc format;
1095 };
1096
1097 union {
1098 int int_value;
1099 unsigned uint_value;
1100 LongLong long_long_value;
1101 ULongLong ulong_long_value;
1102 double double_value;
1103 long double long_double_value;
1104 const void *pointer;
1105 StringValue<char> string;
1106 StringValue<signed char> sstring;
1107 StringValue<unsigned char> ustring;
1108 StringValue<wchar_t> wstring;
1109 CustomValue custom;
1110 };
1111
1112 enum Type {
1113 NONE, NAMED_ARG,
1114 // Integer types should go first,
1115 INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
1116 // followed by floating-point types.
1117 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
1118 CSTRING, STRING, WSTRING, POINTER, CUSTOM
1119 };
1120 };
1121
1122 // A formatting argument. It is a trivially copyable/constructible type to
1123 // allow storage in internal::MemoryBuffer.
1124 struct Arg : Value {
1125 Type type;
1126 };
1127
1128 template <typename Char>
1129 struct NamedArg;
1130 template <typename Char, typename T>
1131 struct NamedArgWithType;
1132
1133 template <typename T = void>
1134 struct Null {};
1135
1136 // A helper class template to enable or disable overloads taking wide
1137 // characters and strings in MakeValue.
1138 template <typename T, typename Char>
1139 struct WCharHelper {
1140 typedef Null<T> Supported;
1141 typedef T Unsupported;
1142 };
1143
1144 template <typename T>
1145 struct WCharHelper<T, wchar_t> {
1146 typedef T Supported;
1147 typedef Null<T> Unsupported;
1148 };
1149
1150 typedef char Yes[1];
1151 typedef char No[2];
1152
1153 template <typename T>
1154 T &get();
1155
1156 // These are non-members to workaround an overload resolution bug in bcc32.
1157 Yes &convert(fmt::ULongLong);
1158 No &convert(...);
1159
1160 template<typename T, bool ENABLE_CONVERSION>
1161 struct ConvertToIntImpl {
1162 enum { value = ENABLE_CONVERSION };
1163 };
1164
1165 template<typename T, bool ENABLE_CONVERSION>
1166 struct ConvertToIntImpl2 {
1167 enum { value = false };
1168 };
1169
1170 template<typename T>
1171 struct ConvertToIntImpl2<T, true> {
1172 enum {
1173 // Don't convert numeric types.
1174 value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value
1175 };
1176 };
1177
1178 template<typename T>
1179 struct ConvertToInt {
1180 enum {
1181 enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
1182 };
1183 enum { value = ConvertToIntImpl2<T, enable_conversion>::value };
1184 };
1185
1186 #define FMT_DISABLE_CONVERSION_TO_INT(Type) \
1187 template <> \
1188 struct ConvertToInt<Type> { enum { value = 0 }; }
1189
1190 // Silence warnings about convering float to int.
1191 FMT_DISABLE_CONVERSION_TO_INT(float);
1192 FMT_DISABLE_CONVERSION_TO_INT(double);
1193 FMT_DISABLE_CONVERSION_TO_INT(long double);
1194
1195 template<bool B, class T = void>
1196 struct EnableIf {};
1197
1198 template<class T>
1199 struct EnableIf<true, T> { typedef T type; };
1200
1201 template<bool B, class T, class F>
1202 struct Conditional { typedef T type; };
1203
1204 template<class T, class F>
1205 struct Conditional<false, T, F> { typedef F type; };
1206
1207 // For bcc32 which doesn't understand ! in template arguments.
1208 template <bool>
1209 struct Not { enum { value = 0 }; };
1210
1211 template <>
1212 struct Not<false> { enum { value = 1 }; };
1213
1214 template <typename T>
1215 struct FalseType { enum { value = 0 }; };
1216
1217 template <typename T, T> struct LConvCheck {
1218 LConvCheck(int) {}
1219 };
1220
1221 // Returns the thousands separator for the current locale.
1222 // We check if ``lconv`` contains ``thousands_sep`` because on Android
1223 // ``lconv`` is stubbed as an empty struct.
1224 template <typename LConv>
1225 inline StringRef thousands_sep(
1226 LConv *lc, LConvCheck<char *LConv::*, &LConv::thousands_sep> = 0) {
1227 return lc->thousands_sep;
1228 }
1229
1230 inline fmt::StringRef thousands_sep(...) { return ""; }
1231
1232 #define FMT_CONCAT(a, b) a##b
1233
1234 #if FMT_GCC_VERSION >= 303
1235 # define FMT_UNUSED __attribute__((unused))
1236 #else
1237 # define FMT_UNUSED
1238 #endif
1239
1240 #ifndef FMT_USE_STATIC_ASSERT
1241 # define FMT_USE_STATIC_ASSERT 0
1242 #endif
1243
1244 #if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
1245 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
1246 # define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
1247 #else
1248 # define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
1249 # define FMT_STATIC_ASSERT(cond, message) \
1250 typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
1251 #endif
1252
1253 template <typename Formatter, typename Char, typename T>
1254 void format_arg(Formatter &, const Char *, const T &) {
1255 FMT_STATIC_ASSERT(FalseType<T>::value,
1256 "Cannot format argument. To enable the use of ostream "
1257 "operator<< include fmt/ostream.h. Otherwise provide "
1258 "an overload of format_arg.");
1259 }
1260
1261 // Makes an Arg object from any type.
1262 template <typename Formatter>
1263 class MakeValue : public Arg {
1264 public:
1265 typedef typename Formatter::Char Char;
1266
1267 private:
1268 // The following two methods are private to disallow formatting of
1269 // arbitrary pointers. If you want to output a pointer cast it to
1270 // "void *" or "const void *". In particular, this forbids formatting
1271 // of "[const] volatile char *" which is printed as bool by iostreams.
1272 // Do not implement!
1273 template <typename T>
1274 MakeValue(const T *value);
1275 template <typename T>
1276 MakeValue(T *value);
1277
1278 // The following methods are private to disallow formatting of wide
1279 // characters and strings into narrow strings as in
1280 // fmt::format("{}", L"test");
1281 // To fix this, use a wide format string: fmt::format(L"{}", L"test").
1282 #if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
1283 MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported);
1284 #endif
1285 MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
1286 MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
1287 MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
1288 MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
1289
1290 void set_string(StringRef str) {
1291 string.value = str.data();
1292 string.size = str.size();
1293 }
1294
1295 void set_string(WStringRef str) {
1296 wstring.value = str.data();
1297 wstring.size = str.size();
1298 }
1299
1300 // Formats an argument of a custom type, such as a user-defined class.
1301 template <typename T>
1302 static void format_custom_arg(
1303 void *formatter, const void *arg, void *format_str_ptr) {
1304 format_arg(*static_cast<Formatter*>(formatter),
1305 *static_cast<const Char**>(format_str_ptr),
1306 *static_cast<const T*>(arg));
1307 }
1308
1309 public:
1310 MakeValue() {}
1311
1312 #define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
1313 MakeValue(Type value) { field = rhs; } \
1314 static uint64_t type(Type) { return Arg::TYPE; }
1315
1316 #define FMT_MAKE_VALUE(Type, field, TYPE) \
1317 FMT_MAKE_VALUE_(Type, field, TYPE, value)
1318
1319 FMT_MAKE_VALUE(bool, int_value, BOOL)
1320 FMT_MAKE_VALUE(short, int_value, INT)
1321 FMT_MAKE_VALUE(unsigned short, uint_value, UINT)
1322 FMT_MAKE_VALUE(int, int_value, INT)
1323 FMT_MAKE_VALUE(unsigned, uint_value, UINT)
1324
1325 MakeValue(long value) {
1326 // To minimize the number of types we need to deal with, long is
1327 // translated either to int or to long long depending on its size.
1328 if (const_check(sizeof(long) == sizeof(int)))
1329 int_value = static_cast<int>(value);
1330 else
1331 long_long_value = value;
1332 }
1333 static uint64_t type(long) {
1334 return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG;
1335 }
1336
1337 MakeValue(unsigned long value) {
1338 if (const_check(sizeof(unsigned long) == sizeof(unsigned)))
1339 uint_value = static_cast<unsigned>(value);
1340 else
1341 ulong_long_value = value;
1342 }
1343 static uint64_t type(unsigned long) {
1344 return sizeof(unsigned long) == sizeof(unsigned) ?
1345 Arg::UINT : Arg::ULONG_LONG;
1346 }
1347
1348 FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG)
1349 FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG)
1350 FMT_MAKE_VALUE(float, double_value, DOUBLE)
1351 FMT_MAKE_VALUE(double, double_value, DOUBLE)
1352 FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE)
1353 FMT_MAKE_VALUE(signed char, int_value, INT)
1354 FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
1355 FMT_MAKE_VALUE(char, int_value, CHAR)
1356
1357 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1358 MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) {
1359 int_value = value;
1360 }
1361 static uint64_t type(wchar_t) { return Arg::CHAR; }
1362 #endif
1363
1364 #define FMT_MAKE_STR_VALUE(Type, TYPE) \
1365 MakeValue(Type value) { set_string(value); } \
1366 static uint64_t type(Type) { return Arg::TYPE; }
1367
1368 FMT_MAKE_VALUE(char *, string.value, CSTRING)
1369 FMT_MAKE_VALUE(const char *, string.value, CSTRING)
1370 FMT_MAKE_VALUE(signed char *, sstring.value, CSTRING)
1371 FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING)
1372 FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING)
1373 FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING)
1374 FMT_MAKE_STR_VALUE(const std::string &, STRING)
1375 FMT_MAKE_STR_VALUE(StringRef, STRING)
1376 FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
1377
1378 #define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
1379 MakeValue(typename WCharHelper<Type, Char>::Supported value) { \
1380 set_string(value); \
1381 } \
1382 static uint64_t type(Type) { return Arg::TYPE; }
1383
1384 FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
1385 FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
1386 FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING)
1387 FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
1388
1389 FMT_MAKE_VALUE(void *, pointer, POINTER)
1390 FMT_MAKE_VALUE(const void *, pointer, POINTER)
1391
1392 template <typename T>
1393 MakeValue(const T &value,
1394 typename EnableIf<Not<
1395 ConvertToInt<T>::value>::value, int>::type = 0) {
1396 custom.value = &value;
1397 custom.format = &format_custom_arg<T>;
1398 }
1399
1400 template <typename T>
1401 static typename EnableIf<Not<ConvertToInt<T>::value>::value, uint64_t>::type
1402 type(const T &) {
1403 return Arg::CUSTOM;
1404 }
1405
1406 // Additional template param `Char_` is needed here because make_type always
1407 // uses char.
1408 template <typename Char_>
1409 MakeValue(const NamedArg<Char_> &value) { pointer = &value; }
1410 template <typename Char_, typename T>
1411 MakeValue(const NamedArgWithType<Char_, T> &value) { pointer = &value; }
1412
1413 template <typename Char_>
1414 static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
1415 template <typename Char_, typename T>
1416 static uint64_t type(const NamedArgWithType<Char_, T> &) { return Arg::NAMED_ARG; }
1417 };
1418
1419 template <typename Formatter>
1420 class MakeArg : public Arg {
1421 public:
1422 MakeArg() {
1423 type = Arg::NONE;
1424 }
1425
1426 template <typename T>
1427 MakeArg(const T &value)
1428 : Arg(MakeValue<Formatter>(value)) {
1429 type = static_cast<Arg::Type>(MakeValue<Formatter>::type(value));
1430 }
1431 };
1432
1433 template <typename Char>
1434 struct NamedArg : Arg {
1435 BasicStringRef<Char> name;
1436
1437 template <typename T>
1438 NamedArg(BasicStringRef<Char> argname, const T &value)
1439 : Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
1440 };
1441
1442 template <typename Char, typename T>
1443 struct NamedArgWithType : NamedArg<Char> {
1444 NamedArgWithType(BasicStringRef<Char> argname, const T &value)
1445 : NamedArg<Char>(argname, value) {}
1446 };
1447
1448 class RuntimeError : public std::runtime_error {
1449 protected:
1450 RuntimeError() : std::runtime_error("") {}
1451 RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {}
1452 FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT;
1453 };
1454
1455 template <typename Char>
1456 class ArgMap;
1457 } // namespace internal
1458
1460 class ArgList {
1461 private:
1462 // To reduce compiled code size per formatting function call, types of first
1463 // MAX_PACKED_ARGS arguments are passed in the types_ field.
1464 uint64_t types_;
1465 union {
1466 // If the number of arguments is less than MAX_PACKED_ARGS, the argument
1467 // values are stored in values_, otherwise they are stored in args_.
1468 // This is done to reduce compiled code size as storing larger objects
1469 // may require more code (at least on x86-64) even if the same amount of
1470 // data is actually copied to stack. It saves ~10% on the bloat test.
1471 const internal::Value *values_;
1472 const internal::Arg *args_;
1473 };
1474
1475 internal::Arg::Type type(unsigned index) const {
1476 return type(types_, index);
1477 }
1478
1479 template <typename Char>
1480 friend class internal::ArgMap;
1481
1482 public:
1483 // Maximum number of arguments with packed types.
1484 enum { MAX_PACKED_ARGS = 16 };
1485
1486 ArgList() : types_(0) {}
1487
1488 ArgList(ULongLong types, const internal::Value *values)
1489 : types_(types), values_(values) {}
1490 ArgList(ULongLong types, const internal::Arg *args)
1491 : types_(types), args_(args) {}
1492
1493 uint64_t types() const { return types_; }
1494
1496 internal::Arg operator[](unsigned index) const {
1497 using internal::Arg;
1498 Arg arg;
1499 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1500 if (index < MAX_PACKED_ARGS) {
1501 Arg::Type arg_type = type(index);
1502 internal::Value &val = arg;
1503 if (arg_type != Arg::NONE)
1504 val = use_values ? values_[index] : args_[index];
1505 arg.type = arg_type;
1506 return arg;
1507 }
1508 if (use_values) {
1509 // The index is greater than the number of arguments that can be stored
1510 // in values, so return a "none" argument.
1511 arg.type = Arg::NONE;
1512 return arg;
1513 }
1514 for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1515 if (args_[i].type == Arg::NONE)
1516 return args_[i];
1517 }
1518 return args_[index];
1519 }
1520
1521 static internal::Arg::Type type(uint64_t types, unsigned index) {
1522 unsigned shift = index * 4;
1523 uint64_t mask = 0xf;
1524 return static_cast<internal::Arg::Type>(
1525 (types & (mask << shift)) >> shift);
1526 }
1527 };
1528
1529 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
1530
1555 template <typename Impl, typename Result>
1556 class ArgVisitor {
1557 private:
1558 typedef internal::Arg Arg;
1559
1560 public:
1561 void report_unhandled_arg() {}
1562
1563 Result visit_unhandled_arg() {
1564 FMT_DISPATCH(report_unhandled_arg());
1565 return Result();
1566 }
1567
1569 Result visit_int(int value) {
1570 return FMT_DISPATCH(visit_any_int(value));
1571 }
1572
1574 Result visit_long_long(LongLong value) {
1575 return FMT_DISPATCH(visit_any_int(value));
1576 }
1577
1579 Result visit_uint(unsigned value) {
1580 return FMT_DISPATCH(visit_any_int(value));
1581 }
1582
1584 Result visit_ulong_long(ULongLong value) {
1585 return FMT_DISPATCH(visit_any_int(value));
1586 }
1587
1589 Result visit_bool(bool value) {
1590 return FMT_DISPATCH(visit_any_int(value));
1591 }
1592
1594 Result visit_char(int value) {
1595 return FMT_DISPATCH(visit_any_int(value));
1596 }
1597
1599 template <typename T>
1600 Result visit_any_int(T) {
1601 return FMT_DISPATCH(visit_unhandled_arg());
1602 }
1603
1605 Result visit_double(double value) {
1606 return FMT_DISPATCH(visit_any_double(value));
1607 }
1608
1610 Result visit_long_double(long double value) {
1611 return FMT_DISPATCH(visit_any_double(value));
1612 }
1613
1615 template <typename T>
1616 Result visit_any_double(T) {
1617 return FMT_DISPATCH(visit_unhandled_arg());
1618 }
1619
1621 Result visit_cstring(const char *) {
1622 return FMT_DISPATCH(visit_unhandled_arg());
1623 }
1624
1626 Result visit_string(Arg::StringValue<char>) {
1627 return FMT_DISPATCH(visit_unhandled_arg());
1628 }
1629
1631 Result visit_wstring(Arg::StringValue<wchar_t>) {
1632 return FMT_DISPATCH(visit_unhandled_arg());
1633 }
1634
1636 Result visit_pointer(const void *) {
1637 return FMT_DISPATCH(visit_unhandled_arg());
1638 }
1639
1641 Result visit_custom(Arg::CustomValue) {
1642 return FMT_DISPATCH(visit_unhandled_arg());
1643 }
1644
1653 Result visit(const Arg &arg) {
1654 switch (arg.type) {
1655 case Arg::NONE:
1656 case Arg::NAMED_ARG:
1657 FMT_ASSERT(false, "invalid argument type");
1658 break;
1659 case Arg::INT:
1660 return FMT_DISPATCH(visit_int(arg.int_value));
1661 case Arg::UINT:
1662 return FMT_DISPATCH(visit_uint(arg.uint_value));
1663 case Arg::LONG_LONG:
1664 return FMT_DISPATCH(visit_long_long(arg.long_long_value));
1665 case Arg::ULONG_LONG:
1666 return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
1667 case Arg::BOOL:
1668 return FMT_DISPATCH(visit_bool(arg.int_value != 0));
1669 case Arg::CHAR:
1670 return FMT_DISPATCH(visit_char(arg.int_value));
1671 case Arg::DOUBLE:
1672 return FMT_DISPATCH(visit_double(arg.double_value));
1673 case Arg::LONG_DOUBLE:
1674 return FMT_DISPATCH(visit_long_double(arg.long_double_value));
1675 case Arg::CSTRING:
1676 return FMT_DISPATCH(visit_cstring(arg.string.value));
1677 case Arg::STRING:
1678 return FMT_DISPATCH(visit_string(arg.string));
1679 case Arg::WSTRING:
1680 return FMT_DISPATCH(visit_wstring(arg.wstring));
1681 case Arg::POINTER:
1682 return FMT_DISPATCH(visit_pointer(arg.pointer));
1683 case Arg::CUSTOM:
1684 return FMT_DISPATCH(visit_custom(arg.custom));
1685 }
1686 return Result();
1687 }
1688 };
1689
1690 enum Alignment {
1691 ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
1692 };
1693
1694 // Flags.
1695 enum {
1696 SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8,
1697 CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
1698 };
1699
1700 // An empty format specifier.
1701 struct EmptySpec {};
1702
1703 // A type specifier.
1704 template <char TYPE>
1705 struct TypeSpec : EmptySpec {
1706 Alignment align() const { return ALIGN_DEFAULT; }
1707 unsigned width() const { return 0; }
1708 int precision() const { return -1; }
1709 bool flag(unsigned) const { return false; }
1710 char type() const { return TYPE; }
1711 char type_prefix() const { return TYPE; }
1712 char fill() const { return ' '; }
1713 };
1714
1715 // A width specifier.
1716 struct WidthSpec {
1717 unsigned width_;
1718 // Fill is always wchar_t and cast to char if necessary to avoid having
1719 // two specialization of WidthSpec and its subclasses.
1720 wchar_t fill_;
1721
1722 WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {}
1723
1724 unsigned width() const { return width_; }
1725 wchar_t fill() const { return fill_; }
1726 };
1727
1728 // An alignment specifier.
1729 struct AlignSpec : WidthSpec {
1730 Alignment align_;
1731
1732 AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT)
1733 : WidthSpec(width, fill), align_(align) {}
1734
1735 Alignment align() const { return align_; }
1736
1737 int precision() const { return -1; }
1738 };
1739
1740 // An alignment and type specifier.
1741 template <char TYPE>
1742 struct AlignTypeSpec : AlignSpec {
1743 AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {}
1744
1745 bool flag(unsigned) const { return false; }
1746 char type() const { return TYPE; }
1747 char type_prefix() const { return TYPE; }
1748 };
1749
1750 // A full format specifier.
1751 struct FormatSpec : AlignSpec {
1752 unsigned flags_;
1753 int precision_;
1754 char type_;
1755
1756 FormatSpec(
1757 unsigned width = 0, char type = 0, wchar_t fill = ' ')
1758 : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1759
1760 bool flag(unsigned f) const { return (flags_ & f) != 0; }
1761 int precision() const { return precision_; }
1762 char type() const { return type_; }
1763 char type_prefix() const { return type_; }
1764 };
1765
1766 // An integer format specifier.
1767 template <typename T, typename SpecT = TypeSpec<0>, typename Char = char>
1768 class IntFormatSpec : public SpecT {
1769 private:
1770 T value_;
1771
1772 public:
1773 IntFormatSpec(T val, const SpecT &spec = SpecT())
1774 : SpecT(spec), value_(val) {}
1775
1776 T value() const { return value_; }
1777 };
1778
1779 // A string format specifier.
1780 template <typename Char>
1781 class StrFormatSpec : public AlignSpec {
1782 private:
1783 const Char *str_;
1784
1785 public:
1786 template <typename FillChar>
1787 StrFormatSpec(const Char *str, unsigned width, FillChar fill)
1788 : AlignSpec(width, fill), str_(str) {
1789 internal::CharTraits<Char>::convert(FillChar());
1790 }
1791
1792 const Char *str() const { return str_; }
1793 };
1794
1798 IntFormatSpec<int, TypeSpec<'b'> > bin(int value);
1799
1803 IntFormatSpec<int, TypeSpec<'o'> > oct(int value);
1804
1809 IntFormatSpec<int, TypeSpec<'x'> > hex(int value);
1810
1815 IntFormatSpec<int, TypeSpec<'X'> > hexu(int value);
1816
1831 template <char TYPE_CODE, typename Char>
1832 IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
1833 int value, unsigned width, Char fill = ' ');
1834
1835 #define FMT_DEFINE_INT_FORMATTERS(TYPE) \
1836 inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
1837 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
1838 } \
1839 \
1840 inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
1841 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
1842 } \
1843 \
1844 inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
1845 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
1846 } \
1847 \
1848 inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
1849 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
1850 } \
1851 \
1852 template <char TYPE_CODE> \
1853 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
1854 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
1855 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
1856 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
1857 } \
1858 \
1859 /* For compatibility with older compilers we provide two overloads for pad, */ \
1860 /* one that takes a fill character and one that doesn't. In the future this */ \
1861 /* can be replaced with one overload making the template argument Char */ \
1862 /* default to char (C++11). */ \
1863 template <char TYPE_CODE, typename Char> \
1864 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
1865 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \
1866 unsigned width, Char fill) { \
1867 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
1868 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
1869 } \
1870 \
1871 inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
1872 TYPE value, unsigned width) { \
1873 return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
1874 value, AlignTypeSpec<0>(width, ' ')); \
1875 } \
1876 \
1877 template <typename Char> \
1878 inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
1879 TYPE value, unsigned width, Char fill) { \
1880 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
1881 value, AlignTypeSpec<0>(width, fill)); \
1882 }
1883
1884 FMT_DEFINE_INT_FORMATTERS(int)
1885 FMT_DEFINE_INT_FORMATTERS(long)
1886 FMT_DEFINE_INT_FORMATTERS(unsigned)
1887 FMT_DEFINE_INT_FORMATTERS(unsigned long)
1888 FMT_DEFINE_INT_FORMATTERS(LongLong)
1889 FMT_DEFINE_INT_FORMATTERS(ULongLong)
1890
1903 template <typename Char>
1904 inline StrFormatSpec<Char> pad(
1905 const Char *str, unsigned width, Char fill = ' ') {
1906 return StrFormatSpec<Char>(str, width, fill);
1907 }
1908
1909 inline StrFormatSpec<wchar_t> pad(
1910 const wchar_t *str, unsigned width, char fill = ' ') {
1911 return StrFormatSpec<wchar_t>(str, width, fill);
1912 }
1913
1914 namespace internal {
1915
1916 template <typename Char>
1917 class ArgMap {
1918 private:
1919 typedef std::vector<
1920 std::pair<fmt::BasicStringRef<Char>, internal::Arg> > MapType;
1921 typedef typename MapType::value_type Pair;
1922
1923 MapType map_;
1924
1925 public:
1926 FMT_API void init(const ArgList &args);
1927
1928 const internal::Arg *find(const fmt::BasicStringRef<Char> &name) const {
1929 // The list is unsorted, so just return the first matching name.
1930 for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
1931 it != end; ++it) {
1932 if (it->first == name)
1933 return &it->second;
1934 }
1935 return FMT_NULL;
1936 }
1937 };
1938
1939 template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
1940 class ArgFormatterBase : public ArgVisitor<Impl, void> {
1941 private:
1942 BasicWriter<Char> &writer_;
1943 Spec &spec_;
1944
1945 FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
1946
1947 void write_pointer(const void *p) {
1948 spec_.flags_ = HASH_FLAG;
1949 spec_.type_ = 'x';
1950 writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
1951 }
1952
1953 // workaround MSVC two-phase lookup issue
1954 typedef internal::Arg Arg;
1955
1956 protected:
1957 BasicWriter<Char> &writer() { return writer_; }
1958 Spec &spec() { return spec_; }
1959
1960 void write(bool value) {
1961 const char *str_value = value ? "true" : "false";
1962 Arg::StringValue<char> str = { str_value, std::strlen(str_value) };
1963 writer_.write_str(str, spec_);
1964 }
1965
1966 void write(const char *value) {
1967 Arg::StringValue<char> str = {value, value ? std::strlen(value) : 0};
1968 writer_.write_str(str, spec_);
1969 }
1970
1971 public:
1972 typedef Spec SpecType;
1973
1974 ArgFormatterBase(BasicWriter<Char> &w, Spec &s)
1975 : writer_(w), spec_(s) {}
1976
1977 template <typename T>
1978 void visit_any_int(T value) { writer_.write_int(value, spec_); }
1979
1980 template <typename T>
1981 void visit_any_double(T value) { writer_.write_double(value, spec_); }
1982
1983 void visit_bool(bool value) {
1984 if (spec_.type_) {
1985 visit_any_int(value);
1986 return;
1987 }
1988 write(value);
1989 }
1990
1991 void visit_char(int value) {
1992 if (spec_.type_ && spec_.type_ != 'c') {
1993 spec_.flags_ |= CHAR_FLAG;
1994 writer_.write_int(value, spec_);
1995 return;
1996 }
1997 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
1998 FMT_THROW(FormatError("invalid format specifier for char"));
1999 typedef typename BasicWriter<Char>::CharPtr CharPtr;
2000 Char fill = internal::CharTraits<Char>::cast(spec_.fill());
2001 CharPtr out = CharPtr();
2002 const unsigned CHAR_SIZE = 1;
2003 if (spec_.width_ > CHAR_SIZE) {
2004 out = writer_.grow_buffer(spec_.width_);
2005 if (spec_.align_ == ALIGN_RIGHT) {
2006 std::uninitialized_fill_n(out, spec_.width_ - CHAR_SIZE, fill);
2007 out += spec_.width_ - CHAR_SIZE;
2008 } else if (spec_.align_ == ALIGN_CENTER) {
2009 out = writer_.fill_padding(out, spec_.width_,
2010 internal::const_check(CHAR_SIZE), fill);
2011 } else {
2012 std::uninitialized_fill_n(out + CHAR_SIZE,
2013 spec_.width_ - CHAR_SIZE, fill);
2014 }
2015 } else {
2016 out = writer_.grow_buffer(CHAR_SIZE);
2017 }
2018 *out = internal::CharTraits<Char>::cast(value);
2019 }
2020
2021 void visit_cstring(const char *value) {
2022 if (spec_.type_ == 'p')
2023 return write_pointer(value);
2024 write(value);
2025 }
2026
2027 // Qualification with "internal" here and below is a workaround for nvcc.
2028 void visit_string(internal::Arg::StringValue<char> value) {
2029 writer_.write_str(value, spec_);
2030 }
2031
2032 using ArgVisitor<Impl, void>::visit_wstring;
2033
2034 void visit_wstring(internal::Arg::StringValue<Char> value) {
2035 writer_.write_str(value, spec_);
2036 }
2037
2038 void visit_pointer(const void *value) {
2039 if (spec_.type_ && spec_.type_ != 'p')
2040 report_unknown_type(spec_.type_, "pointer");
2041 write_pointer(value);
2042 }
2043 };
2044
2045 class FormatterBase {
2046 private:
2047 ArgList args_;
2048 int next_arg_index_;
2049
2050 // Returns the argument with specified index.
2051 FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
2052
2053 protected:
2054 const ArgList &args() const { return args_; }
2055
2056 explicit FormatterBase(const ArgList &args) {
2057 args_ = args;
2058 next_arg_index_ = 0;
2059 }
2060
2061 // Returns the next argument.
2062 Arg next_arg(const char *&error) {
2063 if (next_arg_index_ >= 0)
2064 return do_get_arg(internal::to_unsigned(next_arg_index_++), error);
2065 error = "cannot switch from manual to automatic argument indexing";
2066 return Arg();
2067 }
2068
2069 // Checks if manual indexing is used and returns the argument with
2070 // specified index.
2071 Arg get_arg(unsigned arg_index, const char *&error) {
2072 return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
2073 }
2074
2075 bool check_no_auto_index(const char *&error) {
2076 if (next_arg_index_ > 0) {
2077 error = "cannot switch from automatic to manual argument indexing";
2078 return false;
2079 }
2080 next_arg_index_ = -1;
2081 return true;
2082 }
2083
2084 template <typename Char>
2085 void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
2086 if (start != end)
2087 w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
2088 }
2089 };
2090 } // namespace internal
2091
2109 template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
2110 class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char, Spec> {
2111 private:
2112 BasicFormatter<Char, Impl> &formatter_;
2113 const Char *format_;
2114
2115 public:
2124 BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
2125 Spec &spec, const Char *fmt)
2126 : internal::ArgFormatterBase<Impl, Char, Spec>(formatter.writer(), spec),
2127 formatter_(formatter), format_(fmt) {}
2128
2130 void visit_custom(internal::Arg::CustomValue c) {
2131 c.format(&formatter_, c.value, &format_);
2132 }
2133 };
2134
2136 template <typename Char>
2137 class ArgFormatter :
2138 public BasicArgFormatter<ArgFormatter<Char>, Char, FormatSpec> {
2139 public:
2141 ArgFormatter(BasicFormatter<Char> &formatter,
2142 FormatSpec &spec, const Char *fmt)
2143 : BasicArgFormatter<ArgFormatter<Char>,
2144 Char, FormatSpec>(formatter, spec, fmt) {}
2145 };
2146
2148 template <typename CharType, typename ArgFormatter>
2149 class BasicFormatter : private internal::FormatterBase {
2150 public:
2152 typedef CharType Char;
2153
2154 private:
2155 BasicWriter<Char> &writer_;
2156 internal::ArgMap<Char> map_;
2157
2158 FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter);
2159
2160 using internal::FormatterBase::get_arg;
2161
2162 // Checks if manual indexing is used and returns the argument with
2163 // specified name.
2164 internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error);
2165
2166 // Parses argument index and returns corresponding argument.
2167 internal::Arg parse_arg_index(const Char *&s);
2168
2169 // Parses argument name and returns corresponding argument.
2170 internal::Arg parse_arg_name(const Char *&s);
2171
2172 public:
2180 BasicFormatter(const ArgList &args, BasicWriter<Char> &w)
2181 : internal::FormatterBase(args), writer_(w) {}
2182
2184 BasicWriter<Char> &writer() { return writer_; }
2185
2187 void format(BasicCStringRef<Char> format_str);
2188
2189 // Formats a single argument and advances format_str, a format string pointer.
2190 const Char *format(const Char *&format_str, const internal::Arg &arg);
2191 };
2192
2193 // Generates a comma-separated list with results of applying f to
2194 // numbers 0..n-1.
2195 # define FMT_GEN(n, f) FMT_GEN##n(f)
2196 # define FMT_GEN1(f) f(0)
2197 # define FMT_GEN2(f) FMT_GEN1(f), f(1)
2198 # define FMT_GEN3(f) FMT_GEN2(f), f(2)
2199 # define FMT_GEN4(f) FMT_GEN3(f), f(3)
2200 # define FMT_GEN5(f) FMT_GEN4(f), f(4)
2201 # define FMT_GEN6(f) FMT_GEN5(f), f(5)
2202 # define FMT_GEN7(f) FMT_GEN6(f), f(6)
2203 # define FMT_GEN8(f) FMT_GEN7(f), f(7)
2204 # define FMT_GEN9(f) FMT_GEN8(f), f(8)
2205 # define FMT_GEN10(f) FMT_GEN9(f), f(9)
2206 # define FMT_GEN11(f) FMT_GEN10(f), f(10)
2207 # define FMT_GEN12(f) FMT_GEN11(f), f(11)
2208 # define FMT_GEN13(f) FMT_GEN12(f), f(12)
2209 # define FMT_GEN14(f) FMT_GEN13(f), f(13)
2210 # define FMT_GEN15(f) FMT_GEN14(f), f(14)
2211
2212 namespace internal {
2213 inline uint64_t make_type() { return 0; }
2214
2215 template <typename T>
2216 inline uint64_t make_type(const T &arg) {
2217 return MakeValue< BasicFormatter<char> >::type(arg);
2218 }
2219
2220 template <std::size_t N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
2221 struct ArgArray;
2222
2223 template <std::size_t N>
2224 struct ArgArray<N, true/*IsPacked*/> {
2225 typedef Value Type[N > 0 ? N : 1];
2226
2227 template <typename Formatter, typename T>
2228 static Value make(const T &value) {
2229 #ifdef __clang__
2230 Value result = MakeValue<Formatter>(value);
2231 // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
2232 // https://github.com/fmtlib/fmt/issues/276
2233 (void)result.custom.format;
2234 return result;
2235 #else
2236 return MakeValue<Formatter>(value);
2237 #endif
2238 }
2239 };
2240
2241 template <std::size_t N>
2242 struct ArgArray<N, false/*IsPacked*/> {
2243 typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
2244
2245 template <typename Formatter, typename T>
2246 static Arg make(const T &value) { return MakeArg<Formatter>(value); }
2247 };
2248
2249 #if FMT_USE_VARIADIC_TEMPLATES
2250 template <typename Arg, typename... Args>
2251 inline uint64_t make_type(const Arg &first, const Args & ... tail) {
2252 return make_type(first) | (make_type(tail...) << 4);
2253 }
2254
2255 #else
2256
2257 struct ArgType {
2258 uint64_t type;
2259
2260 ArgType() : type(0) {}
2261
2262 template <typename T>
2263 ArgType(const T &arg) : type(make_type(arg)) {}
2264 };
2265
2266 # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
2267
2268 inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
2269 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
2270 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
2271 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
2272 (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
2273 }
2274 #endif
2275 } // namespace internal
2276
2277 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
2278 # define FMT_MAKE_ARG_TYPE(n) T##n
2279 # define FMT_MAKE_ARG(n) const T##n &v##n
2280 # define FMT_ASSIGN_char(n) \
2281 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
2282 # define FMT_ASSIGN_wchar_t(n) \
2283 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
2284
2285 #if FMT_USE_VARIADIC_TEMPLATES
2286 // Defines a variadic function returning void.
2287 # define FMT_VARIADIC_VOID(func, arg_type) \
2288 template <typename... Args> \
2289 void func(arg_type arg0, const Args & ... args) { \
2290 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2291 typename ArgArray::Type array{ \
2292 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2293 func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2294 }
2295
2296 // Defines a variadic constructor.
2297 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2298 template <typename... Args> \
2299 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
2300 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2301 typename ArgArray::Type array{ \
2302 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2303 func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2304 }
2305
2306 #else
2307
2308 # define FMT_MAKE_REF(n) \
2309 fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
2310 # define FMT_MAKE_REF2(n) v##n
2311
2312 // Defines a wrapper for a function taking one argument of type arg_type
2313 // and n additional arguments of arbitrary types.
2314 # define FMT_WRAP1(func, arg_type, n) \
2315 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2316 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2317 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2318 func(arg1, fmt::ArgList( \
2319 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2320 }
2321
2322 // Emulates a variadic function returning void on a pre-C++11 compiler.
2323 # define FMT_VARIADIC_VOID(func, arg_type) \
2324 inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \
2325 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \
2326 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \
2327 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \
2328 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \
2329 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
2330
2331 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
2332 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2333 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2334 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2335 func(arg0, arg1, fmt::ArgList( \
2336 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2337 }
2338
2339 // Emulates a variadic constructor on a pre-C++11 compiler.
2340 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2341 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \
2342 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \
2343 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \
2344 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \
2345 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \
2346 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \
2347 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \
2348 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \
2349 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \
2350 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
2351 #endif
2352
2353 // Generates a comma-separated list with results of applying f to pairs
2354 // (argument, index).
2355 #define FMT_FOR_EACH1(f, x0) f(x0, 0)
2356 #define FMT_FOR_EACH2(f, x0, x1) \
2357 FMT_FOR_EACH1(f, x0), f(x1, 1)
2358 #define FMT_FOR_EACH3(f, x0, x1, x2) \
2359 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
2360 #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
2361 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
2362 #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
2363 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
2364 #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
2365 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
2366 #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
2367 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
2368 #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
2369 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
2370 #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
2371 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
2372 #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
2373 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
2374
2379 class SystemError : public internal::RuntimeError {
2380 private:
2381 FMT_API void init(int err_code, CStringRef format_str, ArgList args);
2382
2383 protected:
2384 int error_code_;
2385
2386 typedef char Char; // For FMT_VARIADIC_CTOR.
2387
2388 SystemError() {}
2389
2390 public:
2409 SystemError(int error_code, CStringRef message) {
2410 init(error_code, message, ArgList());
2411 }
2412 FMT_DEFAULTED_COPY_CTOR(SystemError)
2413 FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
2414
2415 FMT_API ~SystemError() FMT_DTOR_NOEXCEPT;
2416
2417 int error_code() const { return error_code_; }
2418 };
2419
2436 FMT_API void format_system_error(fmt::Writer &out, int error_code,
2437 fmt::StringRef message) FMT_NOEXCEPT;
2438
2457 template <typename Char>
2458 class BasicWriter {
2459 private:
2460 // Output buffer.
2461 Buffer<Char> &buffer_;
2462
2463 FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter);
2464
2465 typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
2466
2467 #if FMT_SECURE_SCL
2468 // Returns pointer value.
2469 static Char *get(CharPtr p) { return p.base(); }
2470 #else
2471 static Char *get(Char *p) { return p; }
2472 #endif
2473
2474 // Fills the padding around the content and returns the pointer to the
2475 // content area.
2476 static CharPtr fill_padding(CharPtr buffer,
2477 unsigned total_size, std::size_t content_size, wchar_t fill);
2478
2479 // Grows the buffer by n characters and returns a pointer to the newly
2480 // allocated area.
2481 CharPtr grow_buffer(std::size_t n) {
2482 std::size_t size = buffer_.size();
2483 buffer_.resize(size + n);
2484 return internal::make_ptr(&buffer_[size], n);
2485 }
2486
2487 // Writes an unsigned decimal integer.
2488 template <typename UInt>
2489 Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) {
2490 unsigned num_digits = internal::count_digits(value);
2491 Char *ptr = get(grow_buffer(prefix_size + num_digits));
2492 internal::format_decimal(ptr + prefix_size, value, num_digits);
2493 return ptr;
2494 }
2495
2496 // Writes a decimal integer.
2497 template <typename Int>
2498 void write_decimal(Int value) {
2499 typedef typename internal::IntTraits<Int>::MainType MainType;
2500 MainType abs_value = static_cast<MainType>(value);
2501 if (internal::is_negative(value)) {
2502 abs_value = 0 - abs_value;
2503 *write_unsigned_decimal(abs_value, 1) = '-';
2504 } else {
2505 write_unsigned_decimal(abs_value, 0);
2506 }
2507 }
2508
2509 // Prepare a buffer for integer formatting.
2510 CharPtr prepare_int_buffer(unsigned num_digits,
2511 const EmptySpec &, const char *prefix, unsigned prefix_size) {
2512 unsigned size = prefix_size + num_digits;
2513 CharPtr p = grow_buffer(size);
2514 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2515 return p + size - 1;
2516 }
2517
2518 template <typename Spec>
2519 CharPtr prepare_int_buffer(unsigned num_digits,
2520 const Spec &spec, const char *prefix, unsigned prefix_size);
2521
2522 // Formats an integer.
2523 template <typename T, typename Spec>
2524 void write_int(T value, Spec spec);
2525
2526 // Formats a floating-point number (double or long double).
2527 template <typename T, typename Spec>
2528 void write_double(T value, const Spec &spec);
2529
2530 // Writes a formatted string.
2531 template <typename StrChar>
2532 CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
2533
2534 template <typename StrChar, typename Spec>
2535 void write_str(const internal::Arg::StringValue<StrChar> &str,
2536 const Spec &spec);
2537
2538 // This following methods are private to disallow writing wide characters
2539 // and strings to a char stream. If you want to print a wide string as a
2540 // pointer as std::ostream does, cast it to const void*.
2541 // Do not implement!
2542 void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported);
2543 void operator<<(
2544 typename internal::WCharHelper<const wchar_t *, Char>::Unsupported);
2545
2546 // Appends floating-point length specifier to the format string.
2547 // The second argument is only used for overload resolution.
2548 void append_float_length(Char *&format_ptr, long double) {
2549 *format_ptr++ = 'L';
2550 }
2551
2552 template<typename T>
2553 void append_float_length(Char *&, T) {}
2554
2555 template <typename Impl, typename Char_, typename Spec_>
2556 friend class internal::ArgFormatterBase;
2557
2558 template <typename Impl, typename Char_, typename Spec_>
2559 friend class BasicPrintfArgFormatter;
2560
2561 protected:
2565 explicit BasicWriter(Buffer<Char> &b) : buffer_(b) {}
2566
2567 public:
2573 virtual ~BasicWriter() {}
2574
2578 std::size_t size() const { return buffer_.size(); }
2579
2584 const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
2585
2590 const Char *c_str() const {
2591 std::size_t size = buffer_.size();
2592 buffer_.reserve(size + 1);
2593 buffer_[size] = '\0';
2594 return &buffer_[0];
2595 }
2596
2602 std::basic_string<Char> str() const {
2603 return std::basic_string<Char>(&buffer_[0], buffer_.size());
2604 }
2605
2631 void write(BasicCStringRef<Char> format, ArgList args) {
2632 BasicFormatter<Char>(args, *this).format(format);
2633 }
2634 FMT_VARIADIC_VOID(write, BasicCStringRef<Char>)
2635
2636 BasicWriter &operator<<(int value) {
2637 write_decimal(value);
2638 return *this;
2639 }
2640 BasicWriter &operator<<(unsigned value) {
2641 return *this << IntFormatSpec<unsigned>(value);
2642 }
2643 BasicWriter &operator<<(long value) {
2644 write_decimal(value);
2645 return *this;
2646 }
2647 BasicWriter &operator<<(unsigned long value) {
2648 return *this << IntFormatSpec<unsigned long>(value);
2649 }
2650 BasicWriter &operator<<(LongLong value) {
2651 write_decimal(value);
2652 return *this;
2653 }
2654
2660 BasicWriter &operator<<(ULongLong value) {
2661 return *this << IntFormatSpec<ULongLong>(value);
2662 }
2663
2664 BasicWriter &operator<<(double value) {
2665 write_double(value, FormatSpec());
2666 return *this;
2667 }
2668
2675 BasicWriter &operator<<(long double value) {
2676 write_double(value, FormatSpec());
2677 return *this;
2678 }
2679
2683 BasicWriter &operator<<(char value) {
2684 buffer_.push_back(value);
2685 return *this;
2686 }
2687
2688 BasicWriter &operator<<(
2689 typename internal::WCharHelper<wchar_t, Char>::Supported value) {
2690 buffer_.push_back(value);
2691 return *this;
2692 }
2693
2699 BasicWriter &operator<<(fmt::BasicStringRef<Char> value) {
2700 const Char *str = value.data();
2701 buffer_.append(str, str + value.size());
2702 return *this;
2703 }
2704
2705 BasicWriter &operator<<(
2706 typename internal::WCharHelper<StringRef, Char>::Supported value) {
2707 const char *str = value.data();
2708 buffer_.append(str, str + value.size());
2709 return *this;
2710 }
2711
2712 template <typename T, typename Spec, typename FillChar>
2713 BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) {
2714 internal::CharTraits<Char>::convert(FillChar());
2715 write_int(spec.value(), spec);
2716 return *this;
2717 }
2718
2719 template <typename StrChar>
2720 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) {
2721 const StrChar *s = spec.str();
2722 write_str(s, std::char_traits<Char>::length(s), spec);
2723 return *this;
2724 }
2725
2726 void clear() FMT_NOEXCEPT { buffer_.clear(); }
2727
2728 Buffer<Char> &buffer() FMT_NOEXCEPT { return buffer_; }
2729 };
2730
2731 template <typename Char>
2732 template <typename StrChar>
2733 typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
2734 const StrChar *s, std::size_t size, const AlignSpec &spec) {
2735 CharPtr out = CharPtr();
2736 if (spec.width() > size) {
2737 out = grow_buffer(spec.width());
2738 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2739 if (spec.align() == ALIGN_RIGHT) {
2740 std::uninitialized_fill_n(out, spec.width() - size, fill);
2741 out += spec.width() - size;
2742 } else if (spec.align() == ALIGN_CENTER) {
2743 out = fill_padding(out, spec.width(), size, fill);
2744 } else {
2745 std::uninitialized_fill_n(out + size, spec.width() - size, fill);
2746 }
2747 } else {
2748 out = grow_buffer(size);
2749 }
2750 std::uninitialized_copy(s, s + size, out);
2751 return out;
2752 }
2753
2754 template <typename Char>
2755 template <typename StrChar, typename Spec>
2756 void BasicWriter<Char>::write_str(
2757 const internal::Arg::StringValue<StrChar> &s, const Spec &spec) {
2758 // Check if StrChar is convertible to Char.
2759 internal::CharTraits<Char>::convert(StrChar());
2760 if (spec.type_ && spec.type_ != 's')
2761 internal::report_unknown_type(spec.type_, "string");
2762 const StrChar *str_value = s.value;
2763 std::size_t str_size = s.size;
2764 if (str_size == 0) {
2765 if (!str_value) {
2766 FMT_THROW(FormatError("string pointer is null"));
2767 }
2768 }
2769 std::size_t precision = static_cast<std::size_t>(spec.precision_);
2770 if (spec.precision_ >= 0 && precision < str_size)
2771 str_size = precision;
2772 write_str(str_value, str_size, spec);
2773 }
2774
2775 template <typename Char>
2776 typename BasicWriter<Char>::CharPtr
2777 BasicWriter<Char>::fill_padding(
2778 CharPtr buffer, unsigned total_size,
2779 std::size_t content_size, wchar_t fill) {
2780 std::size_t padding = total_size - content_size;
2781 std::size_t left_padding = padding / 2;
2782 Char fill_char = internal::CharTraits<Char>::cast(fill);
2783 std::uninitialized_fill_n(buffer, left_padding, fill_char);
2784 buffer += left_padding;
2785 CharPtr content = buffer;
2786 std::uninitialized_fill_n(buffer + content_size,
2787 padding - left_padding, fill_char);
2788 return content;
2789 }
2790
2791 template <typename Char>
2792 template <typename Spec>
2793 typename BasicWriter<Char>::CharPtr
2794 BasicWriter<Char>::prepare_int_buffer(
2795 unsigned num_digits, const Spec &spec,
2796 const char *prefix, unsigned prefix_size) {
2797 unsigned width = spec.width();
2798 Alignment align = spec.align();
2799 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2800 if (spec.precision() > static_cast<int>(num_digits)) {
2801 // Octal prefix '0' is counted as a digit, so ignore it if precision
2802 // is specified.
2803 if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
2804 --prefix_size;
2805 unsigned number_size =
2806 prefix_size + internal::to_unsigned(spec.precision());
2807 AlignSpec subspec(number_size, '0', ALIGN_NUMERIC);
2808 if (number_size >= width)
2809 return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
2810 buffer_.reserve(width);
2811 unsigned fill_size = width - number_size;
2812 if (align != ALIGN_LEFT) {
2813 CharPtr p = grow_buffer(fill_size);
2814 std::uninitialized_fill(p, p + fill_size, fill);
2815 }
2816 CharPtr result = prepare_int_buffer(
2817 num_digits, subspec, prefix, prefix_size);
2818 if (align == ALIGN_LEFT) {
2819 CharPtr p = grow_buffer(fill_size);
2820 std::uninitialized_fill(p, p + fill_size, fill);
2821 }
2822 return result;
2823 }
2824 unsigned size = prefix_size + num_digits;
2825 if (width <= size) {
2826 CharPtr p = grow_buffer(size);
2827 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2828 return p + size - 1;
2829 }
2830 CharPtr p = grow_buffer(width);
2831 CharPtr end = p + width;
2832 if (align == ALIGN_LEFT) {
2833 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2834 p += size;
2835 std::uninitialized_fill(p, end, fill);
2836 } else if (align == ALIGN_CENTER) {
2837 p = fill_padding(p, width, size, fill);
2838 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2839 p += size;
2840 } else {
2841 if (align == ALIGN_NUMERIC) {
2842 if (prefix_size != 0) {
2843 p = std::uninitialized_copy(prefix, prefix + prefix_size, p);
2844 size -= prefix_size;
2845 }
2846 } else {
2847 std::uninitialized_copy(prefix, prefix + prefix_size, end - size);
2848 }
2849 std::uninitialized_fill(p, end - size, fill);
2850 p = end;
2851 }
2852 return p - 1;
2853 }
2854
2855 template <typename Char>
2856 template <typename T, typename Spec>
2857 void BasicWriter<Char>::write_int(T value, Spec spec) {
2858 unsigned prefix_size = 0;
2859 typedef typename internal::IntTraits<T>::MainType UnsignedType;
2860 UnsignedType abs_value = static_cast<UnsignedType>(value);
2861 char prefix[4] = "";
2862 if (internal::is_negative(value)) {
2863 prefix[0] = '-';
2864 ++prefix_size;
2865 abs_value = 0 - abs_value;
2866 } else if (spec.flag(SIGN_FLAG)) {
2867 prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' ';
2868 ++prefix_size;
2869 }
2870 switch (spec.type()) {
2871 case 0: case 'd': {
2872 unsigned num_digits = internal::count_digits(abs_value);
2873 CharPtr p = prepare_int_buffer(num_digits, spec, prefix, prefix_size) + 1;
2874 internal::format_decimal(get(p), abs_value, 0);
2875 break;
2876 }
2877 case 'x': case 'X': {
2878 UnsignedType n = abs_value;
2879 if (spec.flag(HASH_FLAG)) {
2880 prefix[prefix_size++] = '0';
2881 prefix[prefix_size++] = spec.type_prefix();
2882 }
2883 unsigned num_digits = 0;
2884 do {
2885 ++num_digits;
2886 } while ((n >>= 4) != 0);
2887 Char *p = get(prepare_int_buffer(
2888 num_digits, spec, prefix, prefix_size));
2889 n = abs_value;
2890 const char *digits = spec.type() == 'x' ?
2891 "0123456789abcdef" : "0123456789ABCDEF";
2892 do {
2893 *p-- = digits[n & 0xf];
2894 } while ((n >>= 4) != 0);
2895 break;
2896 }
2897 case 'b': case 'B': {
2898 UnsignedType n = abs_value;
2899 if (spec.flag(HASH_FLAG)) {
2900 prefix[prefix_size++] = '0';
2901 prefix[prefix_size++] = spec.type_prefix();
2902 }
2903 unsigned num_digits = 0;
2904 do {
2905 ++num_digits;
2906 } while ((n >>= 1) != 0);
2907 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2908 n = abs_value;
2909 do {
2910 *p-- = static_cast<Char>('0' + (n & 1));
2911 } while ((n >>= 1) != 0);
2912 break;
2913 }
2914 case 'o': {
2915 UnsignedType n = abs_value;
2916 if (spec.flag(HASH_FLAG))
2917 prefix[prefix_size++] = '0';
2918 unsigned num_digits = 0;
2919 do {
2920 ++num_digits;
2921 } while ((n >>= 3) != 0);
2922 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2923 n = abs_value;
2924 do {
2925 *p-- = static_cast<Char>('0' + (n & 7));
2926 } while ((n >>= 3) != 0);
2927 break;
2928 }
2929 case 'n': {
2930 unsigned num_digits = internal::count_digits(abs_value);
2931 fmt::StringRef sep = "";
2932 #if !(defined(ANDROID) || defined(__ANDROID__))
2933 sep = internal::thousands_sep(std::localeconv());
2934 #endif
2935 unsigned size = static_cast<unsigned>(
2936 num_digits + sep.size() * ((num_digits - 1) / 3));
2937 CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1;
2938 internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep));
2939 break;
2940 }
2941 default:
2942 internal::report_unknown_type(
2943 spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer");
2944 break;
2945 }
2946 }
2947
2948 template <typename Char>
2949 template <typename T, typename Spec>
2950 void BasicWriter<Char>::write_double(T value, const Spec &spec) {
2951 // Check type.
2952 char type = spec.type();
2953 bool upper = false;
2954 switch (type) {
2955 case 0:
2956 type = 'g';
2957 break;
2958 case 'e': case 'f': case 'g': case 'a':
2959 break;
2960 case 'F':
2961 #if FMT_MSC_VER
2962 // MSVC's printf doesn't support 'F'.
2963 type = 'f';
2964 #endif
2965 // Fall through.
2966 case 'E': case 'G': case 'A':
2967 upper = true;
2968 break;
2969 default:
2970 internal::report_unknown_type(type, "double");
2971 break;
2972 }
2973
2974 char sign = 0;
2975 // Use isnegative instead of value < 0 because the latter is always
2976 // false for NaN.
2977 if (internal::FPUtil::isnegative(static_cast<double>(value))) {
2978 sign = '-';
2979 value = -value;
2980 } else if (spec.flag(SIGN_FLAG)) {
2981 sign = spec.flag(PLUS_FLAG) ? '+' : ' ';
2982 }
2983
2984 if (internal::FPUtil::isnotanumber(value)) {
2985 // Format NaN ourselves because sprintf's output is not consistent
2986 // across platforms.
2987 std::size_t nan_size = 4;
2988 const char *nan = upper ? " NAN" : " nan";
2989 if (!sign) {
2990 --nan_size;
2991 ++nan;
2992 }
2993 CharPtr out = write_str(nan, nan_size, spec);
2994 if (sign)
2995 *out = sign;
2996 return;
2997 }
2998
2999 if (internal::FPUtil::isinfinity(value)) {
3000 // Format infinity ourselves because sprintf's output is not consistent
3001 // across platforms.
3002 std::size_t inf_size = 4;
3003 const char *inf = upper ? " INF" : " inf";
3004 if (!sign) {
3005 --inf_size;
3006 ++inf;
3007 }
3008 CharPtr out = write_str(inf, inf_size, spec);
3009 if (sign)
3010 *out = sign;
3011 return;
3012 }
3013
3014 std::size_t offset = buffer_.size();
3015 unsigned width = spec.width();
3016 if (sign) {
3017 buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u));
3018 if (width > 0)
3019 --width;
3020 ++offset;
3021 }
3022
3023 // Build format string.
3024 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
3025 Char format[MAX_FORMAT_SIZE];
3026 Char *format_ptr = format;
3027 *format_ptr++ = '%';
3028 unsigned width_for_sprintf = width;
3029 if (spec.flag(HASH_FLAG))
3030 *format_ptr++ = '#';
3031 if (spec.align() == ALIGN_CENTER) {
3032 width_for_sprintf = 0;
3033 } else {
3034 if (spec.align() == ALIGN_LEFT)
3035 *format_ptr++ = '-';
3036 if (width != 0)
3037 *format_ptr++ = '*';
3038 }
3039 if (spec.precision() >= 0) {
3040 *format_ptr++ = '.';
3041 *format_ptr++ = '*';
3042 }
3043
3044 append_float_length(format_ptr, value);
3045 *format_ptr++ = type;
3046 *format_ptr = '\0';
3047
3048 // Format using snprintf.
3049 Char fill = internal::CharTraits<Char>::cast(spec.fill());
3050 unsigned n = 0;
3051 Char *start = FMT_NULL;
3052 for (;;) {
3053 std::size_t buffer_size = buffer_.capacity() - offset;
3054 #if FMT_MSC_VER
3055 // MSVC's vsnprintf_s doesn't work with zero size, so reserve
3056 // space for at least one extra character to make the size non-zero.
3057 // Note that the buffer's capacity will increase by more than 1.
3058 if (buffer_size == 0) {
3059 buffer_.reserve(offset + 1);
3060 buffer_size = buffer_.capacity() - offset;
3061 }
3062 #endif
3063 start = &buffer_[offset];
3064 int result = internal::CharTraits<Char>::format_float(
3065 start, buffer_size, format, width_for_sprintf, spec.precision(), value);
3066 if (result >= 0) {
3067 n = internal::to_unsigned(result);
3068 if (offset + n < buffer_.capacity())
3069 break; // The buffer is large enough - continue with formatting.
3070 buffer_.reserve(offset + n + 1);
3071 } else {
3072 // If result is negative we ask to increase the capacity by at least 1,
3073 // but as std::vector, the buffer grows exponentially.
3074 buffer_.reserve(buffer_.capacity() + 1);
3075 }
3076 }
3077 if (sign) {
3078 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
3079 *start != ' ') {
3080 *(start - 1) = sign;
3081 sign = 0;
3082 } else {
3083 *(start - 1) = fill;
3084 }
3085 ++n;
3086 }
3087 if (spec.align() == ALIGN_CENTER && spec.width() > n) {
3088 width = spec.width();
3089 CharPtr p = grow_buffer(width);
3090 std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
3091 fill_padding(p, spec.width(), n, fill);
3092 return;
3093 }
3094 if (spec.fill() != ' ' || sign) {
3095 while (*start == ' ')
3096 *start++ = fill;
3097 if (sign)
3098 *(start - 1) = sign;
3099 }
3100 grow_buffer(n);
3101 }
3102
3137 template <typename Char, typename Allocator = std::allocator<Char> >
3138 class BasicMemoryWriter : public BasicWriter<Char> {
3139 private:
3140 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
3141
3142 public:
3143 explicit BasicMemoryWriter(const Allocator& alloc = Allocator())
3144 : BasicWriter<Char>(buffer_), buffer_(alloc) {}
3145
3146 #if FMT_USE_RVALUE_REFERENCES
3147
3153 BasicMemoryWriter(BasicMemoryWriter &&other)
3154 : BasicWriter<Char>(buffer_), buffer_(std::move(other.buffer_)) {
3155 }
3156
3162 BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
3163 buffer_ = std::move(other.buffer_);
3164 return *this;
3165 }
3166 #endif
3167 };
3168
3169 typedef BasicMemoryWriter<char> MemoryWriter;
3170 typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
3171
3192 template <typename Char>
3193 class BasicArrayWriter : public BasicWriter<Char> {
3194 private:
3195 internal::FixedBuffer<Char> buffer_;
3196
3197 public:
3204 BasicArrayWriter(Char *array, std::size_t size)
3205 : BasicWriter<Char>(buffer_), buffer_(array, size) {}
3206
3213 template <std::size_t SIZE>
3214 explicit BasicArrayWriter(Char (&array)[SIZE])
3215 : BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
3216 };
3217
3218 typedef BasicArrayWriter<char> ArrayWriter;
3219 typedef BasicArrayWriter<wchar_t> WArrayWriter;
3220
3221 // Reports a system error without throwing an exception.
3222 // Can be used to report errors from destructors.
3223 FMT_API void report_system_error(int error_code,
3224 StringRef message) FMT_NOEXCEPT;
3225
3226 #if FMT_USE_WINDOWS_H
3227
3229 class WindowsError : public SystemError {
3230 private:
3231 FMT_API void init(int error_code, CStringRef format_str, ArgList args);
3232
3233 public:
3262 WindowsError(int error_code, CStringRef message) {
3263 init(error_code, message, ArgList());
3264 }
3265 FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef)
3266 };
3267
3268 // Reports a Windows error without throwing an exception.
3269 // Can be used to report errors from destructors.
3270 FMT_API void report_windows_error(int error_code,
3271 StringRef message) FMT_NOEXCEPT;
3272
3273 #endif
3274
3275 enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
3276
3283 FMT_API void print_colored(Color c, CStringRef format, ArgList args);
3284
3294 inline std::string format(CStringRef format_str, ArgList args) {
3295 MemoryWriter w;
3296 w.write(format_str, args);
3297 return w.str();
3298 }
3299
3300 inline std::wstring format(WCStringRef format_str, ArgList args) {
3301 WMemoryWriter w;
3302 w.write(format_str, args);
3303 return w.str();
3304 }
3305
3315 FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
3316
3326 FMT_API void print(CStringRef format_str, ArgList args);
3327
3331 class FormatInt {
3332 private:
3333 // Buffer should be large enough to hold all digits (digits10 + 1),
3334 // a sign and a null character.
3335 enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3};
3336 mutable char buffer_[BUFFER_SIZE];
3337 char *str_;
3338
3339 // Formats value in reverse and returns the number of digits.
3340 char *format_decimal(ULongLong value) {
3341 char *buffer_end = buffer_ + BUFFER_SIZE - 1;
3342 while (value >= 100) {
3343 // Integer division is slow so do it for a group of two digits instead
3344 // of for every digit. The idea comes from the talk by Alexandrescu
3345 // "Three Optimization Tips for C++". See speed-test for a comparison.
3346 unsigned index = static_cast<unsigned>((value % 100) * 2);
3347 value /= 100;
3348 *--buffer_end = internal::Data::DIGITS[index + 1];
3349 *--buffer_end = internal::Data::DIGITS[index];
3350 }
3351 if (value < 10) {
3352 *--buffer_end = static_cast<char>('0' + value);
3353 return buffer_end;
3354 }
3355 unsigned index = static_cast<unsigned>(value * 2);
3356 *--buffer_end = internal::Data::DIGITS[index + 1];
3357 *--buffer_end = internal::Data::DIGITS[index];
3358 return buffer_end;
3359 }
3360
3361 void FormatSigned(LongLong value) {
3362 ULongLong abs_value = static_cast<ULongLong>(value);
3363 bool negative = value < 0;
3364 if (negative)
3365 abs_value = 0 - abs_value;
3366 str_ = format_decimal(abs_value);
3367 if (negative)
3368 *--str_ = '-';
3369 }
3370
3371 public:
3372 explicit FormatInt(int value) { FormatSigned(value); }
3373 explicit FormatInt(long value) { FormatSigned(value); }
3374 explicit FormatInt(LongLong value) { FormatSigned(value); }
3375 explicit FormatInt(unsigned value) : str_(format_decimal(value)) {}
3376 explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
3377 explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
3378
3380 std::size_t size() const {
3381 return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
3382 }
3383
3388 const char *data() const { return str_; }
3389
3394 const char *c_str() const {
3395 buffer_[BUFFER_SIZE - 1] = '\0';
3396 return str_;
3397 }
3398
3404 std::string str() const { return std::string(str_, size()); }
3405 };
3406
3407 // Formats a decimal integer value writing into buffer and returns
3408 // a pointer to the end of the formatted string. This function doesn't
3409 // write a terminating null character.
3410 template <typename T>
3411 inline void format_decimal(char *&buffer, T value) {
3412 typedef typename internal::IntTraits<T>::MainType MainType;
3413 MainType abs_value = static_cast<MainType>(value);
3414 if (internal::is_negative(value)) {
3415 *buffer++ = '-';
3416 abs_value = 0 - abs_value;
3417 }
3418 if (abs_value < 100) {
3419 if (abs_value < 10) {
3420 *buffer++ = static_cast<char>('0' + abs_value);
3421 return;
3422 }
3423 unsigned index = static_cast<unsigned>(abs_value * 2);
3424 *buffer++ = internal::Data::DIGITS[index];
3425 *buffer++ = internal::Data::DIGITS[index + 1];
3426 return;
3427 }
3428 unsigned num_digits = internal::count_digits(abs_value);
3429 internal::format_decimal(buffer, abs_value, num_digits);
3430 buffer += num_digits;
3431 }
3432
3443 template <typename T>
3444 inline internal::NamedArgWithType<char, T> arg(StringRef name, const T &arg) {
3445 return internal::NamedArgWithType<char, T>(name, arg);
3446 }
3447
3448 template <typename T>
3449 inline internal::NamedArgWithType<wchar_t, T> arg(WStringRef name, const T &arg) {
3450 return internal::NamedArgWithType<wchar_t, T>(name, arg);
3451 }
3452
3453 // The following two functions are deleted intentionally to disable
3454 // nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``.
3455 template <typename Char>
3456 void arg(StringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3457 template <typename Char>
3458 void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3459 }
3460
3461 #if FMT_GCC_VERSION
3462 // Use the system_header pragma to suppress warnings about variadic macros
3463 // because suppressing -Wvariadic-macros with the diagnostic pragma doesn't
3464 // work. It is used at the end because we want to suppress as little warnings
3465 // as possible.
3466 # pragma GCC system_header
3467 #endif
3468
3469 // This is used to work around VC++ bugs in handling variadic macros.
3470 #define FMT_EXPAND(args) args
3471
3472 // Returns the number of arguments.
3473 // Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s.
3474 #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
3475 #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
3476 #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3477 #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
3478
3479 #define FMT_FOR_EACH_(N, f, ...) \
3480 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
3481 #define FMT_FOR_EACH(f, ...) \
3482 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
3483
3484 #define FMT_ADD_ARG_NAME(type, index) type arg##index
3485 #define FMT_GET_ARG_NAME(type, index) arg##index
3486
3487 #if FMT_USE_VARIADIC_TEMPLATES
3488 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3489 template <typename... Args> \
3490 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3491 const Args & ... args) { \
3492 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
3493 typename ArgArray::Type array{ \
3494 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
3495 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
3496 fmt::ArgList(fmt::internal::make_type(args...), array)); \
3497 }
3498 #else
3499 // Defines a wrapper for a function taking __VA_ARGS__ arguments
3500 // and n additional arguments of arbitrary types.
3501 # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
3502 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
3503 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3504 FMT_GEN(n, FMT_MAKE_ARG)) { \
3505 fmt::internal::ArgArray<n>::Type arr; \
3506 FMT_GEN(n, FMT_ASSIGN_##Char); \
3507 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
3508 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
3509 }
3510
3511 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3512 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
3513 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
3514 } \
3515 FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
3516 FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
3517 FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
3518 FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
3519 FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
3520 FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
3521 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
3522 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
3523 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
3524 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
3525 FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
3526 FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
3527 FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
3528 FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
3529 FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
3530 #endif // FMT_USE_VARIADIC_TEMPLATES
3531
3559 #define FMT_VARIADIC(ReturnType, func, ...) \
3560 FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
3561
3562 #define FMT_VARIADIC_W(ReturnType, func, ...) \
3563 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
3564
3565 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
3566
3567 #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
3568
3583 #define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
3584
3585 #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
3586
3587 namespace fmt {
3588 FMT_VARIADIC(std::string, format, CStringRef)
3589 FMT_VARIADIC_W(std::wstring, format, WCStringRef)
3590 FMT_VARIADIC(void, print, CStringRef)
3591 FMT_VARIADIC(void, print, std::FILE *, CStringRef)
3592 FMT_VARIADIC(void, print_colored, Color, CStringRef)
3593
3594 namespace internal {
3595 template <typename Char>
3596 inline bool is_name_start(Char c) {
3597 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
3598 }
3599
3600 // Parses an unsigned integer advancing s to the end of the parsed input.
3601 // This function assumes that the first character of s is a digit.
3602 template <typename Char>
3603 unsigned parse_nonnegative_int(const Char *&s) {
3604 assert('0' <= *s && *s <= '9');
3605 unsigned value = 0;
3606 do {
3607 unsigned new_value = value * 10 + (*s++ - '0');
3608 // Check if value wrapped around.
3609 if (new_value < value) {
3610 value = (std::numeric_limits<unsigned>::max)();
3611 break;
3612 }
3613 value = new_value;
3614 } while ('0' <= *s && *s <= '9');
3615 // Convert to unsigned to prevent a warning.
3616 unsigned max_int = (std::numeric_limits<int>::max)();
3617 if (value > max_int)
3618 FMT_THROW(FormatError("number is too big"));
3619 return value;
3620 }
3621
3622 inline void require_numeric_argument(const Arg &arg, char spec) {
3623 if (arg.type > Arg::LAST_NUMERIC_TYPE) {
3624 std::string message =
3625 fmt::format("format specifier '{}' requires numeric argument", spec);
3626 FMT_THROW(fmt::FormatError(message));
3627 }
3628 }
3629
3630 template <typename Char>
3631 void check_sign(const Char *&s, const Arg &arg) {
3632 char sign = static_cast<char>(*s);
3633 require_numeric_argument(arg, sign);
3634 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) {
3635 FMT_THROW(FormatError(fmt::format(
3636 "format specifier '{}' requires signed argument", sign)));
3637 }
3638 ++s;
3639 }
3640 } // namespace internal
3641
3642 template <typename Char, typename AF>
3643 inline internal::Arg BasicFormatter<Char, AF>::get_arg(
3644 BasicStringRef<Char> arg_name, const char *&error) {
3645 if (check_no_auto_index(error)) {
3646 map_.init(args());
3647 const internal::Arg *arg = map_.find(arg_name);
3648 if (arg)
3649 return *arg;
3650 error = "argument not found";
3651 }
3652 return internal::Arg();
3653 }
3654
3655 template <typename Char, typename AF>
3656 inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s) {
3657 const char *error = FMT_NULL;
3658 internal::Arg arg = *s < '0' || *s > '9' ?
3659 next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
3660 if (error) {
3661 FMT_THROW(FormatError(
3662 *s != '}' && *s != ':' ? "invalid format string" : error));
3663 }
3664 return arg;
3665 }
3666
3667 template <typename Char, typename AF>
3668 inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s) {
3669 assert(internal::is_name_start(*s));
3670 const Char *start = s;
3671 Char c;
3672 do {
3673 c = *++s;
3674 } while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
3675 const char *error = FMT_NULL;
3676 internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
3677 if (error)
3678 FMT_THROW(FormatError(error));
3679 return arg;
3680 }
3681
3682 template <typename Char, typename ArgFormatter>
3683 const Char *BasicFormatter<Char, ArgFormatter>::format(
3684 const Char *&format_str, const internal::Arg &arg) {
3685 using internal::Arg;
3686 const Char *s = format_str;
3687 typename ArgFormatter::SpecType spec;
3688 if (*s == ':') {
3689 if (arg.type == Arg::CUSTOM) {
3690 arg.custom.format(this, arg.custom.value, &s);
3691 return s;
3692 }
3693 ++s;
3694 // Parse fill and alignment.
3695 if (Char c = *s) {
3696 const Char *p = s + 1;
3697 spec.align_ = ALIGN_DEFAULT;
3698 do {
3699 switch (*p) {
3700 case '<':
3701 spec.align_ = ALIGN_LEFT;
3702 break;
3703 case '>':
3704 spec.align_ = ALIGN_RIGHT;
3705 break;
3706 case '=':
3707 spec.align_ = ALIGN_NUMERIC;
3708 break;
3709 case '^':
3710 spec.align_ = ALIGN_CENTER;
3711 break;
3712 }
3713 if (spec.align_ != ALIGN_DEFAULT) {
3714 if (p != s) {
3715 if (c == '}') break;
3716 if (c == '{')
3717 FMT_THROW(FormatError("invalid fill character '{'"));
3718 s += 2;
3719 spec.fill_ = c;
3720 } else ++s;
3721 if (spec.align_ == ALIGN_NUMERIC)
3722 require_numeric_argument(arg, '=');
3723 break;
3724 }
3725 } while (--p >= s);
3726 }
3727
3728 // Parse sign.
3729 switch (*s) {
3730 case '+':
3731 check_sign(s, arg);
3732 spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
3733 break;
3734 case '-':
3735 check_sign(s, arg);
3736 spec.flags_ |= MINUS_FLAG;
3737 break;
3738 case ' ':
3739 check_sign(s, arg);
3740 spec.flags_ |= SIGN_FLAG;
3741 break;
3742 }
3743
3744 if (*s == '#') {
3745 require_numeric_argument(arg, '#');
3746 spec.flags_ |= HASH_FLAG;
3747 ++s;
3748 }
3749
3750 // Parse zero flag.
3751 if (*s == '0') {
3752 require_numeric_argument(arg, '0');
3753 spec.align_ = ALIGN_NUMERIC;
3754 spec.fill_ = '0';
3755 ++s;
3756 }
3757
3758 // Parse width.
3759 if ('0' <= *s && *s <= '9') {
3760 spec.width_ = internal::parse_nonnegative_int(s);
3761 } else if (*s == '{') {
3762 ++s;
3763 Arg width_arg = internal::is_name_start(*s) ?
3764 parse_arg_name(s) : parse_arg_index(s);
3765 if (*s++ != '}')
3766 FMT_THROW(FormatError("invalid format string"));
3767 ULongLong value = 0;
3768 switch (width_arg.type) {
3769 case Arg::INT:
3770 if (width_arg.int_value < 0)
3771 FMT_THROW(FormatError("negative width"));
3772 value = width_arg.int_value;
3773 break;
3774 case Arg::UINT:
3775 value = width_arg.uint_value;
3776 break;
3777 case Arg::LONG_LONG:
3778 if (width_arg.long_long_value < 0)
3779 FMT_THROW(FormatError("negative width"));
3780 value = width_arg.long_long_value;
3781 break;
3782 case Arg::ULONG_LONG:
3783 value = width_arg.ulong_long_value;
3784 break;
3785 default:
3786 FMT_THROW(FormatError("width is not integer"));
3787 }
3788 if (value > (std::numeric_limits<int>::max)())
3789 FMT_THROW(FormatError("number is too big"));
3790 spec.width_ = static_cast<int>(value);
3791 }
3792
3793 // Parse precision.
3794 if (*s == '.') {
3795 ++s;
3796 spec.precision_ = 0;
3797 if ('0' <= *s && *s <= '9') {
3798 spec.precision_ = internal::parse_nonnegative_int(s);
3799 } else if (*s == '{') {
3800 ++s;
3801 Arg precision_arg = internal::is_name_start(*s) ?
3802 parse_arg_name(s) : parse_arg_index(s);
3803 if (*s++ != '}')
3804 FMT_THROW(FormatError("invalid format string"));
3805 ULongLong value = 0;
3806 switch (precision_arg.type) {
3807 case Arg::INT:
3808 if (precision_arg.int_value < 0)
3809 FMT_THROW(FormatError("negative precision"));
3810 value = precision_arg.int_value;
3811 break;
3812 case Arg::UINT:
3813 value = precision_arg.uint_value;
3814 break;
3815 case Arg::LONG_LONG:
3816 if (precision_arg.long_long_value < 0)
3817 FMT_THROW(FormatError("negative precision"));
3818 value = precision_arg.long_long_value;
3819 break;
3820 case Arg::ULONG_LONG:
3821 value = precision_arg.ulong_long_value;
3822 break;
3823 default:
3824 FMT_THROW(FormatError("precision is not integer"));
3825 }
3826 if (value > (std::numeric_limits<int>::max)())
3827 FMT_THROW(FormatError("number is too big"));
3828 spec.precision_ = static_cast<int>(value);
3829 } else {
3830 FMT_THROW(FormatError("missing precision specifier"));
3831 }
3832 if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
3833 FMT_THROW(FormatError(
3834 fmt::format("precision not allowed in {} format specifier",
3835 arg.type == Arg::POINTER ? "pointer" : "integer")));
3836 }
3837 }
3838
3839 // Parse type.
3840 if (*s != '}' && *s)
3841 spec.type_ = static_cast<char>(*s++);
3842 }
3843
3844 if (*s++ != '}')
3845 FMT_THROW(FormatError("missing '}' in format string"));
3846
3847 // Format argument.
3848 ArgFormatter(*this, spec, s - 1).visit(arg);
3849 return s;
3850 }
3851
3852 template <typename Char, typename AF>
3853 void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
3854 const Char *s = format_str.c_str();
3855 const Char *start = s;
3856 while (*s) {
3857 Char c = *s++;
3858 if (c != '{' && c != '}') continue;
3859 if (*s == c) {
3860 write(writer_, start, s);
3861 start = ++s;
3862 continue;
3863 }
3864 if (c == '}')
3865 FMT_THROW(FormatError("unmatched '}' in format string"));
3866 write(writer_, start, s - 1);
3867 internal::Arg arg = internal::is_name_start(*s) ?
3868 parse_arg_name(s) : parse_arg_index(s);
3869 start = s = format(s, arg);
3870 }
3871 write(writer_, start, s);
3872 }
3873
3874 template <typename Char, typename It>
3875 struct ArgJoin {
3876 It first;
3877 It last;
3878 BasicCStringRef<Char> sep;
3879
3880 ArgJoin(It first, It last, const BasicCStringRef<Char>& sep) :
3881 first(first),
3882 last(last),
3883 sep(sep) {}
3884 };
3885
3886 template <typename It>
3887 ArgJoin<char, It> join(It first, It last, const BasicCStringRef<char>& sep) {
3888 return ArgJoin<char, It>(first, last, sep);
3889 }
3890
3891 template <typename It>
3892 ArgJoin<wchar_t, It> join(It first, It last, const BasicCStringRef<wchar_t>& sep) {
3893 return ArgJoin<wchar_t, It>(first, last, sep);
3894 }
3895
3896 #if FMT_HAS_GXX_CXX11
3897 template <typename Range>
3898 auto join(const Range& range, const BasicCStringRef<char>& sep)
3899 -> ArgJoin<char, decltype(std::begin(range))> {
3900 return join(std::begin(range), std::end(range), sep);
3901 }
3902
3903 template <typename Range>
3904 auto join(const Range& range, const BasicCStringRef<wchar_t>& sep)
3905 -> ArgJoin<wchar_t, decltype(std::begin(range))> {
3906 return join(std::begin(range), std::end(range), sep);
3907 }
3908 #endif
3909
3910 template <typename ArgFormatter, typename Char, typename It>
3911 void format_arg(fmt::BasicFormatter<Char, ArgFormatter> &f,
3912 const Char *&format_str, const ArgJoin<Char, It>& e) {
3913 const Char* end = format_str;
3914 if (*end == ':')
3915 ++end;
3916 while (*end && *end != '}')
3917 ++end;
3918 if (*end != '}')
3919 FMT_THROW(FormatError("missing '}' in format string"));
3920
3921 It it = e.first;
3922 if (it != e.last) {
3923 const Char* save = format_str;
3924 f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
3925 while (it != e.last) {
3926 f.writer().write(e.sep);
3927 format_str = save;
3928 f.format(format_str, internal::MakeArg<fmt::BasicFormatter<Char, ArgFormatter> >(*it++));
3929 }
3930 }
3931 format_str = end + 1;
3932 }
3933 } // namespace fmt
3934
3935 #if FMT_USE_USER_DEFINED_LITERALS
3936 namespace fmt {
3937 namespace internal {
3938
3939 template <typename Char>
3940 struct UdlFormat {
3941 const Char *str;
3942
3943 template <typename... Args>
3944 auto operator()(Args && ... args) const
3945 -> decltype(format(str, std::forward<Args>(args)...)) {
3946 return format(str, std::forward<Args>(args)...);
3947 }
3948 };
3949
3950 template <typename Char>
3951 struct UdlArg {
3952 const Char *str;
3953
3954 template <typename T>
3955 NamedArgWithType<Char, T> operator=(T &&value) const {
3956 return {str, std::forward<T>(value)};
3957 }
3958 };
3959
3960 } // namespace internal
3961
3962 inline namespace literals {
3963
3974 inline internal::UdlFormat<char>
3975 operator"" _format(const char *s, std::size_t) { return {s}; }
3976 inline internal::UdlFormat<wchar_t>
3977 operator"" _format(const wchar_t *s, std::size_t) { return {s}; }
3978
3989 inline internal::UdlArg<char>
3990 operator"" _a(const char *s, std::size_t) { return {s}; }
3991 inline internal::UdlArg<wchar_t>
3992 operator"" _a(const wchar_t *s, std::size_t) { return {s}; }
3993
3994 } // inline namespace literals
3995 } // namespace fmt
3996 #endif // FMT_USE_USER_DEFINED_LITERALS
3997
3998 // Restore warnings.
3999 #if FMT_GCC_VERSION >= 406
4000 # pragma GCC diagnostic pop
4001 #endif
4002
4003 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
4004 # pragma clang diagnostic pop
4005 #endif
4006
4007 #ifdef FMT_HEADER_ONLY
4008 # define FMT_FUNC inline
4009 # include "format.cc"
4010 #else
4011 # define FMT_FUNC
4012 #endif
4013
4014 #endif // FMT_FORMAT_H_
fmt::internal::Value
Definition: format.h:1082
fmt::FormatInt::size
std::size_t size() const
Definition: format.h:3380
fmt::BasicFormatter::writer
BasicWriter< Char > & writer()
Definition: format.h:2184
fmt::FormatSpec
Definition: format.h:1751
fmt::ArgVisitor::visit_custom
Result visit_custom(Arg::CustomValue)
Definition: format.h:1641
fmt::BasicStringRef::size
std::size_t size() const
Definition: format.h:523
fmt::internal::ConvertToIntImpl
Definition: format.h:1161
fmt::BasicCStringRef::BasicCStringRef
BasicCStringRef(const Char *s)
Definition: format.h:589
fmt::ArgVisitor::visit_string
Result visit_string(Arg::StringValue< char >)
Definition: format.h:1626
fmt::internal::ConvertToIntImpl2< T, true >
Definition: format.h:1171
fmt::ArgVisitor::visit_pointer
Result visit_pointer(const void *)
Definition: format.h:1636
fmt::internal::WCharHelper
Definition: format.h:1139
fmt::BasicWriter::operator<<
BasicWriter & operator<<(long double value)
Definition: format.h:2675
fmt::IntFormatSpec
Definition: format.h:1768
fmt::ArgList
Definition: format.h:1460
fmt::internal::ArgArray
Definition: format.h:2221
fmt::ArgVisitor::visit_uint
Result visit_uint(unsigned value)
Definition: format.h:1579
fmt::BasicCStringRef
Definition: format.h:583
fmt::FormatInt
Definition: format.h:3331
fmt::ArgVisitor::visit_bool
Result visit_bool(bool value)
Definition: format.h:1589
fmt::internal::IntTraits
Definition: format.h:914
fmt::internal::MakeArg
Definition: format.h:1420
fmt::internal::DummyInt
Definition: format.h:355
fmt::internal::SignChecker
Definition: format.h:888
fmt::BasicWriter::data
const Char * data() const FMT_NOEXCEPT
Definition: format.h:2584
fmt::ArgVisitor::visit_ulong_long
Result visit_ulong_long(ULongLong value)
Definition: format.h:1584
fmt::ArgVisitor::visit_any_int
Result visit_any_int(T)
Definition: format.h:1600
fmt::SystemError::SystemError
SystemError(int error_code, CStringRef message)
Definition: format.h:2409
fmt::BasicWriter::c_str
const Char * c_str() const
Definition: format.h:2590
fmt::ArgVisitor::visit_long_long
Result visit_long_long(LongLong value)
Definition: format.h:1574
fmt::BasicFormatter::format
void format(BasicCStringRef< Char > format_str)
Definition: format.h:3853
fmt::internal::Value::CustomValue
Definition: format.h:1092
fmt::BasicFormatter::Char
CharType Char
Definition: format.h:2152
fmt::internal::Arg
Definition: format.h:1124
fmt::ArgVisitor::visit_any_double
Result visit_any_double(T)
Definition: format.h:1616
fmt::AlignTypeSpec
Definition: format.h:1742
fmt::internal::LConvCheck
Definition: format.h:1217
fmt::ArgVisitor
Definition: format.h:1556
diy::save
void save(BinaryBuffer &bb, const T &x)
Saves x to bb by calling diy::Serialization<T>::save(bb,x).
Definition: serialization.hpp:102
fmt::FormatInt::data
const char * data() const
Definition: format.h:3388
fmt::BasicCStringRef::c_str
const Char * c_str() const
Definition: format.h:602
fmt::Buffer
Definition: format.h:663
fmt::ArgList::operator[]
internal::Arg operator[](unsigned index) const
Definition: format.h:1496
fmt::internal::WCharHelper< T, wchar_t >
Definition: format.h:1145
fmt::BasicArrayWriter
Definition: format.h:3193
fmt::internal::NoThousandsSep
Definition: format.h:974
fmt::BasicStringRef::data
const Char * data() const
Definition: format.h:520
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const Char *s)
Definition: format.h:497
fmt::BasicCStringRef::BasicCStringRef
BasicCStringRef(const std::basic_string< Char, std::char_traits< Char >, Allocator > &s)
Definition: format.h:597
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const Char *s, std::size_t size)
Definition: format.h:489
fmt::ArgVisitor::visit_wstring
Result visit_wstring(Arg::StringValue< wchar_t >)
Definition: format.h:1631
fmt::ArgVisitor::visit_double
Result visit_double(double value)
Definition: format.h:1605
fmt::ArgVisitor::visit_long_double
Result visit_long_double(long double value)
Definition: format.h:1610
fmt::BasicWriter::write
void write(BasicCStringRef< Char > format, ArgList args)
Definition: format.h:2631
fmt::ArgVisitor::visit_char
Result visit_char(int value)
Definition: format.h:1594
fmt::BasicStringRef::BasicStringRef
BasicStringRef(const std::basic_string< Char, std::char_traits< Char >, Allocator > &s)
Definition: format.h:506
fmt::internal::Value::StringValue
Definition: format.h:1084
fmt::BasicArrayWriter::BasicArrayWriter
BasicArrayWriter(Char(&array)[SIZE])
Definition: format.h:3214
fmt::FormatInt::c_str
const char * c_str() const
Definition: format.h:3394
fmt::BasicFormatter::BasicFormatter
BasicFormatter(const ArgList &args, BasicWriter< Char > &w)
Definition: format.h:2180
fmt::internal::FormatterBase
Definition: format.h:2045
fmt::BasicFormatter
Definition: format.h:454
fmt::Buffer::reserve
void reserve(std::size_t capacity)
Definition: format.h:706
fmt::internal::ConvertToIntImpl2
Definition: format.h:1166
fmt::internal::EnableIf
Definition: format.h:1196
fmt::internal::NamedArgWithType
Definition: format.h:1131
fmt::internal::FixedBuffer
Definition: format.h:820
fmt::internal::RuntimeError
Definition: format.h:1448
fmt::internal::BasicCharTraits
Definition: format.h:829
fmt::AlignSpec
Definition: format.h:1729
fmt::internal::ArgFormatterBase
Definition: format.h:1940
fmt::internal::MemoryBuffer
Definition: format.h:744
fmt::BasicWriter::operator<<
BasicWriter & operator<<(char value)
Definition: format.h:2683
fmt::TypeSpec
Definition: format.h:1705
fmt::internal::ThousandsSep
Definition: format.h:980
fmt::internal::NamedArg
Definition: format.h:1129
fmt::ArgFormatter::ArgFormatter
ArgFormatter(BasicFormatter< Char > &formatter, FormatSpec &spec, const Char *fmt)
Definition: format.h:2141
fmt::ArgVisitor::visit_int
Result visit_int(int value)
Definition: format.h:1569
std::numeric_limits< fmt::internal::DummyInt >
Definition: format.h:383
fmt::BasicMemoryWriter
Definition: format.h:3138
fmt::EmptySpec
Definition: format.h:1701
fmt::internal::ArgMap
Definition: format.h:1456
fmt::internal::CharTraits
Definition: format.h:840
fmt::ArgVisitor::visit_cstring
Result visit_cstring(const char *)
Definition: format.h:1621
fmt::Buffer::capacity
std::size_t capacity() const
Definition: format.h:690
fmt::Buffer::resize
void resize(std::size_t new_size)
Definition: format.h:695
fmt::BasicWriter::operator<<
BasicWriter & operator<<(ULongLong value)
Definition: format.h:2660
fmt::FormatError
Definition: format.h:609
fmt::internal::BasicData
Definition: format.h:926
fmt::Buffer::append
void append(const U *begin, const U *end)
Definition: format.h:729
fmt::ArgVisitor::visit
Result visit(const Arg &arg)
Definition: format.h:1653
fmt::BasicStringRef
Definition: format.h:482
fmt::internal::Not
Definition: format.h:1209
fmt::internal::TypeSelector
Definition: format.h:908
fmt::BasicPrintfArgFormatter
Definition: format.h:450
fmt::BasicWriter::BasicWriter
BasicWriter(Buffer< Char > &b)
Definition: format.h:2565
fmt::BasicArgFormatter::BasicArgFormatter
BasicArgFormatter(BasicFormatter< Char, Impl > &formatter, Spec &spec, const Char *fmt)
Definition: format.h:2124
fmt::Buffer::size
std::size_t size() const
Definition: format.h:687
fmt::ArgFormatter
Definition: format.h:445
fmt::BasicArrayWriter::BasicArrayWriter
BasicArrayWriter(Char *array, std::size_t size)
Definition: format.h:3204
fmt::internal::ArgType
Definition: format.h:2257
fmt::SystemError
Definition: format.h:2379
fmt::internal::MakeUnsigned
Definition: format.h:621
fmt::internal::Conditional
Definition: format.h:1202
fmt::BasicArgFormatter
Definition: format.h:2110
fmt::internal::Null
Definition: format.h:1134
fmt::BasicWriter::~BasicWriter
virtual ~BasicWriter()
Definition: format.h:2573
fmt::BasicWriter::str
std::basic_string< Char > str() const
Definition: format.h:2602
fmt::internal::ConvertToInt
Definition: format.h:1179
fmt::BasicWriter
Definition: format.h:439
fmt::BasicStringRef::to_string
std::basic_string< Char > to_string() const
Definition: format.h:515
fmt::internal::FalseType
Definition: format.h:1215
fmt::ArgJoin
Definition: format.h:3875
fmt::internal::MakeValue
Definition: format.h:1263
fmt::WidthSpec
Definition: format.h:1716
fmt::StrFormatSpec
Definition: format.h:1781
fmt::FormatInt::str
std::string str() const
Definition: format.h:3404
fmt::BasicWriter::size
std::size_t size() const
Definition: format.h:2578
fmt::BasicArgFormatter::visit_custom
void visit_custom(internal::Arg::CustomValue c)
Definition: format.h:2130