diff --git a/example/example.vcxproj b/example/example.vcxproj
index 2b8c4e55..63db2b5d 100644
--- a/example/example.vcxproj
+++ b/example/example.vcxproj
@@ -56,13 +56,13 @@
Application
true
- v140
+ v120
Unicode
Application
false
- v140
+ v120
true
Unicode
diff --git a/include/spdlog/fmt/bundled/format.cc b/include/spdlog/fmt/bundled/format.cc
index 0f7e0aa2..dbe0c1ec 100644
--- a/include/spdlog/fmt/bundled/format.cc
+++ b/include/spdlog/fmt/bundled/format.cc
@@ -1,557 +1,560 @@
-/*
- Formatting library for C++
-
- Copyright (c) 2012 - 2016, Victor Zverovich
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Commented out by spdlog to use header only
-// #include "fmt/format.h"
-// #include "fmt/printf.h"
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include // for std::ptrdiff_t
-
-#if defined(_WIN32) && defined(__MINGW32__)
-# include
-#endif
-
-#if FMT_USE_WINDOWS_H
-# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
-# include
-# else
-# define NOMINMAX
-# include
-# undef NOMINMAX
-# endif
-#endif
-
-using fmt::internal::Arg;
-
-#if FMT_EXCEPTIONS
-# define FMT_TRY try
-# define FMT_CATCH(x) catch (x)
-#else
-# define FMT_TRY if (true)
-# define FMT_CATCH(x) if (false)
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable: 4127) // conditional expression is constant
-# pragma warning(disable: 4702) // unreachable code
-// Disable deprecation warning for strerror. The latter is not called but
-// MSVC fails to detect it.
-# pragma warning(disable: 4996)
-#endif
-
-// Dummy implementations of strerror_r and strerror_s called if corresponding
-// system functions are not available.
-static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
- return fmt::internal::Null<>();
-}
-static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
- return fmt::internal::Null<>();
-}
-
-namespace fmt {
-
-FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {}
-FMT_FUNC FormatError::~FormatError() throw() {}
-FMT_FUNC SystemError::~SystemError() throw() {}
-
-namespace {
-
-#ifndef _MSC_VER
-# define FMT_SNPRINTF snprintf
-#else // _MSC_VER
-inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
- va_list args;
- va_start(args, format);
- int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
- va_end(args);
- return result;
-}
-# define FMT_SNPRINTF fmt_snprintf
-#endif // _MSC_VER
-
-#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
-# define FMT_SWPRINTF snwprintf
-#else
-# define FMT_SWPRINTF swprintf
-#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
-
-const char RESET_COLOR[] = "\x1b[0m";
-
-typedef void (*FormatFunc)(Writer &, int, StringRef);
-
-// Portable thread-safe version of strerror.
-// Sets buffer to point to a string describing the error code.
-// This can be either a pointer to a string stored in buffer,
-// or a pointer to some static immutable string.
-// Returns one of the following values:
-// 0 - success
-// ERANGE - buffer is not large enough to store the error message
-// other - failure
-// Buffer should be at least of size 1.
-int safe_strerror(
- int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
- FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
-
- class StrError {
- private:
- int error_code_;
- char *&buffer_;
- std::size_t buffer_size_;
-
- // A noop assignment operator to avoid bogus warnings.
- void operator=(const StrError &) {}
-
- // Handle the result of XSI-compliant version of strerror_r.
- int handle(int result) {
- // glibc versions before 2.13 return result in errno.
- return result == -1 ? errno : result;
- }
-
- // Handle the result of GNU-specific version of strerror_r.
- int handle(char *message) {
- // If the buffer is full then the message is probably truncated.
- if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
- return ERANGE;
- buffer_ = message;
- return 0;
- }
-
- // Handle the case when strerror_r is not available.
- int handle(internal::Null<>) {
- return fallback(strerror_s(buffer_, buffer_size_, error_code_));
- }
-
- // Fallback to strerror_s when strerror_r is not available.
- int fallback(int result) {
- // If the buffer is full then the message is probably truncated.
- return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
- ERANGE : result;
- }
-
- // Fallback to strerror if strerror_r and strerror_s are not available.
- int fallback(internal::Null<>) {
- errno = 0;
- buffer_ = strerror(error_code_);
- return errno;
- }
-
- public:
- StrError(int err_code, char *&buf, std::size_t buf_size)
- : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
-
- int run() {
- strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
- return handle(strerror_r(error_code_, buffer_, buffer_size_));
- }
- };
- return StrError(error_code, buffer, buffer_size).run();
-}
-
-void format_error_code(Writer &out, int error_code,
- StringRef message) FMT_NOEXCEPT {
- // Report error code making sure that the output fits into
- // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
- // bad_alloc.
- out.clear();
- static const char SEP[] = ": ";
- static const char ERROR_STR[] = "error ";
- // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
- std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
- typedef internal::IntTraits::MainType MainType;
- MainType abs_value = static_cast(error_code);
- if (internal::is_negative(error_code)) {
- abs_value = 0 - abs_value;
- ++error_code_size;
- }
- error_code_size += internal::count_digits(abs_value);
- if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
- out << message << SEP;
- out << ERROR_STR << error_code;
- assert(out.size() <= internal::INLINE_BUFFER_SIZE);
-}
-
-void report_error(FormatFunc func, int error_code,
- StringRef message) FMT_NOEXCEPT {
- MemoryWriter full_message;
- func(full_message, error_code, message);
- // Use Writer::data instead of Writer::c_str to avoid potential memory
- // allocation.
- std::fwrite(full_message.data(), full_message.size(), 1, stderr);
- std::fputc('\n', stderr);
-}
-} // namespace
-
-namespace internal {
-
-// This method is used to preserve binary compatibility with fmt 3.0.
-// It can be removed in 4.0.
-FMT_FUNC void format_system_error(
- Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
- fmt::format_system_error(out, error_code, message);
-}
-} // namespace internal
-
-FMT_FUNC void SystemError::init(
- int err_code, CStringRef format_str, ArgList args) {
- error_code_ = err_code;
- MemoryWriter w;
- format_system_error(w, err_code, format(format_str, args));
- std::runtime_error &base = *this;
- base = std::runtime_error(w.str());
-}
-
-template
-int internal::CharTraits::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, T value) {
- if (width == 0) {
- return precision < 0 ?
- FMT_SNPRINTF(buffer, size, format, value) :
- FMT_SNPRINTF(buffer, size, format, precision, value);
- }
- return precision < 0 ?
- FMT_SNPRINTF(buffer, size, format, width, value) :
- FMT_SNPRINTF(buffer, size, format, width, precision, value);
-}
-
-template
-int internal::CharTraits::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, T value) {
- if (width == 0) {
- return precision < 0 ?
- FMT_SWPRINTF(buffer, size, format, value) :
- FMT_SWPRINTF(buffer, size, format, precision, value);
- }
- return precision < 0 ?
- FMT_SWPRINTF(buffer, size, format, width, value) :
- FMT_SWPRINTF(buffer, size, format, width, precision, value);
-}
-
-template
-const char internal::BasicData::DIGITS[] =
- "0001020304050607080910111213141516171819"
- "2021222324252627282930313233343536373839"
- "4041424344454647484950515253545556575859"
- "6061626364656667686970717273747576777879"
- "8081828384858687888990919293949596979899";
-
-#define FMT_POWERS_OF_10(factor) \
- factor * 10, \
- factor * 100, \
- factor * 1000, \
- factor * 10000, \
- factor * 100000, \
- factor * 1000000, \
- factor * 10000000, \
- factor * 100000000, \
- factor * 1000000000
-
-template
-const uint32_t internal::BasicData::POWERS_OF_10_32[] = {
- 0, FMT_POWERS_OF_10(1)
-};
-
-template
-const uint64_t internal::BasicData::POWERS_OF_10_64[] = {
- 0,
- FMT_POWERS_OF_10(1),
- FMT_POWERS_OF_10(ULongLong(1000000000)),
- // Multiply several constants instead of using a single long long constant
- // to avoid warnings about C++98 not supporting long long.
- ULongLong(1000000000) * ULongLong(1000000000) * 10
-};
-
-FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
- (void)type;
- if (std::isprint(static_cast(code))) {
- FMT_THROW(FormatError(
- format("unknown format code '{}' for {}", code, type)));
- }
- FMT_THROW(FormatError(
- format("unknown format code '\\x{:02x}' for {}",
- static_cast(code), type)));
-}
-
-#if FMT_USE_WINDOWS_H
-
-FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
- static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
- if (s.size() > INT_MAX)
- FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
- int s_size = static_cast(s.size());
- int length = MultiByteToWideChar(
- CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
- if (length == 0)
- FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
- buffer_.resize(length + 1);
- length = MultiByteToWideChar(
- CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
- if (length == 0)
- FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
- buffer_[length] = 0;
-}
-
-FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
- if (int error_code = convert(s)) {
- FMT_THROW(WindowsError(error_code,
- "cannot convert string from UTF-16 to UTF-8"));
- }
-}
-
-FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) {
- if (s.size() > INT_MAX)
- return ERROR_INVALID_PARAMETER;
- int s_size = static_cast(s.size());
- int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
- if (length == 0)
- return GetLastError();
- buffer_.resize(length + 1);
- length = WideCharToMultiByte(
- CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
- if (length == 0)
- return GetLastError();
- buffer_[length] = 0;
- return 0;
-}
-
-FMT_FUNC void WindowsError::init(
- int err_code, CStringRef format_str, ArgList args) {
- error_code_ = err_code;
- MemoryWriter w;
- internal::format_windows_error(w, err_code, format(format_str, args));
- std::runtime_error &base = *this;
- base = std::runtime_error(w.str());
-}
-
-FMT_FUNC void internal::format_windows_error(
- Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
- FMT_TRY {
- MemoryBuffer buffer;
- buffer.resize(INLINE_BUFFER_SIZE);
- for (;;) {
- wchar_t *system_message = &buffer[0];
- int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- system_message, static_cast(buffer.size()), 0);
- if (result != 0) {
- UTF16ToUTF8 utf8_message;
- if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
- out << message << ": " << utf8_message;
- return;
- }
- break;
- }
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- break; // Can't get error message, report error code instead.
- buffer.resize(buffer.size() * 2);
- }
- } FMT_CATCH(...) {}
- fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
-}
-
-#endif // FMT_USE_WINDOWS_H
-
-FMT_FUNC void format_system_error(
- Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
- FMT_TRY {
- internal::MemoryBuffer buffer;
- buffer.resize(internal::INLINE_BUFFER_SIZE);
- for (;;) {
- char *system_message = &buffer[0];
- int result = safe_strerror(error_code, system_message, buffer.size());
- if (result == 0) {
- out << message << ": " << system_message;
- return;
- }
- if (result != ERANGE)
- break; // Can't get error message, report error code instead.
- buffer.resize(buffer.size() * 2);
- }
- } FMT_CATCH(...) {}
- fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
-}
-
-template
-void internal::ArgMap::init(const ArgList &args) {
- if (!map_.empty())
- return;
- typedef internal::NamedArg NamedArg;
- const NamedArg *named_arg = 0;
- bool use_values =
- args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
- if (use_values) {
- for (unsigned i = 0;/*nothing*/; ++i) {
- internal::Arg::Type arg_type = args.type(i);
- switch (arg_type) {
- case internal::Arg::NONE:
- return;
- case internal::Arg::NAMED_ARG:
- named_arg = static_cast(args.values_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- break;
- default:
- /*nothing*/;
- }
- }
- return;
- }
- for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
- internal::Arg::Type arg_type = args.type(i);
- if (arg_type == internal::Arg::NAMED_ARG) {
- named_arg = static_cast(args.args_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- }
- }
- for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
- switch (args.args_[i].type) {
- case internal::Arg::NONE:
- return;
- case internal::Arg::NAMED_ARG:
- named_arg = static_cast(args.args_[i].pointer);
- map_.push_back(Pair(named_arg->name, *named_arg));
- break;
- default:
- /*nothing*/;
- }
- }
-}
-
-template
-void internal::FixedBuffer::grow(std::size_t) {
- FMT_THROW(std::runtime_error("buffer overflow"));
-}
-
-FMT_FUNC Arg internal::FormatterBase::do_get_arg(
- unsigned arg_index, const char *&error) {
- Arg arg = args_[arg_index];
- switch (arg.type) {
- case Arg::NONE:
- error = "argument index out of range";
- break;
- case Arg::NAMED_ARG:
- arg = *static_cast(arg.pointer);
- break;
- default:
- /*nothing*/;
- }
- return arg;
-}
-
-FMT_FUNC void report_system_error(
- int error_code, fmt::StringRef message) FMT_NOEXCEPT {
- // 'fmt::' is for bcc32.
- report_error(format_system_error, error_code, message);
-}
-
-#if FMT_USE_WINDOWS_H
-FMT_FUNC void report_windows_error(
- int error_code, fmt::StringRef message) FMT_NOEXCEPT {
- // 'fmt::' is for bcc32.
- report_error(internal::format_windows_error, error_code, message);
-}
-#endif
-
-FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
- MemoryWriter w;
- w.write(format_str, args);
- std::fwrite(w.data(), 1, w.size(), f);
-}
-
-FMT_FUNC void print(CStringRef format_str, ArgList args) {
- print(stdout, format_str, args);
-}
-
-FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) {
- char escape[] = "\x1b[30m";
- escape[3] = static_cast('0' + c);
- std::fputs(escape, stdout);
- print(format, args);
- std::fputs(RESET_COLOR, stdout);
-}
-
-template
-void printf(BasicWriter &w, BasicCStringRef format, ArgList args);
-
-FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) {
- MemoryWriter w;
- printf(w, format, args);
- std::size_t size = w.size();
- return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size);
-}
-
-#ifndef FMT_HEADER_ONLY
-
-template struct internal::BasicData;
-
-// Explicit instantiations for char.
-
-template void internal::FixedBuffer::grow(std::size_t);
-
-template void internal::ArgMap::init(const ArgList &args);
-
-template void PrintfFormatter::format(CStringRef format);
-
-template int internal::CharTraits::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, double value);
-
-template int internal::CharTraits::format_float(
- char *buffer, std::size_t size, const char *format,
- unsigned width, int precision, long double value);
-
-// Explicit instantiations for wchar_t.
-
-template void internal::FixedBuffer::grow(std::size_t);
-
-template void internal::ArgMap::init(const ArgList &args);
-
-template void PrintfFormatter::format(WCStringRef format);
-
-template int internal::CharTraits::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, double value);
-
-template int internal::CharTraits::format_float(
- wchar_t *buffer, std::size_t size, const wchar_t *format,
- unsigned width, int precision, long double value);
-
-#endif // FMT_HEADER_ONLY
-
-} // namespace fmt
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
+/*
+Formatting library for C++
+
+Copyright (c) 2012 - 2016, Victor Zverovich
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// commented out by spdlog
+// #include "format.h"
+// #include "printf.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include // for std::ptrdiff_t
+
+#if defined(_WIN32) && defined(__MINGW32__)
+# include
+#endif
+
+#if FMT_USE_WINDOWS_H
+# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
+# include
+# else
+# define NOMINMAX
+# include
+# undef NOMINMAX
+# endif
+#endif
+
+using fmt::internal::Arg;
+
+#if FMT_EXCEPTIONS
+# define FMT_TRY try
+# define FMT_CATCH(x) catch (x)
+#else
+# define FMT_TRY if (true)
+# define FMT_CATCH(x) if (false)
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4702) // unreachable code
+// Disable deprecation warning for strerror. The latter is not called but
+// MSVC fails to detect it.
+# pragma warning(disable: 4996)
+#endif
+
+// Dummy implementations of strerror_r and strerror_s called if corresponding
+// system functions are not available.
+static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
+ return fmt::internal::Null<>();
+}
+static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
+ return fmt::internal::Null<>();
+}
+
+namespace fmt {
+
+FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {}
+FMT_FUNC FormatError::~FormatError() throw() {}
+FMT_FUNC SystemError::~SystemError() throw() {}
+
+namespace {
+
+#ifndef _MSC_VER
+# define FMT_SNPRINTF snprintf
+#else // _MSC_VER
+inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
+ va_end(args);
+ return result;
+}
+# define FMT_SNPRINTF fmt_snprintf
+#endif // _MSC_VER
+
+#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+# define FMT_SWPRINTF snwprintf
+#else
+# define FMT_SWPRINTF swprintf
+#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+
+const char RESET_COLOR[] = "\x1b[0m";
+
+typedef void(*FormatFunc)(Writer &, int, StringRef);
+
+// Portable thread-safe version of strerror.
+// Sets buffer to point to a string describing the error code.
+// This can be either a pointer to a string stored in buffer,
+// or a pointer to some static immutable string.
+// Returns one of the following values:
+// 0 - success
+// ERANGE - buffer is not large enough to store the error message
+// other - failure
+// Buffer should be at least of size 1.
+int safe_strerror(
+ int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT{
+ FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
+
+ class StrError {
+ private:
+ int error_code_;
+ char *&buffer_;
+ std::size_t buffer_size_;
+
+ // A noop assignment operator to avoid bogus warnings.
+ void operator=(const StrError &) {}
+
+ // Handle the result of XSI-compliant version of strerror_r.
+ int handle(int result) {
+ // glibc versions before 2.13 return result in errno.
+ return result == -1 ? errno : result;
+ }
+
+ // Handle the result of GNU-specific version of strerror_r.
+ int handle(char *message) {
+ // If the buffer is full then the message is probably truncated.
+ if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
+ return ERANGE;
+ buffer_ = message;
+ return 0;
+ }
+
+ // Handle the case when strerror_r is not available.
+ int handle(internal::Null<>) {
+ return fallback(strerror_s(buffer_, buffer_size_, error_code_));
+ }
+
+ // Fallback to strerror_s when strerror_r is not available.
+ int fallback(int result) {
+ // If the buffer is full then the message is probably truncated.
+ return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
+ ERANGE : result;
+ }
+
+ // Fallback to strerror if strerror_r and strerror_s are not available.
+ int fallback(internal::Null<>) {
+ errno = 0;
+ buffer_ = strerror(error_code_);
+ return errno;
+ }
+
+ public:
+ StrError(int err_code, char *&buf, std::size_t buf_size)
+ : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
+
+ int run() {
+ strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
+ return handle(strerror_r(error_code_, buffer_, buffer_size_));
+ }
+ };
+ return StrError(error_code, buffer, buffer_size).run();
+}
+
+void format_error_code(Writer &out, int error_code,
+ StringRef message) FMT_NOEXCEPT{
+ // Report error code making sure that the output fits into
+ // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
+ // bad_alloc.
+ out.clear();
+ static const char SEP[] = ": ";
+ static const char ERROR_STR[] = "error ";
+ // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
+ std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
+ typedef internal::IntTraits::MainType MainType;
+ MainType abs_value = static_cast(error_code);
+ if (internal::is_negative(error_code)) {
+ abs_value = 0 - abs_value;
+ ++error_code_size;
+ }
+ error_code_size += internal::count_digits(abs_value);
+ if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
+ out << message << SEP;
+ out << ERROR_STR << error_code;
+ assert(out.size() <= internal::INLINE_BUFFER_SIZE);
+}
+
+void report_error(FormatFunc func, int error_code,
+ StringRef message) FMT_NOEXCEPT{
+ MemoryWriter full_message;
+ func(full_message, error_code, message);
+ // Use Writer::data instead of Writer::c_str to avoid potential memory
+ // allocation.
+ std::fwrite(full_message.data(), full_message.size(), 1, stderr);
+ std::fputc('\n', stderr);
+}
+} // namespace
+
+namespace internal {
+
+// This method is used to preserve binary compatibility with fmt 3.0.
+// It can be removed in 4.0.
+FMT_FUNC void format_system_error(
+ Writer &out, int error_code, StringRef message) FMT_NOEXCEPT{
+ fmt::format_system_error(out, error_code, message);
+}
+} // namespace internal
+
+FMT_FUNC void SystemError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ format_system_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+template
+int internal::CharTraits::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, value) :
+ FMT_SNPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, width, value) :
+ FMT_SNPRINTF(buffer, size, format, width, precision, value);
+}
+
+template
+int internal::CharTraits::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, value) :
+ FMT_SWPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, width, value) :
+ FMT_SWPRINTF(buffer, size, format, width, precision, value);
+}
+
+template
+const char internal::BasicData::DIGITS[] =
+ "0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899";
+
+#define FMT_POWERS_OF_10(factor) \
+ factor * 10, \
+ factor * 100, \
+ factor * 1000, \
+ factor * 10000, \
+ factor * 100000, \
+ factor * 1000000, \
+ factor * 10000000, \
+ factor * 100000000, \
+ factor * 1000000000
+
+template
+const uint32_t internal::BasicData::POWERS_OF_10_32[] = {
+ 0, FMT_POWERS_OF_10(1)
+};
+
+template
+const uint64_t internal::BasicData::POWERS_OF_10_64[] = {
+ 0,
+ FMT_POWERS_OF_10(1),
+ FMT_POWERS_OF_10(ULongLong(1000000000)),
+ // Multiply several constants instead of using a single long long constant
+ // to avoid warnings about C++98 not supporting long long.
+ ULongLong(1000000000) * ULongLong(1000000000) * 10
+};
+
+FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
+ (void)type;
+ if (std::isprint(static_cast(code))) {
+ FMT_THROW(FormatError(
+ format("unknown format code '{}' for {}", code, type)));
+ }
+ FMT_THROW(FormatError(
+ format("unknown format code '\\x{:02x}' for {}",
+ static_cast(code), type)));
+}
+
+#if FMT_USE_WINDOWS_H
+
+FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
+ static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
+ if (s.size() > INT_MAX)
+ FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
+ int s_size = static_cast(s.size());
+ int length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_.resize(length + 1);
+ length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_[length] = 0;
+}
+
+FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
+ if (int error_code = convert(s)) {
+ FMT_THROW(WindowsError(error_code,
+ "cannot convert string from UTF-16 to UTF-8"));
+ }
+}
+
+FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) {
+ if (s.size() > INT_MAX)
+ return ERROR_INVALID_PARAMETER;
+ int s_size = static_cast(s.size());
+ int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
+ if (length == 0)
+ return GetLastError();
+ buffer_.resize(length + 1);
+ length = WideCharToMultiByte(
+ CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
+ if (length == 0)
+ return GetLastError();
+ buffer_[length] = 0;
+ return 0;
+}
+
+FMT_FUNC void WindowsError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ internal::format_windows_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+FMT_FUNC void internal::format_windows_error(
+ Writer &out, int error_code, StringRef message) FMT_NOEXCEPT{
+ FMT_TRY{
+ MemoryBuffer buffer;
+ buffer.resize(INLINE_BUFFER_SIZE);
+ for (;;) {
+ wchar_t *system_message = &buffer[0];
+ int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ system_message, static_cast(buffer.size()), 0);
+ if (result != 0) {
+ UTF16ToUTF8 utf8_message;
+ if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
+ out << message << ": " << utf8_message;
+ return;
+ }
+ break;
+ }
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+#endif // FMT_USE_WINDOWS_H
+
+FMT_FUNC void format_system_error(
+ Writer &out, int error_code, StringRef message) FMT_NOEXCEPT{
+ FMT_TRY{
+ internal::MemoryBuffer buffer;
+ buffer.resize(internal::INLINE_BUFFER_SIZE);
+ for (;;) {
+ char *system_message = &buffer[0];
+ int result = safe_strerror(error_code, system_message, buffer.size());
+ if (result == 0) {
+ out << message << ": " << system_message;
+ return;
+ }
+ if (result != ERANGE)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+template
+void internal::ArgMap::init(const ArgList &args) {
+ if (!map_.empty())
+ return;
+ typedef internal::NamedArg NamedArg;
+ const NamedArg *named_arg = 0;
+ bool use_values =
+ args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
+ if (use_values) {
+ for (unsigned i = 0;/*nothing*/; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ switch (arg_type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast(args.values_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/
+ ;
+ }
+ }
+ return;
+ }
+ for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ if (arg_type == internal::Arg::NAMED_ARG) {
+ named_arg = static_cast(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ }
+ }
+ for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
+ switch (args.args_[i].type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/
+ ;
+ }
+ }
+}
+
+template
+void internal::FixedBuffer::grow(std::size_t) {
+ FMT_THROW(std::runtime_error("buffer overflow"));
+}
+
+FMT_FUNC Arg internal::FormatterBase::do_get_arg(
+ unsigned arg_index, const char *&error) {
+ Arg arg = args_[arg_index];
+ switch (arg.type) {
+ case Arg::NONE:
+ error = "argument index out of range";
+ break;
+ case Arg::NAMED_ARG:
+ arg = *static_cast(arg.pointer);
+ break;
+ default:
+ /*nothing*/
+ ;
+ }
+ return arg;
+}
+
+FMT_FUNC void report_system_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT{
+ // 'fmt::' is for bcc32.
+ report_error(format_system_error, error_code, message);
+}
+
+#if FMT_USE_WINDOWS_H
+FMT_FUNC void report_windows_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT{
+ // 'fmt::' is for bcc32.
+ report_error(internal::format_windows_error, error_code, message);
+}
+#endif
+
+FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
+ MemoryWriter w;
+ w.write(format_str, args);
+ std::fwrite(w.data(), 1, w.size(), f);
+}
+
+FMT_FUNC void print(CStringRef format_str, ArgList args) {
+ print(stdout, format_str, args);
+}
+
+FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) {
+ char escape[] = "\x1b[30m";
+ escape[3] = static_cast('0' + c);
+ std::fputs(escape, stdout);
+ print(format, args);
+ std::fputs(RESET_COLOR, stdout);
+}
+
+template
+void printf(BasicWriter &w, BasicCStringRef format, ArgList args);
+
+FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) {
+ MemoryWriter w;
+ printf(w, format, args);
+ std::size_t size = w.size();
+ return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size);
+}
+
+#ifndef FMT_HEADER_ONLY
+
+template struct internal::BasicData;
+
+// Explicit instantiations for char.
+
+template void internal::FixedBuffer::grow(std::size_t);
+
+template void internal::ArgMap::init(const ArgList &args);
+
+template void PrintfFormatter::format(CStringRef format);
+
+template int internal::CharTraits::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, double value);
+
+template int internal::CharTraits::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, long double value);
+
+// Explicit instantiations for wchar_t.
+
+template void internal::FixedBuffer::grow(std::size_t);
+
+template void internal::ArgMap::init(const ArgList &args);
+
+template void PrintfFormatter::format(WCStringRef format);
+
+template int internal::CharTraits::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, double value);
+
+template int internal::CharTraits::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, long double value);
+
+#endif // FMT_HEADER_ONLY
+
+} // namespace fmt
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
\ No newline at end of file
diff --git a/include/spdlog/fmt/bundled/format.h b/include/spdlog/fmt/bundled/format.h
index 294a686f..0309bca5 100644
--- a/include/spdlog/fmt/bundled/format.h
+++ b/include/spdlog/fmt/bundled/format.h
@@ -1,4455 +1,4069 @@
-/*
- Formatting library for C++
-
- Copyright (c) 2012 - 2016, Victor Zverovich
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef FMT_FORMAT_H_
-#define FMT_FORMAT_H_
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef _SECURE_SCL
-# define FMT_SECURE_SCL _SECURE_SCL
-#else
-# define FMT_SECURE_SCL 0
-#endif
-
-#if FMT_SECURE_SCL
-# include
-#endif
-
-#ifdef _MSC_VER
-# define FMT_MSC_VER _MSC_VER
-#else
-# define FMT_MSC_VER 0
-#endif
-
-#if FMT_MSC_VER && FMT_MSC_VER <= 1500
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64 intmax_t;
-#else
-#include
-#endif
-
-#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
-# ifdef FMT_EXPORT
-# define FMT_API __declspec(dllexport)
-# elif defined(FMT_SHARED)
-# define FMT_API __declspec(dllimport)
-# endif
-#endif
-#ifndef FMT_API
-# define FMT_API
-#endif
-
-#ifdef __GNUC__
-# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
-# define FMT_GCC_EXTENSION __extension__
-# if FMT_GCC_VERSION >= 406
-# pragma GCC diagnostic push
-// Disable the warning about "long long" which is sometimes reported even
-// when using __extension__.
-# pragma GCC diagnostic ignored "-Wlong-long"
-// Disable the warning about declaration shadowing because it affects too
-// many valid cases.
-# pragma GCC diagnostic ignored "-Wshadow"
-// Disable the warning about implicit conversions that may change the sign of
-// an integer; silencing it otherwise would require many explicit casts.
-# pragma GCC diagnostic ignored "-Wsign-conversion"
-# endif
-# if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
-# define FMT_HAS_GXX_CXX11 1
-# endif
-#else
-# define FMT_GCC_EXTENSION
-#endif
-
-#if defined(__INTEL_COMPILER)
-# define FMT_ICC_VERSION __INTEL_COMPILER
-#elif defined(__ICL)
-# define FMT_ICC_VERSION __ICL
-#endif
-
-#if defined(__clang__) && !defined(FMT_ICC_VERSION)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
-# pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-#ifdef __GNUC_LIBSTD__
-# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
-#endif
-
-#ifdef __has_feature
-# define FMT_HAS_FEATURE(x) __has_feature(x)
-#else
-# define FMT_HAS_FEATURE(x) 0
-#endif
-
-#ifdef __has_builtin
-# define FMT_HAS_BUILTIN(x) __has_builtin(x)
-#else
-# define FMT_HAS_BUILTIN(x) 0
-#endif
-
-#ifdef __has_cpp_attribute
-# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
-#else
-# define FMT_HAS_CPP_ATTRIBUTE(x) 0
-#endif
-
-#ifndef FMT_USE_VARIADIC_TEMPLATES
-// Variadic templates are available in GCC since version 4.4
-// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
-// since version 2013.
-# define FMT_USE_VARIADIC_TEMPLATES \
- (FMT_HAS_FEATURE(cxx_variadic_templates) || \
- (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800)
-#endif
-
-#ifndef FMT_USE_RVALUE_REFERENCES
-// Don't use rvalue references when compiling with clang and an old libstdc++
-// as the latter doesn't provide std::move.
-# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
-# define FMT_USE_RVALUE_REFERENCES 0
-# else
-# define FMT_USE_RVALUE_REFERENCES \
- (FMT_HAS_FEATURE(cxx_rvalue_references) || \
- (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600)
-# endif
-#endif
-
-#if FMT_USE_RVALUE_REFERENCES
-# include // for std::move
-#endif
-
-// Check if exceptions are disabled.
-#if defined(__GNUC__) && !defined(__EXCEPTIONS)
-# define FMT_EXCEPTIONS 0
-#endif
-#if FMT_MSC_VER && !_HAS_EXCEPTIONS
-# define FMT_EXCEPTIONS 0
-#endif
-#ifndef FMT_EXCEPTIONS
-# define FMT_EXCEPTIONS 1
-#endif
-
-#ifndef FMT_THROW
-# if FMT_EXCEPTIONS
-# define FMT_THROW(x) throw x
-# else
-# define FMT_THROW(x) assert(false)
-# endif
-#endif
-
-// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
-#ifndef FMT_USE_NOEXCEPT
-# define FMT_USE_NOEXCEPT 0
-#endif
-
-#ifndef FMT_NOEXCEPT
-# if FMT_EXCEPTIONS
-# if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
- (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
- FMT_MSC_VER >= 1900
-# define FMT_NOEXCEPT noexcept
-# else
-# define FMT_NOEXCEPT throw()
-# endif
-# else
-# define FMT_NOEXCEPT
-# endif
-#endif
-
-// A macro to disallow the copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#ifndef FMT_USE_DELETED_FUNCTIONS
-# define FMT_USE_DELETED_FUNCTIONS 0
-#endif
-
-#if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \
- (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
-# define FMT_DELETED_OR_UNDEFINED = delete
-# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&) = delete; \
- TypeName& operator=(const TypeName&) = delete
-#else
-# define FMT_DELETED_OR_UNDEFINED
-# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- TypeName& operator=(const TypeName&)
-#endif
-
-#ifndef FMT_USE_USER_DEFINED_LITERALS
-// All compilers which support UDLs also support variadic templates. This
-// makes the fmt::literals implementation easier. However, an explicit check
-// for variadic templates is added here just in case.
-// For Intel's compiler both it and the system gcc/msc must support UDLs.
-# define FMT_USE_USER_DEFINED_LITERALS \
- FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
- (FMT_HAS_FEATURE(cxx_user_literals) || \
- (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \
- (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
-#endif
-
-#ifndef FMT_ASSERT
-# define FMT_ASSERT(condition, message) assert((condition) && message)
-#endif
-
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
-# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
-#endif
-
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
-# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
-#endif
-
-// Some compilers masquerade as both MSVC and GCC-likes or
-// otherwise support __builtin_clz and __builtin_clzll, so
-// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
-// if the clz and clzll builtins are not available.
-#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
-# include // _BitScanReverse, _BitScanReverse64
-
-namespace fmt
-{
-namespace internal
-{
-# pragma intrinsic(_BitScanReverse)
-inline uint32_t clz(uint32_t x)
-{
- unsigned long r = 0;
- _BitScanReverse(&r, x);
-
- assert(x != 0);
- // Static analysis complains about using uninitialized data
- // "r", but the only way that can happen is if "x" is 0,
- // which the callers guarantee to not happen.
-# pragma warning(suppress: 6102)
- return 31 - r;
-}
-# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
-
-# ifdef _WIN64
-# pragma intrinsic(_BitScanReverse64)
-# endif
-
-inline uint32_t clzll(uint64_t x)
-{
- unsigned long r = 0;
-# ifdef _WIN64
- _BitScanReverse64(&r, x);
-# else
- // Scan the high 32 bits.
- if (_BitScanReverse(&r, static_cast(x >> 32)))
- return 63 - (r + 32);
-
- // Scan the low 32 bits.
- _BitScanReverse(&r, static_cast(x));
-# endif
-
- assert(x != 0);
- // Static analysis complains about using uninitialized data
- // "r", but the only way that can happen is if "x" is 0,
- // which the callers guarantee to not happen.
-# pragma warning(suppress: 6102)
- return 63 - r;
-}
-# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
-}
-}
-#endif
-
-namespace fmt
-{
-namespace internal
-{
-struct DummyInt
-{
- int data[2];
- operator int() const
- {
- return 0;
- }
-};
-typedef std::numeric_limits FPUtil;
-
-// Dummy implementations of system functions such as signbit and ecvt called
-// if the latter are not available.
-inline DummyInt signbit(...)
-{
- return DummyInt();
-}
-inline DummyInt _ecvt_s(...)
-{
- return DummyInt();
-}
-inline DummyInt isinf(...)
-{
- return DummyInt();
-}
-inline DummyInt _finite(...)
-{
- return DummyInt();
-}
-inline DummyInt isnan(...)
-{
- return DummyInt();
-}
-inline DummyInt _isnan(...)
-{
- return DummyInt();
-}
-
-// A helper function to suppress bogus "conditional expression is constant"
-// warnings.
-template
-inline T const_check(T value)
-{
- return value;
-}
-}
-} // namespace fmt
-
-namespace std
-{
-// Standard permits specialization of std::numeric_limits. This specialization
-// is used to resolve ambiguity between isinf and std::isinf in glibc:
-// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
-// and the same for isnan and signbit.
-template <>
-class numeric_limits :
- public std::numeric_limits
-{
-public:
- // Portable version of isinf.
- template
- static bool isinfinity(T x)
- {
- using namespace fmt::internal;
- // The resolution "priority" is:
- // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
- if (const_check(sizeof(isinf(x)) == sizeof(bool) ||
- sizeof(isinf(x)) == sizeof(int)))
- {
- return isinf(x) != 0;
- }
- return !_finite(static_cast(x));
- }
-
- // Portable version of isnan.
- template
- static bool isnotanumber(T x)
- {
- using namespace fmt::internal;
- if (const_check(sizeof(isnan(x)) == sizeof(bool) ||
- sizeof(isnan(x)) == sizeof(int)))
- {
- return isnan(x) != 0;
- }
- return _isnan(static_cast(x)) != 0;
- }
-
- // Portable version of signbit.
- static bool isnegative(double x)
- {
- using namespace fmt::internal;
- if (const_check(sizeof(signbit(x)) == sizeof(int)))
- return signbit(x) != 0;
- if (x < 0) return true;
- if (!isnotanumber(x)) return false;
- int dec = 0, sign = 0;
- char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
- _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
- return sign != 0;
- }
-};
-} // namespace std
-
-namespace fmt
-{
-
-// Fix the warning about long long on older versions of GCC
-// that don't support the diagnostic pragma.
-FMT_GCC_EXTENSION typedef long long LongLong;
-FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
-
-#if FMT_USE_RVALUE_REFERENCES
-using std::move;
-#endif
-
-template
-class BasicWriter;
-
-typedef BasicWriter Writer;
-typedef BasicWriter WWriter;
-
-template
-class ArgFormatter;
-
-template
-class BasicPrintfArgFormatter;
-
-template >
-class BasicFormatter;
-
-/**
- \rst
- A string reference. It can be constructed from a C string or ``std::string``.
-
- You can use one of the following typedefs for common character types:
-
- +------------+-------------------------+
- | Type | Definition |
- +============+=========================+
- | StringRef | BasicStringRef |
- +------------+-------------------------+
- | WStringRef | BasicStringRef |
- +------------+-------------------------+
-
- This class is most useful as a parameter type to allow passing
- different types of strings to a function, for example::
-
- template
- std::string format(StringRef format_str, const Args & ... args);
-
- format("{}", 42);
- format(std::string("{}"), 42);
- \endrst
- */
-template
-class BasicStringRef
-{
-private:
- const Char *data_;
- std::size_t size_;
-
-public:
- /** Constructs a string reference object from a C string and a size. */
- BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {}
-
- /**
- \rst
- Constructs a string reference object from a C string computing
- the size with ``std::char_traits::length``.
- \endrst
- */
- BasicStringRef(const Char *s)
- : data_(s), size_(std::char_traits::length(s)) {}
-
- /**
- \rst
- Constructs a string reference from an ``std::string`` object.
- \endrst
- */
- BasicStringRef(const std::basic_string &s)
- : data_(s.c_str()), size_(s.size()) {}
-
- /**
- \rst
- Converts a string reference to an ``std::string`` object.
- \endrst
- */
- std::basic_string to_string() const
- {
- return std::basic_string(data_, size_);
- }
-
- /** Returns a pointer to the string data. */
- const Char *data() const
- {
- return data_;
- }
-
- /** Returns the string size. */
- std::size_t size() const
- {
- return size_;
- }
-
- // Lexicographically compare this string reference to other.
- int compare(BasicStringRef other) const
- {
- std::size_t size = size_ < other.size_ ? size_ : other.size_;
- int result = std::char_traits::compare(data_, other.data_, size);
- if (result == 0)
- result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
- return result;
- }
-
- friend bool operator==(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) == 0;
- }
- friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) != 0;
- }
- friend bool operator<(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) < 0;
- }
- friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) <= 0;
- }
- friend bool operator>(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) > 0;
- }
- friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs)
- {
- return lhs.compare(rhs) >= 0;
- }
-};
-
-typedef BasicStringRef StringRef;
-typedef BasicStringRef WStringRef;
-
-/**
- \rst
- A reference to a null terminated string. It can be constructed from a C
- string or ``std::string``.
-
- You can use one of the following typedefs for common character types:
-
- +-------------+--------------------------+
- | Type | Definition |
- +=============+==========================+
- | CStringRef | BasicCStringRef |
- +-------------+--------------------------+
- | WCStringRef | BasicCStringRef |
- +-------------+--------------------------+
-
- This class is most useful as a parameter type to allow passing
- different types of strings to a function, for example::
-
- template
- std::string format(CStringRef format_str, const Args & ... args);
-
- format("{}", 42);
- format(std::string("{}"), 42);
- \endrst
- */
-template
-class BasicCStringRef
-{
-private:
- const Char *data_;
-
-public:
- /** Constructs a string reference object from a C string. */
- BasicCStringRef(const Char *s) : data_(s) {}
-
- /**
- \rst
- Constructs a string reference from an ``std::string`` object.
- \endrst
- */
- BasicCStringRef(const std::basic_string &s) : data_(s.c_str()) {}
-
- /** Returns the pointer to a C string. */
- const Char *c_str() const
- {
- return data_;
- }
-};
-
-typedef BasicCStringRef CStringRef;
-typedef BasicCStringRef WCStringRef;
-
-/** A formatting error such as invalid format string. */
-class FormatError : public std::runtime_error
-{
-public:
- explicit FormatError(CStringRef message)
- : std::runtime_error(message.c_str()) {}
- ~FormatError() throw();
-};
-
-namespace internal
-{
-
-// MakeUnsigned::Type gives an unsigned type corresponding to integer type T.
-template
-struct MakeUnsigned
-{
- typedef T Type;
-};
-
-#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
- template <> \
- struct MakeUnsigned { typedef U Type; }
-
-FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
-FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
-FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
-FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
-
-// Casts nonnegative integer to unsigned.
-template
-inline typename MakeUnsigned::Type to_unsigned(Int value)
-{
- FMT_ASSERT(value >= 0, "negative value");
- return static_cast::Type>(value);
-}
-
-// The number of characters to store in the MemoryBuffer object itself
-// to avoid dynamic memory allocation.
-enum { INLINE_BUFFER_SIZE = 500 };
-
-#if FMT_SECURE_SCL
-// Use checked iterator to avoid warnings on MSVC.
-template
-inline stdext::checked_array_iterator make_ptr(T *ptr, std::size_t size)
-{
- return stdext::checked_array_iterator(ptr, size);
-}
-#else
-template
-inline T *make_ptr(T *ptr, std::size_t)
-{
- return ptr;
-}
-#endif
-} // namespace internal
-
-/**
- \rst
- A buffer supporting a subset of ``std::vector``'s operations.
- \endrst
- */
-template
-class Buffer
-{
-private:
- FMT_DISALLOW_COPY_AND_ASSIGN(Buffer);
-
-protected:
- T *ptr_;
- std::size_t size_;
- std::size_t capacity_;
-
- Buffer(T *ptr = 0, std::size_t capacity = 0)
- : ptr_(ptr), size_(0), capacity_(capacity) {}
-
- /**
- \rst
- Increases the buffer capacity to hold at least *size* elements updating
- ``ptr_`` and ``capacity_``.
- \endrst
- */
- virtual void grow(std::size_t size) = 0;
-
-public:
- virtual ~Buffer() {}
-
- /** Returns the size of this buffer. */
- std::size_t size() const
- {
- return size_;
- }
-
- /** Returns the capacity of this buffer. */
- std::size_t capacity() const
- {
- return capacity_;
- }
-
- /**
- Resizes the buffer. If T is a POD type new elements may not be initialized.
- */
- void resize(std::size_t new_size)
- {
- if (new_size > capacity_)
- grow(new_size);
- size_ = new_size;
- }
-
- /**
- \rst
- Reserves space to store at least *capacity* elements.
- \endrst
- */
- void reserve(std::size_t capacity)
- {
- if (capacity > capacity_)
- grow(capacity);
- }
-
- void clear() FMT_NOEXCEPT { size_ = 0; }
-
- void push_back(const T &value)
- {
- if (size_ == capacity_)
- grow(size_ + 1);
- ptr_[size_++] = value;
- }
-
- /** Appends data to the end of the buffer. */
- template
- void append(const U *begin, const U *end);
-
- T &operator[](std::size_t index)
- {
- return ptr_[index];
- }
- const T &operator[](std::size_t index) const
- {
- return ptr_[index];
- }
-};
-
-template
-template
-void Buffer::append(const U *begin, const U *end)
-{
- std::size_t new_size = size_ + internal::to_unsigned(end - begin);
- if (new_size > capacity_)
- grow(new_size);
- std::uninitialized_copy(begin, end,
- internal::make_ptr(ptr_, capacity_) + size_);
- size_ = new_size;
-}
-
-namespace internal
-{
-
-// A memory buffer for trivially copyable/constructible types with the first
-// SIZE elements stored in the object itself.
-template >
-class MemoryBuffer : private Allocator, public Buffer
-{
-private:
- T data_[SIZE];
-
- // Deallocate memory allocated by the buffer.
- void deallocate()
- {
- if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
- }
-
-protected:
- void grow(std::size_t size);
-
-public:
- explicit MemoryBuffer(const Allocator &alloc = Allocator())
- : Allocator(alloc), Buffer(data_, SIZE) {}
- ~MemoryBuffer()
- {
- deallocate();
- }
-
-#if FMT_USE_RVALUE_REFERENCES
-private:
- // Move data from other to this buffer.
- void move(MemoryBuffer &other)
- {
- Allocator &this_alloc = *this, &other_alloc = other;
- this_alloc = std::move(other_alloc);
- this->size_ = other.size_;
- this->capacity_ = other.capacity_;
- if (other.ptr_ == other.data_)
- {
- this->ptr_ = data_;
- std::uninitialized_copy(other.data_, other.data_ + this->size_,
- make_ptr(data_, this->capacity_));
- }
- else
- {
- this->ptr_ = other.ptr_;
- // Set pointer to the inline array so that delete is not called
- // when deallocating.
- other.ptr_ = other.data_;
- }
- }
-
-public:
- MemoryBuffer(MemoryBuffer &&other)
- {
- move(other);
- }
-
- MemoryBuffer &operator=(MemoryBuffer &&other)
- {
- assert(this != &other);
- deallocate();
- move(other);
- return *this;
- }
-#endif
-
- // Returns a copy of the allocator associated with this buffer.
- Allocator get_allocator() const
- {
- return *this;
- }
-};
-
-template
-void MemoryBuffer::grow(std::size_t size)
-{
- std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
- if (size > new_capacity)
- new_capacity = size;
- T *new_ptr = this->allocate(new_capacity);
- // The following code doesn't throw, so the raw pointer above doesn't leak.
- std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
- make_ptr(new_ptr, new_capacity));
- std::size_t old_capacity = this->capacity_;
- T *old_ptr = this->ptr_;
- this->capacity_ = new_capacity;
- this->ptr_ = new_ptr;
- // deallocate may throw (at least in principle), but it doesn't matter since
- // the buffer already uses the new storage and will deallocate it in case
- // of exception.
- if (old_ptr != data_)
- Allocator::deallocate(old_ptr, old_capacity);
-}
-
-// A fixed-size buffer.
-template
-class FixedBuffer : public fmt::Buffer
-{
-public:
- FixedBuffer(Char *array, std::size_t size) : fmt::Buffer(array, size) {}
-
-protected:
- FMT_API void grow(std::size_t size);
-};
-
-template
-class BasicCharTraits
-{
-public:
-#if FMT_SECURE_SCL
- typedef stdext::checked_array_iterator CharPtr;
-#else
- typedef Char *CharPtr;
-#endif
- static Char cast(int value)
- {
- return static_cast(value);
- }
-};
-
-template
-class CharTraits;
-
-template <>
-class CharTraits : public BasicCharTraits
-{
-private:
- // Conversion from wchar_t to char is not allowed.
- static char convert(wchar_t);
-
-public:
- static char convert(char value)
- {
- return value;
- }
-
- // Formats a floating-point number.
- template
- FMT_API static int format_float(char *buffer, std::size_t size,
- const char *format, unsigned width, int precision, T value);
-};
-
-template <>
-class CharTraits : public BasicCharTraits
-{
-public:
- static wchar_t convert(char value)
- {
- return value;
- }
- static wchar_t convert(wchar_t value)
- {
- return value;
- }
-
- template
- FMT_API static int format_float(wchar_t *buffer, std::size_t size,
- const wchar_t *format, unsigned width, int precision, T value);
-};
-
-// Checks if a number is negative - used to avoid warnings.
-template
-struct SignChecker
-{
- template
- static bool is_negative(T value)
- {
- return value < 0;
- }
-};
-
-template <>
-struct SignChecker
-{
- template
- static bool is_negative(T)
- {
- return false;
- }
-};
-
-// Returns true if value is negative, false otherwise.
-// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
-template
-inline bool is_negative(T value)
-{
- return SignChecker::is_signed>::is_negative(value);
-}
-
-// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
-template
-struct TypeSelector
-{
- typedef uint32_t Type;
-};
-
-template <>
-struct TypeSelector
-{
- typedef uint64_t Type;
-};
-
-template
-struct IntTraits
-{
- // Smallest of uint32_t and uint64_t that is large enough to represent
- // all values of T.
- typedef typename
- TypeSelector::digits <= 32>::Type MainType;
-};
-
-FMT_API void report_unknown_type(char code, const char *type);
-
-// Static data is placed in this class template to allow header-only
-// configuration.
-template
-struct FMT_API BasicData
-{
- static const uint32_t POWERS_OF_10_32[];
- static const uint64_t POWERS_OF_10_64[];
- static const char DIGITS[];
-};
-
-#ifndef FMT_USE_EXTERN_TEMPLATES
-// Clang doesn't have a feature check for extern templates so we check
-// for variadic templates which were introduced in the same version.
-# define FMT_USE_EXTERN_TEMPLATES (__clang__ && FMT_USE_VARIADIC_TEMPLATES)
-#endif
-
-#if FMT_USE_EXTERN_TEMPLATES && !defined(FMT_HEADER_ONLY)
-extern template struct BasicData;
-#endif
-
-typedef BasicData<> Data;
-
-#ifdef FMT_BUILTIN_CLZLL
-// Returns the number of decimal digits in n. Leading zeros are not counted
-// except for n == 0 in which case count_digits returns 1.
-inline unsigned count_digits(uint64_t n)
-{
- // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
- // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
- int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
- return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
-}
-#else
-// Fallback version of count_digits used when __builtin_clz is not available.
-inline unsigned count_digits(uint64_t n)
-{
- unsigned count = 1;
- for (;;)
- {
- // Integer division is slow so do it for a group of four digits instead
- // of for every digit. The idea comes from the talk by Alexandrescu
- // "Three Optimization Tips for C++". See speed-test for a comparison.
- if (n < 10) return count;
- if (n < 100) return count + 1;
- if (n < 1000) return count + 2;
- if (n < 10000) return count + 3;
- n /= 10000u;
- count += 4;
- }
-}
-#endif
-
-#ifdef FMT_BUILTIN_CLZ
-// Optional version of count_digits for better performance on 32-bit platforms.
-inline unsigned count_digits(uint32_t n)
-{
- int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
- return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
-}
-#endif
-
-// A functor that doesn't add a thousands separator.
-struct NoThousandsSep
-{
- template
- void operator()(Char *) {}
-};
-
-// A functor that adds a thousands separator.
-class ThousandsSep
-{
-private:
- fmt::StringRef sep_;
-
- // Index of a decimal digit with the least significant digit having index 0.
- unsigned digit_index_;
-
-public:
- explicit ThousandsSep(fmt::StringRef sep) : sep_(sep), digit_index_(0) {}
-
- template
- void operator()(Char *&buffer)
- {
- if (++digit_index_ % 3 != 0)
- return;
- buffer -= sep_.size();
- std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
- internal::make_ptr(buffer, sep_.size()));
- }
-};
-
-// Formats a decimal unsigned integer value writing into buffer.
-// thousands_sep is a functor that is called after writing each char to
-// add a thousands separator if necessary.
-template
-inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
- ThousandsSep thousands_sep)
-{
- buffer += num_digits;
- while (value >= 100)
- {
- // Integer division is slow so do it for a group of two digits instead
- // of for every digit. The idea comes from the talk by Alexandrescu
- // "Three Optimization Tips for C++". See speed-test for a comparison.
- unsigned index = static_cast((value % 100) * 2);
- value /= 100;
- *--buffer = Data::DIGITS[index + 1];
- thousands_sep(buffer);
- *--buffer = Data::DIGITS[index];
- thousands_sep(buffer);
- }
- if (value < 10)
- {
- *--buffer = static_cast('0' + value);
- return;
- }
- unsigned index = static_cast(value * 2);
- *--buffer = Data::DIGITS[index + 1];
- thousands_sep(buffer);
- *--buffer = Data::DIGITS[index];
-}
-
-template
-inline void format_decimal(Char *buffer, UInt value, unsigned num_digits)
-{
- return format_decimal(buffer, value, num_digits, NoThousandsSep());
-}
-
-#ifndef _WIN32
-# define FMT_USE_WINDOWS_H 0
-#elif !defined(FMT_USE_WINDOWS_H)
-# define FMT_USE_WINDOWS_H 1
-#endif
-
-// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
-// All the functionality that relies on it will be disabled too.
-#if FMT_USE_WINDOWS_H
-// A converter from UTF-8 to UTF-16.
-// It is only provided for Windows since other systems support UTF-8 natively.
-class UTF8ToUTF16
-{
-private:
- MemoryBuffer buffer_;
-
-public:
- FMT_API explicit UTF8ToUTF16(StringRef s);
- operator WStringRef() const
- {
- return WStringRef(&buffer_[0], size());
- }
- size_t size() const
- {
- return buffer_.size() - 1;
- }
- const wchar_t *c_str() const
- {
- return &buffer_[0];
- }
- std::wstring str() const
- {
- return std::wstring(&buffer_[0], size());
- }
-};
-
-// A converter from UTF-16 to UTF-8.
-// It is only provided for Windows since other systems support UTF-8 natively.
-class UTF16ToUTF8
-{
-private:
- MemoryBuffer buffer_;
-
-public:
- UTF16ToUTF8() {}
- FMT_API explicit UTF16ToUTF8(WStringRef s);
- operator StringRef() const
- {
- return StringRef(&buffer_[0], size());
- }
- size_t size() const
- {
- return buffer_.size() - 1;
- }
- const char *c_str() const
- {
- return &buffer_[0];
- }
- std::string str() const
- {
- return std::string(&buffer_[0], size());
- }
-
- // Performs conversion returning a system error code instead of
- // throwing exception on conversion error. This method may still throw
- // in case of memory allocation error.
- FMT_API int convert(WStringRef s);
-};
-
-FMT_API void format_windows_error(fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT;
-#endif
-
-// A formatting argument value.
-struct Value
-{
- template
- struct StringValue
- {
- const Char *value;
- std::size_t size;
- };
-
- typedef void (*FormatFunc)(
- void *formatter, const void *arg, void *format_str_ptr);
-
- struct CustomValue
- {
- const void *value;
- FormatFunc format;
- };
-
- union
- {
- int int_value;
- unsigned uint_value;
- LongLong long_long_value;
- ULongLong ulong_long_value;
- double double_value;
- long double long_double_value;
- const void *pointer;
- StringValue string;
- StringValue sstring;
- StringValue ustring;
- StringValue wstring;
- CustomValue custom;
- };
-
- enum Type
- {
- NONE, NAMED_ARG,
- // Integer types should go first,
- INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
- // followed by floating-point types.
- DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
- CSTRING, STRING, WSTRING, POINTER, CUSTOM
- };
-};
-
-// A formatting argument. It is a trivially copyable/constructible type to
-// allow storage in internal::MemoryBuffer.
-struct Arg : Value
-{
- Type type;
-};
-
-template
-struct NamedArg;
-
-template
-struct Null {};
-
-// A helper class template to enable or disable overloads taking wide
-// characters and strings in MakeValue.
-template
-struct WCharHelper
-{
- typedef Null Supported;
- typedef T Unsupported;
-};
-
-template
-struct WCharHelper
-{
- typedef T Supported;
- typedef Null Unsupported;
-};
-
-typedef char Yes[1];
-typedef char No[2];
-
-template
-T &get();
-
-// These are non-members to workaround an overload resolution bug in bcc32.
-Yes &convert(fmt::ULongLong);
-No &convert(...);
-
-template
-struct ConvertToIntImpl
-{
- enum { value = ENABLE_CONVERSION };
-};
-
-template
-struct ConvertToIntImpl2
-{
- enum { value = false };
-};
-
-template
-struct ConvertToIntImpl2
-{
- enum
- {
- // Don't convert numeric types.
- value = ConvertToIntImpl::is_specialized>::value
- };
-};
-
-template
-struct ConvertToInt
-{
- enum { enable_conversion = sizeof(convert(get())) == sizeof(Yes) };
- enum { value = ConvertToIntImpl2::value };
-};
-
-#define FMT_DISABLE_CONVERSION_TO_INT(Type) \
- template <> \
- struct ConvertToInt { enum { value = 0 }; }
-
-// Silence warnings about convering float to int.
-FMT_DISABLE_CONVERSION_TO_INT(float);
-FMT_DISABLE_CONVERSION_TO_INT(double);
-FMT_DISABLE_CONVERSION_TO_INT(long double);
-
-template
-struct EnableIf {};
-
-template
-struct EnableIf
-{
- typedef T type;
-};
-
-template
-struct Conditional
-{
- typedef T type;
-};
-
-template
-struct Conditional
-{
- typedef F type;
-};
-
-// For bcc32 which doesn't understand ! in template arguments.
-template
-struct Not
-{
- enum { value = 0 };
-};
-
-template <>
-struct Not
-{
- enum { value = 1 };
-};
-
-template
-struct False
-{
- enum { value = 0 };
-};
-
-template struct LConvCheck
-{
- LConvCheck(int) {}
-};
-
-// Returns the thousands separator for the current locale.
-// We check if ``lconv`` contains ``thousands_sep`` because on Android
-// ``lconv`` is stubbed as an empty struct.
-template
-inline StringRef thousands_sep(
- LConv *lc, LConvCheck = 0)
-{
- return lc->thousands_sep;
-}
-
-inline fmt::StringRef thousands_sep(...)
-{
- return "";
-}
-
-#define FMT_CONCAT(a, b) a##b
-
-#if FMT_GCC_VERSION >= 407
-# define FMT_UNUSED __attribute__((unused))
-#else
-# define FMT_UNUSED
-#endif
-
-#ifndef FMT_USE_STATIC_ASSERT
-# define FMT_USE_STATIC_ASSERT 0
-#endif
-
-#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
- (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
-# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
-#else
-# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
-# define FMT_STATIC_ASSERT(cond, message) \
- typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
-#endif
-
-template
-void format_arg(Formatter &, const Char *, const T &)
-{
- FMT_STATIC_ASSERT(False::value,
- "Cannot format argument. To enable the use of ostream "
- "operator<< include fmt/ostream.h. Otherwise provide "
- "an overload of format_arg.");
-}
-
-// Makes an Arg object from any type.
-template
-class MakeValue : public Arg
-{
-public:
- typedef typename Formatter::Char Char;
-
-private:
- // The following two methods are private to disallow formatting of
- // arbitrary pointers. If you want to output a pointer cast it to
- // "void *" or "const void *". In particular, this forbids formatting
- // of "[const] volatile char *" which is printed as bool by iostreams.
- // Do not implement!
- template
- MakeValue(const T *value);
- template
- MakeValue(T *value);
-
- // The following methods are private to disallow formatting of wide
- // characters and strings into narrow strings as in
- // fmt::format("{}", L"test");
- // To fix this, use a wide format string: fmt::format(L"{}", L"test").
-#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
- MakeValue(typename WCharHelper::Unsupported);
-#endif
- MakeValue(typename WCharHelper::Unsupported);
- MakeValue(typename WCharHelper::Unsupported);
- MakeValue(typename WCharHelper