Ark Server API (ASE) - Wiki
Loading...
Searching...
No Matches
format.h
Go to the documentation of this file.
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_INCLUDE
32#include <cassert>
33#include <clocale>
34#include <cmath>
35#include <cstdio>
36#include <cstring>
37#include <limits>
38#include <memory>
39#include <stdexcept>
40#include <string>
41#include <vector>
42#include <utility> // for std::pair
43#undef FMT_INCLUDE
44
45// The fmt library version in the form major * 10000 + minor * 100 + patch.
46#define FMT_VERSION 40100
47
48#if defined(__has_include)
49# define FMT_HAS_INCLUDE(x) __has_include(x)
50#else
51# define FMT_HAS_INCLUDE(x) 0
52#endif
53
54#if (FMT_HAS_INCLUDE(<string_view>) && __cplusplus > 201402L) ||
55 (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
56# include <string_view>
57# define FMT_HAS_STRING_VIEW 1
58#else
59# define FMT_HAS_STRING_VIEW 0
60#endif
61
62#if defined _SECURE_SCL && _SECURE_SCL
63# define FMT_SECURE_SCL _SECURE_SCL
64#else
65# define FMT_SECURE_SCL 0
66#endif
67
69# include <iterator>
70#endif
71
72#ifdef _MSC_VER
73# define FMT_MSC_VER _MSC_VER
74#else
75# define FMT_MSC_VER 0
76#endif
77
78#if FMT_MSC_VER && FMT_MSC_VER <= 1500
79typedef unsigned __int32 uint32_t;
80typedef unsigned __int64 uint64_t;
81typedef __int64 intmax_t;
82#else
83#include <stdint.h>
84#endif
85
86#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
87# ifdef FMT_EXPORT
88# define FMT_API __declspec(dllexport)
89# elif defined(FMT_SHARED)
90# define FMT_API __declspec(dllimport)
91# endif
92#endif
93#ifndef FMT_API
94# define FMT_API
95#endif
96
97#ifdef __GNUC__
98# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
99# define FMT_GCC_EXTENSION __extension__
100# if FMT_GCC_VERSION >= 406
101# pragma GCC diagnostic push
102// Disable the warning about "long long" which is sometimes reported even
103// when using __extension__.
104# pragma GCC diagnostic ignored "-Wlong-long"
105// Disable the warning about declaration shadowing because it affects too
106// many valid cases.
107# pragma GCC diagnostic ignored "-Wshadow"
108// Disable the warning about implicit conversions that may change the sign of
109// an integer; silencing it otherwise would require many explicit casts.
110# pragma GCC diagnostic ignored "-Wsign-conversion"
111# endif
112# if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
113# define FMT_HAS_GXX_CXX11 1
114# endif
115#else
116# define FMT_GCC_VERSION 0
117# define FMT_GCC_EXTENSION
118# define FMT_HAS_GXX_CXX11 0
119#endif
120
121#if defined(__INTEL_COMPILER)
122# define FMT_ICC_VERSION __INTEL_COMPILER
123#elif defined(__ICL)
124# define FMT_ICC_VERSION __ICL
125#endif
126
127#if defined(__clang__) && !defined(FMT_ICC_VERSION)
128# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
129# pragma clang diagnostic push
130# pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
131# pragma clang diagnostic ignored "-Wpadded"
132#endif
133
134#ifdef __GNUC_LIBSTD__
135# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
136#endif
137
138#ifdef __has_feature
139# define FMT_HAS_FEATURE(x) __has_feature(x)
140#else
141# define FMT_HAS_FEATURE(x) 0
142#endif
143
144#ifdef __has_builtin
145# define FMT_HAS_BUILTIN(x) __has_builtin(x)
146#else
147# define FMT_HAS_BUILTIN(x) 0
148#endif
149
150#ifdef __has_cpp_attribute
151# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
152#else
153# define FMT_HAS_CPP_ATTRIBUTE(x) 0
154#endif
155
156#if FMT_HAS_CPP_ATTRIBUTE(maybe_unused)
157# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
158// VC++ 1910 support /std: option and that will set _MSVC_LANG macro
159// Clang with Microsoft CodeGen doesn't define _MSVC_LANG macro
160#elif defined(_MSVC_LANG) && _MSVC_LANG > 201402 && _MSC_VER >= 1910
161# define FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
162#endif
163
164#ifdef FMT_HAS_CXX17_ATTRIBUTE_MAYBE_UNUSED
165# define FMT_MAYBE_UNUSED [[maybe_unused]]
166// g++/clang++ also support [[gnu::unused]]. However, we don't use it.
167#elif defined(__GNUC__)
168# define FMT_MAYBE_UNUSED __attribute__((unused))
169#else
170# define FMT_MAYBE_UNUSED
171#endif
172
173// Use the compiler's attribute noreturn
174#if defined(__MINGW32__) || defined(__MINGW64__)
175# define FMT_NORETURN __attribute__((noreturn))
176#elif FMT_HAS_CPP_ATTRIBUTE(noreturn) && __cplusplus >= 201103L
177# define FMT_NORETURN [[noreturn]]
178#else
179# define FMT_NORETURN
180#endif
181
182#ifndef FMT_USE_VARIADIC_TEMPLATES
183// Variadic templates are available in GCC since version 4.4
184// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
185// since version 2013.
186# define FMT_USE_VARIADIC_TEMPLATES
187 (FMT_HAS_FEATURE(cxx_variadic_templates) ||
188 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800)
189#endif
190
191#ifndef FMT_USE_RVALUE_REFERENCES
192// Don't use rvalue references when compiling with clang and an old libstdc++
193// as the latter doesn't provide std::move.
194# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
195# define FMT_USE_RVALUE_REFERENCES 0
196# else
197# define FMT_USE_RVALUE_REFERENCES
198 (FMT_HAS_FEATURE(cxx_rvalue_references) ||
199 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600)
200# endif
201#endif
202
203#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
204# define FMT_USE_ALLOCATOR_TRAITS 1
205#else
206# define FMT_USE_ALLOCATOR_TRAITS 0
207#endif
208
209// Check if exceptions are disabled.
210#if defined(__GNUC__) && !defined(__EXCEPTIONS)
211# define FMT_EXCEPTIONS 0
212#endif
213#if FMT_MSC_VER && !_HAS_EXCEPTIONS
214# define FMT_EXCEPTIONS 0
215#endif
216#ifndef FMT_EXCEPTIONS
217# define FMT_EXCEPTIONS 1
218#endif
219
220#ifndef FMT_THROW
222# define FMT_THROW(x) throw x
223# else
224# define FMT_THROW(x) assert(false)
225# endif
226#endif
227
228// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
229#ifndef FMT_USE_NOEXCEPT
230# define FMT_USE_NOEXCEPT 0
231#endif
232
233#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) ||
235 FMT_MSC_VER >= 1900
236# define FMT_DETECTED_NOEXCEPT noexcept
237#else
238# define FMT_DETECTED_NOEXCEPT throw()
239#endif
240
241#ifndef FMT_NOEXCEPT
243# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
244# else
245# define FMT_NOEXCEPT
246# endif
247#endif
248
249// This is needed because GCC still uses throw() in its headers when exceptions
250// are disabled.
252# define FMT_DTOR_NOEXCEPT FMT_DETECTED_NOEXCEPT
253#else
254# define FMT_DTOR_NOEXCEPT FMT_NOEXCEPT
255#endif
256
257#ifndef FMT_OVERRIDE
258# if (defined(FMT_USE_OVERRIDE) && FMT_USE_OVERRIDE) || FMT_HAS_FEATURE(cxx_override) ||
260 FMT_MSC_VER >= 1900
261# define FMT_OVERRIDE override
262# else
263# define FMT_OVERRIDE
264# endif
265#endif
266
267#ifndef FMT_NULL
268# if FMT_HAS_FEATURE(cxx_nullptr) ||
270 FMT_MSC_VER >= 1600
271# define FMT_NULL nullptr
272# else
273# define FMT_NULL NULL
274# endif
275#endif
276
277// A macro to disallow the copy constructor and operator= functions
278// This should be used in the private: declarations for a class
279#ifndef FMT_USE_DELETED_FUNCTIONS
280# define FMT_USE_DELETED_FUNCTIONS 0
281#endif
282
283#if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) ||
284 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
285# define FMT_DELETED_OR_UNDEFINED = delete
286# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName)
287 TypeName(const TypeName&) = delete;
288 TypeName& operator=(const TypeName&) = delete
289#else
290# define FMT_DELETED_OR_UNDEFINED
291# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName)
292 TypeName(const TypeName&);
293 TypeName& operator=(const TypeName&)
294#endif
295
296#ifndef FMT_USE_DEFAULTED_FUNCTIONS
297# define FMT_USE_DEFAULTED_FUNCTIONS 0
298#endif
299
300#ifndef FMT_DEFAULTED_COPY_CTOR
301# if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) ||
302 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
303# define FMT_DEFAULTED_COPY_CTOR(TypeName)
304 TypeName(const TypeName&) = default;
305# else
306# define FMT_DEFAULTED_COPY_CTOR(TypeName)
307# endif
308#endif
309
310#ifndef FMT_USE_USER_DEFINED_LITERALS
311// All compilers which support UDLs also support variadic templates. This
312// makes the fmt::literals implementation easier. However, an explicit check
313// for variadic templates is added here just in case.
314// For Intel's compiler both it and the system gcc/msc must support UDLs.
316 (FMT_HAS_FEATURE(cxx_user_literals) ||
317 (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) &&
318 (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
319# define FMT_USE_USER_DEFINED_LITERALS 1
320# else
321# define FMT_USE_USER_DEFINED_LITERALS 0
322# endif
323#endif
324
325#ifndef FMT_USE_EXTERN_TEMPLATES
326# define FMT_USE_EXTERN_TEMPLATES
327 (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
328#endif
329
330#ifdef FMT_HEADER_ONLY
331// If header only do not use extern templates.
332# undef FMT_USE_EXTERN_TEMPLATES
333# define FMT_USE_EXTERN_TEMPLATES 0
334#endif
335
336#ifndef FMT_ASSERT
337# define FMT_ASSERT(condition, message) assert((condition) && message)
338#endif
339
340// __builtin_clz is broken in clang with Microsoft CodeGen:
341// https://github.com/fmtlib/fmt/issues/519
342#ifndef _MSC_VER
343# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
344# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
345# endif
346
347# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
348# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
349# endif
350#endif
351
352// Some compilers masquerade as both MSVC and GCC-likes or
353// otherwise support __builtin_clz and __builtin_clzll, so
354// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
355// if the clz and clzll builtins are not available.
356#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
357# include <intrin.h> // _BitScanReverse, _BitScanReverse64
358
359namespace fmt {
360namespace internal {
361// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
362# ifndef __clang__
363# pragma intrinsic(_BitScanReverse)
364# endif
365inline uint32_t clz(uint32_t x) {
366 unsigned long r = 0;
367 _BitScanReverse(&r, x);
368
369 assert(x != 0);
370 // Static analysis complains about using uninitialized data
371 // "r", but the only way that can happen is if "x" is 0,
372 // which the callers guarantee to not happen.
373# pragma warning(suppress: 6102)
374 return 31 - r;
375}
376# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
377
378// avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning
379# if defined(_WIN64) && !defined(__clang__)
380# pragma intrinsic(_BitScanReverse64)
381# endif
382
383inline uint32_t clzll(uint64_t x) {
384 unsigned long r = 0;
385# ifdef _WIN64
386 _BitScanReverse64(&r, x);
387# else
388 // Scan the high 32 bits.
389 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
390 return 63 - (r + 32);
391
392 // Scan the low 32 bits.
393 _BitScanReverse(&r, static_cast<uint32_t>(x));
394# endif
395
396 assert(x != 0);
397 // Static analysis complains about using uninitialized data
398 // "r", but the only way that can happen is if "x" is 0,
399 // which the callers guarantee to not happen.
400# pragma warning(suppress: 6102)
401 return 63 - r;
402}
403# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
404}
405}
406#endif
407
408namespace fmt {
409namespace internal {
410struct DummyInt {
411 int data[2];
412 operator int() const { return 0; }
413};
415
416// Dummy implementations of system functions such as signbit and ecvt called
417// if the latter are not available.
418inline DummyInt signbit(...) { return DummyInt(); }
419inline DummyInt _ecvt_s(...) { return DummyInt(); }
420inline DummyInt isinf(...) { return DummyInt(); }
421inline DummyInt _finite(...) { return DummyInt(); }
422inline DummyInt isnan(...) { return DummyInt(); }
423inline DummyInt _isnan(...) { return DummyInt(); }
424
425// A helper function to suppress bogus "conditional expression is constant"
426// warnings.
427template <typename T>
428inline T const_check(T value) { return value; }
429}
430} // namespace fmt
431
432namespace std {
433// Standard permits specialization of std::numeric_limits. This specialization
434// is used to resolve ambiguity between isinf and std::isinf in glibc:
435// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
436// and the same for isnan and signbit.
437template <>
438class numeric_limits<fmt::internal::DummyInt> :
439 public std::numeric_limits<int> {
440 public:
441 // Portable version of isinf.
442 template <typename T>
443 static bool isinfinity(T x) {
444 using namespace fmt::internal;
445 // The resolution "priority" is:
446 // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
447 if (const_check(sizeof(isinf(x)) == sizeof(bool) ||
448 sizeof(isinf(x)) == sizeof(int))) {
449 return isinf(x) != 0;
450 }
451 return !_finite(static_cast<double>(x));
452 }
453
454 // Portable version of isnan.
455 template <typename T>
456 static bool isnotanumber(T x) {
457 using namespace fmt::internal;
458 if (const_check(sizeof(isnan(x)) == sizeof(bool) ||
459 sizeof(isnan(x)) == sizeof(int))) {
460 return isnan(x) != 0;
461 }
462 return _isnan(static_cast<double>(x)) != 0;
463 }
464
465 // Portable version of signbit.
466 static bool isnegative(double x) {
467 using namespace fmt::internal;
468 if (const_check(sizeof(signbit(x)) == sizeof(bool) ||
469 sizeof(signbit(x)) == sizeof(int))) {
470 return signbit(x) != 0;
471 }
472 if (x < 0) return true;
473 if (!isnotanumber(x)) return false;
474 int dec = 0, sign = 0;
475 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
476 _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
477 return sign != 0;
478 }
479};
480} // namespace std
481
482namespace fmt {
483
484// Fix the warning about long long on older versions of GCC
485// that don't support the diagnostic pragma.
486FMT_GCC_EXTENSION typedef long long LongLong;
487FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
488
490using std::move;
491#endif
492
493template <typename Char>
494class BasicWriter;
495
496typedef BasicWriter<char> Writer;
497typedef BasicWriter<wchar_t> WWriter;
498
499template <typename Char>
500class ArgFormatter;
501
502struct FormatSpec;
503
504template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
506
507template <typename CharType,
508 typename ArgFormatter = fmt::ArgFormatter<CharType> >
509class BasicFormatter;
510
511/**
512 \rst
513 A string reference. It can be constructed from a C string or
514 ``std::basic_string``.
515
516 You can use one of the following typedefs for common character types:
517
518 +------------+-------------------------+
519 | Type | Definition |
520 +============+=========================+
521 | StringRef | BasicStringRef<char> |
522 +------------+-------------------------+
523 | WStringRef | BasicStringRef<wchar_t> |
524 +------------+-------------------------+
525
526 This class is most useful as a parameter type to allow passing
527 different types of strings to a function, for example::
528
529 template <typename... Args>
530 std::string format(StringRef format_str, const Args & ... args);
531
532 format("{}", 42);
533 format(std::string("{}"), 42);
534 \endrst
535 */
536template <typename Char>
538 private:
539 const Char *data_;
540 std::size_t size_;
541
542 public:
543 /** Constructs a string reference object from a C string and a size. */
544 BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {}
545
546 /**
547 \rst
548 Constructs a string reference object from a C string computing
549 the size with ``std::char_traits<Char>::length``.
550 \endrst
551 */
552 BasicStringRef(const Char *s)
553 : data_(s), size_(std::char_traits<Char>::length(s)) {}
554
555 /**
556 \rst
557 Constructs a string reference from a ``std::basic_string`` object.
558 \endrst
559 */
560 template <typename Allocator>
561 BasicStringRef(
562 const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
563 : data_(s.c_str()), size_(s.size()) {}
564
566 /**
567 \rst
568 Constructs a string reference from a ``std::basic_string_view`` object.
569 \endrst
570 */
573 : data_(s.data()), size_(s.size()) {}
574
575 /**
576 \rst
577 Converts a string reference to an ``std::string_view`` object.
578 \endrst
579 */
580 explicit operator std::basic_string_view<Char>() const FMT_NOEXCEPT {
582 }
583#endif
584
585 /**
586 \rst
587 Converts a string reference to an ``std::string`` object.
588 \endrst
589 */
591 return std::basic_string<Char>(data_, size_);
592 }
593
594 /** Returns a pointer to the string data. */
595 const Char *data() const { return data_; }
596
597 /** Returns the string size. */
598 std::size_t size() const { return size_; }
599
600 // Lexicographically compare this string reference to other.
601 int compare(BasicStringRef other) const {
604 if (result == 0)
605 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
606 return result;
607 }
608
609 friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
610 return lhs.compare(rhs) == 0;
611 }
612 friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
613 return lhs.compare(rhs) != 0;
614 }
615 friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) {
616 return lhs.compare(rhs) < 0;
617 }
618 friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) {
619 return lhs.compare(rhs) <= 0;
620 }
621 friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) {
622 return lhs.compare(rhs) > 0;
623 }
624 friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) {
625 return lhs.compare(rhs) >= 0;
626 }
627};
628
630typedef BasicStringRef<wchar_t> WStringRef;
631
632/**
633 \rst
634 A reference to a null terminated string. It can be constructed from a C
635 string or ``std::basic_string``.
636
637 You can use one of the following typedefs for common character types:
638
639 +-------------+--------------------------+
640 | Type | Definition |
641 +=============+==========================+
642 | CStringRef | BasicCStringRef<char> |
643 +-------------+--------------------------+
644 | WCStringRef | BasicCStringRef<wchar_t> |
645 +-------------+--------------------------+
646
647 This class is most useful as a parameter type to allow passing
648 different types of strings to a function, for example::
649
650 template <typename... Args>
651 std::string format(CStringRef format_str, const Args & ... args);
652
653 format("{}", 42);
654 format(std::string("{}"), 42);
655 \endrst
656 */
657template <typename Char>
659 private:
660 const Char *data_;
661
662 public:
663 /** Constructs a string reference object from a C string. */
664 BasicCStringRef(const Char *s) : data_(s) {}
665
666 /**
667 \rst
668 Constructs a string reference from a ``std::basic_string`` object.
669 \endrst
670 */
671 template <typename Allocator>
672 BasicCStringRef(
673 const std::basic_string<Char, std::char_traits<Char>, Allocator> &s)
674 : data_(s.c_str()) {}
675
676 /** Returns the pointer to a C string. */
677 const Char *c_str() const { return data_; }
678};
679
682
683/** A formatting error such as invalid format string. */
684class FormatError : public std::runtime_error {
685 public:
686 explicit FormatError(CStringRef message)
688 FormatError(const FormatError &ferr) : std::runtime_error(ferr) {}
690};
691
692namespace internal {
693
694// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
695template <typename T>
696struct MakeUnsigned { typedef T Type; };
697
698#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U)
699 template <>
700 struct MakeUnsigned<T> { typedef U Type; }
701
702FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
703FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
704FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
706FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
708
709// Casts nonnegative integer to unsigned.
710template <typename Int>
711inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
712 FMT_ASSERT(value >= 0, "negative value");
713 return static_cast<typename MakeUnsigned<Int>::Type>(value);
714}
715
716// The number of characters to store in the MemoryBuffer object itself
717// to avoid dynamic memory allocation.
718enum { INLINE_BUFFER_SIZE = 500 };
719
721// Use checked iterator to avoid warnings on MSVC.
722template <typename T>
725}
726#else
727template <typename T>
728inline T *make_ptr(T *ptr, std::size_t) { return ptr; }
729#endif
730} // namespace internal
731
732/**
733 \rst
734 A buffer supporting a subset of ``std::vector``'s operations.
735 \endrst
736 */
737template <typename T>
738class Buffer {
739 private:
741
742 protected:
744 std::size_t size_;
745 std::size_t capacity_;
746
747 Buffer(T *ptr = FMT_NULL, std::size_t capacity = 0)
748 : ptr_(ptr), size_(0), capacity_(capacity) {}
749
750 /**
751 \rst
752 Increases the buffer capacity to hold at least *size* elements updating
753 ``ptr_`` and ``capacity_``.
754 \endrst
755 */
756 virtual void grow(std::size_t size) = 0;
757
758 public:
759 virtual ~Buffer() {}
760
761 /** Returns the size of this buffer. */
762 std::size_t size() const { return size_; }
763
764 /** Returns the capacity of this buffer. */
765 std::size_t capacity() const { return capacity_; }
766
767 /**
768 Resizes the buffer. If T is a POD type new elements may not be initialized.
769 */
770 void resize(std::size_t new_size) {
771 if (new_size > capacity_)
772 grow(new_size);
773 size_ = new_size;
774 }
775
776 /**
777 \rst
778 Reserves space to store at least *capacity* elements.
779 \endrst
780 */
781 void reserve(std::size_t capacity) {
782 if (capacity > capacity_)
783 grow(capacity);
784 }
785
786 void clear() FMT_NOEXCEPT { size_ = 0; }
787
788 void push_back(const T &value) {
789 if (size_ == capacity_)
790 grow(size_ + 1);
791 ptr_[size_++] = value;
792 }
793
794 /** Appends data to the end of the buffer. */
795 template <typename U>
796 void append(const U *begin, const U *end);
797
798 T &operator[](std::size_t index) { return ptr_[index]; }
799 const T &operator[](std::size_t index) const { return ptr_[index]; }
800};
801
802template <typename T>
803template <typename U>
804void Buffer<T>::append(const U *begin, const U *end) {
805 FMT_ASSERT(end >= begin, "negative value");
806 std::size_t new_size = size_ + static_cast<std::size_t>(end - begin);
807 if (new_size > capacity_)
808 grow(new_size);
811 size_ = new_size;
812}
813
814namespace internal {
815
816// A memory buffer for trivially copyable/constructible types with the first
817// SIZE elements stored in the object itself.
818template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
819class MemoryBuffer : private Allocator, public Buffer<T> {
820 private:
822
823 // Deallocate memory allocated by the buffer.
824 void deallocate() {
825 if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
826 }
827
828 protected:
830
831 public:
833 : Allocator(alloc), Buffer<T>(data_, SIZE) {}
835
837 private:
838 // Move data from other to this buffer.
839 void move(MemoryBuffer &other) {
842 this->size_ = other.size_;
843 this->capacity_ = other.capacity_;
844 if (other.ptr_ == other.data_) {
845 this->ptr_ = data_;
847 make_ptr(data_, this->capacity_));
848 } else {
849 this->ptr_ = other.ptr_;
850 // Set pointer to the inline array so that delete is not called
851 // when deallocating.
853 }
854 }
855
856 public:
858 move(other);
859 }
860
862 assert(this != &other);
863 deallocate();
864 move(other);
865 return *this;
866 }
867#endif
868
869 // Returns a copy of the allocator associated with this buffer.
870 Allocator get_allocator() const { return *this; }
871};
872
873template <typename T, std::size_t SIZE, typename Allocator>
875 std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
876 if (size > new_capacity)
879 T *new_ptr =
881#else
883#endif
884 // The following code doesn't throw, so the raw pointer above doesn't leak.
885 std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
888 T *old_ptr = this->ptr_;
889 this->capacity_ = new_capacity;
890 this->ptr_ = new_ptr;
891 // deallocate may throw (at least in principle), but it doesn't matter since
892 // the buffer already uses the new storage and will deallocate it in case
893 // of exception.
894 if (old_ptr != data_)
896}
897
898// A fixed-size buffer.
899template <typename Char>
900class FixedBuffer : public fmt::Buffer<Char> {
901 public:
903
904 protected:
906};
907
908template <typename Char>
910 public:
913#else
914 typedef Char *CharPtr;
915#endif
916 static Char cast(int value) { return static_cast<Char>(value); }
917};
918
919template <typename Char>
920class CharTraits;
921
922template <>
923class CharTraits<char> : public BasicCharTraits<char> {
924 private:
925 // Conversion from wchar_t to char is not allowed.
926 static char convert(wchar_t);
927
928 public:
929 static char convert(char value) { return value; }
930
931 // Formats a floating-point number.
932 template <typename T>
933 FMT_API static int format_float(char *buffer, std::size_t size,
934 const char *format, unsigned width, int precision, T value);
935};
936
938extern template int CharTraits<char>::format_float<double>
939 (char *buffer, std::size_t size,
940 const char* format, unsigned width, int precision, double value);
941extern template int CharTraits<char>::format_float<long double>
942 (char *buffer, std::size_t size,
943 const char* format, unsigned width, int precision, long double value);
944#endif
945
946template <>
947class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
948 public:
949 static wchar_t convert(char value) { return value; }
950 static wchar_t convert(wchar_t value) { return value; }
951
952 template <typename T>
953 FMT_API static int format_float(wchar_t *buffer, std::size_t size,
954 const wchar_t *format, unsigned width, int precision, T value);
955};
956
958extern template int CharTraits<wchar_t>::format_float<double>
959 (wchar_t *buffer, std::size_t size,
960 const wchar_t* format, unsigned width, int precision, double value);
961extern template int CharTraits<wchar_t>::format_float<long double>
962 (wchar_t *buffer, std::size_t size,
963 const wchar_t* format, unsigned width, int precision, long double value);
964#endif
965
966// Checks if a number is negative - used to avoid warnings.
967template <bool IsSigned>
969 template <typename T>
970 static bool is_negative(T value) { return value < 0; }
971};
972
973template <>
974struct SignChecker<false> {
975 template <typename T>
976 static bool is_negative(T) { return false; }
977};
978
979// Returns true if value is negative, false otherwise.
980// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
981template <typename T>
982inline bool is_negative(T value) {
984}
985
986// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
987template <bool FitsIn32Bits>
988struct TypeSelector { typedef uint32_t Type; };
989
990template <>
991struct TypeSelector<false> { typedef uint64_t Type; };
992
993template <typename T>
994struct IntTraits {
995 // Smallest of uint32_t and uint64_t that is large enough to represent
996 // all values of T.
997 typedef typename
999};
1000
1001FMT_API FMT_NORETURN void report_unknown_type(char code, const char *type);
1002
1003// Static data is placed in this class template to allow header-only
1004// configuration.
1005template <typename T = void>
1007 static const uint32_t POWERS_OF_10_32[];
1008 static const uint64_t POWERS_OF_10_64[];
1009 static const char DIGITS[];
1010};
1011
1013extern template struct BasicData<void>;
1014#endif
1015
1016typedef BasicData<> Data;
1017
1018#ifdef FMT_BUILTIN_CLZLL
1019// Returns the number of decimal digits in n. Leading zeros are not counted
1020// except for n == 0 in which case count_digits returns 1.
1021inline unsigned count_digits(uint64_t n) {
1022 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
1023 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
1024 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
1025 return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
1026}
1027#else
1028// Fallback version of count_digits used when __builtin_clz is not available.
1029inline unsigned count_digits(uint64_t n) {
1030 unsigned count = 1;
1031 for (;;) {
1032 // Integer division is slow so do it for a group of four digits instead
1033 // of for every digit. The idea comes from the talk by Alexandrescu
1034 // "Three Optimization Tips for C++". See speed-test for a comparison.
1035 if (n < 10) return count;
1036 if (n < 100) return count + 1;
1037 if (n < 1000) return count + 2;
1038 if (n < 10000) return count + 3;
1039 n /= 10000u;
1040 count += 4;
1041 }
1042}
1043#endif
1044
1045#ifdef FMT_BUILTIN_CLZ
1046// Optional version of count_digits for better performance on 32-bit platforms.
1047inline unsigned count_digits(uint32_t n) {
1048 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
1049 return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
1050}
1051#endif
1052
1053// A functor that doesn't add a thousands separator.
1055 template <typename Char>
1056 void operator()(Char *) {}
1057};
1058
1059// A functor that adds a thousands separator.
1061 private:
1063
1064 // Index of a decimal digit with the least significant digit having index 0.
1066
1067 public:
1069
1070 template <typename Char>
1071 void operator()(Char *&buffer) {
1072 if (++digit_index_ % 3 != 0)
1073 return;
1074 buffer -= sep_.size();
1077 }
1078};
1079
1080// Formats a decimal unsigned integer value writing into buffer.
1081// thousands_sep is a functor that is called after writing each char to
1082// add a thousands separator if necessary.
1083template <typename UInt, typename Char, typename ThousandsSep>
1084inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
1085 ThousandsSep thousands_sep) {
1086 buffer += num_digits;
1087 while (value >= 100) {
1088 // Integer division is slow so do it for a group of two digits instead
1089 // of for every digit. The idea comes from the talk by Alexandrescu
1090 // "Three Optimization Tips for C++". See speed-test for a comparison.
1091 unsigned index = static_cast<unsigned>((value % 100) * 2);
1092 value /= 100;
1093 *--buffer = Data::DIGITS[index + 1];
1095 *--buffer = Data::DIGITS[index];
1097 }
1098 if (value < 10) {
1099 *--buffer = static_cast<char>('0' + value);
1100 return;
1101 }
1102 unsigned index = static_cast<unsigned>(value * 2);
1103 *--buffer = Data::DIGITS[index + 1];
1105 *--buffer = Data::DIGITS[index];
1106}
1107
1108template <typename UInt, typename Char>
1109inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
1111 return;
1112}
1113
1114#ifndef _WIN32
1115# define FMT_USE_WINDOWS_H 0
1116#elif !defined(FMT_USE_WINDOWS_H)
1117# define FMT_USE_WINDOWS_H 1
1118#endif
1119
1120// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
1121// All the functionality that relies on it will be disabled too.
1123// A converter from UTF-8 to UTF-16.
1124// It is only provided for Windows since other systems support UTF-8 natively.
1125class UTF8ToUTF16 {
1126 private:
1127 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
1128
1129 public:
1130 FMT_API explicit UTF8ToUTF16(StringRef s);
1131 operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
1132 size_t size() const { return buffer_.size() - 1; }
1133 const wchar_t *c_str() const { return &buffer_[0]; }
1134 std::wstring str() const { return std::wstring(&buffer_[0], size()); }
1135};
1136
1137// A converter from UTF-16 to UTF-8.
1138// It is only provided for Windows since other systems support UTF-8 natively.
1139class UTF16ToUTF8 {
1140 private:
1141 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_;
1142
1143 public:
1144 UTF16ToUTF8() {}
1145 FMT_API explicit UTF16ToUTF8(WStringRef s);
1146 operator StringRef() const { return StringRef(&buffer_[0], size()); }
1147 size_t size() const { return buffer_.size() - 1; }
1148 const char *c_str() const { return &buffer_[0]; }
1149 std::string str() const { return std::string(&buffer_[0], size()); }
1150
1151 // Performs conversion returning a system error code instead of
1152 // throwing exception on conversion error. This method may still throw
1153 // in case of memory allocation error.
1154 FMT_API int convert(WStringRef s);
1155};
1156
1157FMT_API void format_windows_error(fmt::Writer &out, int error_code,
1158 fmt::StringRef message) FMT_NOEXCEPT;
1159#endif
1160
1161// A formatting argument value.
1162struct Value {
1163 template <typename Char>
1165 const Char *value;
1166 std::size_t size;
1167 };
1168
1169 typedef void (*FormatFunc)(
1170 void *formatter, const void *arg, void *format_str_ptr);
1171
1173 const void *value;
1175 };
1176
1177 union {
1179 unsigned uint_value;
1184 const void *pointer;
1186 StringValue<signed char> sstring;
1187 StringValue<unsigned char> ustring;
1190 };
1191
1192 enum Type {
1194 // Integer types should go first,
1196 // followed by floating-point types.
1200};
1201
1202// A formatting argument. It is a trivially copyable/constructible type to
1203// allow storage in internal::MemoryBuffer.
1204struct Arg : Value {
1206};
1207
1208template <typename Char>
1209struct NamedArg;
1210template <typename Char, typename T>
1211struct NamedArgWithType;
1212
1213template <typename T = void>
1214struct Null {};
1215
1216// A helper class template to enable or disable overloads taking wide
1217// characters and strings in MakeValue.
1218template <typename T, typename Char>
1220 typedef Null<T> Supported;
1221 typedef T Unsupported;
1222};
1223
1224template <typename T>
1225struct WCharHelper<T, wchar_t> {
1226 typedef T Supported;
1227 typedef Null<T> Unsupported;
1228};
1229
1230typedef char Yes[1];
1231typedef char No[2];
1232
1233template <typename T>
1234T &get();
1235
1236// These are non-members to workaround an overload resolution bug in bcc32.
1239
1240template <typename T, bool ENABLE_CONVERSION>
1242 enum { value = ENABLE_CONVERSION };
1243};
1244
1245template <typename T, bool ENABLE_CONVERSION>
1247 enum { value = false };
1248};
1249
1250template <typename T>
1251struct ConvertToIntImpl2<T, true> {
1252 enum {
1253 // Don't convert numeric types.
1254 value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value
1256};
1257
1258template <typename T>
1260 enum {
1261 enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
1264};
1265
1266#define FMT_DISABLE_CONVERSION_TO_INT(Type)
1267 template <>
1268 struct ConvertToInt<Type> { enum { value = 0 }; }
1269
1270// Silence warnings about convering float to int.
1274
1275template <bool B, class T = void>
1276struct EnableIf {};
1277
1278template <class T>
1279struct EnableIf<true, T> { typedef T type; };
1280
1281template <bool B, class T, class F>
1282struct Conditional { typedef T type; };
1283
1284template <class T, class F>
1285struct Conditional<false, T, F> { typedef F type; };
1286
1287// For bcc32 which doesn't understand ! in template arguments.
1288template <bool>
1289struct Not { enum { value = 0 }; };
1290
1291template <>
1292struct Not<false> { enum { value = 1 }; };
1293
1294template <typename T>
1295struct FalseType { enum { value = 0 }; };
1296
1297template <typename T, T> struct LConvCheck {
1299};
1300
1301// Returns the thousands separator for the current locale.
1302// We check if ``lconv`` contains ``thousands_sep`` because on Android
1303// ``lconv`` is stubbed as an empty struct.
1304template <typename LConv>
1306 LConv *lc, LConvCheck<char *LConv::*, &LConv::thousands_sep> = 0) {
1307 return lc->thousands_sep;
1308}
1309
1310inline fmt::StringRef thousands_sep(...) { return ""; }
1311
1312#define FMT_CONCAT(a, b) a##b
1313
1314#if FMT_GCC_VERSION >= 303
1315# define FMT_UNUSED __attribute__((unused))
1316#else
1317# define FMT_UNUSED
1318#endif
1319
1320#ifndef FMT_USE_STATIC_ASSERT
1321# define FMT_USE_STATIC_ASSERT 0
1322#endif
1323
1324#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) ||
1325 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
1326# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
1327#else
1328# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
1329# define FMT_STATIC_ASSERT(cond, message)
1330 typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
1331#endif
1332
1333template <typename Formatter>
1334void format_arg(Formatter&, ...) {
1336 "Cannot format argument. To enable the use of ostream "
1337 "operator<< include fmt/ostream.h. Otherwise provide "
1338 "an overload of format_arg.");
1339}
1340
1341// Makes an Arg object from any type.
1342template <typename Formatter>
1343class MakeValue : public Arg {
1344 public:
1345 typedef typename Formatter::Char Char;
1346
1347 private:
1348 // The following two methods are private to disallow formatting of
1349 // arbitrary pointers. If you want to output a pointer cast it to
1350 // "void *" or "const void *". In particular, this forbids formatting
1351 // of "[const] volatile char *" which is printed as bool by iostreams.
1352 // Do not implement!
1353 template <typename T>
1354 MakeValue(const T *value);
1355 template <typename T>
1356 MakeValue(T *value);
1357
1358 // The following methods are private to disallow formatting of wide
1359 // characters and strings into narrow strings as in
1360 // fmt::format("{}", L"test");
1361 // To fix this, use a wide format string: fmt::format(L"{}", L"test").
1362#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
1363 MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported);
1364#endif
1365 MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
1366 MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
1367 MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
1369 MakeValue(typename WCharHelper<const std::wstring_view &, Char>::Unsupported);
1370#endif
1371 MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
1372
1374 string.value = str.data();
1375 string.size = str.size();
1376 }
1377
1379 wstring.value = str.data();
1380 wstring.size = str.size();
1381 }
1382
1383 // Formats an argument of a custom type, such as a user-defined class.
1384 template <typename T>
1386 void *formatter, const void *arg, void *format_str_ptr) {
1387 format_arg(*static_cast<Formatter*>(formatter),
1388 *static_cast<const Char**>(format_str_ptr),
1389 *static_cast<const T*>(arg));
1390 }
1391
1392 public:
1394
1395#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs)
1396 MakeValue(Type value) { field = rhs; }
1397 static uint64_t type(Type) { return Arg::TYPE; }
1398
1399#define FMT_MAKE_VALUE(Type, field, TYPE)
1400 FMT_MAKE_VALUE_(Type, field, TYPE, value)
1401
1404 FMT_MAKE_VALUE(unsigned short, uint_value, UINT)
1406 FMT_MAKE_VALUE(unsigned, uint_value, UINT)
1407
1408 MakeValue(long value) {
1409 // To minimize the number of types we need to deal with, long is
1410 // translated either to int or to long long depending on its size.
1411 if (const_check(sizeof(long) == sizeof(int)))
1412 int_value = static_cast<int>(value);
1413 else
1415 }
1416 static uint64_t type(long) {
1417 return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG;
1418 }
1419
1420 MakeValue(unsigned long value) {
1421 if (const_check(sizeof(unsigned long) == sizeof(unsigned)))
1422 uint_value = static_cast<unsigned>(value);
1423 else
1425 }
1426 static uint64_t type(unsigned long) {
1427 return sizeof(unsigned long) == sizeof(unsigned) ?
1428 Arg::UINT : Arg::ULONG_LONG;
1429 }
1430
1436 FMT_MAKE_VALUE(signed char, int_value, INT)
1437 FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
1439
1440#if __cplusplus >= 201103L
1441 template <
1442 typename T,
1443 typename = typename std::enable_if<
1446
1447 template <
1448 typename T,
1449 typename = typename std::enable_if<
1451 static uint64_t type(T) { return Arg::INT; }
1452#endif
1453
1454#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1456 int_value = value;
1457 }
1458 static uint64_t type(wchar_t) { return Arg::CHAR; }
1459#endif
1460
1461#define FMT_MAKE_STR_VALUE(Type, TYPE)
1462 MakeValue(Type value) { set_string(value); }
1463 static uint64_t type(Type) { return Arg::TYPE; }
1464
1466 FMT_MAKE_VALUE(const char *, string.value, CSTRING)
1467 FMT_MAKE_VALUE(signed char *, sstring.value, CSTRING)
1468 FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING)
1469 FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING)
1470 FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING)
1474#endif
1477
1478#define FMT_MAKE_WSTR_VALUE(Type, TYPE)
1479 MakeValue(typename WCharHelper<Type, Char>::Supported value) {
1480 set_string(value);
1481 }
1482 static uint64_t type(Type) { return Arg::TYPE; }
1483
1484 FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
1485 FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
1489#endif
1491
1493 FMT_MAKE_VALUE(const void *, pointer, POINTER)
1494
1495 template <typename T>
1497 typename EnableIf<Not<
1498 ConvertToInt<T>::value>::value, int>::type = 0) {
1499 custom.value = &value;
1501 }
1502
1503 template <typename T>
1504 static typename EnableIf<Not<ConvertToInt<T>::value>::value, uint64_t>::type
1505 type(const T &) {
1506 return Arg::CUSTOM;
1507 }
1508
1509 // Additional template param `Char_` is needed here because make_type always
1510 // uses char.
1511 template <typename Char_>
1513 template <typename Char_, typename T>
1515
1516 template <typename Char_>
1517 static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
1518 template <typename Char_, typename T>
1519 static uint64_t type(const NamedArgWithType<Char_, T> &) { return Arg::NAMED_ARG; }
1520};
1521
1522template <typename Formatter>
1523class MakeArg : public Arg {
1524public:
1526 type = Arg::NONE;
1527 }
1528
1529 template <typename T>
1530 MakeArg(const T &value)
1532 type = static_cast<Arg::Type>(MakeValue<Formatter>::type(value));
1533 }
1534};
1535
1536template <typename Char>
1537struct NamedArg : Arg {
1539
1540 template <typename T>
1541 NamedArg(BasicStringRef<Char> argname, const T &value)
1542 : Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
1543};
1544
1545template <typename Char, typename T>
1546struct NamedArgWithType : NamedArg<Char> {
1547 NamedArgWithType(BasicStringRef<Char> argname, const T &value)
1548 : NamedArg<Char>(argname, value) {}
1549};
1550
1551class RuntimeError : public std::runtime_error {
1552 protected:
1553 RuntimeError() : std::runtime_error("") {}
1554 RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {}
1556};
1557
1558template <typename Char>
1559class ArgMap;
1560} // namespace internal
1561
1562/** An argument list. */
1563class ArgList {
1564 private:
1565 // To reduce compiled code size per formatting function call, types of first
1566 // MAX_PACKED_ARGS arguments are passed in the types_ field.
1567 uint64_t types_;
1568 union {
1569 // If the number of arguments is less than MAX_PACKED_ARGS, the argument
1570 // values are stored in values_, otherwise they are stored in args_.
1571 // This is done to reduce compiled code size as storing larger objects
1572 // may require more code (at least on x86-64) even if the same amount of
1573 // data is actually copied to stack. It saves ~10% on the bloat test.
1576 };
1577
1578 internal::Arg::Type type(unsigned index) const {
1579 return type(types_, index);
1580 }
1581
1582 template <typename Char>
1583 friend class internal::ArgMap;
1584
1585 public:
1586 // Maximum number of arguments with packed types.
1587 enum { MAX_PACKED_ARGS = 16 };
1588
1589 ArgList() : types_(0) {}
1590
1591 ArgList(ULongLong types, const internal::Value *values)
1592 : types_(types), values_(values) {}
1593 ArgList(ULongLong types, const internal::Arg *args)
1594 : types_(types), args_(args) {}
1595
1596 uint64_t types() const { return types_; }
1597
1598 /** Returns the argument at specified index. */
1599 internal::Arg operator[](unsigned index) const {
1600 using internal::Arg;
1601 Arg arg;
1602 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1603 if (index < MAX_PACKED_ARGS) {
1604 Arg::Type arg_type = type(index);
1605 internal::Value &val = arg;
1606 if (arg_type != Arg::NONE)
1607 val = use_values ? values_[index] : args_[index];
1608 arg.type = arg_type;
1609 return arg;
1610 }
1611 if (use_values) {
1612 // The index is greater than the number of arguments that can be stored
1613 // in values, so return a "none" argument.
1614 arg.type = Arg::NONE;
1615 return arg;
1616 }
1617 for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1618 if (args_[i].type == Arg::NONE)
1619 return args_[i];
1620 }
1621 return args_[index];
1622 }
1623
1624 static internal::Arg::Type type(uint64_t types, unsigned index) {
1625 unsigned shift = index * 4;
1626 uint64_t mask = 0xf;
1627 return static_cast<internal::Arg::Type>(
1628 (types & (mask << shift)) >> shift);
1629 }
1630};
1631
1632#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
1633
1634/**
1635 \rst
1636 An argument visitor based on the `curiously recurring template pattern
1637 <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
1638
1639 To use `~fmt::ArgVisitor` define a subclass that implements some or all of the
1640 visit methods with the same signatures as the methods in `~fmt::ArgVisitor`,
1641 for example, `~fmt::ArgVisitor::visit_int()`.
1642 Pass the subclass as the *Impl* template parameter. Then calling
1643 `~fmt::ArgVisitor::visit` for some argument will dispatch to a visit method
1644 specific to the argument type. For example, if the argument type is
1645 ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
1646 will be called. If the subclass doesn't contain a method with this signature,
1647 then a corresponding method of `~fmt::ArgVisitor` will be called.
1648
1649 **Example**::
1650
1651 class MyArgVisitor : public fmt::ArgVisitor<MyArgVisitor, void> {
1652 public:
1653 void visit_int(int value) { fmt::print("{}", value); }
1654 void visit_double(double value) { fmt::print("{}", value ); }
1655 };
1656 \endrst
1657 */
1658template <typename Impl, typename Result>
1660 private:
1661 typedef internal::Arg Arg;
1662
1663 public:
1665
1668 return Result();
1669 }
1670
1671 /** Visits an ``int`` argument. **/
1672 Result visit_int(int value) {
1674 }
1675
1676 /** Visits a ``long long`` argument. **/
1679 }
1680
1681 /** Visits an ``unsigned`` argument. **/
1682 Result visit_uint(unsigned value) {
1684 }
1685
1686 /** Visits an ``unsigned long long`` argument. **/
1689 }
1690
1691 /** Visits a ``bool`` argument. **/
1692 Result visit_bool(bool value) {
1694 }
1695
1696 /** Visits a ``char`` or ``wchar_t`` argument. **/
1697 Result visit_char(int value) {
1699 }
1700
1701 /** Visits an argument of any integral type. **/
1702 template <typename T>
1703 Result visit_any_int(T) {
1705 }
1706
1707 /** Visits a ``double`` argument. **/
1708 Result visit_double(double value) {
1710 }
1711
1712 /** Visits a ``long double`` argument. **/
1713 Result visit_long_double(long double value) {
1715 }
1716
1717 /** Visits a ``double`` or ``long double`` argument. **/
1718 template <typename T>
1721 }
1722
1723 /** Visits a null-terminated C string (``const char *``) argument. **/
1724 Result visit_cstring(const char *) {
1726 }
1727
1728 /** Visits a string argument. **/
1731 }
1732
1733 /** Visits a wide string argument. **/
1734 Result visit_wstring(Arg::StringValue<wchar_t>) {
1736 }
1737
1738 /** Visits a pointer argument. **/
1739 Result visit_pointer(const void *) {
1741 }
1742
1743 /** Visits an argument of a custom (user-defined) type. **/
1746 }
1747
1748 /**
1749 \rst
1750 Visits an argument dispatching to the appropriate visit method based on
1751 the argument type. For example, if the argument type is ``double`` then
1752 the `~fmt::ArgVisitor::visit_double()` method of the *Impl* class will be
1753 called.
1754 \endrst
1755 */
1756 Result visit(const Arg &arg) {
1757 switch (arg.type) {
1758 case Arg::NONE:
1759 case Arg::NAMED_ARG:
1760 FMT_ASSERT(false, "invalid argument type");
1761 break;
1762 case Arg::INT:
1764 case Arg::UINT:
1766 case Arg::LONG_LONG:
1768 case Arg::ULONG_LONG:
1770 case Arg::BOOL:
1771 return FMT_DISPATCH(visit_bool(arg.int_value != 0));
1772 case Arg::CHAR:
1774 case Arg::DOUBLE:
1776 case Arg::LONG_DOUBLE:
1778 case Arg::CSTRING:
1780 case Arg::STRING:
1782 case Arg::WSTRING:
1784 case Arg::POINTER:
1786 case Arg::CUSTOM:
1788 }
1789 return Result();
1790 }
1791};
1792
1796
1797// Flags.
1798enum {
1800 CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
1802
1803// An empty format specifier.
1804struct EmptySpec {};
1805
1806// A type specifier.
1807template <char TYPE>
1809 Alignment align() const { return ALIGN_DEFAULT; }
1810 unsigned width() const { return 0; }
1811 int precision() const { return -1; }
1812 bool flag(unsigned) const { return false; }
1813 char type() const { return TYPE; }
1814 char type_prefix() const { return TYPE; }
1815 char fill() const { return ' '; }
1816};
1817
1818// A width specifier.
1820 unsigned width_;
1821 // Fill is always wchar_t and cast to char if necessary to avoid having
1822 // two specialization of WidthSpec and its subclasses.
1823 wchar_t fill_;
1824
1825 WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {}
1826
1827 unsigned width() const { return width_; }
1828 wchar_t fill() const { return fill_; }
1829};
1830
1831// An alignment specifier.
1834
1835 AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT)
1836 : WidthSpec(width, fill), align_(align) {}
1837
1838 Alignment align() const { return align_; }
1839
1840 int precision() const { return -1; }
1841};
1842
1843// An alignment and type specifier.
1844template <char TYPE>
1846 AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {}
1847
1848 bool flag(unsigned) const { return false; }
1849 char type() const { return TYPE; }
1850 char type_prefix() const { return TYPE; }
1851};
1852
1853// A full format specifier.
1855 unsigned flags_;
1857 char type_;
1858
1860 unsigned width = 0, char type = 0, wchar_t fill = ' ')
1861 : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1862
1863 bool flag(unsigned f) const { return (flags_ & f) != 0; }
1864 int precision() const { return precision_; }
1865 char type() const { return type_; }
1866 char type_prefix() const { return type_; }
1867};
1868
1869// An integer format specifier.
1870template <typename T, typename SpecT = TypeSpec<0>, typename Char = char>
1871class IntFormatSpec : public SpecT {
1872 private:
1874
1875 public:
1876 IntFormatSpec(T val, const SpecT &spec = SpecT())
1877 : SpecT(spec), value_(val) {}
1878
1879 T value() const { return value_; }
1880};
1881
1882// A string format specifier.
1883template <typename Char>
1884class StrFormatSpec : public AlignSpec {
1885 private:
1886 const Char *str_;
1887
1888 public:
1889 template <typename FillChar>
1890 StrFormatSpec(const Char *str, unsigned width, FillChar fill)
1891 : AlignSpec(width, fill), str_(str) {
1892 internal::CharTraits<Char>::convert(FillChar());
1893 }
1894
1895 const Char *str() const { return str_; }
1896};
1897
1898/**
1899 Returns an integer format specifier to format the value in base 2.
1900 */
1901IntFormatSpec<int, TypeSpec<'b'> > bin(int value);
1902
1903/**
1904 Returns an integer format specifier to format the value in base 8.
1905 */
1906IntFormatSpec<int, TypeSpec<'o'> > oct(int value);
1907
1908/**
1909 Returns an integer format specifier to format the value in base 16 using
1910 lower-case letters for the digits above 9.
1911 */
1912IntFormatSpec<int, TypeSpec<'x'> > hex(int value);
1913
1914/**
1915 Returns an integer formatter format specifier to format in base 16 using
1916 upper-case letters for the digits above 9.
1917 */
1918IntFormatSpec<int, TypeSpec<'X'> > hexu(int value);
1919
1920/**
1921 \rst
1922 Returns an integer format specifier to pad the formatted argument with the
1923 fill character to the specified width using the default (right) numeric
1924 alignment.
1925
1926 **Example**::
1927
1928 MemoryWriter out;
1929 out << pad(hex(0xcafe), 8, '0');
1930 // out.str() == "0000cafe"
1931
1932 \endrst
1933 */
1934template <char TYPE_CODE, typename Char>
1935IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
1936 int value, unsigned width, Char fill = ' ');
1937
1938#define FMT_DEFINE_INT_FORMATTERS(TYPE) inline
1939 IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) {
1940 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
1941}
1942 inline
1943 IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) {
1944 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
1945}
1946 inline
1947 IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) {
1948 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
1949}
1950 inline
1951 IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) {
1952 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
1953}
1954 template
1955 <char TYPE_CODE> inline
1956 IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad(
1957 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) {
1958 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >(
1959 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
1960}
1961 \
1962/* For compatibility with older compilers we provide two overloads for pad, */\
1963/* one that takes a fill character and one that doesn't. In the future this */\
1964/* can be replaced with one overload making the template argument Char */\
1965/* default to char (C++11). */template
1966 <char TYPE_CODE, typename Char> inline
1967 IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad(
1968 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f,
1969 unsigned width, Char fill) {
1970 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>(
1971 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
1972}
1973 inline
1974 IntFormatSpec<TYPE, AlignTypeSpec<0> > pad(
1975 TYPE value, unsigned width) {
1976 return IntFormatSpec<TYPE, AlignTypeSpec<0> >(
1977 value, AlignTypeSpec<0>(width, ' ')); \
1978}
1979 template
1980 <typename Char> inline
1981 IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad(
1982 TYPE value, unsigned width, Char fill) {
1983 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>(
1984 value, AlignTypeSpec<0>(width, fill)); \
1985}
1986
1990FMT_DEFINE_INT_FORMATTERS(unsigned long)
1993
1994/**
1995 \rst
1996 Returns a string formatter that pads the formatted argument with the fill
1997 character to the specified width using the default (left) string alignment.
1998
1999 **Example**::
2000
2001 std::string s = str(MemoryWriter() << pad("abc", 8));
2002 // s == "abc "
2003
2004 \endrst
2005 */
2006template <typename Char>
2007inline StrFormatSpec<Char> pad(
2008 const Char *str, unsigned width, Char fill = ' ') {
2009 return StrFormatSpec<Char>(str, width, fill);
2010}
2011
2012inline StrFormatSpec<wchar_t> pad(
2013 const wchar_t *str, unsigned width, char fill = ' ') {
2014 return StrFormatSpec<wchar_t>(str, width, fill);
2015}
2016
2017namespace internal {
2018
2019template <typename Char>
2020class ArgMap {
2021 private:
2022 typedef std::vector<
2024 typedef typename MapType::value_type Pair;
2025
2027
2028 public:
2029 void init(const ArgList &args);
2030
2031 const internal::Arg *find(const fmt::BasicStringRef<Char> &name) const {
2032 // The list is unsorted, so just return the first matching name.
2033 for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
2034 it != end; ++it) {
2035 if (it->first == name)
2036 return &it->second;
2037 }
2038 return FMT_NULL;
2039 }
2040};
2041
2042template <typename Char>
2043void ArgMap<Char>::init(const ArgList &args) {
2044 if (!map_.empty())
2045 return;
2046 typedef internal::NamedArg<Char> NamedArg;
2047 const NamedArg *named_arg = FMT_NULL;
2048 bool use_values =
2050 if (use_values) {
2051 for (unsigned i = 0;/*nothing*/; ++i) {
2053 switch (arg_type) {
2054 case internal::Arg::NONE:
2055 return;
2056 case internal::Arg::NAMED_ARG:
2057 named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
2059 break;
2060 default:
2061 /*nothing*/;
2062 }
2063 }
2064 return;
2065 }
2066 for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
2068 if (arg_type == internal::Arg::NAMED_ARG) {
2069 named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
2071 }
2072 }
2073 for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
2074 switch (args.args_[i].type) {
2075 case internal::Arg::NONE:
2076 return;
2077 case internal::Arg::NAMED_ARG:
2078 named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
2080 break;
2081 default:
2082 /*nothing*/;
2083 }
2084 }
2085}
2086
2087template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
2088class ArgFormatterBase : public ArgVisitor<Impl, void> {
2089 private:
2090 BasicWriter<Char> &writer_;
2091 Spec &spec_;
2092
2094
2095 void write_pointer(const void *p) {
2097 spec_.type_ = 'x';
2098 writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
2099 }
2100
2101 // workaround MSVC two-phase lookup issue
2102 typedef internal::Arg Arg;
2103
2104 protected:
2105 BasicWriter<Char> &writer() { return writer_; }
2106 Spec &spec() { return spec_; }
2107
2108 void write(bool value) {
2109 const char *str_value = value ? "true" : "false";
2112 }
2113
2114 void write(const char *value) {
2115 Arg::StringValue<char> str = {value, value ? std::strlen(value) : 0};
2117 }
2118
2119 public:
2120 typedef Spec SpecType;
2121
2122 ArgFormatterBase(BasicWriter<Char> &w, Spec &s)
2123 : writer_(w), spec_(s) {}
2124
2125 template <typename T>
2127
2128 template <typename T>
2130
2131 void visit_bool(bool value) {
2132 if (spec_.type_) {
2134 return;
2135 }
2136 write(value);
2137 }
2138
2139 void visit_char(int value) {
2140 if (spec_.type_ && spec_.type_ != 'c') {
2143 return;
2144 }
2145 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
2146 FMT_THROW(FormatError("invalid format specifier for char"));
2147 typedef typename BasicWriter<Char>::CharPtr CharPtr;
2149 CharPtr out = CharPtr();
2150 const unsigned CHAR_SIZE = 1;
2151 if (spec_.width_ > CHAR_SIZE) {
2153 if (spec_.align_ == ALIGN_RIGHT) {
2156 } else if (spec_.align_ == ALIGN_CENTER) {
2159 } else {
2162 }
2163 } else {
2165 }
2167 }
2168
2169 void visit_cstring(const char *value) {
2170 if (spec_.type_ == 'p')
2171 return write_pointer(value);
2172 write(value);
2173 }
2174
2175 // Qualification with "internal" here and below is a workaround for nvcc.
2176 void visit_string(internal::Arg::StringValue<char> value) {
2178 }
2179
2180 using ArgVisitor<Impl, void>::visit_wstring;
2181
2184 }
2185
2186 void visit_pointer(const void *value) {
2187 if (spec_.type_ && spec_.type_ != 'p')
2188 report_unknown_type(spec_.type_, "pointer");
2190 }
2191};
2192
2194 private:
2197
2198 // Returns the argument with specified index.
2199 FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
2200
2201 protected:
2202 const ArgList &args() const { return args_; }
2203
2204 explicit FormatterBase(const ArgList &args) {
2205 args_ = args;
2206 next_arg_index_ = 0;
2207 }
2208
2209 // Returns the next argument.
2210 Arg next_arg(const char *&error) {
2211 if (next_arg_index_ >= 0)
2213 error = "cannot switch from manual to automatic argument indexing";
2214 return Arg();
2215 }
2216
2217 // Checks if manual indexing is used and returns the argument with
2218 // specified index.
2219 Arg get_arg(unsigned arg_index, const char *&error) {
2220 return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
2221 }
2222
2223 bool check_no_auto_index(const char *&error) {
2224 if (next_arg_index_ > 0) {
2225 error = "cannot switch from automatic to manual argument indexing";
2226 return false;
2227 }
2228 next_arg_index_ = -1;
2229 return true;
2230 }
2231
2232 template <typename Char>
2233 void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
2234 if (start != end)
2236 }
2237};
2238} // namespace internal
2239
2240/**
2241 \rst
2242 An argument formatter based on the `curiously recurring template pattern
2243 <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
2244
2245 To use `~fmt::BasicArgFormatter` define a subclass that implements some or
2246 all of the visit methods with the same signatures as the methods in
2247 `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
2248 Pass the subclass as the *Impl* template parameter. When a formatting
2249 function processes an argument, it will dispatch to a visit method
2250 specific to the argument type. For example, if the argument type is
2251 ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
2252 will be called. If the subclass doesn't contain a method with this signature,
2253 then a corresponding method of `~fmt::BasicArgFormatter` or its superclass
2254 will be called.
2255 \endrst
2256 */
2257template <typename Impl, typename Char, typename Spec = fmt::FormatSpec>
2258class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char, Spec> {
2259 private:
2260 BasicFormatter<Char, Impl> &formatter_;
2261 const Char *format_;
2262
2263 public:
2264 /**
2265 \rst
2266 Constructs an argument formatter object.
2267 *formatter* is a reference to the main formatter object, *spec* contains
2268 format specifier information for standard argument types, and *fmt* points
2269 to the part of the format string being parsed for custom argument types.
2270 \endrst
2271 */
2272 BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
2273 Spec &spec, const Char *fmt)
2276
2277 /** Formats an argument of a custom (user-defined) type. */
2280 }
2281};
2282
2283/** The default argument formatter. */
2284template <typename Char>
2285class ArgFormatter :
2286 public BasicArgFormatter<ArgFormatter<Char>, Char, FormatSpec> {
2287 public:
2288 /** Constructs an argument formatter object. */
2289 ArgFormatter(BasicFormatter<Char> &formatter,
2290 FormatSpec &spec, const Char *fmt)
2291 : BasicArgFormatter<ArgFormatter<Char>,
2292 Char, FormatSpec>(formatter, spec, fmt) {}
2293};
2294
2295/** This template formats data and writes the output to a writer. */
2296template <typename CharType, typename ArgFormatter>
2297class BasicFormatter : private internal::FormatterBase {
2298 public:
2299 /** The character type for the output. */
2300 typedef CharType Char;
2301
2302 private:
2303 BasicWriter<Char> &writer_;
2305
2307
2308 using internal::FormatterBase::get_arg;
2309
2310 // Checks if manual indexing is used and returns the argument with
2311 // specified name.
2312 internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error);
2313
2314 // Parses argument index and returns corresponding argument.
2316
2317 // Parses argument name and returns corresponding argument.
2319
2320 public:
2321 /**
2322 \rst
2323 Constructs a ``BasicFormatter`` object. References to the arguments and
2324 the writer are stored in the formatter object so make sure they have
2325 appropriate lifetimes.
2326 \endrst
2327 */
2328 BasicFormatter(const ArgList &args, BasicWriter<Char> &w)
2329 : internal::FormatterBase(args), writer_(w) {}
2330
2331 /** Returns a reference to the writer associated with this formatter. */
2332 BasicWriter<Char> &writer() { return writer_; }
2333
2334 /** Formats stored arguments and writes the output to the writer. */
2335 void format(BasicCStringRef<Char> format_str);
2336
2337 // Formats a single argument and advances format_str, a format string pointer.
2338 const Char *format(const Char *&format_str, const internal::Arg &arg);
2339};
2340
2341// Generates a comma-separated list with results of applying f to
2342// numbers 0..n-1.
2343# define FMT_GEN(n, f) FMT_GEN##n(f)
2344# define FMT_GEN1(f) f(0)
2345# define FMT_GEN2(f) FMT_GEN1(f), f(1)
2346# define FMT_GEN3(f) FMT_GEN2(f), f(2)
2347# define FMT_GEN4(f) FMT_GEN3(f), f(3)
2348# define FMT_GEN5(f) FMT_GEN4(f), f(4)
2349# define FMT_GEN6(f) FMT_GEN5(f), f(5)
2350# define FMT_GEN7(f) FMT_GEN6(f), f(6)
2351# define FMT_GEN8(f) FMT_GEN7(f), f(7)
2352# define FMT_GEN9(f) FMT_GEN8(f), f(8)
2353# define FMT_GEN10(f) FMT_GEN9(f), f(9)
2354# define FMT_GEN11(f) FMT_GEN10(f), f(10)
2355# define FMT_GEN12(f) FMT_GEN11(f), f(11)
2356# define FMT_GEN13(f) FMT_GEN12(f), f(12)
2357# define FMT_GEN14(f) FMT_GEN13(f), f(13)
2358# define FMT_GEN15(f) FMT_GEN14(f), f(14)
2359
2360namespace internal {
2361inline uint64_t make_type() { return 0; }
2362
2363template <typename T>
2364inline uint64_t make_type(const T &arg) {
2365 return MakeValue< BasicFormatter<char> >::type(arg);
2366}
2367
2368template <std::size_t N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
2369struct ArgArray;
2370
2371template <std::size_t N>
2372struct ArgArray<N, true/*IsPacked*/> {
2373 // '+' is used to silence GCC -Wduplicated-branches warning.
2374 typedef Value Type[N > 0 ? N : +1];
2375
2376 template <typename Formatter, typename T>
2377 static Value make(const T &value) {
2378#ifdef __clang__
2379 Value result = MakeValue<Formatter>(value);
2380 // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
2381 // https://github.com/fmtlib/fmt/issues/276
2382 (void)result.custom.format;
2383 return result;
2384#else
2385 return MakeValue<Formatter>(value);
2386#endif
2387 }
2388};
2389
2390template <std::size_t N>
2391struct ArgArray<N, false/*IsPacked*/> {
2392 typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
2393
2394 template <typename Formatter, typename T>
2395 static Arg make(const T &value) { return MakeArg<Formatter>(value); }
2396};
2397
2399template <typename Arg, typename... Args>
2400inline uint64_t make_type(const Arg &first, const Args & ... tail) {
2401 return make_type(first) | (make_type(tail...) << 4);
2402}
2403
2404#else
2405
2406struct ArgType {
2408
2409 ArgType() : type(0) {}
2410
2411 template <typename T>
2413};
2414
2415# define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
2416
2418 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
2419 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
2420 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
2421 (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
2422}
2423#endif
2424} // namespace internal
2425
2426# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
2427# define FMT_MAKE_ARG_TYPE(n) T##n
2428# define FMT_MAKE_ARG(n) const T##n &v##n
2429# define FMT_ASSIGN_char(n)
2430 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
2431# define FMT_ASSIGN_wchar_t(n)
2432 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
2433
2435// Defines a variadic function returning void.
2436# define FMT_VARIADIC_VOID(func, arg_type)
2437 template <typename... Args>
2438 void func(arg_type arg0, const Args & ... args) {
2439 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray;
2440 typename ArgArray::Type array{
2441 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...};
2442 func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array));
2443 }
2444
2445// Defines a variadic constructor.
2446# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type)
2447 template <typename... Args>
2448 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) {
2449 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray;
2450 typename ArgArray::Type array{
2451 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...};
2452 func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array));
2453 }
2454
2455#else
2456
2457# define FMT_MAKE_REF(n)
2458 fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
2459# define FMT_MAKE_REF2(n) v##n
2460
2461// Defines a wrapper for a function taking one argument of type arg_type
2462// and n additional arguments of arbitrary types.
2463# define FMT_WRAP1(func, arg_type, n)
2464 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)>
2465 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) {
2466 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)};
2467 func(arg1, fmt::ArgList(
2468 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array));
2469 }
2470
2471// Emulates a variadic function returning void on a pre-C++11 compiler.
2472# define FMT_VARIADIC_VOID(func, arg_type)
2473 inline void func(arg_type arg) { func(arg, fmt::ArgList()); }
2474 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2)
2475 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4)
2476 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6)
2477 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8)
2478 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
2479
2480# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n)
2481 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)>
2482 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) {
2483 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)};
2484 func(arg0, arg1, fmt::ArgList(
2485 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array));
2486 }
2487
2488// Emulates a variadic constructor on a pre-C++11 compiler.
2489# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type)
2490 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1)
2491 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2)
2492 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3)
2493 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4)
2494 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5)
2495 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6)
2496 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7)
2497 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8)
2498 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9)
2499 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
2500#endif
2501
2502// Generates a comma-separated list with results of applying f to pairs
2503// (argument, index).
2504#define FMT_FOR_EACH1(f, x0) f(x0, 0)
2505#define FMT_FOR_EACH2(f, x0, x1)
2506 FMT_FOR_EACH1(f, x0), f(x1, 1)
2507#define FMT_FOR_EACH3(f, x0, x1, x2)
2508 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
2509#define FMT_FOR_EACH4(f, x0, x1, x2, x3)
2510 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
2511#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4)
2512 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
2513#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5)
2514 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
2515#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6)
2516 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
2517#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7)
2518 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
2519#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8)
2520 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
2521#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)
2522 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
2523
2524/**
2525 An error returned by an operating system or a language runtime,
2526 for example a file opening error.
2527*/
2529 private:
2530 FMT_API void init(int err_code, CStringRef format_str, ArgList args);
2531
2532 protected:
2534
2535 typedef char Char; // For FMT_VARIADIC_CTOR.
2536
2538
2539 public:
2540 /**
2541 \rst
2542 Constructs a :class:`fmt::SystemError` object with a description
2543 formatted with `fmt::format_system_error`. *message* and additional
2544 arguments passed into the constructor are formatted similarly to
2545 `fmt::format`.
2546
2547 **Example**::
2548
2549 // This throws a SystemError with the description
2550 // cannot open file 'madeup': No such file or directory
2551 // or similar (system message may vary).
2552 const char *filename = "madeup";
2553 std::FILE *file = std::fopen(filename, "r");
2554 if (!file)
2555 throw fmt::SystemError(errno, "cannot open file '{}'", filename);
2556 \endrst
2557 */
2558 SystemError(int error_code, CStringRef message) {
2559 init(error_code, message, ArgList());
2560 }
2562 FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
2563
2565
2566 int error_code() const { return error_code_; }
2567};
2568
2569/**
2570 \rst
2571 Formats an error returned by an operating system or a language runtime,
2572 for example a file opening error, and writes it to *out* in the following
2573 form:
2574
2575 .. parsed-literal::
2576 *<message>*: *<system-message>*
2577
2578 where *<message>* is the passed message and *<system-message>* is
2579 the system message corresponding to the error code.
2580 *error_code* is a system error code as given by ``errno``.
2581 If *error_code* is not a valid error code such as -1, the system message
2582 may look like "Unknown error -1" and is platform-dependent.
2583 \endrst
2584 */
2585FMT_API void format_system_error(fmt::Writer &out, int error_code,
2586 fmt::StringRef message) FMT_NOEXCEPT;
2587
2588/**
2589 \rst
2590 This template provides operations for formatting and writing data into
2591 a character stream. The output is stored in a buffer provided by a subclass
2592 such as :class:`fmt::BasicMemoryWriter`.
2593
2594 You can use one of the following typedefs for common character types:
2595
2596 +---------+----------------------+
2597 | Type | Definition |
2598 +=========+======================+
2599 | Writer | BasicWriter<char> |
2600 +---------+----------------------+
2601 | WWriter | BasicWriter<wchar_t> |
2602 +---------+----------------------+
2603
2604 \endrst
2605 */
2606template <typename Char>
2607class BasicWriter {
2608 private:
2609 // Output buffer.
2611
2613
2614 typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
2615
2617 // Returns pointer value.
2618 static Char *get(CharPtr p) { return p.base(); }
2619#else
2620 static Char *get(Char *p) { return p; }
2621#endif
2622
2623 // Fills the padding around the content and returns the pointer to the
2624 // content area.
2626 unsigned total_size, std::size_t content_size, wchar_t fill);
2627
2628 // Grows the buffer by n characters and returns a pointer to the newly
2629 // allocated area.
2631 std::size_t size = buffer_.size();
2632 buffer_.resize(size + n);
2633 return internal::make_ptr(&buffer_[size], n);
2634 }
2635
2636 // Writes an unsigned decimal integer.
2637 template <typename UInt>
2638 Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) {
2639 unsigned num_digits = internal::count_digits(value);
2640 Char *ptr = get(grow_buffer(prefix_size + num_digits));
2641 internal::format_decimal(ptr + prefix_size, value, num_digits);
2642 return ptr;
2643 }
2644
2645 // Writes a decimal integer.
2646 template <typename Int>
2647 void write_decimal(Int value) {
2648 typedef typename internal::IntTraits<Int>::MainType MainType;
2649 MainType abs_value = static_cast<MainType>(value);
2650 if (internal::is_negative(value)) {
2651 abs_value = 0 - abs_value;
2652 *write_unsigned_decimal(abs_value, 1) = '-';
2653 } else {
2654 write_unsigned_decimal(abs_value, 0);
2655 }
2656 }
2657
2658 // Prepare a buffer for integer formatting.
2659 CharPtr prepare_int_buffer(unsigned num_digits,
2660 const EmptySpec &, const char *prefix, unsigned prefix_size) {
2661 unsigned size = prefix_size + num_digits;
2662 CharPtr p = grow_buffer(size);
2663 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2664 return p + size - 1;
2665 }
2666
2667 template <typename Spec>
2668 CharPtr prepare_int_buffer(unsigned num_digits,
2669 const Spec &spec, const char *prefix, unsigned prefix_size);
2670
2671 // Formats an integer.
2672 template <typename T, typename Spec>
2673 void write_int(T value, Spec spec);
2674
2675 // Formats a floating-point number (double or long double).
2676 template <typename T, typename Spec>
2677 void write_double(T value, const Spec &spec);
2678
2679 // Writes a formatted string.
2680 template <typename StrChar>
2681 CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
2682
2683 template <typename StrChar, typename Spec>
2684 void write_str(const internal::Arg::StringValue<StrChar> &str,
2685 const Spec &spec);
2686
2687 // This following methods are private to disallow writing wide characters
2688 // and strings to a char stream. If you want to print a wide string as a
2689 // pointer as std::ostream does, cast it to const void*.
2690 // Do not implement!
2691 void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported);
2692 void operator<<(
2693 typename internal::WCharHelper<const wchar_t *, Char>::Unsupported);
2694
2695 // Appends floating-point length specifier to the format string.
2696 // The second argument is only used for overload resolution.
2697 void append_float_length(Char *&format_ptr, long double) {
2698 *format_ptr++ = 'L';
2699 }
2700
2701 template<typename T>
2702 void append_float_length(Char *&, T) {}
2703
2704 template <typename Impl, typename Char_, typename Spec_>
2706
2707 template <typename Impl, typename Char_, typename Spec_>
2709
2710 protected:
2711 /**
2712 Constructs a ``BasicWriter`` object.
2713 */
2714 explicit BasicWriter(Buffer<Char> &b) : buffer_(b) {}
2715
2716 public:
2717 /**
2718 \rst
2719 Destroys a ``BasicWriter`` object.
2720 \endrst
2721 */
2722 virtual ~BasicWriter() {}
2723
2724 /**
2725 Returns the total number of characters written.
2726 */
2727 std::size_t size() const { return buffer_.size(); }
2728
2729 /**
2730 Returns a pointer to the output buffer content. No terminating null
2731 character is appended.
2732 */
2733 const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
2734
2735 /**
2736 Returns a pointer to the output buffer content with terminating null
2737 character appended.
2738 */
2739 const Char *c_str() const {
2740 std::size_t size = buffer_.size();
2741 buffer_.reserve(size + 1);
2742 buffer_[size] = '\0';
2743 return &buffer_[0];
2744 }
2745
2746 /**
2747 \rst
2748 Returns the content of the output buffer as an `std::string`.
2749 \endrst
2750 */
2752 return std::basic_string<Char>(&buffer_[0], buffer_.size());
2753 }
2754
2755 /**
2756 \rst
2757 Writes formatted data.
2758
2759 *args* is an argument list representing arbitrary arguments.
2760
2761 **Example**::
2762
2763 MemoryWriter out;
2764 out.write("Current point:\n");
2765 out.write("({:+f}, {:+f})", -3.14, 3.14);
2766
2767 This will write the following output to the ``out`` object:
2768
2769 .. code-block:: none
2770
2771 Current point:
2772 (-3.140000, +3.140000)
2773
2774 The output can be accessed using :func:`data()`, :func:`c_str` or
2775 :func:`str` methods.
2776
2777 See also :ref:`syntax`.
2778 \endrst
2779 */
2780 void write(BasicCStringRef<Char> format, ArgList args) {
2781 BasicFormatter<Char>(args, *this).format(format);
2782 }
2784
2785 BasicWriter &operator<<(int value) {
2786 write_decimal(value);
2787 return *this;
2788 }
2789 BasicWriter &operator<<(unsigned value) {
2790 return *this << IntFormatSpec<unsigned>(value);
2791 }
2792 BasicWriter &operator<<(long value) {
2793 write_decimal(value);
2794 return *this;
2795 }
2796 BasicWriter &operator<<(unsigned long value) {
2797 return *this << IntFormatSpec<unsigned long>(value);
2798 }
2799 BasicWriter &operator<<(LongLong value) {
2800 write_decimal(value);
2801 return *this;
2802 }
2803
2804 /**
2805 \rst
2806 Formats *value* and writes it to the stream.
2807 \endrst
2808 */
2809 BasicWriter &operator<<(ULongLong value) {
2810 return *this << IntFormatSpec<ULongLong>(value);
2811 }
2812
2813 BasicWriter &operator<<(double value) {
2814 write_double(value, FormatSpec());
2815 return *this;
2816 }
2817
2818 /**
2819 \rst
2820 Formats *value* using the general format for floating-point numbers
2821 (``'g'``) and writes it to the stream.
2822 \endrst
2823 */
2824 BasicWriter &operator<<(long double value) {
2825 write_double(value, FormatSpec());
2826 return *this;
2827 }
2828
2829 /**
2830 Writes a character to the stream.
2831 */
2832 BasicWriter &operator<<(char value) {
2833 buffer_.push_back(value);
2834 return *this;
2835 }
2836
2837 BasicWriter &operator<<(
2838 typename internal::WCharHelper<wchar_t, Char>::Supported value) {
2839 buffer_.push_back(value);
2840 return *this;
2841 }
2842
2843 /**
2844 \rst
2845 Writes *value* to the stream.
2846 \endrst
2847 */
2848 BasicWriter &operator<<(fmt::BasicStringRef<Char> value) {
2849 const Char *str = value.data();
2850 buffer_.append(str, str + value.size());
2851 return *this;
2852 }
2853
2854 BasicWriter &operator<<(
2855 typename internal::WCharHelper<StringRef, Char>::Supported value) {
2856 const char *str = value.data();
2857 buffer_.append(str, str + value.size());
2858 return *this;
2859 }
2860
2861 template <typename T, typename Spec, typename FillChar>
2862 BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) {
2863 internal::CharTraits<Char>::convert(FillChar());
2864 write_int(spec.value(), spec);
2865 return *this;
2866 }
2867
2868 template <typename StrChar>
2869 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) {
2870 const StrChar *s = spec.str();
2871 write_str(s, std::char_traits<Char>::length(s), spec);
2872 return *this;
2873 }
2874
2875 void clear() FMT_NOEXCEPT { buffer_.clear(); }
2876
2877 Buffer<Char> &buffer() FMT_NOEXCEPT { return buffer_; }
2878};
2879
2880template <typename Char>
2881template <typename StrChar>
2882typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
2883 const StrChar *s, std::size_t size, const AlignSpec &spec) {
2884 CharPtr out = CharPtr();
2885 if (spec.width() > size) {
2888 if (spec.align() == ALIGN_RIGHT) {
2890 out += spec.width() - size;
2891 } else if (spec.align() == ALIGN_CENTER) {
2893 } else {
2895 }
2896 } else {
2897 out = grow_buffer(size);
2898 }
2900 return out;
2901}
2902
2903template <typename Char>
2904template <typename StrChar, typename Spec>
2905void BasicWriter<Char>::write_str(
2906 const internal::Arg::StringValue<StrChar> &s, const Spec &spec) {
2907 // Check if StrChar is convertible to Char.
2909 if (spec.type_ && spec.type_ != 's')
2911 const StrChar *str_value = s.value;
2913 if (str_size == 0) {
2914 if (!str_value) {
2915 FMT_THROW(FormatError("string pointer is null"));
2916 }
2917 }
2918 std::size_t precision = static_cast<std::size_t>(spec.precision_);
2919 if (spec.precision_ >= 0 && precision < str_size)
2922}
2923
2924template <typename Char>
2925typename BasicWriter<Char>::CharPtr
2926 BasicWriter<Char>::fill_padding(
2927 CharPtr buffer, unsigned total_size,
2928 std::size_t content_size, wchar_t fill) {
2937 return content;
2938}
2939
2940template <typename Char>
2941template <typename Spec>
2942typename BasicWriter<Char>::CharPtr
2943 BasicWriter<Char>::prepare_int_buffer(
2944 unsigned num_digits, const Spec &spec,
2945 const char *prefix, unsigned prefix_size) {
2946 unsigned width = spec.width();
2949 if (spec.precision() > static_cast<int>(num_digits)) {
2950 // Octal prefix '0' is counted as a digit, so ignore it if precision
2951 // is specified.
2952 if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
2953 --prefix_size;
2954 unsigned number_size =
2957 if (number_size >= width)
2960 unsigned fill_size = width - number_size;
2961 if (align != ALIGN_LEFT) {
2964 }
2967 if (align == ALIGN_LEFT) {
2970 }
2971 return result;
2972 }
2973 unsigned size = prefix_size + num_digits;
2974 if (width <= size) {
2977 return p + size - 1;
2978 }
2980 CharPtr end = p + width;
2981 if (align == ALIGN_LEFT) {
2983 p += size;
2985 } else if (align == ALIGN_CENTER) {
2986 p = fill_padding(p, width, size, fill);
2988 p += size;
2989 } else {
2990 if (align == ALIGN_NUMERIC) {
2991 if (prefix_size != 0) {
2993 size -= prefix_size;
2994 }
2995 } else {
2997 }
2999 p = end;
3000 }
3001 return p - 1;
3002}
3003
3004template <typename Char>
3005template <typename T, typename Spec>
3006void BasicWriter<Char>::write_int(T value, Spec spec) {
3007 unsigned prefix_size = 0;
3008 typedef typename internal::IntTraits<T>::MainType UnsignedType;
3009 UnsignedType abs_value = static_cast<UnsignedType>(value);
3010 char prefix[4] = "";
3011 if (internal::is_negative(value)) {
3012 prefix[0] = '-';
3013 ++prefix_size;
3014 abs_value = 0 - abs_value;
3015 } else if (spec.flag(SIGN_FLAG)) {
3016 prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' ';
3017 ++prefix_size;
3018 }
3019 switch (spec.type()) {
3020 case 0: case 'd': {
3024 break;
3025 }
3026 case 'x': case 'X': {
3028 if (spec.flag(HASH_FLAG)) {
3029 prefix[prefix_size++] = '0';
3031 }
3032 unsigned num_digits = 0;
3033 do {
3034 ++num_digits;
3035 } while ((n >>= 4) != 0);
3038 n = abs_value;
3039 const char *digits = spec.type() == 'x' ?
3040 "0123456789abcdef" : "0123456789ABCDEF";
3041 do {
3042 *p-- = digits[n & 0xf];
3043 } while ((n >>= 4) != 0);
3044 break;
3045 }
3046 case 'b': case 'B': {
3048 if (spec.flag(HASH_FLAG)) {
3049 prefix[prefix_size++] = '0';
3051 }
3052 unsigned num_digits = 0;
3053 do {
3054 ++num_digits;
3055 } while ((n >>= 1) != 0);
3057 n = abs_value;
3058 do {
3059 *p-- = static_cast<Char>('0' + (n & 1));
3060 } while ((n >>= 1) != 0);
3061 break;
3062 }
3063 case 'o': {
3065 if (spec.flag(HASH_FLAG))
3066 prefix[prefix_size++] = '0';
3067 unsigned num_digits = 0;
3068 do {
3069 ++num_digits;
3070 } while ((n >>= 3) != 0);
3072 n = abs_value;
3073 do {
3074 *p-- = static_cast<Char>('0' + (n & 7));
3075 } while ((n >>= 3) != 0);
3076 break;
3077 }
3078 case 'n': {
3080 fmt::StringRef sep = "";
3081#if !(defined(ANDROID) || defined(__ANDROID__))
3083#endif
3084 unsigned size = static_cast<unsigned>(
3085 num_digits + sep.size() * ((num_digits - 1) / 3));
3088 break;
3089 }
3090 default:
3092 spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer");
3093 break;
3094 }
3095}
3096
3097template <typename Char>
3098template <typename T, typename Spec>
3099void BasicWriter<Char>::write_double(T value, const Spec &spec) {
3100 // Check type.
3101 char type = spec.type();
3102 bool upper = false;
3103 switch (type) {
3104 case 0:
3105 type = 'g';
3106 break;
3107 case 'e': case 'f': case 'g': case 'a':
3108 break;
3109 case 'F':
3110#if FMT_MSC_VER
3111 // MSVC's printf doesn't support 'F'.
3112 type = 'f';
3113#endif
3114 // Fall through.
3115 case 'E': case 'G': case 'A':
3116 upper = true;
3117 break;
3118 default:
3119 internal::report_unknown_type(type, "double");
3120 break;
3121 }
3122
3123 char sign = 0;
3124 // Use isnegative instead of value < 0 because the latter is always
3125 // false for NaN.
3126 if (internal::FPUtil::isnegative(static_cast<double>(value))) {
3127 sign = '-';
3128 value = -value;
3129 } else if (spec.flag(SIGN_FLAG)) {
3130 sign = spec.flag(PLUS_FLAG) ? '+' : ' ';
3131 }
3132
3134 // Format NaN ourselves because sprintf's output is not consistent
3135 // across platforms.
3136 std::size_t nan_size = 4;
3137 const char *nan = upper ? " NAN" : " nan";
3138 if (!sign) {
3139 --nan_size;
3140 ++nan;
3141 }
3143 if (sign)
3144 *out = sign;
3145 return;
3146 }
3147
3149 // Format infinity ourselves because sprintf's output is not consistent
3150 // across platforms.
3151 std::size_t inf_size = 4;
3152 const char *inf = upper ? " INF" : " inf";
3153 if (!sign) {
3154 --inf_size;
3155 ++inf;
3156 }
3158 if (sign)
3159 *out = sign;
3160 return;
3161 }
3162
3164 unsigned width = spec.width();
3165 if (sign) {
3166 buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u));
3167 if (width > 0)
3168 --width;
3169 ++offset;
3170 }
3171
3172 // Build format string.
3173 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
3176 *format_ptr++ = '%';
3177 unsigned width_for_sprintf = width;
3178 if (spec.flag(HASH_FLAG))
3179 *format_ptr++ = '#';
3180 if (spec.align() == ALIGN_CENTER) {
3182 } else {
3183 if (spec.align() == ALIGN_LEFT)
3184 *format_ptr++ = '-';
3185 if (width != 0)
3186 *format_ptr++ = '*';
3187 }
3188 if (spec.precision() >= 0) {
3189 *format_ptr++ = '.';
3190 *format_ptr++ = '*';
3191 }
3192
3194 *format_ptr++ = type;
3195 *format_ptr = '\0';
3196
3197 // Format using snprintf.
3199 unsigned n = 0;
3200 Char *start = FMT_NULL;
3201 for (;;) {
3203#if FMT_MSC_VER
3204 // MSVC's vsnprintf_s doesn't work with zero size, so reserve
3205 // space for at least one extra character to make the size non-zero.
3206 // Note that the buffer's capacity will increase by more than 1.
3207 if (buffer_size == 0) {
3208 buffer_.reserve(offset + 1);
3210 }
3211#endif
3212 start = &buffer_[offset];
3215 if (result >= 0) {
3217 if (offset + n < buffer_.capacity())
3218 break; // The buffer is large enough - continue with formatting.
3219 buffer_.reserve(offset + n + 1);
3220 } else {
3221 // If result is negative we ask to increase the capacity by at least 1,
3222 // but as std::vector, the buffer grows exponentially.
3224 }
3225 }
3226 if (sign) {
3227 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
3228 *start != ' ') {
3229 *(start - 1) = sign;
3230 sign = 0;
3231 } else {
3232 *(start - 1) = fill;
3233 }
3234 ++n;
3235 }
3236 if (spec.align() == ALIGN_CENTER && spec.width() > n) {
3237 width = spec.width();
3239 std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
3240 fill_padding(p, spec.width(), n, fill);
3241 return;
3242 }
3243 if (spec.fill() != ' ' || sign) {
3244 while (*start == ' ')
3245 *start++ = fill;
3246 if (sign)
3247 *(start - 1) = sign;
3248 }
3249 grow_buffer(n);
3250}
3251
3252/**
3253 \rst
3254 This class template provides operations for formatting and writing data
3255 into a character stream. The output is stored in a memory buffer that grows
3256 dynamically.
3257
3258 You can use one of the following typedefs for common character types
3259 and the standard allocator:
3260
3261 +---------------+-----------------------------------------------------+
3262 | Type | Definition |
3263 +===============+=====================================================+
3264 | MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
3265 +---------------+-----------------------------------------------------+
3266 | WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
3267 +---------------+-----------------------------------------------------+
3268
3269 **Example**::
3270
3271 MemoryWriter out;
3272 out << "The answer is " << 42 << "\n";
3273 out.write("({:+f}, {:+f})", -3.14, 3.14);
3274
3275 This will write the following output to the ``out`` object:
3276
3277 .. code-block:: none
3278
3279 The answer is 42
3280 (-3.140000, +3.140000)
3281
3282 The output can be converted to an ``std::string`` with ``out.str()`` or
3283 accessed as a C string with ``out.c_str()``.
3284 \endrst
3285 */
3286template <typename Char, typename Allocator = std::allocator<Char> >
3288 private:
3290
3291 public:
3294
3296 /**
3297 \rst
3298 Constructs a :class:`fmt::BasicMemoryWriter` object moving the content
3299 of the other object to it.
3300 \endrst
3301 */
3304 }
3305
3306 /**
3307 \rst
3308 Moves the content of the other ``BasicMemoryWriter`` object to this one.
3309 \endrst
3310 */
3313 return *this;
3314 }
3315#endif
3316};
3317
3320
3321/**
3322 \rst
3323 This class template provides operations for formatting and writing data
3324 into a fixed-size array. For writing into a dynamically growing buffer
3325 use :class:`fmt::BasicMemoryWriter`.
3326
3327 Any write method will throw ``std::runtime_error`` if the output doesn't fit
3328 into the array.
3329
3330 You can use one of the following typedefs for common character types:
3331
3332 +--------------+---------------------------+
3333 | Type | Definition |
3334 +==============+===========================+
3335 | ArrayWriter | BasicArrayWriter<char> |
3336 +--------------+---------------------------+
3337 | WArrayWriter | BasicArrayWriter<wchar_t> |
3338 +--------------+---------------------------+
3339 \endrst
3340 */
3341template <typename Char>
3342class BasicArrayWriter : public BasicWriter<Char> {
3343 private:
3345
3346 public:
3347 /**
3348 \rst
3349 Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
3350 given size.
3351 \endrst
3352 */
3353 BasicArrayWriter(Char *array, std::size_t size)
3355
3356 /**
3357 \rst
3358 Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
3359 size known at compile time.
3360 \endrst
3361 */
3362 template <std::size_t SIZE>
3363 explicit BasicArrayWriter(Char (&array)[SIZE])
3365};
3366
3369
3370// Reports a system error without throwing an exception.
3371// Can be used to report errors from destructors.
3372FMT_API void report_system_error(int error_code,
3373 StringRef message) FMT_NOEXCEPT;
3374
3376
3377/** A Windows error. */
3378class WindowsError : public SystemError {
3379 private:
3380 FMT_API void init(int error_code, CStringRef format_str, ArgList args);
3381
3382 public:
3383 /**
3384 \rst
3385 Constructs a :class:`fmt::WindowsError` object with the description
3386 of the form
3387
3388 .. parsed-literal::
3389 *<message>*: *<system-message>*
3390
3391 where *<message>* is the formatted message and *<system-message>* is the
3392 system message corresponding to the error code.
3393 *error_code* is a Windows error code as given by ``GetLastError``.
3394 If *error_code* is not a valid error code such as -1, the system message
3395 will look like "error -1".
3396
3397 **Example**::
3398
3399 // This throws a WindowsError with the description
3400 // cannot open file 'madeup': The system cannot find the file specified.
3401 // or similar (system message may vary).
3402 const char *filename = "madeup";
3403 LPOFSTRUCT of = LPOFSTRUCT();
3404 HFILE file = OpenFile(filename, &of, OF_READ);
3405 if (file == HFILE_ERROR) {
3406 throw fmt::WindowsError(GetLastError(),
3407 "cannot open file '{}'", filename);
3408 }
3409 \endrst
3410 */
3411 WindowsError(int error_code, CStringRef message) {
3412 init(error_code, message, ArgList());
3413 }
3414 FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef)
3415};
3416
3417// Reports a Windows error without throwing an exception.
3418// Can be used to report errors from destructors.
3419FMT_API void report_windows_error(int error_code,
3420 StringRef message) FMT_NOEXCEPT;
3421
3422#endif
3423
3425
3426/**
3427 Formats a string and prints it to stdout using ANSI escape sequences
3428 to specify color (experimental).
3429 Example:
3430 print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23);
3431 */
3432FMT_API void print_colored(Color c, CStringRef format, ArgList args);
3433
3434/**
3435 \rst
3436 Formats arguments and returns the result as a string.
3437
3438 **Example**::
3439
3440 std::string message = format("The answer is {}", 42);
3441 \endrst
3442*/
3444 MemoryWriter w;
3445 w.write(format_str, args);
3446 return w.str();
3447}
3448
3450 WMemoryWriter w;
3451 w.write(format_str, args);
3452 return w.str();
3453}
3454
3455/**
3456 \rst
3457 Prints formatted data to the file *f*.
3458
3459 **Example**::
3460
3461 print(stderr, "Don't {}!", "panic");
3462 \endrst
3463 */
3464FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
3465
3466/**
3467 \rst
3468 Prints formatted data to ``stdout``.
3469
3470 **Example**::
3471
3472 print("Elapsed time: {0:.2f} seconds", 1.23);
3473 \endrst
3474 */
3475FMT_API void print(CStringRef format_str, ArgList args);
3476
3477/**
3478 Fast integer formatter.
3479 */
3481 private:
3482 // Buffer should be large enough to hold all digits (digits10 + 1),
3483 // a sign and a null character.
3484 enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3};
3485 mutable char buffer_[BUFFER_SIZE];
3486 char *str_;
3487
3488 // Formats value in reverse and returns the number of digits.
3490 char *buffer_end = buffer_ + BUFFER_SIZE - 1;
3491 while (value >= 100) {
3492 // Integer division is slow so do it for a group of two digits instead
3493 // of for every digit. The idea comes from the talk by Alexandrescu
3494 // "Three Optimization Tips for C++". See speed-test for a comparison.
3495 unsigned index = static_cast<unsigned>((value % 100) * 2);
3496 value /= 100;
3497 *--buffer_end = internal::Data::DIGITS[index + 1];
3498 *--buffer_end = internal::Data::DIGITS[index];
3499 }
3500 if (value < 10) {
3501 *--buffer_end = static_cast<char>('0' + value);
3502 return buffer_end;
3503 }
3504 unsigned index = static_cast<unsigned>(value * 2);
3505 *--buffer_end = internal::Data::DIGITS[index + 1];
3506 *--buffer_end = internal::Data::DIGITS[index];
3507 return buffer_end;
3508 }
3509
3511 ULongLong abs_value = static_cast<ULongLong>(value);
3512 bool negative = value < 0;
3513 if (negative)
3514 abs_value = 0 - abs_value;
3515 str_ = format_decimal(abs_value);
3516 if (negative)
3517 *--str_ = '-';
3518 }
3519
3520 public:
3521 explicit FormatInt(int value) { FormatSigned(value); }
3522 explicit FormatInt(long value) { FormatSigned(value); }
3523 explicit FormatInt(LongLong value) { FormatSigned(value); }
3524 explicit FormatInt(unsigned value) : str_(format_decimal(value)) {}
3525 explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
3526 explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
3527
3528 /** Returns the number of characters written to the output buffer. */
3529 std::size_t size() const {
3531 }
3532
3533 /**
3534 Returns a pointer to the output buffer content. No terminating null
3535 character is appended.
3536 */
3537 const char *data() const { return str_; }
3538
3539 /**
3540 Returns a pointer to the output buffer content with terminating null
3541 character appended.
3542 */
3543 const char *c_str() const {
3544 buffer_[BUFFER_SIZE - 1] = '\0';
3545 return str_;
3546 }
3547
3548 /**
3549 \rst
3550 Returns the content of the output buffer as an ``std::string``.
3551 \endrst
3552 */
3553 std::string str() const { return std::string(str_, size()); }
3554};
3555
3556// Formats a decimal integer value writing into buffer and returns
3557// a pointer to the end of the formatted string. This function doesn't
3558// write a terminating null character.
3559template <typename T>
3560inline void format_decimal(char *&buffer, T value) {
3561 typedef typename internal::IntTraits<T>::MainType MainType;
3562 MainType abs_value = static_cast<MainType>(value);
3563 if (internal::is_negative(value)) {
3564 *buffer++ = '-';
3565 abs_value = 0 - abs_value;
3566 }
3567 if (abs_value < 100) {
3568 if (abs_value < 10) {
3569 *buffer++ = static_cast<char>('0' + abs_value);
3570 return;
3571 }
3572 unsigned index = static_cast<unsigned>(abs_value * 2);
3574 *buffer++ = internal::Data::DIGITS[index + 1];
3575 return;
3576 }
3579 buffer += num_digits;
3580}
3581
3582/**
3583 \rst
3584 Returns a named argument for formatting functions.
3585
3586 **Example**::
3587
3588 print("Elapsed time: {s:.2f} seconds", arg("s", 1.23));
3589
3590 \endrst
3591 */
3592template <typename T>
3593inline internal::NamedArgWithType<char, T> arg(StringRef name, const T &arg) {
3594 return internal::NamedArgWithType<char, T>(name, arg);
3595}
3596
3597template <typename T>
3598inline internal::NamedArgWithType<wchar_t, T> arg(WStringRef name, const T &arg) {
3599 return internal::NamedArgWithType<wchar_t, T>(name, arg);
3600}
3601
3602// The following two functions are deleted intentionally to disable
3603// nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``.
3604template <typename Char>
3605void arg(StringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3606template <typename Char>
3607void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3608}
3609
3611// Use the system_header pragma to suppress warnings about variadic macros
3612// because suppressing -Wvariadic-macros with the diagnostic pragma doesn't
3613// work. It is used at the end because we want to suppress as little warnings
3614// as possible.
3615# pragma GCC system_header
3616#endif
3617
3618// This is used to work around VC++ bugs in handling variadic macros.
3619#define FMT_EXPAND(args) args
3620
3621// Returns the number of arguments.
3622// Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s.
3623#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
3624#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
3625#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3626#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
3627
3628#define FMT_FOR_EACH_(N, f, ...)
3629 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
3630#define FMT_FOR_EACH(f, ...)
3631 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
3632
3633#define FMT_ADD_ARG_NAME(type, index) type arg##index
3634#define FMT_GET_ARG_NAME(type, index) arg##index
3635
3637# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...)
3638 template <typename... Args>
3639 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__),
3640 const Args & ... args) Const {
3641 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray;
3642 typename ArgArray::Type array{
3643 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...};
3644 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__),
3645 fmt::ArgList(fmt::internal::make_type(args...), array));
3646 }
3647#else
3648// Defines a wrapper for a function taking __VA_ARGS__ arguments
3649// and n additional arguments of arbitrary types.
3650# define FMT_WRAP(Const, Char, ReturnType, func, call, n, ...)
3651 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)>
3652 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__),
3653 FMT_GEN(n, FMT_MAKE_ARG)) Const {
3654 fmt::internal::ArgArray<n>::Type arr;
3655 FMT_GEN(n, FMT_ASSIGN_##Char);
3656 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList(
3657 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr));
3658 }
3659
3660# define FMT_VARIADIC_(Const, Char, ReturnType, func, call, ...)
3661 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) Const {
3662 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList());
3663 }
3664 FMT_WRAP(Const, Char, ReturnType, func, call, 1, __VA_ARGS__)
3665 FMT_WRAP(Const, Char, ReturnType, func, call, 2, __VA_ARGS__)
3666 FMT_WRAP(Const, Char, ReturnType, func, call, 3, __VA_ARGS__)
3667 FMT_WRAP(Const, Char, ReturnType, func, call, 4, __VA_ARGS__)
3668 FMT_WRAP(Const, Char, ReturnType, func, call, 5, __VA_ARGS__)
3669 FMT_WRAP(Const, Char, ReturnType, func, call, 6, __VA_ARGS__)
3670 FMT_WRAP(Const, Char, ReturnType, func, call, 7, __VA_ARGS__)
3671 FMT_WRAP(Const, Char, ReturnType, func, call, 8, __VA_ARGS__)
3672 FMT_WRAP(Const, Char, ReturnType, func, call, 9, __VA_ARGS__)
3673 FMT_WRAP(Const, Char, ReturnType, func, call, 10, __VA_ARGS__)
3674 FMT_WRAP(Const, Char, ReturnType, func, call, 11, __VA_ARGS__)
3675 FMT_WRAP(Const, Char, ReturnType, func, call, 12, __VA_ARGS__)
3676 FMT_WRAP(Const, Char, ReturnType, func, call, 13, __VA_ARGS__)
3677 FMT_WRAP(Const, Char, ReturnType, func, call, 14, __VA_ARGS__)
3678 FMT_WRAP(Const, Char, ReturnType, func, call, 15, __VA_ARGS__)
3679#endif // FMT_USE_VARIADIC_TEMPLATES
3680
3681/**
3682 \rst
3683 Defines a variadic function with the specified return type, function name
3684 and argument types passed as variable arguments to this macro.
3685
3686 **Example**::
3687
3688 void print_error(const char *file, int line, const char *format,
3689 fmt::ArgList args) {
3690 fmt::print("{}: {}: ", file, line);
3691 fmt::print(format, args);
3692 }
3693 FMT_VARIADIC(void, print_error, const char *, int, const char *)
3694
3695 ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that
3696 don't implement variadic templates. You don't have to use this macro if
3697 you don't need legacy compiler support and can use variadic templates
3698 directly::
3699
3700 template <typename... Args>
3701 void print_error(const char *file, int line, const char *format,
3702 const Args & ... args) {
3703 fmt::print("{}: {}: ", file, line);
3704 fmt::print(format, args...);
3705 }
3706 \endrst
3707 */
3708#define FMT_VARIADIC(ReturnType, func, ...)
3709 FMT_VARIADIC_(, char, ReturnType, func, return func, __VA_ARGS__)
3710
3711#define FMT_VARIADIC_CONST(ReturnType, func, ...)
3712 FMT_VARIADIC_(const, char, ReturnType, func, return func, __VA_ARGS__)
3713
3714#define FMT_VARIADIC_W(ReturnType, func, ...)
3715 FMT_VARIADIC_(, wchar_t, ReturnType, func, return func, __VA_ARGS__)
3716
3717#define FMT_VARIADIC_CONST_W(ReturnType, func, ...)
3718 FMT_VARIADIC_(const, wchar_t, ReturnType, func, return func, __VA_ARGS__)
3719
3720#define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
3721
3722#define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
3723
3724/**
3725 \rst
3726 Convenient macro to capture the arguments' names and values into several
3727 ``fmt::arg(name, value)``.
3728
3729 **Example**::
3730
3731 int x = 1, y = 2;
3732 print("point: ({x}, {y})", FMT_CAPTURE(x, y));
3733 // same as:
3734 // print("point: ({x}, {y})", arg("x", x), arg("y", y));
3735
3736 \endrst
3737 */
3738#define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
3739
3740#define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
3741
3742namespace fmt {
3743FMT_VARIADIC(std::string, format, CStringRef)
3744FMT_VARIADIC_W(std::wstring, format, WCStringRef)
3748
3749namespace internal {
3750template <typename Char>
3751inline bool is_name_start(Char c) {
3752 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
3753}
3754
3755// Parses an unsigned integer advancing s to the end of the parsed input.
3756// This function assumes that the first character of s is a digit.
3757template <typename Char>
3758unsigned parse_nonnegative_int(const Char *&s) {
3759 assert('0' <= *s && *s <= '9');
3760 unsigned value = 0;
3761 // Convert to unsigned to prevent a warning.
3762 unsigned max_int = (std::numeric_limits<int>::max)();
3763 unsigned big = max_int / 10;
3764 do {
3765 // Check for overflow.
3766 if (value > big) {
3767 value = max_int + 1;
3768 break;
3769 }
3770 value = value * 10 + (*s - '0');
3771 ++s;
3772 } while ('0' <= *s && *s <= '9');
3773 // Convert to unsigned to prevent a warning.
3774 if (value > max_int)
3775 FMT_THROW(FormatError("number is too big"));
3776 return value;
3777}
3778
3779inline void require_numeric_argument(const Arg &arg, char spec) {
3780 if (arg.type > Arg::LAST_NUMERIC_TYPE) {
3781 std::string message =
3782 fmt::format("format specifier '{}' requires numeric argument", spec);
3783 FMT_THROW(fmt::FormatError(message));
3784 }
3785}
3786
3787template <typename Char>
3788void check_sign(const Char *&s, const Arg &arg) {
3789 char sign = static_cast<char>(*s);
3791 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) {
3793 "format specifier '{}' requires signed argument", sign)));
3794 }
3795 ++s;
3796}
3797} // namespace internal
3798
3799template <typename Char, typename AF>
3800inline internal::Arg BasicFormatter<Char, AF>::get_arg(
3801 BasicStringRef<Char> arg_name, const char *&error) {
3803 map_.init(args());
3804 const internal::Arg *arg = map_.find(arg_name);
3805 if (arg)
3806 return *arg;
3807 error = "argument not found";
3808 }
3809 return internal::Arg();
3810}
3811
3812template <typename Char, typename AF>
3813inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s) {
3814 const char *error = FMT_NULL;
3815 internal::Arg arg = *s < '0' || *s > '9' ?
3817 if (error) {
3819 *s != '}' && *s != ':' ? "invalid format string" : error));
3820 }
3821 return arg;
3822}
3823
3824template <typename Char, typename AF>
3825inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s) {
3826 assert(internal::is_name_start(*s));
3827 const Char *start = s;
3828 Char c;
3829 do {
3830 c = *++s;
3831 } while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
3832 const char *error = FMT_NULL;
3834 if (error)
3836 return arg;
3837}
3838
3839template <typename Char, typename ArgFormatter>
3840const Char *BasicFormatter<Char, ArgFormatter>::format(
3841 const Char *&format_str, const internal::Arg &arg) {
3842 using internal::Arg;
3843 const Char *s = format_str;
3844 typename ArgFormatter::SpecType spec;
3845 if (*s == ':') {
3846 if (arg.type == Arg::CUSTOM) {
3847 arg.custom.format(this, arg.custom.value, &s);
3848 return s;
3849 }
3850 ++s;
3851 // Parse fill and alignment.
3852 if (Char c = *s) {
3853 const Char *p = s + 1;
3855 do {
3856 switch (*p) {
3857 case '<':
3859 break;
3860 case '>':
3862 break;
3863 case '=':
3865 break;
3866 case '^':
3868 break;
3869 }
3870 if (spec.align_ != ALIGN_DEFAULT) {
3871 if (p != s) {
3872 if (c == '}') break;
3873 if (c == '{')
3874 FMT_THROW(FormatError("invalid fill character '{'"));
3875 s += 2;
3876 spec.fill_ = c;
3877 } else ++s;
3878 if (spec.align_ == ALIGN_NUMERIC)
3880 break;
3881 }
3882 } while (--p >= s);
3883 }
3884
3885 // Parse sign.
3886 switch (*s) {
3887 case '+':
3888 check_sign(s, arg);
3890 break;
3891 case '-':
3892 check_sign(s, arg);
3894 break;
3895 case ' ':
3896 check_sign(s, arg);
3898 break;
3899 }
3900
3901 if (*s == '#') {
3904 ++s;
3905 }
3906
3907 // Parse zero flag.
3908 if (*s == '0') {
3911 spec.fill_ = '0';
3912 ++s;
3913 }
3914
3915 // Parse width.
3916 if ('0' <= *s && *s <= '9') {
3918 } else if (*s == '{') {
3919 ++s;
3922 if (*s++ != '}')
3923 FMT_THROW(FormatError("invalid format string"));
3924 ULongLong value = 0;
3925 switch (width_arg.type) {
3926 case Arg::INT:
3927 if (width_arg.int_value < 0)
3928 FMT_THROW(FormatError("negative width"));
3930 break;
3931 case Arg::UINT:
3933 break;
3934 case Arg::LONG_LONG:
3935 if (width_arg.long_long_value < 0)
3936 FMT_THROW(FormatError("negative width"));
3938 break;
3939 case Arg::ULONG_LONG:
3941 break;
3942 default:
3943 FMT_THROW(FormatError("width is not integer"));
3944 }
3945 unsigned max_int = (std::numeric_limits<int>::max)();
3946 if (value > max_int)
3947 FMT_THROW(FormatError("number is too big"));
3948 spec.width_ = static_cast<int>(value);
3949 }
3950
3951 // Parse precision.
3952 if (*s == '.') {
3953 ++s;
3954 spec.precision_ = 0;
3955 if ('0' <= *s && *s <= '9') {
3957 } else if (*s == '{') {
3958 ++s;
3961 if (*s++ != '}')
3962 FMT_THROW(FormatError("invalid format string"));
3963 ULongLong value = 0;
3964 switch (precision_arg.type) {
3965 case Arg::INT:
3966 if (precision_arg.int_value < 0)
3967 FMT_THROW(FormatError("negative precision"));
3969 break;
3970 case Arg::UINT:
3972 break;
3973 case Arg::LONG_LONG:
3975 FMT_THROW(FormatError("negative precision"));
3977 break;
3978 case Arg::ULONG_LONG:
3980 break;
3981 default:
3982 FMT_THROW(FormatError("precision is not integer"));
3983 }
3984 unsigned max_int = (std::numeric_limits<int>::max)();
3985 if (value > max_int)
3986 FMT_THROW(FormatError("number is too big"));
3987 spec.precision_ = static_cast<int>(value);
3988 } else {
3989 FMT_THROW(FormatError("missing precision specifier"));
3990 }
3991 if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
3993 fmt::format("precision not allowed in {} format specifier",
3994 arg.type == Arg::POINTER ? "pointer" : "integer")));
3995 }
3996 }
3997
3998 // Parse type.
3999 if (*s != '}' && *s)
4000 spec.type_ = static_cast<char>(*s++);
4001 }
4002
4003 if (*s++ != '}')
4004 FMT_THROW(FormatError("missing '}' in format string"));
4005
4006 // Format argument.
4007 ArgFormatter(*this, spec, s - 1).visit(arg);
4008 return s;
4009}
4010
4011template <typename Char, typename AF>
4012void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
4013 const Char *s = format_str.c_str();
4014 const Char *start = s;
4015 while (*s) {
4016 Char c = *s++;
4017 if (c != '{' && c != '}') continue;
4018 if (*s == c) {
4019 write(writer_, start, s);
4020 start = ++s;
4021 continue;
4022 }
4023 if (c == '}')
4024 FMT_THROW(FormatError("unmatched '}' in format string"));
4025 write(writer_, start, s - 1);
4028 start = s = format(s, arg);
4029 }
4030 write(writer_, start, s);
4031}
4032
4033template <typename Char, typename It>
4034struct ArgJoin {
4038
4039 ArgJoin(It first, It last, const BasicCStringRef<Char>& sep) :
4040 first(first),
4041 last(last),
4042 sep(sep) {}
4043};
4044
4045template <typename It>
4046ArgJoin<char, It> join(It first, It last, const BasicCStringRef<char>& sep) {
4047 return ArgJoin<char, It>(first, last, sep);
4048}
4049
4050template <typename It>
4051ArgJoin<wchar_t, It> join(It first, It last, const BasicCStringRef<wchar_t>& sep) {
4052 return ArgJoin<wchar_t, It>(first, last, sep);
4053}
4054
4056template <typename Range>
4057auto join(const Range& range, const BasicCStringRef<char>& sep)
4058 -> ArgJoin<char, decltype(std::begin(range))> {
4059 return join(std::begin(range), std::end(range), sep);
4060}
4061
4062template <typename Range>
4063auto join(const Range& range, const BasicCStringRef<wchar_t>& sep)
4064 -> ArgJoin<wchar_t, decltype(std::begin(range))> {
4065 return join(std::begin(range), std::end(range), sep);
4066}
4067#endif
4068
4069template <typename ArgFormatter, typename Char, typename It>
4070void format_arg(fmt::BasicFormatter<Char, ArgFormatter> &f,
4071 const Char *&format_str, const ArgJoin<Char, It>& e) {
4072 const Char* end = format_str;
4073 if (*end == ':')
4074 ++end;
4075 while (*end && *end != '}')
4076 ++end;
4077 if (*end != '}')
4078 FMT_THROW(FormatError("missing '}' in format string"));
4079
4080 It it = e.first;
4081 if (it != e.last) {
4082 const Char* save = format_str;
4084 while (it != e.last) {
4085 f.writer().write(e.sep);
4086 format_str = save;
4088 }
4089 }
4090 format_str = end + 1;
4091}
4092} // namespace fmt
4093
4095namespace fmt {
4096namespace internal {
4097
4098template <typename Char>
4099struct UdlFormat {
4100 const Char *str;
4101
4102 template <typename... Args>
4103 auto operator()(Args && ... args) const
4104 -> decltype(format(str, std::forward<Args>(args)...)) {
4105 return format(str, std::forward<Args>(args)...);
4106 }
4107};
4108
4109template <typename Char>
4110struct UdlArg {
4111 const Char *str;
4112
4113 template <typename T>
4114 NamedArgWithType<Char, T> operator=(T &&value) const {
4115 return {str, std::forward<T>(value)};
4116 }
4117};
4118
4119} // namespace internal
4120
4121inline namespace literals {
4122
4123/**
4124 \rst
4125 C++11 literal equivalent of :func:`fmt::format`.
4126
4127 **Example**::
4128
4129 using namespace fmt::literals;
4130 std::string message = "The answer is {}"_format(42);
4131 \endrst
4132 */
4133inline internal::UdlFormat<char>
4134operator"" _format(const char *s, std::size_t) { return {s}; }
4135inline internal::UdlFormat<wchar_t>
4136operator"" _format(const wchar_t *s, std::size_t) { return {s}; }
4137
4138/**
4139 \rst
4140 C++11 literal equivalent of :func:`fmt::arg`.
4141
4142 **Example**::
4143
4144 using namespace fmt::literals;
4145 print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
4146 \endrst
4147 */
4148inline internal::UdlArg<char>
4149operator"" _a(const char *s, std::size_t) { return {s}; }
4150inline internal::UdlArg<wchar_t>
4151operator"" _a(const wchar_t *s, std::size_t) { return {s}; }
4152
4153} // inline namespace literals
4154} // namespace fmt
4155#endif // FMT_USE_USER_DEFINED_LITERALS
4156
4157// Restore warnings.
4158#if FMT_GCC_VERSION >= 406
4159# pragma GCC diagnostic pop
4160#endif
4161
4162#if defined(__clang__) && !defined(FMT_ICC_VERSION)
4163# pragma clang diagnostic pop
4164#endif
4165
4166#ifdef FMT_HEADER_ONLY
4167# define FMT_FUNC inline
4168# include "format.cc"
4169#else
4170# define FMT_FUNC
4171#endif
4172
4173#endif // FMT_FORMAT_H_
static unsigned int GetBuildUniqueId()
Definition Atlas.h:30
ARK_API LPVOID GetDataAddress(const std::string &name)
Definition Base.cpp:15
ARK_API BitField GetBitField(LPVOID base, const std::string &name)
Definition Base.cpp:25
ARK_API BitField GetBitField(const void *base, const std::string &name)
Definition Base.cpp:20
#define ARK_API
Definition Base.h:9
ARK_API DWORD64 GetAddress(const void *base, const std::string &name)
Definition Base.cpp:5
ARK_API LPVOID GetAddress(const std::string &name)
Definition Base.cpp:10
FPlatformTypes::CHAR16 UCS2CHAR
A 16-bit character containing a UCS2 (Unicode, 16-bit, fixed-width) code unit, used for compatibility...
Definition BasicTypes.h:124
@ INDEX_NONE
Definition BasicTypes.h:144
FWindowsPlatformTypes FPlatformTypes
Definition BasicTypes.h:94
#define PLATFORM_LITTLE_ENDIAN
Definition BasicTypes.h:12
FPlatformTypes::CHAR8 UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition BasicTypes.h:122
ENoInit
Definition BasicTypes.h:151
@ NoInit
Definition BasicTypes.h:151
#define check(expr)
Definition BasicTypes.h:14
FPlatformTypes::CHAR16 UTF16CHAR
A 16-bit character containing a UTF16 (Unicode, 16-bit, variable-width) code unit.
Definition BasicTypes.h:126
#define CONSTEXPR
Definition BasicTypes.h:7
EForceInit
Definition BasicTypes.h:147
@ ForceInitToZero
Definition BasicTypes.h:149
@ ForceInit
Definition BasicTypes.h:148
FPlatformTypes::CHAR32 UTF32CHAR
A 32-bit character containing a UTF32 (Unicode, 32-bit, fixed-width) code unit.
Definition BasicTypes.h:128
TCString< TCHAR > FCString
Definition CString.h:335
TChar< TCHAR > FChar
Definition Char.h:142
int32 FindMatchingClosingParenthesis(const FString &TargetString, const int32 StartSearch)
Definition FString.h:3011
int32 HexToBytes(const FString &HexString, uint8 *OutBytes)
Definition FString.h:1803
const TCHAR * GetData(const FString &String)
Definition FString.h:1672
const uint8 TCharToNibble(const TCHAR Char)
Definition FString.h:1783
const bool CheckTCharIsHex(const TCHAR Char)
Definition FString.h:1773
FORCEINLINE uint32 GetTypeHash(const FString &Thing)
Definition FString.h:1646
TCHAR * GetData(FString &String)
Definition FString.h:1667
SIZE_T GetNum(const FString &String)
Definition FString.h:1677
void ByteToHex(uint8 In, FString &Result)
Definition FString.h:1743
static const uint32 MaxSupportedEscapeChars
Definition FString.h:2924
FString BytesToHex(const uint8 *In, int32 Count)
Definition FString.h:1755
int32 StringToBytes(const FString &String, uint8 *OutBytes, int32 MaxBufferSize)
Definition FString.h:1714
static const TCHAR * CharToEscapeSeqMap[][2]
Definition FString.h:2913
TCHAR NibbleToTChar(uint8 Num)
Definition FString.h:1729
FString BytesToString(const uint8 *In, int32 Count)
Definition FString.h:1688
ARK_API std::vector< spdlog::sink_ptr > &APIENTRY GetLogSinks()
Definition Logger.cpp:31
FORCEINLINE TEnableIf< TIsTriviallyCopyAssignable< ElementType >::Value >::Type CopyAssignItems(ElementType *Dest, const ElementType *Source, int32 Count)
Definition MemoryOps.h:162
FMicrosoftPlatformString FPlatformString
#define THRESH_VECTOR_NORMALIZED
#define THRESH_NORMALS_ARE_PARALLEL
#define THRESH_POINTS_ARE_SAME
#define SMALL_NUMBER
#define THRESH_POINT_ON_PLANE
#define PI
#define THRESH_NORMALS_ARE_ORTHOGONAL
#define KINDA_SMALL_NUMBER
#define BIG_NUMBER
#define FASTASIN_HALF_PI
#define HALF_PI
#define INV_PI
#define ARRAY_COUNT(array)
FORCEINLINE TRemoveReference< T >::Type && MoveTemp(T &&Obj)
#define Expose_TNameOf(type)
FORCEINLINE float ComputeSquaredDistanceFromBoxToPoint(const FVector &Mins, const FVector &Maxs, const FVector &Point)
Definition Vector.h:893
FORCEINLINE FVector ClampVector(const FVector &V, const FVector &Min, const FVector &Max)
Definition Vector.h:1646
FORCEINLINE FVector operator*(float Scale, const FVector &V)
Definition Vector.h:870
ApiUtils & operator=(ApiUtils &&)=delete
ApiUtils()=default
void SetCheatManager(UShooterCheatManager *cheatmanager)
Definition ApiUtils.cpp:44
void SetWorld(UWorld *uworld)
Definition ApiUtils.cpp:9
ApiUtils & operator=(const ApiUtils &)=delete
void SetShooterGameMode(AShooterGameMode *shooter_game_mode)
Definition ApiUtils.cpp:21
std::unordered_map< uint64, AShooterPlayerController * > steam_id_map_
Definition ApiUtils.h:38
UShooterCheatManager * GetCheatManager() const override
Returns a point to URCON CheatManager.
Definition ApiUtils.cpp:93
UWorld * u_world_
Definition ApiUtils.h:34
ApiUtils(ApiUtils &&)=delete
AShooterGameMode * shooter_game_mode_
Definition ApiUtils.h:35
AShooterGameMode * GetShooterGameMode() const override
Returns a pointer to AShooterGameMode.
Definition ApiUtils.cpp:26
void RemovePlayerController(AShooterPlayerController *player_controller)
Definition ApiUtils.cpp:62
UShooterCheatManager * cheatmanager_
Definition ApiUtils.h:37
void SetPlayerController(AShooterPlayerController *player_controller)
Definition ApiUtils.cpp:49
ServerStatus GetStatus() const override
Returns the current server status.
Definition ApiUtils.cpp:38
ServerStatus status_
Definition ApiUtils.h:36
AShooterPlayerController * FindPlayerFromSteamId_Internal(uint64 steam_id) const override
Definition ApiUtils.cpp:75
~ApiUtils() override=default
void SetStatus(ServerStatus status)
Definition ApiUtils.cpp:33
UWorld * GetWorld() const override
Returns a pointer to UWorld.
Definition ApiUtils.cpp:14
ApiUtils(const ApiUtils &)=delete
static FString GetSteamName(AController *player_controller)
Returns the steam name of player.
static FORCEINLINE FString GetItemBlueprint(UPrimalItem *item)
Returns blueprint from UPrimalItem.
static FVector GetPosition(APlayerController *player_controller)
Returns the position of a player.
uint64 GetSteamIDForPlayerID(int player_id) const
static FORCEINLINE FString GetClassBlueprint(UClass *the_class)
Returns blueprint path from any UClass.
void SendServerMessageToAll(FLinearColor msg_color, const T *msg, Args &&... args)
Sends server message to all players. Using fmt::format.
virtual UShooterCheatManager * GetCheatManager() const =0
Returns a point to URCON CheatManager.
UPrimalGameData * GetGameData()
Returns pointer to Primal Game Data.
static bool IsRidingDino(AShooterPlayerController *player_controller)
Returns true if character is riding a dino, false otherwise.
AShooterGameState * GetGameState()
Get Shooter Game State.
virtual ~IApiUtils()=default
AShooterPlayerController * FindPlayerFromSteamName(const FString &steam_name) const
Finds player from the given steam name.
static UShooterCheatManager * GetCheatManagerByPC(AShooterPlayerController *SPC)
Get UShooterCheatManager* of player controller.
static uint64 GetPlayerID(AController *controller)
static bool IsPlayerDead(AShooterPlayerController *player)
Returns true if player is dead, false otherwise.
void SendNotificationToAll(FLinearColor color, float display_scale, float display_time, UTexture2D *icon, const T *msg, Args &&... args)
Sends notification (on-screen message) to all players. Using fmt::format.
APrimalDinoCharacter * SpawnDino(AShooterPlayerController *player, FString blueprint, FVector *location, int lvl, bool force_tame, bool neutered) const
Spawns a dino near player or at specific coordinates.
TArray< AShooterPlayerController * > FindPlayerFromCharacterName(const FString &character_name, ESearchCase::Type search, bool full_match) const
Finds all matching players from the given character name.
static FORCEINLINE FString GetBlueprint(UObjectBase *object)
Returns blueprint path from any UObject.
static FString GetCharacterName(AShooterPlayerController *player_controller, bool include_first_name=true, bool include_last_name=true)
Returns the character name of player.
TArray< AActor * > GetAllActorsInRange(FVector location, float radius, EServerOctreeGroup::Type ActorType)
Gets all actors in radius at location.
void SendChatMessageToAll(const FString &sender_name, const T *msg, Args &&... args)
Sends chat message to all players. Using fmt::format.
TArray< AActor * > GetAllActorsInRange(FVector location, float radius, EServerOctreeGroup::Type ActorType, TArray< AActor * > ignores)
Gets all actors in radius at location, with ignore actors.
virtual AShooterGameMode * GetShooterGameMode() const =0
Returns a pointer to AShooterGameMode.
static uint64 GetSteamIdFromController(AController *controller)
Returns Steam ID from player controller.
virtual UWorld * GetWorld() const =0
Returns a pointer to UWorld.
static bool TeleportToPos(AShooterPlayerController *player_controller, const FVector &pos)
Teleports player to the given position.
void SendNotification(AShooterPlayerController *player_controller, FLinearColor color, float display_scale, float display_time, UTexture2D *icon, const T *msg, Args &&... args)
Sends notification (on-screen message) to the specific player. Using fmt::format.
static uint64 GetPlayerID(APrimalCharacter *character)
virtual AShooterPlayerController * FindPlayerFromSteamId_Internal(uint64 steam_id) const =0
AShooterPlayerController * FindControllerFromCharacter(AShooterCharacter *character) const
Finds player controller from the given player character.
static APrimalDinoCharacter * GetRidingDino(AShooterPlayerController *player_controller)
Returns the dino the character is riding.
static FString GetIPAddress(AShooterPlayerController *player_controller)
Returns IP address of player.
AShooterPlayerController * FindPlayerFromSteamId(uint64 steam_id) const
Finds player from the given steam id.
virtual ServerStatus GetStatus() const =0
Returns the current server status.
void SendServerMessage(AShooterPlayerController *player_controller, FLinearColor msg_color, const T *msg, Args &&... args)
Sends server message to the specific player. Using fmt::format.
static std::optional< FString > TeleportToPlayer(AShooterPlayerController *me, AShooterPlayerController *him, bool check_for_dino, float max_dist)
Teleport one player to another.
static int GetInventoryItemCount(AShooterPlayerController *player_controller, const FString &item_name)
Counts a specific items quantity.
void SendChatMessage(AShooterPlayerController *player_controller, const FString &sender_name, const T *msg, Args &&... args)
Sends chat message to the specific player. Using fmt::format.
FORCEINLINE const DataType & GetCharArray() const
Definition FString.h:299
FORCEINLINE friend bool operator<=(const FString &Lhs, const CharType *Rhs)
Definition FString.h:844
FORCEINLINE void RemoveAt(int32 Index, int32 Count=1, bool bAllowShrinking=true)
Definition FString.h:435
FORCEINLINE friend FString operator+(FString &&Lhs, FString &&Rhs)
Definition FString.h:661
FORCEINLINE FString & Append(const FString &Text)
Definition FString.h:396
FORCEINLINE uint32 GetAllocatedSize() const
Definition FString.h:214
void ToUpperInline()
Definition FString.h:2097
FString TrimStart() const &
Definition FString.h:2296
int32 Find(const TCHAR *SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart, int32 StartPosition=INDEX_NONE) const
Definition FString.h:2027
FORCEINLINE friend FString operator/(const FString &Lhs, const FString &Rhs)
Definition FString.h:781
FORCEINLINE FString(const std::string &str)
Definition FString.h:129
int32 ParseIntoArray(TArray< FString > &OutArray, const TCHAR **DelimArray, int32 NumDelims, bool InCullEmpty=true) const
Definition FString.h:2702
bool IsNumeric() const
Definition FString.h:2541
FORCEINLINE friend FString operator+(const FString &Lhs, const TCHAR *Rhs)
Definition FString.h:700
FORCEINLINE friend bool operator!=(const FString &Lhs, const CharType *Rhs)
Definition FString.h:1049
FORCEINLINE int32 Find(const FString &SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart, int32 StartPosition=INDEX_NONE) const
Definition FString.h:1128
FORCEINLINE friend DataType::RangedForIteratorType end(FString &Str)
Definition FString.h:210
FORCEINLINE friend FString operator+(FString &&Lhs, const FString &Rhs)
Definition FString.h:635
FString(FString &&)=default
FORCEINLINE FString & operator=(const TCHAR *Other)
Definition FString.h:147
FORCEINLINE friend bool operator<(const CharType *Lhs, const FString &Rhs)
Definition FString.h:899
FString TrimEnd() const &
Definition FString.h:2320
void TrimStartInline()
Definition FString.h:2286
FString Replace(const TCHAR *From, const TCHAR *To, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2766
FORCEINLINE FString LeftChop(int32 Count) const
Definition FString.h:1081
FORCEINLINE bool FindChar(TCHAR InChar, int32 &Index) const
Definition FString.h:1169
FORCEINLINE friend bool operator!=(const FString &Lhs, const FString &Rhs)
Definition FString.h:1035
int32 ReplaceInline(const TCHAR *SearchText, const TCHAR *ReplacementText, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase)
Definition FString.h:2805
FORCEINLINE FString Mid(int32 Start, int32 Count=INT_MAX) const
Definition FString.h:1099
FORCEINLINE FString(FString &&Other, int32 ExtraSlack)
Definition FString.h:87
static FORCEINLINE FString ConcatFStrings(typename TIdentity< LhsType >::Type Lhs, typename TIdentity< RhsType >::Type Rhs)
Definition FString.h:550
static FString Chr(TCHAR Ch)
Definition FString.h:2494
FORCEINLINE friend DataType::RangedForIteratorType begin(FString &Str)
Definition FString.h:208
FORCEINLINE friend FString operator+(const FString &Lhs, FString &&Rhs)
Definition FString.h:648
FORCEINLINE DataType & GetCharArray()
Definition FString.h:293
FORCEINLINE friend bool operator==(const FString &Lhs, const CharType *Rhs)
Definition FString.h:1008
static FORCEINLINE FString FromInt(int32 Num)
Definition FString.h:1548
FORCEINLINE FString & operator+=(const FString &Str)
Definition FString.h:500
FString & Append(const TCHAR *Text, int32 Count)
Definition FString.h:402
FORCEINLINE FString & operator/=(const FString &Str)
Definition FString.h:736
FString TrimStart() &&
Definition FString.h:2303
FORCEINLINE friend FString operator+(const FString &Lhs, const FString &Rhs)
Definition FString.h:622
FORCEINLINE int32 Compare(const FString &Other, ESearchCase::Type SearchCase=ESearchCase::CaseSensitive) const
Definition FString.h:1240
FORCEINLINE friend bool operator<=(const CharType *Lhs, const FString &Rhs)
Definition FString.h:858
FORCEINLINE friend bool operator==(const FString &Lhs, const FString &Rhs)
Definition FString.h:994
FString TrimStartAndEnd() &&
Definition FString.h:2279
FORCEINLINE friend FString operator+(const TCHAR *Lhs, const FString &Rhs)
Definition FString.h:674
FORCEINLINE TIterator CreateIterator()
Definition FString.h:192
FORCEINLINE void Reserve(const uint32 CharacterCount)
Definition FString.h:1542
FString ReplaceQuotesWithEscapedQuotes() const
Definition FString.h:2880
FString & operator=(FString &&)=default
static int32 CullArray(TArray< FString > *InArray)
Definition FString.h:2361
bool MatchesWildcard(const FString &Wildcard, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2585
FString Reverse() const
Definition FString.h:2368
FString ConvertTabsToSpaces(const int32 InSpacesPerTab)
Definition FString.h:2980
bool StartsWith(const TCHAR *InSuffix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2131
FORCEINLINE friend bool operator!=(const CharType *Lhs, const FString &Rhs)
Definition FString.h:1063
static FORCEINLINE FString ConcatTCHARsToFString(const TCHAR *Lhs, typename TIdentity< RhsType >::Type Rhs)
Definition FString.h:569
FORCEINLINE FString Left(int32 Count) const
Definition FString.h:1075
static bool ToHexBlob(const FString &Source, uint8 *DestBuffer, const uint32 DestSize)
Definition FString.h:2471
int32 ParseIntoArrayLines(TArray< FString > &OutArray, bool InCullEmpty=true) const
Definition FString.h:2684
FORCEINLINE bool FindLastChar(TCHAR InChar, int32 &Index) const
Definition FString.h:1181
std::string ToString() const
Convert FString to std::string.
Definition FString.h:1611
FString TrimQuotes(bool *bQuotesRemoved=nullptr) const
Definition FString.h:2334
FORCEINLINE FString & operator+=(const TCHAR *Str)
Definition FString.h:347
void AppendInt(int32 InNum)
Definition FString.h:2415
FORCEINLINE const TCHAR * operator*() const
Definition FString.h:282
FORCEINLINE friend FString operator/(FString &&Lhs, const TCHAR *Rhs)
Definition FString.h:765
FString()=default
FORCEINLINE friend FString operator/(FString &&Lhs, const FString &Rhs)
Definition FString.h:797
FString RightPad(int32 ChCount) const
Definition FString.h:2527
FORCEINLINE friend TEnableIf< TIsCharType< CharType >::Value, FString >::Type operator+(const FString &Lhs, CharType Rhs)
Definition FString.h:519
FORCEINLINE friend DataType::RangedForConstIteratorType end(const FString &Str)
Definition FString.h:211
void PathAppend(const TCHAR *Str, int32 StrLength)
Definition FString.h:2234
FORCEINLINE bool Contains(const FString &SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart) const
Definition FString.h:1156
FORCEINLINE FString(const CharType *Src, typename TEnableIf< TIsCharType< CharType >::Value >::Type *Dummy=nullptr)
Definition FString.h:98
void TrimEndInline()
Definition FString.h:2310
FORCEINLINE FString RightChop(int32 Count) const
Definition FString.h:1093
FString TrimEnd() &&
Definition FString.h:2327
bool EndsWith(const FString &InSuffix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2180
FString ToLower() &&
Definition FString.h:2115
static FString ChrN(int32 NumCharacters, TCHAR Char)
Definition FString.h:2501
static FORCEINLINE FString ConcatFStringToTCHARs(typename TIdentity< LhsType >::Type Lhs, const TCHAR *Rhs)
Definition FString.h:596
FORCEINLINE friend FString operator+(const TCHAR *Lhs, FString &&Rhs)
Definition FString.h:687
FORCEINLINE TConstIterator CreateConstIterator() const
Definition FString.h:198
bool StartsWith(const FString &InPrefix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2143
FString ToUpper() const &
Definition FString.h:2084
FString(const FString &)=default
static FString FormatAsNumber(int32 InNumber)
Definition FString.h:2395
FORCEINLINE bool Equals(const FString &Other, ESearchCase::Type SearchCase=ESearchCase::CaseSensitive) const
Definition FString.h:1221
FORCEINLINE bool IsValidIndex(int32 Index) const
Definition FString.h:272
FORCEINLINE friend FString operator/(const FString &Lhs, const TCHAR *Rhs)
Definition FString.h:749
void ToLowerInline()
Definition FString.h:2121
TArray< TCHAR > DataType
Definition FString.h:58
DataType Data
Definition FString.h:59
FString ToUpper() &&
Definition FString.h:2091
void TrimStartAndEndInline()
Definition FString.h:2266
int32 ParseIntoArray(TArray< FString > &OutArray, const TCHAR *pchDelim, bool InCullEmpty=true) const
Definition FString.h:2560
bool EndsWith(const TCHAR *InSuffix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase) const
Definition FString.h:2155
FORCEINLINE FString(int32 InCount, const TCHAR *InSrc)
Definition FString.h:116
FORCEINLINE friend DataType::RangedForConstIteratorType begin(const FString &Str)
Definition FString.h:209
FORCEINLINE friend bool operator>(const FString &Lhs, const CharType *Rhs)
Definition FString.h:967
FString ReplaceCharWithEscapedChar(const TArray< TCHAR > *Chars=nullptr) const
Definition FString.h:2934
static bool ToBlob(const FString &Source, uint8 *DestBuffer, const uint32 DestSize)
Definition FString.h:2448
FORCEINLINE TCHAR & operator[](int32 Index)
Definition FString.h:169
FORCEINLINE void InsertAt(int32 Index, TCHAR Character)
Definition FString.h:440
FORCEINLINE friend bool operator>=(const CharType *Lhs, const FString &Rhs)
Definition FString.h:940
FORCEINLINE friend FString operator/(const TCHAR *Lhs, const FString &Rhs)
Definition FString.h:813
FORCEINLINE void AppendChars(const TCHAR *Array, int32 Count)
Definition FString.h:322
FORCEINLINE friend TEnableIf< TIsCharType< CharType >::Value, FString >::Type operator+(FString &&Lhs, CharType Rhs)
Definition FString.h:538
FORCEINLINE void Shrink()
Definition FString.h:260
FORCEINLINE friend bool operator>(const CharType *Lhs, const FString &Rhs)
Definition FString.h:981
void ReverseString()
Definition FString.h:2375
FORCEINLINE bool IsEmpty() const
Definition FString.h:241
FORCEINLINE FString Right(int32 Count) const
Definition FString.h:1087
FORCEINLINE void InsertAt(int32 Index, const FString &Characters)
Definition FString.h:455
FORCEINLINE bool Contains(const TCHAR *SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart) const
Definition FString.h:1142
FORCEINLINE friend bool operator>(const FString &Lhs, const FString &Rhs)
Definition FString.h:953
FORCEINLINE friend bool operator==(const CharType *Lhs, const FString &Rhs)
Definition FString.h:1022
FORCEINLINE friend bool operator<(const FString &Lhs, const CharType *Rhs)
Definition FString.h:885
static FString Join(const TArray< T, Allocator > &Array, const TCHAR *Separator)
Definition FString.h:1587
bool RemoveFromEnd(const FString &InSuffix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase)
Definition FString.h:2212
FORCEINLINE TEnableIf< TIsCharType< CharType >::Value, FString & >::Type operator+=(CharType InChar)
Definition FString.h:363
FORCEINLINE const TCHAR & operator[](int32 Index) const
Definition FString.h:180
FORCEINLINE friend bool operator<(const FString &Lhs, const FString &Rhs)
Definition FString.h:871
FORCEINLINE friend bool operator>=(const FString &Lhs, const FString &Rhs)
Definition FString.h:912
FString ToLower() const &
Definition FString.h:2108
int32 ParseIntoArrayWS(TArray< FString > &OutArray, const TCHAR *pchExtraDelim=nullptr, bool InCullEmpty=true) const
Definition FString.h:2660
bool Split(const FString &InS, FString *LeftS, FString *RightS, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart) const
Definition FString.h:1262
static FString Format(const T *format, Args &&... args)
Formats text using fmt::format.
Definition FString.h:1633
FString LeftPad(int32 ChCount) const
Definition FString.h:2513
FORCEINLINE int32 FindLastCharByPredicate(Predicate Pred) const
Definition FString.h:1209
FORCEINLINE void Reset(int32 NewReservedSize=0)
Definition FString.h:251
FORCEINLINE void Empty(int32 Slack=0)
Definition FString.h:231
FORCEINLINE int32 Len() const
Definition FString.h:1069
FORCEINLINE int32 FindLastCharByPredicate(Predicate Pred, int32 Count) const
Definition FString.h:1195
void TrimToNullTerminator()
Definition FString.h:2015
bool RemoveFromStart(const FString &InPrefix, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase)
Definition FString.h:2196
FORCEINLINE FString & AppendChar(const TCHAR InChar)
Definition FString.h:390
FORCEINLINE friend bool operator>=(const FString &Lhs, const CharType *Rhs)
Definition FString.h:926
FORCEINLINE friend bool operator<=(const FString &Lhs, const FString &Rhs)
Definition FString.h:830
FORCEINLINE void CheckInvariants() const
Definition FString.h:222
FORCEINLINE friend FString operator+(FString &&Lhs, const TCHAR *Rhs)
Definition FString.h:713
FString ReplaceEscapedCharWithChar(const TArray< TCHAR > *Chars=nullptr) const
Definition FString.h:2956
FORCEINLINE FString(const FString &Other, int32 ExtraSlack)
Definition FString.h:76
FORCEINLINE FString & operator/=(const TCHAR *Str)
Definition FString.h:724
FString & operator=(const FString &)=default
FString TrimStartAndEnd() const &
Definition FString.h:2272
Definition Logger.h:9
Log()=default
~Log()=default
std::shared_ptr< spdlog::logger > logger_
Definition Logger.h:41
Log(Log &&)=delete
Log & operator=(Log &&)=delete
static std::shared_ptr< spdlog::logger > & GetLog()
Definition Logger.h:22
Log & operator=(const Log &)=delete
Log(const Log &)=delete
static Log & Get()
Definition Logger.h:16
FORCEINLINE int32 Num() const
Definition TArray.h:611
FORCEINLINE int32 Add(const ElementType &Item)
Definition TArray.h:1564
void Reset(int32 NewSize=0)
Definition TArray.h:1302
int32 Remove(const ElementType &Item)
Definition TArray.h:1709
void Empty(int32 Slack=0)
Definition TArray.h:1321
FORCEINLINE ElementType * GetData() const
Definition TArray.h:533
FORCEINLINE ObjectType * Get() const
ArgFormatter(BasicFormatter< Char > &formatter, FormatSpec &spec, const Char *fmt)
Definition format.h:2289
uint64_t types_
Definition format.h:1567
ArgList(ULongLong types, const internal::Value *values)
Definition format.h:1591
internal::Arg::Type type(unsigned index) const
Definition format.h:1578
friend class internal::ArgMap
Definition format.h:1583
@ MAX_PACKED_ARGS
Definition format.h:1587
internal::Arg operator[](unsigned index) const
Definition format.h:1599
static internal::Arg::Type type(uint64_t types, unsigned index)
Definition format.h:1624
uint64_t types() const
Definition format.h:1596
ArgList(ULongLong types, const internal::Arg *args)
Definition format.h:1593
void report_unhandled_arg()
Definition format.h:1664
Result visit_custom(Arg::CustomValue)
Definition format.h:1744
Result visit(const Arg &arg)
Definition format.h:1756
Result visit_double(double value)
Definition format.h:1708
Result visit_uint(unsigned value)
Definition format.h:1682
Result visit_any_int(T)
Definition format.h:1703
Result visit_cstring(const char *)
Definition format.h:1724
Result visit_pointer(const void *)
Definition format.h:1739
Result visit_unhandled_arg()
Definition format.h:1666
Result visit_any_double(T)
Definition format.h:1719
Result visit_long_double(long double value)
Definition format.h:1713
Result visit_long_long(LongLong value)
Definition format.h:1677
Result visit_wstring(Arg::StringValue< wchar_t >)
Definition format.h:1734
Result visit_string(Arg::StringValue< char >)
Definition format.h:1729
Result visit_ulong_long(ULongLong value)
Definition format.h:1687
Result visit_int(int value)
Definition format.h:1672
Result visit_bool(bool value)
Definition format.h:1692
Result visit_char(int value)
Definition format.h:1697
BasicFormatter< Char, Impl > & formatter_
Definition format.h:2260
const Char * format_
Definition format.h:2261
BasicArgFormatter(BasicFormatter< Char, Impl > &formatter, Spec &spec, const Char *fmt)
Definition format.h:2272
void visit_custom(internal::Arg::CustomValue c)
Definition format.h:2278
BasicArrayWriter(Char *array, std::size_t size)
Definition format.h:3353
internal::FixedBuffer< Char > buffer_
Definition format.h:3344
BasicArrayWriter(Char(&array)[SIZE])
Definition format.h:3363
const Char * data_
Definition format.h:660
const Char * c_str() const
Definition format.h:677
BasicCStringRef(const Char *s)
Definition format.h:664
BasicFormatter(const ArgList &args, BasicWriter< Char > &w)
Definition format.h:2328
void format(BasicCStringRef< Char > format_str)
Definition format.h:4012
internal::ArgMap< Char > map_
Definition format.h:2304
internal::Arg get_arg(BasicStringRef< Char > arg_name, const char *&error)
Definition format.h:3800
const Char * format(const Char *&format_str, const internal::Arg &arg)
Definition format.h:3840
BasicWriter< Char > & writer()
Definition format.h:2332
internal::Arg parse_arg_name(const Char *&s)
Definition format.h:3825
BasicWriter< Char > & writer_
Definition format.h:2303
internal::Arg parse_arg_index(const Char *&s)
Definition format.h:3813
const Char * data_
Definition format.h:539
BasicStringRef(const Char *s)
Definition format.h:552
std::size_t size() const
Definition format.h:598
friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:612
friend bool operator<(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:615
const Char * data() const
Definition format.h:595
friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:618
friend bool operator>(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:621
std::basic_string< Char > to_string() const
Definition format.h:590
friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:624
BasicStringRef(const Char *s, std::size_t size)
Definition format.h:544
friend bool operator==(BasicStringRef lhs, BasicStringRef rhs)
Definition format.h:609
std::size_t size_
Definition format.h:540
int compare(BasicStringRef other) const
Definition format.h:601
static CharPtr fill_padding(CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill)
Definition format.h:2926
void write_decimal(Int value)
Definition format.h:2647
virtual ~BasicWriter()
Definition format.h:2722
void append_float_length(Char *&, T)
Definition format.h:2702
void write_int(T value, Spec spec)
Definition format.h:3006
static Char * get(Char *p)
Definition format.h:2620
Buffer< Char > & buffer_
Definition format.h:2610
friend class BasicPrintfArgFormatter
Definition format.h:2708
BasicWriter(Buffer< Char > &b)
Definition format.h:2714
CharPtr prepare_int_buffer(unsigned num_digits, const Spec &spec, const char *prefix, unsigned prefix_size)
Definition format.h:2943
Char * write_unsigned_decimal(UInt value, unsigned prefix_size=0)
Definition format.h:2638
void append_float_length(Char *&format_ptr, long double)
Definition format.h:2697
void operator<<(typename internal::WCharHelper< const wchar_t *, Char >::Unsupported)
std::size_t size() const
Definition format.h:2727
CharPtr grow_buffer(std::size_t n)
Definition format.h:2630
void write_str(const internal::Arg::StringValue< StrChar > &str, const Spec &spec)
Definition format.h:2905
const Char * data() const FMT_NOEXCEPT
Definition format.h:2733
std::basic_string< Char > str() const
Definition format.h:2751
void clear() FMT_NOEXCEPT
Definition format.h:2875
CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec)
Definition format.h:2882
void write(BasicCStringRef< Char > format, ArgList args)
Definition format.h:2780
Buffer< Char > & buffer() FMT_NOEXCEPT
Definition format.h:2877
CharPtr prepare_int_buffer(unsigned num_digits, const EmptySpec &, const char *prefix, unsigned prefix_size)
Definition format.h:2659
void operator<<(typename internal::WCharHelper< wchar_t, Char >::Unsupported)
internal::CharTraits< Char >::CharPtr CharPtr
Definition format.h:2614
void write_double(T value, const Spec &spec)
Definition format.h:3099
const Char * c_str() const
Definition format.h:2739
void resize(std::size_t new_size)
Definition format.h:770
std::size_t size() const
Definition format.h:762
std::size_t size_
Definition format.h:744
void push_back(const T &value)
Definition format.h:788
void clear() FMT_NOEXCEPT
Definition format.h:786
virtual ~Buffer()
Definition format.h:759
void append(const U *begin, const U *end)
Definition format.h:804
void reserve(std::size_t capacity)
Definition format.h:781
std::size_t capacity_
Definition format.h:745
virtual void grow(std::size_t size)=0
Buffer(T *ptr=FMT_NULL, std::size_t capacity=0)
Definition format.h:747
T & operator[](std::size_t index)
Definition format.h:798
std::size_t capacity() const
Definition format.h:765
const T & operator[](std::size_t index) const
Definition format.h:799
FormatError(const FormatError &ferr)
Definition format.h:688
FMT_API ~FormatError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE
FormatError(CStringRef message)
Definition format.h:686
const char * data() const
Definition format.h:3537
char * str_
Definition format.h:3486
FormatInt(unsigned long value)
Definition format.h:3525
void FormatSigned(LongLong value)
Definition format.h:3510
char * format_decimal(ULongLong value)
Definition format.h:3489
FormatInt(unsigned value)
Definition format.h:3524
std::string str() const
Definition format.h:3553
std::size_t size() const
Definition format.h:3529
FormatInt(int value)
Definition format.h:3521
FormatInt(ULongLong value)
Definition format.h:3526
char buffer_[BUFFER_SIZE]
Definition format.h:3485
const char * c_str() const
Definition format.h:3543
FormatInt(LongLong value)
Definition format.h:3523
FormatInt(long value)
Definition format.h:3522
T value() const
Definition format.h:1879
IntFormatSpec(T val, const SpecT &spec=SpecT())
Definition format.h:1876
StrFormatSpec(const Char *str, unsigned width, FillChar fill)
Definition format.h:1890
const Char * str_
Definition format.h:1886
const Char * str() const
Definition format.h:1895
int error_code() const
Definition format.h:2566
SystemError(int error_code, CStringRef message)
Definition format.h:2558
FMT_API ~SystemError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE
FMT_API void init(int err_code, CStringRef format_str, ArgList args)
Definition format.cc:225
void visit_wstring(internal::Arg::StringValue< Char > value)
Definition format.h:2182
void visit_string(internal::Arg::StringValue< char > value)
Definition format.h:2176
BasicWriter< Char > & writer_
Definition format.h:2090
void visit_pointer(const void *value)
Definition format.h:2186
BasicWriter< Char > & writer()
Definition format.h:2105
void visit_cstring(const char *value)
Definition format.h:2169
void write(const char *value)
Definition format.h:2114
void write_pointer(const void *p)
Definition format.h:2095
void visit_bool(bool value)
Definition format.h:2131
ArgFormatterBase(BasicWriter< Char > &w, Spec &s)
Definition format.h:2122
MapType::value_type Pair
Definition format.h:2024
void init(const ArgList &args)
Definition format.h:2043
static Char cast(int value)
Definition format.h:916
static char convert(char value)
Definition format.h:929
static char convert(wchar_t)
static wchar_t convert(char value)
Definition format.h:949
static wchar_t convert(wchar_t value)
Definition format.h:950
bool check_no_auto_index(const char *&error)
Definition format.h:2223
FormatterBase(const ArgList &args)
Definition format.h:2204
const ArgList & args() const
Definition format.h:2202
void write(BasicWriter< Char > &w, const Char *start, const Char *end)
Definition format.h:2233
Arg next_arg(const char *&error)
Definition format.h:2210
Arg get_arg(unsigned arg_index, const char *&error)
Definition format.h:2219
FMT_API Arg do_get_arg(unsigned arg_index, const char *&error)
MakeArg(const T &value)
Definition format.h:1530
MakeValue(unsigned long value)
Definition format.h:1420
MakeValue(typename WCharHelper< wchar_t, Char >::Unsupported)
MakeValue(typename WCharHelper< WStringRef, Char >::Unsupported)
static uint64_t type(long)
Definition format.h:1416
MakeValue(typename WCharHelper< const wchar_t *, Char >::Unsupported)
MakeValue(typename WCharHelper< wchar_t *, Char >::Unsupported)
Formatter::Char Char
Definition format.h:1345
void set_string(WStringRef str)
Definition format.h:1378
static uint64_t type(unsigned long)
Definition format.h:1426
void set_string(StringRef str)
Definition format.h:1373
MakeValue(const T *value)
static void format_custom_arg(void *formatter, const void *arg, void *format_str_ptr)
Definition format.h:1385
MakeValue(long value)
Definition format.h:1408
RuntimeError(const RuntimeError &rerr)
Definition format.h:1554
FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE
ThousandsSep(fmt::StringRef sep)
Definition format.h:1068
void operator()(Char *&buffer)
Definition format.h:1071
std::string _msg
Definition common.h:147
const char * what() const SPDLOG_NOEXCEPT override
Definition common.h:142
#define SPDLOG_NOEXCEPT
Definition common.h:28
#define SPDLOG_LEVEL_NAMES
Definition common.h:86
IApiUtils & GetApiUtils()
Definition ApiUtils.cpp:99
@ CaseSensitive
Definition FString.h:28
@ FromStart
Definition FString.h:41
void FromString(float &OutValue, const TCHAR *Buffer)
Definition FString.h:1845
void FromString(int8 &OutValue, const TCHAR *Buffer)
Definition FString.h:1837
void FromString(uint8 &OutValue, const TCHAR *Buffer)
Definition FString.h:1841
void FromString(uint32 &OutValue, const TCHAR *Buffer)
Definition FString.h:1843
TEnableIf< TIsCharType< CharType >::Value, FString >::Type ToString(const CharType *Ptr)
Definition FString.h:1851
void FromString(int32 &OutValue, const TCHAR *Buffer)
Definition FString.h:1839
void FromString(uint64 &OutValue, const TCHAR *Buffer)
Definition FString.h:1844
FString ToSanitizedString(const T &Value)
Definition FString.h:1873
void FromString(FString &OutValue, const TCHAR *Buffer)
Definition FString.h:1847
void FromString(double &OutValue, const TCHAR *Buffer)
Definition FString.h:1846
void FromString(uint16 &OutValue, const TCHAR *Buffer)
Definition FString.h:1842
static TEnableIf< TIsArithmetic< T >::Value, bool >::Type TryParseString(T &OutValue, const TCHAR *Buffer)
Definition FString.h:1882
void FromString(int16 &OutValue, const TCHAR *Buffer)
Definition FString.h:1838
FString ToString(bool Value)
Definition FString.h:1856
FORCEINLINE FString ToString(FString &&Str)
Definition FString.h:1861
FORCEINLINE FString ToString(const FString &Str)
Definition FString.h:1866
void FromString(int64 &OutValue, const TCHAR *Buffer)
Definition FString.h:1840
bool MatchesWildcardRecursive(const TCHAR *Target, int32 TargetLength, const TCHAR *Wildcard, int32 WildcardLength)
Definition FString.h:1933
No & convert(...)
unsigned parse_nonnegative_int(const Char *&s)
Definition format.h:3758
T * make_ptr(T *ptr, std::size_t)
Definition format.h:728
bool is_name_start(Char c)
Definition format.h:3751
Yes & convert(fmt::ULongLong)
bool is_negative(T value)
Definition format.h:982
DummyInt _finite(...)
Definition format.h:421
char Yes[1]
Definition format.h:1230
fmt::StringRef thousands_sep(...)
Definition format.h:1310
DummyInt isinf(...)
Definition format.h:420
DummyInt signbit(...)
Definition format.h:418
DummyInt _ecvt_s(...)
Definition format.h:419
void require_numeric_argument(const Arg &arg, char spec)
Definition format.h:3779
MakeUnsigned< Int >::Type to_unsigned(Int value)
Definition format.h:711
uint64_t make_type()
Definition format.h:2361
void format_decimal(Char *buffer, UInt value, unsigned num_digits)
Definition format.h:1109
@ INLINE_BUFFER_SIZE
Definition format.h:718
void check_sign(const Char *&s, const Arg &arg)
Definition format.h:3788
StringRef thousands_sep(LConv *lc, LConvCheck< char *LConv::*, &LConv::thousands_sep >=0)
Definition format.h:1305
DummyInt isnan(...)
Definition format.h:422
uint64_t make_type(const T &arg)
Definition format.h:2364
T const_check(T value)
Definition format.h:428
char No[2]
Definition format.h:1231
DummyInt _isnan(...)
Definition format.h:423
void format_arg(Formatter &,...)
Definition format.h:1334
void format_decimal(Char *buffer, UInt value, unsigned num_digits, ThousandsSep thousands_sep)
Definition format.h:1084
BasicData Data
Definition format.h:1016
Definition format.h:408
ArgJoin< wchar_t, It > join(It first, It last, const BasicCStringRef< wchar_t > &sep)
Definition format.h:4051
void format_decimal(char *&buffer, T value)
Definition format.h:3560
FMT_API void print(CStringRef format_str, ArgList args)
Definition format.cc:449
FMT_API void print_colored(Color c, CStringRef format, ArgList args)
Definition format.cc:453
ArgJoin< char, It > join(It first, It last, const BasicCStringRef< char > &sep)
Definition format.h:4046
@ HASH_FLAG
Definition format.h:1799
@ PLUS_FLAG
Definition format.h:1799
@ SIGN_FLAG
Definition format.h:1799
@ CHAR_FLAG
Definition format.h:1800
@ MINUS_FLAG
Definition format.h:1799
__pad6__
Definition format.cc:296
IntFormatSpec< int, TypeSpec< 'o'> > oct(int value)
BasicWriter< char > Writer
Definition format.h:496
StrFormatSpec< wchar_t > pad(const wchar_t *str, unsigned width, char fill=' ')
Definition format.h:2012
BasicArrayWriter< wchar_t > WArrayWriter
Definition format.h:3368
std::string format(CStringRef format_str, ArgList args)
Definition format.h:3443
BasicArrayWriter< char > ArrayWriter
Definition format.h:3367
IntFormatSpec< int, TypeSpec< 'b'> > bin(int value)
BasicMemoryWriter< wchar_t > WMemoryWriter
Definition format.h:3319
IntFormatSpec< int, TypeSpec< 'x'> > hex(int value)
BasicStringRef< wchar_t > WStringRef
Definition format.h:630
BasicMemoryWriter< char > MemoryWriter
Definition format.h:3318
void arg(WStringRef, const internal::NamedArg< Char > &) FMT_DELETED_OR_UNDEFINED
FMT_API void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT
Definition format.cc:429
void format_arg(fmt::BasicFormatter< Char, ArgFormatter > &f, const Char *&format_str, const ArgJoin< Char, It > &e)
Definition format.h:4070
__pad1__
Definition format.cc:236
std::wstring format(WCStringRef format_str, ArgList args)
Definition format.h:3449
__pad2__
Definition format.cc:250
Alignment
Definition format.h:1793
@ ALIGN_LEFT
Definition format.h:1794
@ ALIGN_DEFAULT
Definition format.h:1794
@ ALIGN_NUMERIC
Definition format.h:1794
@ ALIGN_RIGHT
Definition format.h:1794
@ ALIGN_CENTER
Definition format.h:1794
Color
Definition format.h:3424
@ BLUE
Definition format.h:3424
@ BLACK
Definition format.h:3424
@ RED
Definition format.h:3424
@ GREEN
Definition format.h:3424
@ WHITE
Definition format.h:3424
@ YELLOW
Definition format.h:3424
@ CYAN
Definition format.h:3424
@ MAGENTA
Definition format.h:3424
FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args)
Definition format.cc:443
internal::NamedArgWithType< char, T > arg(StringRef name, const T &arg)
Definition format.h:3593
IntFormatSpec< int, AlignTypeSpec< TYPE_CODE >, Char > pad(int value, unsigned width, Char fill=' ')
FMT_API void format_system_error(fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT
Definition format.cc:388
void arg(StringRef, const internal::NamedArg< Char > &) FMT_DELETED_OR_UNDEFINED
internal::NamedArgWithType< wchar_t, T > arg(WStringRef name, const T &arg)
Definition format.h:3598
IntFormatSpec< int, TypeSpec< 'X'> > hexu(int value)
BasicStringRef< char > StringRef
Definition format.h:629
StrFormatSpec< Char > pad(const Char *str, unsigned width, Char fill=' ')
Definition format.h:2007
BasicCStringRef< wchar_t > WCStringRef
Definition format.h:681
FMT_GCC_EXTENSION typedef long long LongLong
Definition format.h:486
BasicCStringRef< char > CStringRef
Definition format.h:680
FMT_GCC_EXTENSION typedef unsigned long long ULongLong
Definition format.h:487
BasicWriter< wchar_t > WWriter
Definition format.h:497
std::string errno_str(int err_num)
Definition os.h:400
const char * to_short_str(spdlog::level::level_enum l)
Definition common.h:97
const char * to_str(spdlog::level::level_enum l)
Definition common.h:92
static const char * short_level_names[]
Definition common.h:90
void set_formatter(formatter_ptr f)
std::shared_ptr< logger > stdout_logger_st(const std::string &logger_name)
Definition spdlog_impl.h:92
std::shared_ptr< logger > create_async(const std::string &logger_name, const sink_ptr &sink, size_t queue_size, const async_overflow_policy overflow_policy=async_overflow_policy::block_retry, const std::function< void()> &worker_warmup_cb=nullptr, const std::chrono::milliseconds &flush_interval_ms=std::chrono::milliseconds::zero(), const std::function< void()> &worker_teardown_cb=nullptr)
void register_logger(std::shared_ptr< logger > logger)
Definition spdlog_impl.h:35
std::shared_ptr< logger > rotating_logger_st(const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
Definition spdlog_impl.h:67
std::shared_ptr< logger > rotating_logger_mt(const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
Definition spdlog_impl.h:62
void set_error_handler(log_err_handler)
async_overflow_policy
Definition common.h:108
std::shared_ptr< logger > create_async(const std::string &logger_name, sinks_init_list sinks, size_t queue_size, const async_overflow_policy overflow_policy=async_overflow_policy::block_retry, const std::function< void()> &worker_warmup_cb=nullptr, const std::chrono::milliseconds &flush_interval_ms=std::chrono::milliseconds::zero(), const std::function< void()> &worker_teardown_cb=nullptr)
std::shared_ptr< logger > stdout_color_mt(const std::string &logger_name)
std::shared_ptr< logger > get(const std::string &name)
Definition spdlog_impl.h:40
std::shared_ptr< logger > create(const std::string &logger_name, sinks_init_list sinks)
std::shared_ptr< logger > create_async(const std::string &logger_name, const It &sinks_begin, const It &sinks_end, size_t queue_size, const async_overflow_policy overflow_policy=async_overflow_policy::block_retry, const std::function< void()> &worker_warmup_cb=nullptr, const std::chrono::milliseconds &flush_interval_ms=std::chrono::milliseconds::zero(), const std::function< void()> &worker_teardown_cb=nullptr)
void apply_all(std::function< void(std::shared_ptr< logger >)> fun)
std::shared_ptr< logger > create(const std::string &logger_name, const It &sinks_begin, const It &sinks_end)
std::shared_ptr< logger > daily_logger_mt(const std::string &logger_name, const filename_t &filename, int hour=0, int minute=0)
Definition spdlog_impl.h:73
std::shared_ptr< logger > stdout_logger_mt(const std::string &logger_name)
Definition spdlog_impl.h:87
std::shared_ptr< logger > stdout_color_st(const std::string &logger_name)
std::shared_ptr< logger > daily_logger_st(const std::string &logger_name, const filename_t &filename, int hour=0, int minute=0)
Definition spdlog_impl.h:78
std::shared_ptr< logger > stderr_color_st(const std::string &logger_name)
std::shared_ptr< logger > basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate=false)
Definition spdlog_impl.h:51
void set_level(level::level_enum log_level)
void set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy=async_overflow_policy::block_retry, const std::function< void()> &worker_warmup_cb=nullptr, const std::chrono::milliseconds &flush_interval_ms=std::chrono::milliseconds::zero(), const std::function< void()> &worker_teardown_cb=nullptr)
std::shared_ptr< logger > stderr_logger_mt(const std::string &logger_name)
Definition spdlog_impl.h:97
std::shared_ptr< spdlog::logger > create(const std::string &logger_name, Args...)
void drop_all()
std::shared_ptr< logger > create(const std::string &logger_name, const sink_ptr &sink)
std::shared_ptr< logger > stderr_logger_st(const std::string &logger_name)
pattern_time_type
Definition common.h:118
void set_sync_mode()
void set_pattern(const std::string &format_string)
std::shared_ptr< logger > stderr_color_mt(const std::string &logger_name)
void drop(const std::string &name)
Definition spdlog_impl.h:45
std::shared_ptr< logger > basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate=false)
Definition spdlog_impl.h:56
Definition json.hpp:4518
#define __has_feature(x)
Definition os.h:53
FVector & DefaultActorLocationField()
Definition Actor.h:920
int & TargetingTeamField()
Definition Actor.h:902
USceneComponent * RootComponentField()
Definition Actor.h:911
APlayerState * PlayerStateField()
Definition Actor.h:2062
UCheatManager * CheatManagerField()
Definition Actor.h:2133
FString * GetPlayerNetworkAddress(FString *result)
Definition Actor.h:2292
FUniqueNetIdRepl & UniqueIdField()
Definition Actor.h:1782
FString & PlayerNameField()
Definition Actor.h:1776
bool TeleportTo(FVector *DestLocation, FRotator *DestRotation, bool bIsATest, bool bNoCheck)
Definition Actor.h:4554
UPrimalInventoryComponent * MyInventoryComponentField()
Definition Actor.h:3798
bool IsDead()
Definition Actor.h:4360
void DoNeuter_Implementation()
Definition Actor.h:7051
static UClass * GetPrivateStaticClass()
Definition Actor.h:6963
void TameDino(AShooterPlayerController *ForPC, bool bIgnoreMaxTameLimit, int OverrideTamingTeamID)
Definition Actor.h:7328
int & TamingTeamIDField()
Definition Actor.h:6194
FString & TamerStringField()
Definition Actor.h:6057
int & AbsoluteBaseLevelField()
Definition Actor.h:6324
UPrimalPlayerData * GetPlayerData()
Definition Actor.h:5166
APrimalDinoCharacter * GetRidingDino()
Definition Actor.h:5159
unsigned __int64 GetSteamIDForPlayerID(int playerDataID)
Definition GameMode.h:1620
void AddPlayerID(int playerDataID, unsigned __int64 netUniqueID)
Definition GameMode.h:1534
__int64 & LinkedPlayerIDField()
Definition Actor.h:2504
void SetPlayerPos(float X, float Y, float Z)
Definition Actor.h:3202
AActor * SpawnActor(FString *blueprintPath, float spawnDistance, float spawnYOffset, float ZOffset, bool bDoDeferBeginPlay)
Definition Actor.h:3222
AShooterCharacter * GetPlayerCharacter()
Definition Actor.h:2916
FString * GetPlayerName(FString *result)
Definition Actor.h:1902
void SetTribeTamingDinoSettings(APrimalDinoCharacter *aDinoChar)
Definition Actor.h:1986
DWORD64 offset
Definition Base.h:674
DWORD bit_position
Definition Base.h:675
ULONGLONG length
Definition Base.h:677
ULONGLONG num_bits
Definition Base.h:676
Definition Base.h:181
Definition Actor.h:10035
ECanvasAllowModes
Definition Base.h:316
@ Allow_DeleteOnRender
Definition Base.h:318
@ Allow_Flush
Definition Base.h:317
EElementType
Definition Base.h:309
@ ET_MAX
Definition Base.h:312
@ ET_Line
Definition Base.h:310
@ ET_Triangle
Definition Base.h:311
Definition Crc.h:11
static uint32 MemCrc32(const void *Data, int32 Lenght)
Definition Crc.h:12
Definition Other.h:244
Definition Actor.h:349
static FORCEINLINE double CeilToDouble(double F)
static FORCEINLINE float CeilToFloat(float F)
static FORCEINLINE float Fractional(float Value)
static FORCEINLINE float RoundToFloat(float F)
static CONSTEXPR FORCEINLINE double FloatSelect(double Comparand, double ValueGEZero, double ValueLTZero)
static FORCEINLINE float InvSqrtEst(float F)
static FORCEINLINE float Acos(float Value)
static FORCEINLINE uint32 ReverseMortonCode3(uint32 x)
static FORCEINLINE uint32 ReverseMortonCode2(uint32 x)
static FORCEINLINE int32 CeilToInt(float F)
static FORCEINLINE uint32 CountTrailingZeros(uint32 Value)
static FORCEINLINE T Max(const TArray< T > &Values, int32 *MaxIndex=NULL)
static FORCEINLINE T Min(const TArray< T > &Values, int32 *MinIndex=NULL)
static FORCEINLINE float InvSqrt(float F)
static FORCEINLINE float Modf(const float InValue, float *OutIntPart)
static CONSTEXPR FORCEINLINE T Min(const T A, const T B)
static FORCEINLINE float FRand()
static FORCEINLINE bool IsNaN(float A)
static FORCEINLINE double RoundToDouble(double F)
static FORCEINLINE float Sinh(float Value)
static CONSTEXPR FORCEINLINE float FloatSelect(float Comparand, float ValueGEZero, float ValueLTZero)
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
static FORCEINLINE float Sqrt(float Value)
static FORCEINLINE float Exp(float Value)
static FORCEINLINE float FloorToFloat(float F)
static FORCEINLINE float LogX(float Base, float Value)
static FORCEINLINE double FloorToDouble(double F)
static FORCEINLINE float Atan(float Value)
static FORCEINLINE uint64 CeilLogTwo64(uint64 Arg)
static FORCEINLINE float Asin(float Value)
static FORCEINLINE int32 RoundToInt(float F)
static FORCEINLINE double Modf(const double InValue, double *OutIntPart)
static FORCEINLINE float Sin(float Value)
static FORCEINLINE float Frac(float Value)
static FORCEINLINE float Tan(float Value)
static FORCEINLINE uint32 RoundUpToPowerOfTwo(uint32 Arg)
static FORCEINLINE bool IsNegativeFloat(const float &A)
static CONSTEXPR FORCEINLINE T Max(const T A, const T B)
static FORCEINLINE bool IsFinite(float A)
static FORCEINLINE float Fmod(float X, float Y)
static FORCEINLINE uint32 MortonCode3(uint32 x)
static CONSTEXPR FORCEINLINE int32 TruncToInt(float F)
static FORCEINLINE float Cos(float Value)
static FORCEINLINE bool IsNegativeDouble(const double &A)
static CONSTEXPR FORCEINLINE float TruncToFloat(float F)
static FORCEINLINE uint64 CountLeadingZeros64(uint64 Value)
static FORCEINLINE int32 Rand()
static FORCEINLINE uint64 FloorLog2_64(uint64 Value)
static FORCEINLINE float Log2(float Value)
static FORCEINLINE uint32 CeilLogTwo(uint32 Arg)
static CONSTEXPR FORCEINLINE T Abs(const T A)
static CONSTEXPR FORCEINLINE T Sign(const T A)
static FORCEINLINE uint32 MortonCode2(uint32 x)
static FORCEINLINE float Pow(float A, float B)
static FORCEINLINE int32 CountBits(uint64 Bits)
static FORCEINLINE uint32 FloorLog2(uint32 Value)
static FORCEINLINE float Exp2(float Value)
static FORCEINLINE void RandInit(int32 Seed)
static FORCEINLINE int32 FloorToInt(float F)
static FORCEINLINE float Loge(float Value)
unsigned long long uint64
Definition BasicTypes.h:55
unsigned char uint8
Definition BasicTypes.h:52
decltype(nullptr) TYPE_OF_NULLPTR
Definition BasicTypes.h:77
signed short int int16
Definition BasicTypes.h:59
SelectIntPointerType< int32, int64, sizeof(void *)>::TIntPointe PTRINT)
Definition BasicTypes.h:72
unsigned short int uint16
Definition BasicTypes.h:53
unsigned int uint32
Definition BasicTypes.h:54
SelectIntPointerType< uint32, uint64, sizeof(void *)>::TIntPointe UPTRINT)
Definition BasicTypes.h:71
signed long long int64
Definition BasicTypes.h:61
Definition Actor.h:9443
int32 X
Definition IntPoint.h:17
int32 Y
Definition IntPoint.h:20
int32 Z
Definition IntVector.h:25
int32 Y
Definition IntVector.h:22
FIntVector(FVector InVector)
Definition Vector.h:936
int32 X
Definition IntVector.h:19
Definition Inventory.h:50
Definition Base.h:120
Definition Base.h:216
float G
Definition Color.h:36
float B
Definition Color.h:37
float R
Definition Color.h:35
static float UnwindRadians(float A)
static T InterpCircularOut(const T &A, const T &B, float Alpha)
static T InterpEaseInOut(const T &A, const T &B, float Alpha, float Exp)
static T InterpExpoInOut(const T &A, const T &B, float Alpha)
static FORCEINLINE double RoundToNegativeInfinity(double F)
static FORCEINLINE int32 RandRange(int32 Min, int32 Max)
static T BiLerp(const T &P00, const T &P10, const T &P01, const T &P11, const U &FracX, const U &FracY)
static T LerpStable(const T &A, const T &B, double Alpha)
static FORCEINLINE float RandRange(float InMin, float InMax)
static float UnwindDegrees(float A)
static FORCEINLINE float FastAsin(float Value)
static FORCEINLINE float RoundToNegativeInfinity(float F)
static float FindDeltaAngleRadians(float A1, float A2)
static U CubicCRSplineInterp(const U &P0, const U &P1, const U &P2, const U &P3, const float T0, const float T1, const float T2, const float T3, const float T)
static T InterpCircularInOut(const T &A, const T &B, float Alpha)
static float SmoothStep(float A, float B, float X)
static FORCEINLINE T Clamp(const T X, const T Min, const T Max)
static FORCEINLINE float RoundFromZero(float F)
static T CubicInterpSecondDerivative(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
static int32 LeastCommonMultiplier(int32 a, int32 b)
static FORCEINLINE T Square(const T A)
static T Lerp(const T &A, const T &B, const U &Alpha)
static FORCEINLINE T Max3(const T A, const T B, const T C)
static T InterpEaseOut(const T &A, const T &B, float Alpha, float Exp)
static FORCEINLINE T DivideAndRoundDown(T Dividend, T Divisor)
static FORCEINLINE float RoundToZero(float F)
static FORCEINLINE int32 RandHelper(int32 A)
static int32 GreatestCommonDivisor(int32 a, int32 b)
static T InterpSinOut(const T &A, const T &B, float Alpha)
static T InterpEaseIn(const T &A, const T &B, float Alpha, float Exp)
static FORCEINLINE float RoundToPositiveInfinity(float F)
static FORCEINLINE void PolarToCartesian(const float Rad, const float Ang, float &OutX, float &OutY)
static FORCEINLINE float FRandRange(float InMin, float InMax)
static float FindDeltaAngleDegrees(float A1, float A2)
static FORCEINLINE bool IsPowerOfTwo(T Value)
static FORCEINLINE auto RadiansToDegrees(T const &RadVal) -> decltype(RadVal *(180.f/PI))
static T InterpCircularIn(const T &A, const T &B, float Alpha)
static T InterpStep(const T &A, const T &B, float Alpha, int32 Steps)
static FORCEINLINE T DivideAndRoundUp(T Dividend, T Divisor)
static T InterpExpoOut(const T &A, const T &B, float Alpha)
static T CubicInterpDerivative(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
static T CubicInterp(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
static FORCEINLINE double RoundToPositiveInfinity(double F)
static FORCEINLINE void SinCos(float *ScalarSin, float *ScalarCos, float Value)
static FORCEINLINE T Min3(const T A, const T B, const T C)
static FORCEINLINE auto DegreesToRadians(T const &DegVal) -> decltype(DegVal *(PI/180.f))
static T LerpStable(const T &A, const T &B, float Alpha)
static T InterpExpoIn(const T &A, const T &B, float Alpha)
static FORCEINLINE double RoundToZero(double F)
static T InterpSinIn(const T &A, const T &B, float Alpha)
static FORCEINLINE double RoundFromZero(double F)
static T InterpSinInOut(const T &A, const T &B, float Alpha)
static FORCEINLINE bool RandBool()
static FORCEINLINE int32 Stricmp(const ANSICHAR *String1, const ANSICHAR *String2)
Definition Other.h:87
Definition Actor.h:9709
Definition Actor.h:9701
Definition Base.h:191
unsigned __int64 & PlayerDataIDField()
Definition Actor.h:5466
Definition Base.h:360
FORCEINLINE FRotator(float InPitch, float InYaw, float InRoll)
Definition Rotator.h:375
TSharedPtr< FUniqueNetId > UniqueNetId
Definition Actor.h:190
float Y
Definition Vector2D.h:22
float X
Definition Vector2D.h:19
FORCEINLINE FVector operator+(float Bias) const
Definition Vector.h:1145
FORCEINLINE FVector operator*=(float Scale)
Definition Vector.h:1210
bool operator!=(const FVector &V) const
Definition Vector.h:1176
FORCEINLINE FVector()
Definition Vector.h:41
static float Triple(const FVector &X, const FVector &Y, const FVector &Z)
Definition Vector.h:1044
static bool Orthogonal(const FVector &Normal1, const FVector &Normal2, float OrthogonalCosineThreshold=THRESH_NORMALS_ARE_ORTHOGONAL)
Definition Vector.h:1031
static bool Parallel(const FVector &Normal1, const FVector &Normal2, float ParallelCosineThreshold=THRESH_NORMALS_ARE_PARALLEL)
Definition Vector.h:1019
FORCEINLINE FVector operator-(const FVector &V) const
Definition Vector.h:1135
FORCEINLINE FVector operator-=(const FVector &V)
Definition Vector.h:1204
FVector GetSafeNormal(float Tolerance=SMALL_NUMBER) const
Definition Vector.h:1520
static FVector VectorPlaneProject(const FVector &V, const FVector &PlaneNormal)
Definition Vector.h:1014
FVector operator/=(const FVector &V)
Definition Vector.h:1229
static bool PointsAreSame(const FVector &P, const FVector &Q)
Definition Vector.h:968
FORCEINLINE FVector(float InF)
Definition Vector.h:1062
FORCEINLINE FVector operator+=(const FVector &V)
Definition Vector.h:1198
FORCEINLINE FVector operator-() const
Definition Vector.h:1192
FORCEINLINE FVector operator^(const FVector &V) const
Definition Vector.h:1105
bool IsUniform(float Tolerance=KINDA_SMALL_NUMBER) const
Definition Vector.h:1510
FORCEINLINE FVector operator-(float Bias) const
Definition Vector.h:1140
FRotator ToOrientationRotator() const
FVector(const FLinearColor &InColor)
Definition Vector.h:1072
FVector MirrorByVector(const FVector &MirrorNormal) const
Definition Vector.h:1515
FVector Reciprocal() const
Definition Vector.h:1476
static FORCEINLINE float DistSquaredXY(const FVector &V1, const FVector &V2)
Definition Vector.h:1627
float X
Definition Vector.h:27
static bool PointsAreNear(const FVector &Point1, const FVector &Point2, float Dist)
Definition Vector.h:987
bool InitFromString(const FString &InSourceString)
static FORCEINLINE float DotProduct(const FVector &A, const FVector &B)
Definition Vector.h:1125
float Y
Definition Vector.h:30
FVector ComponentMax(const FVector &Other) const
Definition Vector.h:1301
void ToDirectionAndLength(FVector &OutDir, float &OutLength) const
Definition Vector.h:1361
FORCEINLINE float operator|(const FVector &V) const
Definition Vector.h:1120
FRotator Rotation() const
FORCEINLINE FVector GetUnsafeNormal() const
Definition Vector.h:1392
FVector GetClampedToMaxSize(float MaxSize) const
Definition Vector.h:1428
FORCEINLINE FVector operator*(const FVector &V) const
Definition Vector.h:1161
void FindBestAxisVectors(FVector &Axis1, FVector &Axis2) const
float Size2D() const
Definition Vector.h:1321
FVector(FIntVector InVector)
Definition Vector.h:1077
static const FVector ZeroVector
Definition Vector.h:38
float SizeSquared2D() const
Definition Vector.h:1326
FVector GetSafeNormal2D(float Tolerance=SMALL_NUMBER) const
Definition Vector.h:1537
float & Component(int32 Index)
Definition Vector.h:1466
static FORCEINLINE float BoxPushOut(const FVector &Normal, const FVector &Size)
Definition Vector.h:1632
FVector operator/(float Scale) const
Definition Vector.h:1155
static FVector RadiansToDegrees(const FVector &RadVector)
Definition Vector.h:1052
float GetAbsMin() const
Definition Vector.h:1291
FVector2D UnitCartesianToSpherical() const
bool IsZero() const
Definition Vector.h:1339
FVector GetAbs() const
Definition Vector.h:1306
static float PointPlaneDist(const FVector &Point, const FVector &PlaneBase, const FVector &PlaneNormal)
Definition Vector.h:997
FVector BoundToCube(float Radius) const
Definition Vector.h:1398
static FORCEINLINE float DistSquared(const FVector &V1, const FVector &V2)
Definition Vector.h:1622
FORCEINLINE FVector GetSignVector() const
Definition Vector.h:1376
FORCEINLINE FVector operator/(const FVector &V) const
Definition Vector.h:1166
static FORCEINLINE float Dist2D(const FVector &V1, const FVector &V2)
Definition Vector.h:751
FVector ComponentMin(const FVector &Other) const
Definition Vector.h:1296
float Size() const
Definition Vector.h:1311
float GetMin() const
Definition Vector.h:1286
float Z
Definition Vector.h:33
FString ToString() const
Definition Vector.h:1637
float & operator[](int32 Index)
Definition Vector.h:1235
static FORCEINLINE float Dist(const FVector &V1, const FVector &V2)
Definition Vector.h:1612
FVector GridSnap(const float &GridSz) const
static bool Coincident(const FVector &Normal1, const FVector &Normal2, float ParallelCosineThreshold=THRESH_NORMALS_ARE_PARALLEL)
Definition Vector.h:1025
FVector Projection() const
Definition Vector.h:1386
static bool Coplanar(const FVector &Base1, const FVector &Normal1, const FVector &Base2, const FVector &Normal2, float ParallelCosineThreshold=THRESH_NORMALS_ARE_PARALLEL)
Definition Vector.h:1037
FORCEINLINE FVector ProjectOnTo(const FVector &A) const
Definition Vector.h:1572
static FVector PointPlaneProject(const FVector &Point, const FVector &PlaneBase, const FVector &PlaneNormal)
Definition Vector.h:1007
bool IsNormalized() const
Definition Vector.h:1356
FORCEINLINE FVector ProjectOnToNormal(const FVector &Normal) const
Definition Vector.h:1577
static FVector PointPlaneProject(const FVector &Point, const FVector &A, const FVector &B, const FVector &C)
void UnwindEuler()
bool Equals(const FVector &V, float Tolerance=KINDA_SMALL_NUMBER) const
Definition Vector.h:1181
FQuat ToOrientationQuat() const
bool operator==(const FVector &V) const
Definition Vector.h:1171
FVector GetClampedToSize2D(float Min, float Max) const
Definition Vector.h:1418
float SizeSquared() const
Definition Vector.h:1316
float operator[](int32 Index) const
Definition Vector.h:1252
FVector GetClampedToSize(float Min, float Max) const
Definition Vector.h:1408
float GetAbsMax() const
Definition Vector.h:1281
static FORCEINLINE float DistSquared2D(const FVector &V1, const FVector &V2)
Definition Vector.h:770
FVector operator/=(float V)
Definition Vector.h:1216
float GetMax() const
Definition Vector.h:1276
FVector(FIntPoint A)
Definition Vector.h:1082
static FORCEINLINE FVector CrossProduct(const FVector &A, const FVector &B)
Definition Vector.h:1115
FVector operator*=(const FVector &V)
Definition Vector.h:1223
void Set(float InX, float InY, float InZ)
Definition Vector.h:1269
FORCEINLINE FVector operator+(const FVector &V) const
Definition Vector.h:1130
FORCEINLINE FVector operator*(float Scale) const
Definition Vector.h:1150
static FVector DegreesToRadians(const FVector &DegVector)
Definition Vector.h:1057
FORCEINLINE CONSTEXPR FVector(float InX, float InY, float InZ)
Definition Vector.h:1067
FORCEINLINE float CosineAngle2D(FVector B) const
Definition Vector.h:1562
bool AllComponentsEqual(float Tolerance=KINDA_SMALL_NUMBER) const
Definition Vector.h:1186
FVector GetClampedToMaxSize2D(float MaxSize) const
Definition Vector.h:1447
static FORCEINLINE float DistXY(const FVector &V1, const FVector &V2)
Definition Vector.h:1617
static void CreateOrthonormalBasis(FVector &XAxis, FVector &YAxis, FVector &ZAxis)
FORCEINLINE bool IsUnit(float LengthSquaredTolerance=KINDA_SMALL_NUMBER) const
Definition Vector.h:1590
FVector RotateAngleAxis(const float AngleDeg, const FVector &Axis) const
Definition Vector.h:942
bool ContainsNaN() const
Definition Vector.h:1583
float HeadingAngle() const
Definition Vector.h:1595
static float EvaluateBezier(const FVector *ControlPoints, int32 NumPoints, TArray< FVector > &OutPoints)
float Component(int32 Index) const
Definition Vector.h:1471
FORCEINLINE FVector(const FVector2D V, float InZ)
Definition Vector.h:931
bool IsNearlyZero(float Tolerance=KINDA_SMALL_NUMBER) const
Definition Vector.h:1331
FORCEINLINE FVector(EForceInit)
Definition Vector.h:1087
static FORCEINLINE float Distance(const FVector &V1, const FVector &V2)
Definition Vector.h:741
bool Normalize(float Tolerance=SMALL_NUMBER)
Definition Vector.h:1344
Definition UE.h:623
static FORCEINLINE uint64 Strtoui64(const CharType *Start, CharType **End, int32 Base)
Definition CString.h:743
static CharType * Stristr(CharType *Str, const CharType *Find)
Definition CString.h:228
static FORCEINLINE CharType * Strstr(CharType *String, const CharType *Find)
Definition CString.h:591
static FORCEINLINE const CharType * Strstr(const CharType *String, const CharType *Find)
Definition CString.h:584
static FORCEINLINE double Atod(const CharType *String)
Definition CString.h:722
static FORCEINLINE int32 Stricmp(const CharType *String1, const CharType *String2)
Definition CString.h:563
static FORCEINLINE int32 Strnicmp(const CharType *String1, const CharType *String2, SIZE_T Count)
Definition CString.h:570
static FORCEINLINE float Atof(const CharType *String)
Definition CString.h:715
static FORCEINLINE int32 Strlen(const CharType *String)
Definition CString.h:577
static FORCEINLINE int32 Atoi(const CharType *String)
Definition CString.h:701
static FORCEINLINE int32 Strncmp(const CharType *String1, const CharType *String2, SIZE_T Count)
Definition CString.h:556
static FORCEINLINE int32 Strtoi(const CharType *Start, CharType **End, int32 Base)
Definition CString.h:729
static const CharType * Stristr(const CharType *Str, const CharType *Find)
Definition CString.h:485
static FORCEINLINE int64 Atoi64(const CharType *String)
Definition CString.h:708
static FORCEINLINE int32 Strcmp(const CharType *String1, const CharType *String2)
Definition CString.h:549
static CharType ToLower(CharType Char)
static bool IsWhitespace(CharType Char)
static CharType ToUpper(CharType Char)
static void FromString(T &Value, const TCHAR *Buffer)
Definition FString.h:1907
static FString ToSanitizedString(const T &Value)
Definition FString.h:1902
static FString ToString(const T &Value)
Definition FString.h:1901
T * Get(bool bEvenIfPendingKill=false)
Definition UE.h:172
FORCEINLINE T * operator->()
Definition UE.h:167
Definition UE.h:399
UObject * GetDefaultObject(bool bCreateIfNeeded)
Definition UE.h:415
static FORCEINLINE bool Compare(TCHAR Lhs, TCHAR Rhs)
Definition FString.h:1926
static FORCEINLINE bool Compare(TCHAR Lhs, TCHAR Rhs)
Definition FString.h:1918
Definition UE.h:343
Definition Base.h:215
UClass * ClassField()
Definition UE.h:277
FString * GetFullName(FString *result, UObject *StopOuter)
Definition UE.h:296
bool IsA(UClass *SomeBase)
Definition UE.h:299
Definition UE.h:306
Definition Other.h:211
UPrimalGameData * PrimalGameDataOverrideField()
Definition GameMode.h:878
UPrimalGameData * PrimalGameDataField()
Definition GameMode.h:877
FPrimalPlayerDataStruct * MyDataField()
Definition Actor.h:5507
FVector * GetWorldLocation(FVector *result)
Definition Actor.h:523
Definition UE.h:355
Definition UE.h:817
static TArray< AActor * > * ServerOctreeOverlapActors(TArray< AActor * > *result, UWorld *theWorld, FVector AtLoc, float Radius, EServerOctreeGroup::Type OctreeType, bool bForceActorLocationDistanceCheck)
Definition Other.h:410
TArray< TAutoWeakObjectPtr< APlayerController > > & PlayerControllerListField()
Definition GameMode.h:425
APlayerController * GetFirstPlayerController()
Definition GameMode.h:538
AGameState * GameStateField()
Definition GameMode.h:409
AlignSpec(unsigned width, wchar_t fill, Alignment align=ALIGN_DEFAULT)
Definition format.h:1835
int precision() const
Definition format.h:1840
Alignment align_
Definition format.h:1833
Alignment align() const
Definition format.h:1838
bool flag(unsigned) const
Definition format.h:1848
char type_prefix() const
Definition format.h:1850
AlignTypeSpec(unsigned width, wchar_t fill)
Definition format.h:1846
char type() const
Definition format.h:1849
BasicCStringRef< Char > sep
Definition format.h:4037
ArgJoin(It first, It last, const BasicCStringRef< Char > &sep)
Definition format.h:4039
char type() const
Definition format.h:1865
int precision() const
Definition format.h:1864
FormatSpec(unsigned width=0, char type=0, wchar_t fill=' ')
Definition format.h:1859
unsigned flags_
Definition format.h:1855
bool flag(unsigned f) const
Definition format.h:1863
char type_prefix() const
Definition format.h:1866
char type() const
Definition format.h:1813
unsigned width() const
Definition format.h:1810
Alignment align() const
Definition format.h:1809
char fill() const
Definition format.h:1815
int precision() const
Definition format.h:1811
bool flag(unsigned) const
Definition format.h:1812
char type_prefix() const
Definition format.h:1814
WidthSpec(unsigned width, wchar_t fill)
Definition format.h:1825
unsigned width_
Definition format.h:1820
wchar_t fill() const
Definition format.h:1828
unsigned width() const
Definition format.h:1827
wchar_t fill_
Definition format.h:1823
static Arg make(const T &value)
Definition format.h:2395
Value Type[N > 0 ? N :+1]
Definition format.h:2374
static Value make(const T &value)
Definition format.h:2377
static const uint32_t POWERS_OF_10_32[]
Definition format.h:1007
static const char DIGITS[]
Definition format.h:1009
static const uint64_t POWERS_OF_10_64[]
Definition format.h:1008
NamedArg(BasicStringRef< Char > argname, const T &value)
Definition format.h:1541
BasicStringRef< Char > name
Definition format.h:1538
NamedArgWithType(BasicStringRef< Char > argname, const T &value)
Definition format.h:1547
static bool is_negative(T value)
Definition format.h:970
void(* FormatFunc)(void *formatter, const void *arg, void *format_str_ptr)
Definition format.h:1169
LongLong long_long_value
Definition format.h:1180
StringValue< wchar_t > wstring
Definition format.h:1188
CustomValue custom
Definition format.h:1189
const void * pointer
Definition format.h:1184
StringValue< signed char > sstring
Definition format.h:1186
ULongLong ulong_long_value
Definition format.h:1181
long double long_double_value
Definition format.h:1183
StringValue< char > string
Definition format.h:1185
unsigned uint_value
Definition format.h:1179
StringValue< unsigned char > ustring
Definition format.h:1187
int load(std::memory_order) const
Definition null_mutex.h:33
#define FMT_USE_DEFAULTED_FUNCTIONS
Definition format.h:297
#define FMT_OVERRIDE
Definition format.h:263
#define FMT_ASSERT(condition, message)
Definition format.h:337
#define FMT_MAKE_VALUE(Type, field, TYPE)
Definition format.h:1399
#define FMT_GEN3(f)
Definition format.h:2346
#define FMT_GEN11(f)
Definition format.h:2354
#define FMT_FOR_EACH(f,...)
Definition format.h:3630
#define FMT_FOR_EACH3(f, x0, x1, x2)
Definition format.h:2507
#define FMT_CAPTURE_ARG_W_(id, index)
Definition format.h:3722
#define FMT_MAKE_STR_VALUE(Type, TYPE)
Definition format.h:1461
#define FMT_VARIADIC_VOID(func, arg_type)
Definition format.h:2472
#define FMT_RSEQ_N()
Definition format.h:3626
#define FMT_DISABLE_CONVERSION_TO_INT(Type)
Definition format.h:1266
#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7)
Definition format.h:2517
#define FMT_HAS_GXX_CXX11
Definition format.h:118
#define FMT_STATIC_ASSERT(cond, message)
Definition format.h:1329
#define FMT_USE_VARIADIC_TEMPLATES
Definition format.h:186
#define FMT_MSC_VER
Definition format.h:75
#define FMT_USE_EXTERN_TEMPLATES
Definition format.h:326
#define FMT_GEN1(f)
Definition format.h:2344
#define FMT_CONCAT(a, b)
Definition format.h:1312
#define FMT_DEFINE_INT_FORMATTERS(TYPE)
Definition format.h:1938
#define FMT_SECURE_SCL
Definition format.h:65
#define FMT_GCC_EXTENSION
Definition format.h:117
#define FMT_FOR_EACH1(f, x0)
Definition format.h:2504
#define FMT_GCC_VERSION
Definition format.h:116
#define FMT_HAS_CPP_ATTRIBUTE(x)
Definition format.h:153
#define FMT_CAPTURE_ARG_(id, index)
Definition format.h:3720
#define FMT_FOR_EACH2(f, x0, x1)
Definition format.h:2505
#define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type)
Definition format.h:2489
#define FMT_EXCEPTIONS
Definition format.h:217
#define FMT_FOR_EACH4(f, x0, x1, x2, x3)
Definition format.h:2509
#define FMT_VARIADIC(ReturnType, func,...)
Definition format.h:3708
#define FMT_USE_NOEXCEPT
Definition format.h:230
#define FMT_GEN14(f)
Definition format.h:2357
#define FMT_USE_WINDOWS_H
Definition format.h:1115
#define FMT_USE_RVALUE_REFERENCES
Definition format.h:197
#define FMT_VARIADIC_(Const, Char, ReturnType, func, call,...)
Definition format.h:3660
#define FMT_USE_DELETED_FUNCTIONS
Definition format.h:280
#define FMT_DEFAULTED_COPY_CTOR(TypeName)
Definition format.h:306
#define FMT_HAS_FEATURE(x)
Definition format.h:141
#define FMT_USE_USER_DEFINED_LITERALS
Definition format.h:321
#define FMT_GET_ARG_NAME(type, index)
Definition format.h:3634
#define FMT_DETECTED_NOEXCEPT
Definition format.h:238
#define FMT_GEN13(f)
Definition format.h:2356
#define FMT_HAS_STRING_VIEW
Definition format.h:59
#define FMT_GEN8(f)
Definition format.h:2351
#define FMT_GEN6(f)
Definition format.h:2349
#define FMT_DISPATCH(call)
Definition format.h:1632
#define FMT_API
Definition format.h:94
#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N,...)
Definition format.h:3625
#define FMT_ADD_ARG_NAME(type, index)
Definition format.h:3633
#define FMT_USE_ALLOCATOR_TRAITS
Definition format.h:206
#define FMT_GEN(n, f)
Definition format.h:2343
#define FMT_GEN2(f)
Definition format.h:2345
#define FMT_FOR_EACH_(N, f,...)
Definition format.h:3628
#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs)
Definition format.h:1395
#define FMT_DELETED_OR_UNDEFINED
Definition format.h:290
#define FMT_DTOR_NOEXCEPT
Definition format.h:254
#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U)
Definition format.h:698
#define FMT_NORETURN
Definition format.h:179
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition format.h:291
#define FMT_NARG(...)
Definition format.h:3623
#define FMT_NARG_(...)
Definition format.h:3624
#define FMT_USE_STATIC_ASSERT
Definition format.h:1321
#define FMT_GEN7(f)
Definition format.h:2350
#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8)
Definition format.h:2519
#define FMT_THROW(x)
Definition format.h:222
#define FMT_VARIADIC_W(ReturnType, func,...)
Definition format.h:3714
#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4)
Definition format.h:2511
#define FMT_GEN12(f)
Definition format.h:2355
#define FMT_GEN9(f)
Definition format.h:2352
#define FMT_GEN4(f)
Definition format.h:2347
#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5)
Definition format.h:2513
#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6)
Definition format.h:2515
#define FMT_NOEXCEPT
Definition format.h:243
#define FMT_MAKE_WSTR_VALUE(Type, TYPE)
Definition format.h:1478
#define FMT_EXPAND(args)
Definition format.h:3619
#define FMT_NULL
Definition format.h:273
#define FMT_GEN10(f)
Definition format.h:2353
#define FMT_HAS_INCLUDE(x)
Definition format.h:51
#define FMT_GEN5(f)
Definition format.h:2348