mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
3rdparty: Update fmt to 12.0.0
Some checks are pending
🐧 Linux Builds / AppImage (push) Waiting to run
🐧 Linux Builds / Flatpak (push) Waiting to run
🍎 MacOS Builds / Defaults (push) Waiting to run
🖥️ Windows Builds / Lint VS Project Files (push) Waiting to run
🖥️ Windows Builds / SSE4 (push) Blocked by required conditions
🖥️ Windows Builds / AVX2 (push) Blocked by required conditions
🖥️ Windows Builds / CMake (push) Waiting to run
Some checks are pending
🐧 Linux Builds / AppImage (push) Waiting to run
🐧 Linux Builds / Flatpak (push) Waiting to run
🍎 MacOS Builds / Defaults (push) Waiting to run
🖥️ Windows Builds / Lint VS Project Files (push) Waiting to run
🖥️ Windows Builds / SSE4 (push) Blocked by required conditions
🖥️ Windows Builds / AVX2 (push) Blocked by required conditions
🖥️ Windows Builds / CMake (push) Waiting to run
This commit is contained in:
parent
7ab6c62dee
commit
3f437e7496
187
3rdparty/fmt/ChangeLog.md
vendored
187
3rdparty/fmt/ChangeLog.md
vendored
@ -1,3 +1,176 @@
|
||||
# 12.0.0 - 2025-09-17
|
||||
|
||||
- Optimized the default floating point formatting
|
||||
(https://github.com/fmtlib/fmt/issues/3675,
|
||||
https://github.com/fmtlib/fmt/issues/4516). In particular, formatting a
|
||||
`double` with format string compilation into a stack allocated buffer is
|
||||
more than 60% faster in version 12.0 compared to 11.2 according to
|
||||
[dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark):
|
||||
|
||||
```
|
||||
Function Time (ns) Speedup
|
||||
fmt11 34.471 1.00x
|
||||
fmt12 21.000 1.64x
|
||||
```
|
||||
|
||||
<img width="766" height="609" src="https://github.com/user-attachments/assets/d7d768ad-7543-468c-b0bb-449abf73b31b" />
|
||||
|
||||
- Added `constexpr` support to `fmt::format`. For example:
|
||||
|
||||
```c++
|
||||
#include <fmt/compile.h>
|
||||
|
||||
using namespace fmt::literals;
|
||||
std::string s = fmt::format(""_cf, 42);
|
||||
```
|
||||
|
||||
now works at compile time provided that `std::string` supports `constexpr`
|
||||
(https://github.com/fmtlib/fmt/issues/3403,
|
||||
https://github.com/fmtlib/fmt/pull/4456). Thanks @msvetkin.
|
||||
|
||||
- Added `FMT_STATIC_FORMAT` that allows formatting into a string of the exact
|
||||
required size at compile time.
|
||||
|
||||
For example:
|
||||
|
||||
```c++
|
||||
#include <fmt/compile.h>
|
||||
|
||||
constexpr auto s = FMT_STATIC_FORMAT("{}", 42);
|
||||
```
|
||||
|
||||
compiles to just
|
||||
|
||||
```s
|
||||
__ZL1s:
|
||||
.asciiz "42"
|
||||
```
|
||||
|
||||
It can be accessed as a C string with `s.c_str()` or as a string view with
|
||||
`s.str()`.
|
||||
|
||||
- Improved C++20 module support
|
||||
(https://github.com/fmtlib/fmt/pull/4451,
|
||||
https://github.com/fmtlib/fmt/pull/4459,
|
||||
https://github.com/fmtlib/fmt/pull/4476,
|
||||
https://github.com/fmtlib/fmt/pull/4488,
|
||||
https://github.com/fmtlib/fmt/issues/4491,
|
||||
https://github.com/fmtlib/fmt/pull/4495).
|
||||
Thanks @arBmind, @tkhyn, @Mishura4, @anonymouspc and @autoantwort.
|
||||
|
||||
- Switched to using estimated display width in precision. For example:
|
||||
|
||||
```c++
|
||||
fmt::print("|{:.4}|\n|1234|\n", "🐱🐱🐱");
|
||||
```
|
||||
|
||||
prints
|
||||
|
||||

|
||||
|
||||
because `🐱` has an estimated width of 2
|
||||
(https://github.com/fmtlib/fmt/issues/4272,
|
||||
https://github.com/fmtlib/fmt/pull/4443,
|
||||
https://github.com/fmtlib/fmt/pull/4475).
|
||||
Thanks @nikhilreddydev and @localspook.
|
||||
|
||||
- Fix interaction between debug presentation, precision, and width for strings
|
||||
(https://github.com/fmtlib/fmt/pull/4478). Thanks @localspook.
|
||||
|
||||
- Implemented allocator propagation on `basic_memory_buffer` move
|
||||
(https://github.com/fmtlib/fmt/issues/4487,
|
||||
https://github.com/fmtlib/fmt/pull/4490). Thanks @toprakmurat.
|
||||
|
||||
- Fixed an ambiguity between `std::reference_wrapper<T>` and `format_as`
|
||||
formatters (https://github.com/fmtlib/fmt/issues/4424,
|
||||
https://github.com/fmtlib/fmt/pull/4434). Thanks @jeremy-rifkin.
|
||||
|
||||
- Removed the following deprecated APIs:
|
||||
|
||||
- `has_formatter`: use `is_formattable` instead,
|
||||
- `basic_format_args::parse_context_type`,
|
||||
`basic_format_args::formatter_type` and similar aliases in context types,
|
||||
- wide stream overload of `fmt::printf`,
|
||||
- wide stream overloads of `fmt::print` that take text styles,
|
||||
- `is_*char` traits,
|
||||
- `fmt::localtime`.
|
||||
|
||||
- Deprecated wide overloads of `fmt::fprintf` and `fmt::sprintf`.
|
||||
|
||||
- Improved diagnostics for the incorrect usage of `fmt::ptr`
|
||||
(https://github.com/fmtlib/fmt/pull/4453). Thanks @TobiSchluter.
|
||||
|
||||
- Made handling of ANSI escape sequences more efficient
|
||||
(https://github.com/fmtlib/fmt/pull/4511,
|
||||
https://github.com/fmtlib/fmt/pull/4528).
|
||||
Thanks @localspook and @Anas-Hamdane.
|
||||
|
||||
- Fixed a buffer overflow on all emphasis flags set
|
||||
(https://github.com/fmtlib/fmt/pull/4498). Thanks @dominicpoeschko.
|
||||
|
||||
- Fixed an integer overflow for precision close to the max `int` value.
|
||||
|
||||
- Fixed compatibility with WASI (https://github.com/fmtlib/fmt/issues/4496,
|
||||
https://github.com/fmtlib/fmt/pull/4497). Thanks @whitequark.
|
||||
|
||||
- Fixed `back_insert_iterator` detection, preventing a fallback on slower path
|
||||
that handles arbitrary iterators (https://github.com/fmtlib/fmt/issues/4454).
|
||||
|
||||
- Fixed handling of invalid glibc `FILE` buffers
|
||||
(https://github.com/fmtlib/fmt/issues/4469).
|
||||
|
||||
- Added `wchar_t` support to the `std::byte` formatter
|
||||
(https://github.com/fmtlib/fmt/issues/4479,
|
||||
https://github.com/fmtlib/fmt/pull/4480). Thanks @phprus.
|
||||
|
||||
- Changed component prefix from `fmt-` to `fmt_` for compatibility with
|
||||
NSIS/CPack on Windows, e.g. `fmt-doc` changed to `fmt_doc`
|
||||
(https://github.com/fmtlib/fmt/issues/4441,
|
||||
https://github.com/fmtlib/fmt/pull/4442). Thanks @n-stein.
|
||||
|
||||
- Added the `FMT_CUSTOM_ASSERT_FAIL` macro to simplify providing a custom
|
||||
`fmt::assert_fail` implementation (https://github.com/fmtlib/fmt/pull/4505).
|
||||
Thanks @HazardyKnusperkeks.
|
||||
|
||||
- Switched to `FMT_THROW` on reporting format errors so that it can be
|
||||
overriden by users when exceptions are disabled
|
||||
(https://github.com/fmtlib/fmt/pull/4521). Thanks @HazardyKnusperkeks.
|
||||
|
||||
- Improved master project detection and disabled install targets when using
|
||||
{fmt} as a subproject by default (https://github.com/fmtlib/fmt/pull/4536).
|
||||
Thanks @crueter.
|
||||
|
||||
- Made various code improvements
|
||||
(https://github.com/fmtlib/fmt/pull/4445,
|
||||
https://github.com/fmtlib/fmt/pull/4448,
|
||||
https://github.com/fmtlib/fmt/pull/4473,
|
||||
https://github.com/fmtlib/fmt/pull/4522).
|
||||
Thanks @localspook, @tchaikov and @way4sahil.
|
||||
|
||||
- Added Conan instructions to the docs
|
||||
(https://github.com/fmtlib/fmt/pull/4537). Thanks @uilianries.
|
||||
|
||||
- Removed Bazel files to avoid issues with downstream packaging
|
||||
(https://github.com/fmtlib/fmt/pull/4530). Thanks @mering.
|
||||
|
||||
- Added more entries for generated files to `.gitignore`
|
||||
(https://github.com/fmtlib/fmt/pull/4355,
|
||||
https://github.com/fmtlib/fmt/pull/4512).
|
||||
Thanks @dinomight and @localspook.
|
||||
|
||||
- Fixed various warnings and compilation issues
|
||||
(https://github.com/fmtlib/fmt/pull/4447,
|
||||
https://github.com/fmtlib/fmt/issues/4470,
|
||||
https://github.com/fmtlib/fmt/pull/4474,
|
||||
https://github.com/fmtlib/fmt/pull/4477,
|
||||
https://github.com/fmtlib/fmt/pull/4471,
|
||||
https://github.com/fmtlib/fmt/pull/4483,
|
||||
https://github.com/fmtlib/fmt/pull/4515,
|
||||
https://github.com/fmtlib/fmt/issues/4533,
|
||||
https://github.com/fmtlib/fmt/pull/4534).
|
||||
Thanks @dodomorandi, @localspook, @remyjette, @Tomek-Stolarczyk, @Mishura4,
|
||||
@mattiasljungstrom and @FatihBAKIR.
|
||||
|
||||
# 11.2.0 - 2025-05-03
|
||||
|
||||
- Added the `s` specifier for `std::error_code`. It allows formatting an error
|
||||
@ -56,17 +229,18 @@
|
||||
https://github.com/fmtlib/fmt/pull/4361). Thanks @dinomight.
|
||||
|
||||
- Added error reporting for duplicate named arguments
|
||||
(https://github.com/fmtlib/fmt/pull/4367). Thanks @dinomight.
|
||||
(https://github.com/fmtlib/fmt/issues/4282,
|
||||
https://github.com/fmtlib/fmt/pull/4367). Thanks @dinomight.
|
||||
|
||||
- Fixed formatting of `long` with `FMT_BUILTIN_TYPES=0`
|
||||
(https://github.com/fmtlib/fmt/issues/4375,
|
||||
https://github.com/fmtlib/fmt/issues/4394).
|
||||
|
||||
- Optimized `text_style` using bit packing
|
||||
(https://github.com/fmtlib/fmt/pull/4363). Thanks @LocalSpook.
|
||||
(https://github.com/fmtlib/fmt/pull/4363). Thanks @localspook.
|
||||
|
||||
- Added support for incomplete types (https://github.com/fmtlib/fmt/issues/3180,
|
||||
https://github.com/fmtlib/fmt/pull/4383). Thanks @LocalSpook.
|
||||
https://github.com/fmtlib/fmt/pull/4383). Thanks @localspook.
|
||||
|
||||
- Fixed a flush issue in `fmt::print` when using libstdc++
|
||||
(https://github.com/fmtlib/fmt/issues/4398).
|
||||
@ -107,13 +281,14 @@
|
||||
`float` (https://github.com/fmtlib/fmt/issues/3649).
|
||||
|
||||
- Moved `is_compiled_string` to the public API
|
||||
(https://github.com/fmtlib/fmt/issues/4342). Thanks @SwooshyCueb.
|
||||
(https://github.com/fmtlib/fmt/issues/4335,
|
||||
https://github.com/fmtlib/fmt/issues/4342). Thanks @SwooshyCueb.
|
||||
|
||||
- Simplified implementation of `operator""_cf`
|
||||
(https://github.com/fmtlib/fmt/pull/4349). Thanks @LocalSpook.
|
||||
(https://github.com/fmtlib/fmt/pull/4349). Thanks @localspook.
|
||||
|
||||
- Fixed `__builtin_strlen` detection (https://github.com/fmtlib/fmt/pull/4329).
|
||||
Thanks @LocalSpook.
|
||||
Thanks @localspook.
|
||||
|
||||
- Fixed handling of BMI paths with the Ninja generator
|
||||
(https://github.com/fmtlib/fmt/pull/4344). Thanks @tkhyn.
|
||||
|
||||
3
3rdparty/fmt/README.md
vendored
3
3rdparty/fmt/README.md
vendored
@ -4,8 +4,9 @@
|
||||
[](https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos)
|
||||
[](https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?\%0Acolspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\%0ASummary&q=proj%3Dfmt&can=1)
|
||||
[](https://stackoverflow.com/questions/tagged/fmt)
|
||||
[](https://www.bestpractices.dev/projects/8880)
|
||||
[](https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt)
|
||||
[](https://stackoverflow.com/questions/tagged/fmt)
|
||||
|
||||
**{fmt}** is an open-source formatting library providing a fast and safe
|
||||
alternative to C stdio and C++ iostreams.
|
||||
|
||||
4
3rdparty/fmt/include/fmt/args.h
vendored
4
3rdparty/fmt/include/fmt/args.h
vendored
@ -71,7 +71,7 @@ class dynamic_arg_list {
|
||||
* It can be implicitly converted into `fmt::basic_format_args` for passing
|
||||
* into type-erased formatting functions such as `fmt::vformat`.
|
||||
*/
|
||||
template <typename Context> class dynamic_format_arg_store {
|
||||
FMT_EXPORT template <typename Context> class dynamic_format_arg_store {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
@ -212,7 +212,7 @@ template <typename Context> class dynamic_format_arg_store {
|
||||
}
|
||||
|
||||
/// Returns the number of elements in the store.
|
||||
size_t size() const noexcept { return data_.size(); }
|
||||
auto size() const noexcept -> size_t { return data_.size(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
179
3rdparty/fmt/include/fmt/base.h
vendored
179
3rdparty/fmt/include/fmt/base.h
vendored
@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||
#define FMT_VERSION 110200
|
||||
#define FMT_VERSION 120000
|
||||
|
||||
// Detect compiler versions.
|
||||
#if defined(__clang__) && !defined(__ibmxl__)
|
||||
@ -201,14 +201,6 @@
|
||||
# define FMT_NODISCARD
|
||||
#endif
|
||||
|
||||
#ifdef FMT_DEPRECATED
|
||||
// Use the provided definition.
|
||||
#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)
|
||||
# define FMT_DEPRECATED [[deprecated]]
|
||||
#else
|
||||
# define FMT_DEPRECATED /* deprecated */
|
||||
#endif
|
||||
|
||||
#if FMT_GCC_VERSION || FMT_CLANG_VERSION
|
||||
# define FMT_VISIBILITY(value) __attribute__((visibility(value)))
|
||||
#else
|
||||
@ -260,7 +252,7 @@ FMT_PRAGMA_CLANG(diagnostic push)
|
||||
#ifndef FMT_BEGIN_NAMESPACE
|
||||
# define FMT_BEGIN_NAMESPACE \
|
||||
namespace fmt { \
|
||||
inline namespace v11 {
|
||||
inline namespace v12 {
|
||||
# define FMT_END_NAMESPACE \
|
||||
} \
|
||||
}
|
||||
@ -356,6 +348,9 @@ template <typename T> constexpr auto max_of(T a, T b) -> T {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
const char* message);
|
||||
|
||||
namespace detail {
|
||||
// Suppresses "unused variable" warnings with the method described in
|
||||
// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
|
||||
@ -396,7 +391,7 @@ FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
# define FMT_ASSERT(condition, message) \
|
||||
((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
|
||||
? (void)0 \
|
||||
: fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
|
||||
: ::fmt::assert_fail(__FILE__, __LINE__, (message)))
|
||||
#endif
|
||||
|
||||
#ifdef FMT_USE_INT128
|
||||
@ -463,12 +458,13 @@ enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
|
||||
static_assert(!FMT_UNICODE || use_utf8,
|
||||
"Unicode support requires compiling with /utf-8");
|
||||
|
||||
template <typename T> constexpr const char* narrow(const T*) { return nullptr; }
|
||||
constexpr FMT_ALWAYS_INLINE const char* narrow(const char* s) { return s; }
|
||||
template <typename T> constexpr auto narrow(T*) -> char* { return nullptr; }
|
||||
constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* {
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n)
|
||||
-> int {
|
||||
FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int {
|
||||
if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
|
||||
for (; n != 0; ++s1, ++s2, --n) {
|
||||
if (*s1 < *s2) return -1;
|
||||
@ -540,7 +536,7 @@ template <typename Char> class basic_string_view {
|
||||
FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
|
||||
#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
|
||||
if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
|
||||
size_ = __builtin_strlen(detail::narrow(s)); // strlen is not costexpr.
|
||||
size_ = __builtin_strlen(detail::narrow(s)); // strlen is not constexpr.
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -616,19 +612,6 @@ template <typename Char> class basic_string_view {
|
||||
|
||||
using string_view = basic_string_view<char>;
|
||||
|
||||
// DEPRECATED! Will be merged with is_char and moved to detail.
|
||||
template <typename T> struct is_xchar : std::false_type {};
|
||||
template <> struct is_xchar<wchar_t> : std::true_type {};
|
||||
template <> struct is_xchar<char16_t> : std::true_type {};
|
||||
template <> struct is_xchar<char32_t> : std::true_type {};
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_xchar<char8_t> : std::true_type {};
|
||||
#endif
|
||||
|
||||
// Specifies if `T` is a character (code unit) type.
|
||||
template <typename T> struct is_char : is_xchar<T> {};
|
||||
template <> struct is_char<char> : std::true_type {};
|
||||
|
||||
template <typename T> class basic_appender;
|
||||
using appender = basic_appender<char>;
|
||||
|
||||
@ -781,7 +764,7 @@ class basic_specs {
|
||||
(static_cast<unsigned>(p) << precision_shift);
|
||||
}
|
||||
|
||||
constexpr bool dynamic() const {
|
||||
constexpr auto dynamic() const -> bool {
|
||||
return (data_ & (width_mask | precision_mask)) != 0;
|
||||
}
|
||||
|
||||
@ -921,14 +904,47 @@ template <typename Char = char> class parse_context {
|
||||
FMT_CONSTEXPR void check_dynamic_spec(int arg_id);
|
||||
};
|
||||
|
||||
#ifndef FMT_USE_LOCALE
|
||||
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
|
||||
#endif
|
||||
|
||||
// A type-erased reference to std::locale to avoid the heavy <locale> include.
|
||||
class locale_ref {
|
||||
#if FMT_USE_LOCALE
|
||||
private:
|
||||
const void* locale_; // A type-erased pointer to std::locale.
|
||||
|
||||
public:
|
||||
constexpr locale_ref() : locale_(nullptr) {}
|
||||
|
||||
template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>
|
||||
locale_ref(const Locale& loc);
|
||||
|
||||
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
public:
|
||||
template <typename Locale> auto get() const -> Locale;
|
||||
};
|
||||
|
||||
FMT_END_EXPORT
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Specifies if `T` is a code unit type.
|
||||
template <typename T> struct is_code_unit : std::false_type {};
|
||||
template <> struct is_code_unit<char> : std::true_type {};
|
||||
template <> struct is_code_unit<wchar_t> : std::true_type {};
|
||||
template <> struct is_code_unit<char16_t> : std::true_type {};
|
||||
template <> struct is_code_unit<char32_t> : std::true_type {};
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_code_unit<char8_t> : bool_constant<is_utf8_enabled> {};
|
||||
#endif
|
||||
|
||||
// Constructs fmt::basic_string_view<Char> from types implicitly convertible
|
||||
// to it, deducing Char. Explicitly convertible types such as the ones returned
|
||||
// from FMT_STRING are intentionally excluded.
|
||||
template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
|
||||
template <typename Char, FMT_ENABLE_IF(is_code_unit<Char>::value)>
|
||||
constexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {
|
||||
return s;
|
||||
}
|
||||
@ -1057,11 +1073,11 @@ template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
|
||||
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
||||
}
|
||||
|
||||
template <typename... Args> constexpr auto count_named_args() -> int {
|
||||
return count<is_named_arg<Args>::value...>();
|
||||
template <typename... T> constexpr auto count_named_args() -> int {
|
||||
return count<is_named_arg<T>::value...>();
|
||||
}
|
||||
template <typename... Args> constexpr auto count_static_named_args() -> int {
|
||||
return count<is_static_named_arg<Args>::value...>();
|
||||
template <typename... T> constexpr auto count_static_named_args() -> int {
|
||||
return count<is_static_named_arg<T>::value...>();
|
||||
}
|
||||
|
||||
template <typename Char> struct named_arg_info {
|
||||
@ -1069,7 +1085,7 @@ template <typename Char> struct named_arg_info {
|
||||
int id;
|
||||
};
|
||||
|
||||
// named_args is non-const to suppress a bogus -Wmaybe-uninitalized in gcc 13.
|
||||
// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
|
||||
int named_arg_index,
|
||||
@ -1173,7 +1189,7 @@ template <typename Char> struct type_mapper {
|
||||
static auto map(ubitint<N>)
|
||||
-> conditional_t<N <= 64, unsigned long long, void>;
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
|
||||
template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
|
||||
static auto map(T) -> conditional_t<
|
||||
std::is_same<T, char>::value || std::is_same<T, Char>::value, Char, void>;
|
||||
|
||||
@ -1679,12 +1695,12 @@ template <typename... T> struct arg_pack {};
|
||||
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
|
||||
class format_string_checker {
|
||||
private:
|
||||
type types_[max_of(1, NUM_ARGS)];
|
||||
named_arg_info<Char> named_args_[max_of(1, NUM_NAMED_ARGS)];
|
||||
type types_[max_of<size_t>(1, NUM_ARGS)];
|
||||
named_arg_info<Char> named_args_[max_of<size_t>(1, NUM_NAMED_ARGS)];
|
||||
compile_parse_context<Char> context_;
|
||||
|
||||
using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
|
||||
parse_func parse_funcs_[max_of(1, NUM_ARGS)];
|
||||
parse_func parse_funcs_[max_of<size_t>(1, NUM_ARGS)];
|
||||
|
||||
public:
|
||||
template <typename... T>
|
||||
@ -2033,6 +2049,17 @@ struct has_back_insert_iterator_container_append<
|
||||
.append(std::declval<InputIt>(),
|
||||
std::declval<InputIt>()))>> : std::true_type {};
|
||||
|
||||
template <typename OutputIt, typename InputIt, typename = void>
|
||||
struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
|
||||
|
||||
template <typename OutputIt, typename InputIt>
|
||||
struct has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt,
|
||||
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||
.insert(get_container(std::declval<OutputIt>()).end(),
|
||||
std::declval<InputIt>(),
|
||||
std::declval<InputIt>()))>> : std::true_type {};
|
||||
|
||||
// An optimized version of std::copy with the output value type (T).
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
|
||||
@ -2047,6 +2074,8 @@ FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
|
||||
!has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value &&
|
||||
has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt>::value)>
|
||||
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
-> OutputIt {
|
||||
@ -2056,7 +2085,11 @@ FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
|
||||
FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::value &&
|
||||
(has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value ||
|
||||
has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt>::value)))>
|
||||
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
|
||||
while (begin != end) *out++ = static_cast<T>(*begin++);
|
||||
return out;
|
||||
@ -2176,7 +2209,7 @@ template <typename Context> class value {
|
||||
static_assert(N <= 64, "unsupported _BitInt");
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
|
||||
template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
|
||||
constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) {
|
||||
static_assert(
|
||||
std::is_same<T, char>::value || std::is_same<T, char_type>::value,
|
||||
@ -2252,7 +2285,7 @@ template <typename Context> class value {
|
||||
custom.value = const_cast<value_type*>(&x);
|
||||
#endif
|
||||
}
|
||||
custom.format = format_custom<value_type, formatter<value_type, char_type>>;
|
||||
custom.format = format_custom<value_type>;
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>
|
||||
@ -2263,10 +2296,10 @@ template <typename Context> class value {
|
||||
}
|
||||
|
||||
// Formats an argument of a custom type, such as a user-defined class.
|
||||
template <typename T, typename Formatter>
|
||||
template <typename T>
|
||||
static void format_custom(void* arg, parse_context<char_type>& parse_ctx,
|
||||
Context& ctx) {
|
||||
auto f = Formatter();
|
||||
auto f = formatter<T, char_type>();
|
||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||
using qualified_type =
|
||||
conditional_t<has_formatter<const T, char_type>(), const T, T>;
|
||||
@ -2293,35 +2326,14 @@ struct is_output_iterator<
|
||||
enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
|
||||
T>::value>> : std::true_type {};
|
||||
|
||||
#ifndef FMT_USE_LOCALE
|
||||
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
|
||||
#endif
|
||||
|
||||
// A type-erased reference to an std::locale to avoid a heavy <locale> include.
|
||||
class locale_ref {
|
||||
#if FMT_USE_LOCALE
|
||||
private:
|
||||
const void* locale_; // A type-erased pointer to std::locale.
|
||||
|
||||
public:
|
||||
constexpr locale_ref() : locale_(nullptr) {}
|
||||
template <typename Locale> locale_ref(const Locale& loc);
|
||||
|
||||
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
public:
|
||||
template <typename Locale> auto get() const -> Locale;
|
||||
};
|
||||
|
||||
template <typename> constexpr auto encode_types() -> unsigned long long {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Context, typename Arg, typename... Args>
|
||||
template <typename Context, typename First, typename... T>
|
||||
constexpr auto encode_types() -> unsigned long long {
|
||||
return static_cast<unsigned>(stored_type_constant<Arg, Context>::value) |
|
||||
(encode_types<Context, Args...>() << packed_arg_bits);
|
||||
return static_cast<unsigned>(stored_type_constant<First, Context>::value) |
|
||||
(encode_types<Context, T...>() << packed_arg_bits);
|
||||
}
|
||||
|
||||
template <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>
|
||||
@ -2338,8 +2350,9 @@ template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||
unsigned long long DESC>
|
||||
struct named_arg_store {
|
||||
// args_[0].named_args points to named_args to avoid bloating format_args.
|
||||
arg_t<Context, NUM_ARGS> args[1 + NUM_ARGS];
|
||||
named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
|
||||
arg_t<Context, NUM_ARGS> args[1u + NUM_ARGS];
|
||||
named_arg_info<typename Context::char_type>
|
||||
named_args[static_cast<size_t>(NUM_NAMED_ARGS)];
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values)
|
||||
@ -2358,8 +2371,8 @@ struct named_arg_store {
|
||||
}
|
||||
|
||||
named_arg_store(const named_arg_store& rhs) = delete;
|
||||
named_arg_store& operator=(const named_arg_store& rhs) = delete;
|
||||
named_arg_store& operator=(named_arg_store&& rhs) = delete;
|
||||
auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete;
|
||||
auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete;
|
||||
operator const arg_t<Context, NUM_ARGS>*() const { return args + 1; }
|
||||
};
|
||||
|
||||
@ -2372,7 +2385,7 @@ struct format_arg_store {
|
||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||
using type =
|
||||
conditional_t<NUM_NAMED_ARGS == 0,
|
||||
arg_t<Context, NUM_ARGS>[max_of(1, NUM_ARGS)],
|
||||
arg_t<Context, NUM_ARGS>[max_of<size_t>(1, NUM_ARGS)],
|
||||
named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
|
||||
type args;
|
||||
};
|
||||
@ -2656,22 +2669,17 @@ class context {
|
||||
private:
|
||||
appender out_;
|
||||
format_args args_;
|
||||
FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
|
||||
FMT_NO_UNIQUE_ADDRESS locale_ref loc_;
|
||||
|
||||
public:
|
||||
/// The character type for the output.
|
||||
using char_type = char;
|
||||
|
||||
using char_type = char; ///< The character type for the output.
|
||||
using iterator = appender;
|
||||
using format_arg = basic_format_arg<context>;
|
||||
using parse_context_type FMT_DEPRECATED = parse_context<>;
|
||||
template <typename T> using formatter_type FMT_DEPRECATED = formatter<T>;
|
||||
enum { builtin_types = FMT_BUILTIN_TYPES };
|
||||
|
||||
/// Constructs a `context` object. References to the arguments are stored
|
||||
/// in the object so make sure they have appropriate lifetimes.
|
||||
FMT_CONSTEXPR context(iterator out, format_args args,
|
||||
detail::locale_ref loc = {})
|
||||
FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {})
|
||||
: out_(out), args_(args), loc_(loc) {}
|
||||
context(context&&) = default;
|
||||
context(const context&) = delete;
|
||||
@ -2692,7 +2700,7 @@ class context {
|
||||
// Advances the begin iterator to `it`.
|
||||
FMT_CONSTEXPR void advance_to(iterator) {}
|
||||
|
||||
FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; }
|
||||
FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; }
|
||||
};
|
||||
|
||||
template <typename Char = char> struct runtime_format_string {
|
||||
@ -2779,9 +2787,6 @@ template <typename T, typename Char = char>
|
||||
concept formattable = is_formattable<remove_reference_t<T>, Char>::value;
|
||||
#endif
|
||||
|
||||
template <typename T, typename Char>
|
||||
using has_formatter FMT_DEPRECATED = std::is_constructible<formatter<T, Char>>;
|
||||
|
||||
// A formatter specialization for natively supported types.
|
||||
template <typename T, typename Char>
|
||||
struct formatter<T, Char,
|
||||
@ -2978,9 +2983,9 @@ FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
|
||||
return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_PRAGMA_CLANG(diagnostic pop)
|
||||
FMT_PRAGMA_GCC(pop_options)
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#ifdef FMT_HEADER_ONLY
|
||||
|
||||
113
3rdparty/fmt/include/fmt/chrono.h
vendored
113
3rdparty/fmt/include/fmt/chrono.h
vendored
@ -38,6 +38,7 @@ FMT_BEGIN_NAMESPACE
|
||||
// Copyright Paul Dreik 2019
|
||||
namespace safe_duration_cast {
|
||||
|
||||
// DEPRECATED!
|
||||
template <typename To, typename From,
|
||||
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
|
||||
std::numeric_limits<From>::is_signed ==
|
||||
@ -161,17 +162,6 @@ auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
|
||||
int& ec) -> To {
|
||||
using From = std::chrono::duration<FromRep, FromPeriod>;
|
||||
ec = 0;
|
||||
if (std::isnan(from.count())) {
|
||||
// nan in, gives nan out. easy.
|
||||
return To{std::numeric_limits<typename To::rep>::quiet_NaN()};
|
||||
}
|
||||
// maybe we should also check if from is denormal, and decide what to do about
|
||||
// it.
|
||||
|
||||
// +-inf should be preserved.
|
||||
if (std::isinf(from.count())) {
|
||||
return To{from.count()};
|
||||
}
|
||||
|
||||
// the basic idea is that we need to convert from count() in the from type
|
||||
// to count() in the To type, by multiplying it with this:
|
||||
@ -282,8 +272,6 @@ namespace detail {
|
||||
#define FMT_NOMACRO
|
||||
|
||||
template <typename T = void> struct null {};
|
||||
inline auto localtime_r FMT_NOMACRO(...) -> null<> { return null<>(); }
|
||||
inline auto localtime_s(...) -> null<> { return null<>(); }
|
||||
inline auto gmtime_r(...) -> null<> { return null<>(); }
|
||||
inline auto gmtime_s(...) -> null<> { return null<>(); }
|
||||
|
||||
@ -326,7 +314,7 @@ inline auto get_classic_locale() -> const std::locale& {
|
||||
}
|
||||
|
||||
template <typename CodeUnit> struct codecvt_result {
|
||||
static constexpr const size_t max_size = 32;
|
||||
static constexpr size_t max_size = 32;
|
||||
CodeUnit buf[max_size];
|
||||
CodeUnit* end;
|
||||
};
|
||||
@ -443,11 +431,7 @@ auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
|
||||
using common_rep = typename std::common_type<FromRep, typename To::rep,
|
||||
decltype(factor::num)>::type;
|
||||
|
||||
int ec = 0;
|
||||
auto count = safe_duration_cast::lossless_integral_conversion<common_rep>(
|
||||
from.count(), ec);
|
||||
if (ec) throw_duration_error();
|
||||
common_rep count = from.count(); // This conversion is lossless.
|
||||
|
||||
// Multiply from.count() by factor and check for overflow.
|
||||
if (const_check(factor::num != 1)) {
|
||||
@ -458,6 +442,7 @@ auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
count *= factor::num;
|
||||
}
|
||||
if (const_check(factor::den != 1)) count /= factor::den;
|
||||
int ec = 0;
|
||||
auto to =
|
||||
To(safe_duration_cast::lossless_integral_conversion<typename To::rep>(
|
||||
count, ec));
|
||||
@ -471,6 +456,8 @@ template <typename To, typename FromRep, typename FromPeriod,
|
||||
std::is_floating_point<typename To::rep>::value)>
|
||||
auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
#if FMT_SAFE_DURATION_CAST
|
||||
// Preserve infinity and NaN.
|
||||
if (!isfinite(from.count())) return static_cast<To>(from.count());
|
||||
// Throwing version of safe_duration_cast is only available for
|
||||
// integer to integer or float to float casts.
|
||||
int ec;
|
||||
@ -487,7 +474,7 @@ template <typename To, typename FromRep, typename FromPeriod,
|
||||
FMT_ENABLE_IF(
|
||||
!is_similar_arithmetic_type<FromRep, typename To::rep>::value)>
|
||||
auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
// Mixed integer <-> float cast is not supported by safe_duration_cast.
|
||||
// Mixed integer <-> float cast is not supported by safe duration_cast.
|
||||
return std::chrono::duration_cast<To>(from);
|
||||
}
|
||||
|
||||
@ -501,86 +488,10 @@ auto to_time_t(sys_time<Duration> time_point) -> std::time_t {
|
||||
.count();
|
||||
}
|
||||
|
||||
namespace tz {
|
||||
|
||||
// DEPRECATED!
|
||||
struct time_zone {
|
||||
template <typename Duration, typename LocalTime>
|
||||
auto to_sys(LocalTime) -> sys_time<Duration> {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
template <typename... T> auto current_zone(T...) -> time_zone* {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename... T> void _tzset(T...) {}
|
||||
} // namespace tz
|
||||
|
||||
// DEPRECATED!
|
||||
inline void tzset_once() {
|
||||
static bool init = []() {
|
||||
using namespace tz;
|
||||
_tzset();
|
||||
return false;
|
||||
}();
|
||||
ignore_unused(init);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
/**
|
||||
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||
* expressed in local time. Unlike `std::localtime`, this function is
|
||||
* thread-safe on most platforms.
|
||||
*/
|
||||
FMT_DEPRECATED inline auto localtime(std::time_t time) -> std::tm {
|
||||
struct dispatcher {
|
||||
std::time_t time_;
|
||||
std::tm tm_;
|
||||
|
||||
inline dispatcher(std::time_t t) : time_(t) {}
|
||||
|
||||
inline auto run() -> bool {
|
||||
using namespace fmt::detail;
|
||||
return handle(localtime_r(&time_, &tm_));
|
||||
}
|
||||
|
||||
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
||||
|
||||
inline auto handle(detail::null<>) -> bool {
|
||||
using namespace fmt::detail;
|
||||
return fallback(localtime_s(&tm_, &time_));
|
||||
}
|
||||
|
||||
inline auto fallback(int res) -> bool { return res == 0; }
|
||||
|
||||
#if !FMT_MSC_VERSION
|
||||
inline auto fallback(detail::null<>) -> bool {
|
||||
using namespace fmt::detail;
|
||||
std::tm* tm = std::localtime(&time_);
|
||||
if (tm) tm_ = *tm;
|
||||
return tm != nullptr;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
dispatcher lt(time);
|
||||
// Too big time values may be unsupported.
|
||||
if (!lt.run()) FMT_THROW(format_error("time_t value out of range"));
|
||||
return lt.tm_;
|
||||
}
|
||||
|
||||
#if FMT_USE_LOCAL_TIME
|
||||
template <typename Duration>
|
||||
FMT_DEPRECATED auto localtime(std::chrono::local_time<Duration> time)
|
||||
-> std::tm {
|
||||
using namespace std::chrono;
|
||||
using namespace detail::tz;
|
||||
return localtime(detail::to_time_t(current_zone()->to_sys<Duration>(time)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||
* expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this
|
||||
@ -652,7 +563,7 @@ inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
|
||||
// Add ASCII '0' to each digit byte and insert separators.
|
||||
digits |= 0x3030003030003030 | (usep << 16) | (usep << 40);
|
||||
|
||||
constexpr const size_t len = 8;
|
||||
constexpr size_t len = 8;
|
||||
if (const_check(is_big_endian())) {
|
||||
char tmp[len];
|
||||
std::memcpy(tmp, &digits, len);
|
||||
@ -1000,16 +911,16 @@ template <typename T>
|
||||
struct has_tm_zone<T, void_t<decltype(T::tm_zone)>> : std::true_type {};
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
|
||||
bool set_tm_zone(T& time, char* tz) {
|
||||
auto set_tm_zone(T& time, char* tz) -> bool {
|
||||
time.tm_zone = tz;
|
||||
return true;
|
||||
}
|
||||
template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
|
||||
bool set_tm_zone(T&, char*) {
|
||||
auto set_tm_zone(T&, char*) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline char* utc() {
|
||||
inline auto utc() -> char* {
|
||||
static char tz[] = "UTC";
|
||||
return tz;
|
||||
}
|
||||
@ -2230,7 +2141,7 @@ template <typename Char> struct formatter<std::tm, Char> {
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
|
||||
auto loc_ref = specs.localized() ? ctx.locale() : detail::locale_ref();
|
||||
auto loc_ref = specs.localized() ? ctx.locale() : locale_ref();
|
||||
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
|
||||
auto w = detail::tm_writer<basic_appender<Char>, Char, Duration>(
|
||||
loc, out, tm, subsecs);
|
||||
|
||||
36
3rdparty/fmt/include/fmt/color.h
vendored
36
3rdparty/fmt/include/fmt/color.h
vendored
@ -375,19 +375,17 @@ template <typename Char> struct ansi_color_escape {
|
||||
// 10 more.
|
||||
if (is_background) value += 10u;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[size++] = static_cast<Char>('\x1b');
|
||||
buffer[size++] = static_cast<Char>('[');
|
||||
|
||||
if (value >= 100u) {
|
||||
buffer[index++] = static_cast<Char>('1');
|
||||
buffer[size++] = static_cast<Char>('1');
|
||||
value %= 100u;
|
||||
}
|
||||
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||
buffer[size++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[size++] = static_cast<Char>('0' + value % 10u);
|
||||
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[index++] = static_cast<Char>('\0');
|
||||
buffer[size++] = static_cast<Char>('m');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -398,7 +396,7 @@ template <typename Char> struct ansi_color_escape {
|
||||
to_esc(color.r, buffer + 7, ';');
|
||||
to_esc(color.g, buffer + 11, ';');
|
||||
to_esc(color.b, buffer + 15, 'm');
|
||||
buffer[19] = static_cast<Char>(0);
|
||||
size = 19;
|
||||
}
|
||||
FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {
|
||||
uint8_t em_codes[num_emphases] = {};
|
||||
@ -411,26 +409,28 @@ template <typename Char> struct ansi_color_escape {
|
||||
if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
|
||||
if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[size++] = static_cast<Char>('\x1b');
|
||||
buffer[size++] = static_cast<Char>('[');
|
||||
|
||||
for (size_t i = 0; i < num_emphases; ++i) {
|
||||
if (!em_codes[i]) continue;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[size++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[size++] = static_cast<Char>(';');
|
||||
}
|
||||
buffer[index++] = static_cast<Char>(0);
|
||||
|
||||
buffer[size - 1] = static_cast<Char>('m');
|
||||
}
|
||||
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
|
||||
FMT_CONSTEXPR20 auto end() const noexcept -> const Char* {
|
||||
return buffer + basic_string_view<Char>(buffer).size();
|
||||
FMT_CONSTEXPR auto end() const noexcept -> const Char* {
|
||||
return buffer + size;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t num_emphases = 8;
|
||||
Char buffer[7u + 3u * num_emphases + 1u];
|
||||
Char buffer[7u + 4u * num_emphases];
|
||||
size_t size = 0;
|
||||
|
||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
|
||||
char delimiter) noexcept {
|
||||
|
||||
198
3rdparty/fmt/include/fmt/compile.h
vendored
198
3rdparty/fmt/include/fmt/compile.h
vendored
@ -22,8 +22,6 @@ FMT_EXPORT class compiled_string {};
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Converts a string literal `s` into a format string that will be parsed at
|
||||
* compile time and converted into efficient formatting code. Requires C++17
|
||||
@ -41,18 +39,40 @@ namespace detail {
|
||||
# define FMT_COMPILE(s) FMT_STRING(s)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts a string literal into a format string that will be parsed at
|
||||
* compile time and converted into efficient formatting code. Requires support
|
||||
* for class types in constant template parameters (a C++20 feature).
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // Converts 42 into std::string using the most efficient method and no
|
||||
* // runtime format string processing.
|
||||
* using namespace fmt::literals;
|
||||
* std::string s = fmt::format("{}"_cf, 42);
|
||||
*/
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||
return FMT_COMPILE(Str.data);
|
||||
}
|
||||
} // namespace literals
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename... Tail>
|
||||
auto first(const T& value, const Tail&...) -> const T& {
|
||||
constexpr auto first(const T& value, const Tail&...) -> const T& {
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
|
||||
template <typename... Args> struct type_list {};
|
||||
template <typename... T> struct type_list {};
|
||||
|
||||
// Returns a reference to the argument at index N from [first, rest...].
|
||||
template <int N, typename T, typename... Args>
|
||||
constexpr const auto& get([[maybe_unused]] const T& first,
|
||||
[[maybe_unused]] const Args&... rest) {
|
||||
constexpr auto get([[maybe_unused]] const T& first,
|
||||
[[maybe_unused]] const Args&... rest) -> const auto& {
|
||||
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
|
||||
if constexpr (N == 0)
|
||||
return first;
|
||||
@ -84,8 +104,8 @@ FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
|
||||
}
|
||||
|
||||
template <typename Char, typename... Args>
|
||||
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
|
||||
type_list<Args...>) {
|
||||
constexpr auto get_arg_index_by_name(basic_string_view<Char> name,
|
||||
type_list<Args...>) -> int {
|
||||
return get_arg_index_by_name<Args...>(name);
|
||||
}
|
||||
|
||||
@ -105,8 +125,8 @@ template <typename Char> struct text {
|
||||
basic_string_view<Char> data;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&...) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
|
||||
return write<Char>(out, data);
|
||||
}
|
||||
};
|
||||
@ -115,8 +135,8 @@ template <typename Char>
|
||||
struct is_compiled_format<text<Char>> : std::true_type {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
|
||||
size_t size) {
|
||||
constexpr auto make_text(basic_string_view<Char> s, size_t pos, size_t size)
|
||||
-> text<Char> {
|
||||
return {{&s[pos], size}};
|
||||
}
|
||||
|
||||
@ -124,8 +144,8 @@ template <typename Char> struct code_unit {
|
||||
Char value;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&...) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
|
||||
*out++ = value;
|
||||
return out;
|
||||
}
|
||||
@ -133,7 +153,7 @@ template <typename Char> struct code_unit {
|
||||
|
||||
// This ensures that the argument type is convertible to `const T&`.
|
||||
template <typename T, int N, typename... Args>
|
||||
constexpr const T& get_arg_checked(const Args&... args) {
|
||||
constexpr auto get_arg_checked(const Args&... args) -> const T& {
|
||||
const auto& arg = detail::get<N>(args...);
|
||||
if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {
|
||||
return arg.value;
|
||||
@ -146,13 +166,13 @@ template <typename Char>
|
||||
struct is_compiled_format<code_unit<Char>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N.
|
||||
template <typename Char, typename T, int N> struct field {
|
||||
template <typename Char, typename V, int N> struct field {
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
const T& arg = get_arg_checked<T, N>(args...);
|
||||
if constexpr (std::is_convertible<T, basic_string_view<Char>>::value) {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
const V& arg = get_arg_checked<V, N>(args...);
|
||||
if constexpr (std::is_convertible<V, basic_string_view<Char>>::value) {
|
||||
auto s = basic_string_view<Char>(arg);
|
||||
return copy<Char>(s.begin(), s.end(), out);
|
||||
} else {
|
||||
@ -170,10 +190,10 @@ template <typename Char> struct runtime_named_field {
|
||||
basic_string_view<Char> name;
|
||||
|
||||
template <typename OutputIt, typename T>
|
||||
constexpr static bool try_format_argument(
|
||||
constexpr static auto try_format_argument(
|
||||
OutputIt& out,
|
||||
// [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
|
||||
[[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) {
|
||||
[[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) -> bool {
|
||||
if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {
|
||||
if (arg_name == arg.name) {
|
||||
out = write<Char>(out, arg.value);
|
||||
@ -183,8 +203,8 @@ template <typename Char> struct runtime_named_field {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
bool found = (try_format_argument(out, name, args) || ...);
|
||||
if (!found) {
|
||||
FMT_THROW(format_error("argument with specified name is not found"));
|
||||
@ -197,17 +217,17 @@ template <typename Char>
|
||||
struct is_compiled_format<runtime_named_field<Char>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N and has format specifiers.
|
||||
template <typename Char, typename T, int N> struct spec_field {
|
||||
template <typename Char, typename V, int N> struct spec_field {
|
||||
using char_type = Char;
|
||||
formatter<T, Char> fmt;
|
||||
formatter<V, Char> fmt;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr FMT_INLINE OutputIt format(OutputIt out,
|
||||
const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const
|
||||
-> OutputIt {
|
||||
const auto& vargs =
|
||||
fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
|
||||
basic_format_context<OutputIt, Char> ctx(out, vargs);
|
||||
return fmt.format(get_arg_checked<T, N>(args...), ctx);
|
||||
return fmt.format(get_arg_checked<V, N>(args...), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
@ -219,8 +239,8 @@ template <typename L, typename R> struct concat {
|
||||
R rhs;
|
||||
using char_type = typename L::char_type;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
out = lhs.format(out, args...);
|
||||
return rhs.format(out, args...);
|
||||
}
|
||||
@ -230,14 +250,14 @@ template <typename L, typename R>
|
||||
struct is_compiled_format<concat<L, R>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R>
|
||||
constexpr concat<L, R> make_concat(L lhs, R rhs) {
|
||||
constexpr auto make_concat(L lhs, R rhs) -> concat<L, R> {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
struct unknown_format {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
constexpr auto parse_text(basic_string_view<Char> str, size_t pos) -> size_t {
|
||||
for (size_t size = str.size(); pos != size; ++pos) {
|
||||
if (str[pos] == '{' || str[pos] == '}') break;
|
||||
}
|
||||
@ -270,8 +290,8 @@ template <typename T, typename Char> struct parse_specs_result {
|
||||
enum { manual_indexing_id = -1 };
|
||||
|
||||
template <typename T, typename Char>
|
||||
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
size_t pos, int next_arg_id) {
|
||||
constexpr auto parse_specs(basic_string_view<Char> str, size_t pos,
|
||||
int next_arg_id) -> parse_specs_result<T, Char> {
|
||||
str.remove_prefix(pos);
|
||||
auto ctx =
|
||||
compile_parse_context<Char>(str, max_value<int>(), nullptr, next_arg_id);
|
||||
@ -285,16 +305,16 @@ template <typename Char> struct arg_id_handler {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
|
||||
constexpr int on_auto() {
|
||||
constexpr auto on_auto() -> int {
|
||||
FMT_ASSERT(false, "handler cannot be used with automatic indexing");
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_index(int id) {
|
||||
constexpr auto on_index(int id) -> int {
|
||||
kind = arg_id_kind::index;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_name(basic_string_view<Char> id) {
|
||||
constexpr auto on_name(basic_string_view<Char> id) -> int {
|
||||
kind = arg_id_kind::name;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
@ -433,27 +453,28 @@ FMT_BEGIN_EXPORT
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
template <typename CompiledFormat, typename... T,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
FMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf,
|
||||
const T&... args)
|
||||
-> std::basic_string<Char> {
|
||||
auto s = std::basic_string<Char>();
|
||||
cf.format(std::back_inserter(s), args...);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
template <typename OutputIt, typename CompiledFormat, typename... T,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
constexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const T&... args) -> OutputIt {
|
||||
return cf.format(out, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
Args&&... args) {
|
||||
FMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args)
|
||||
-> std::basic_string<typename S::char_type> {
|
||||
if constexpr (std::is_same<typename S::char_type, char>::value) {
|
||||
constexpr auto str = basic_string_view<typename S::char_type>(S());
|
||||
if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {
|
||||
@ -466,72 +487,97 @@ FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
}
|
||||
}
|
||||
}
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
constexpr auto compiled = detail::compile<T...>(S());
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
|
||||
detail::unknown_format>()) {
|
||||
return fmt::format(
|
||||
static_cast<basic_string_view<typename S::char_type>>(S()),
|
||||
std::forward<Args>(args)...);
|
||||
std::forward<T>(args)...);
|
||||
} else {
|
||||
return fmt::format(compiled, std::forward<Args>(args)...);
|
||||
return fmt::format(compiled, std::forward<T>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
FMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt {
|
||||
constexpr auto compiled = detail::compile<T...>(S());
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
|
||||
detail::unknown_format>()) {
|
||||
return fmt::format_to(
|
||||
out, static_cast<basic_string_view<typename S::char_type>>(S()),
|
||||
std::forward<Args>(args)...);
|
||||
std::forward<T>(args)...);
|
||||
} else {
|
||||
return fmt::format_to(out, compiled, std::forward<Args>(args)...);
|
||||
return fmt::format_to(out, compiled, std::forward<T>(args)...);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
auto format_to_n(OutputIt out, size_t n, const S& fmt, Args&&... args)
|
||||
auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
|
||||
fmt::format_to(std::back_inserter(buf), fmt, std::forward<Args>(args)...);
|
||||
fmt::format_to(std::back_inserter(buf), fmt, std::forward<T>(args)...);
|
||||
return {buf.out(), buf.count()};
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
|
||||
-> size_t {
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t {
|
||||
auto buf = detail::counting_buffer<>();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
void print(std::FILE* f, const S& fmt, const Args&... args) {
|
||||
void print(std::FILE* f, const S& fmt, T&&... args) {
|
||||
auto buf = memory_buffer();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
|
||||
detail::print(f, {buf.data(), buf.size()});
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
void print(const S& fmt, const Args&... args) {
|
||||
print(stdout, fmt, args...);
|
||||
void print(const S& fmt, T&&... args) {
|
||||
print(stdout, fmt, std::forward<T>(args)...);
|
||||
}
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||
return FMT_COMPILE(Str.data);
|
||||
}
|
||||
} // namespace literals
|
||||
#endif
|
||||
template <size_t N> class static_format_result {
|
||||
private:
|
||||
char data[N];
|
||||
|
||||
public:
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) {
|
||||
*fmt::format_to(data, fmt, std::forward<T>(args)...) = '\0';
|
||||
}
|
||||
|
||||
auto str() const -> fmt::string_view { return {data, N - 1}; }
|
||||
auto c_str() const -> const char* { return data; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats arguments according to the format string `fmt_str` and produces
|
||||
* a string of the exact required size at compile time. Both the format string
|
||||
* and the arguments must be compile-time expressions.
|
||||
*
|
||||
* The resulting string can be accessed as a C string via `c_str()` or as
|
||||
* a `fmt::string_view` via `str()`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // Produces the static string "42" at compile time.
|
||||
* static constexpr auto result = FMT_STATIC_FORMAT("{}", 42);
|
||||
* const char* s = result.c_str();
|
||||
*/
|
||||
#define FMT_STATIC_FORMAT(fmt_str, ...) \
|
||||
fmt::static_format_result< \
|
||||
fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \
|
||||
FMT_COMPILE(fmt_str), __VA_ARGS__)
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
125
3rdparty/fmt/include/fmt/format-inl.h
vendored
125
3rdparty/fmt/include/fmt/format-inl.h
vendored
@ -22,7 +22,7 @@
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
#if FMT_USE_LOCALE && !defined(FMT_MODULE)
|
||||
# include <locale>
|
||||
#endif
|
||||
|
||||
@ -31,14 +31,49 @@
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
#ifndef FMT_CUSTOM_ASSERT_FAIL
|
||||
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
|
||||
// Use unchecked std::fprintf to avoid triggering another assertion when
|
||||
// writing to stderr fails.
|
||||
fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
namespace detail {
|
||||
using std::locale;
|
||||
using std::numpunct;
|
||||
using std::use_facet;
|
||||
} // namespace detail
|
||||
|
||||
template <typename Locale, enable_if_t<(sizeof(Locale::collate) != 0), int>>
|
||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||
static_assert(std::is_same<Locale, std::locale>::value, "");
|
||||
}
|
||||
#else
|
||||
namespace detail {
|
||||
struct locale {};
|
||||
template <typename Char> struct numpunct {
|
||||
auto grouping() const -> std::string { return "\03"; }
|
||||
auto thousands_sep() const -> Char { return ','; }
|
||||
auto decimal_point() const -> Char { return '.'; }
|
||||
};
|
||||
template <typename Facet> Facet use_facet(locale) { return {}; }
|
||||
} // namespace detail
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto locale_ref::get() const -> Locale {
|
||||
using namespace detail;
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
#if FMT_USE_LOCALE
|
||||
if (locale_) return *static_cast<const locale*>(locale_);
|
||||
#endif
|
||||
return locale();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
||||
string_view message) noexcept {
|
||||
@ -79,33 +114,6 @@ inline void fwrite_all(const void* ptr, size_t count, FILE* stream) {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
|
||||
}
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
using std::locale;
|
||||
using std::numpunct;
|
||||
using std::use_facet;
|
||||
|
||||
template <typename Locale>
|
||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
}
|
||||
#else
|
||||
struct locale {};
|
||||
template <typename Char> struct numpunct {
|
||||
auto grouping() const -> std::string { return "\03"; }
|
||||
auto thousands_sep() const -> Char { return ','; }
|
||||
auto decimal_point() const -> Char { return '.'; }
|
||||
};
|
||||
template <typename Facet> Facet use_facet(locale) { return {}; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto locale_ref::get() const -> Locale {
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
#if FMT_USE_LOCALE
|
||||
if (locale_) return *static_cast<const locale*>(locale_);
|
||||
#endif
|
||||
return locale();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
|
||||
auto&& facet = use_facet<numpunct<Char>>(loc.get<locale>());
|
||||
@ -133,14 +141,13 @@ FMT_FUNC auto write_loc(appender out, loc_value value,
|
||||
} // namespace detail
|
||||
|
||||
FMT_FUNC void report_error(const char* message) {
|
||||
#if FMT_USE_EXCEPTIONS
|
||||
// Use FMT_THROW instead of throw to avoid bogus unreachable code warnings
|
||||
// from MSVC.
|
||||
FMT_THROW(format_error(message));
|
||||
#else
|
||||
fputs(message, stderr);
|
||||
abort();
|
||||
#if FMT_MSC_VERSION || defined(__NVCC__)
|
||||
// Silence unreachable code warnings in MSVC and NVCC because these
|
||||
// are nearly impossible to fix in a generic code.
|
||||
volatile bool b = true;
|
||||
if (!b) return;
|
||||
#endif
|
||||
FMT_THROW(format_error(message));
|
||||
}
|
||||
|
||||
template <typename Locale> typename Locale::id format_facet<Locale>::id;
|
||||
@ -174,11 +181,11 @@ inline auto operator==(basic_fp<F> x, basic_fp<F> y) -> bool {
|
||||
}
|
||||
|
||||
// Compilers should be able to optimize this into the ror instruction.
|
||||
FMT_CONSTEXPR inline auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
|
||||
FMT_INLINE auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
|
||||
r &= 31;
|
||||
return (n >> r) | (n << (32 - r));
|
||||
}
|
||||
FMT_CONSTEXPR inline auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
|
||||
FMT_INLINE auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
|
||||
r &= 63;
|
||||
return (n >> r) | (n << (64 - r));
|
||||
}
|
||||
@ -275,7 +282,7 @@ template <> struct cache_accessor<float> {
|
||||
static auto get_cached_power(int k) noexcept -> uint64_t {
|
||||
FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
|
||||
"k is out of range");
|
||||
static constexpr const uint64_t pow10_significands[] = {
|
||||
static constexpr uint64_t pow10_significands[] = {
|
||||
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
|
||||
0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,
|
||||
0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,
|
||||
@ -370,7 +377,7 @@ template <> struct cache_accessor<double> {
|
||||
FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
|
||||
"k is out of range");
|
||||
|
||||
static constexpr const uint128_fallback pow10_significands[] = {
|
||||
static constexpr uint128_fallback pow10_significands[] = {
|
||||
#if FMT_USE_FULL_CACHE_DRAGONBOX
|
||||
{0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
|
||||
{0x9faacf3df73609b1, 0x77b191618c54e9ad},
|
||||
@ -1037,7 +1044,7 @@ template <> struct cache_accessor<double> {
|
||||
#if FMT_USE_FULL_CACHE_DRAGONBOX
|
||||
return pow10_significands[k - float_info<double>::min_k];
|
||||
#else
|
||||
static constexpr const uint64_t powers_of_5_64[] = {
|
||||
static constexpr uint64_t powers_of_5_64[] = {
|
||||
0x0000000000000001, 0x0000000000000005, 0x0000000000000019,
|
||||
0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,
|
||||
0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,
|
||||
@ -1149,8 +1156,8 @@ auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool {
|
||||
exponent <= case_shorter_interval_left_endpoint_upper_threshold;
|
||||
}
|
||||
|
||||
// Remove trailing zeros from n and return the number of zeros removed (float)
|
||||
FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
|
||||
// Remove trailing zeros from n and return the number of zeros removed (float).
|
||||
FMT_INLINE auto remove_trailing_zeros(uint32_t& n, int s = 0) noexcept -> int {
|
||||
FMT_ASSERT(n != 0, "");
|
||||
// Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1.
|
||||
constexpr uint32_t mod_inv_5 = 0xcccccccd;
|
||||
@ -1170,22 +1177,19 @@ FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Removes trailing zeros and returns the number of zeros removed (double)
|
||||
FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
|
||||
// Removes trailing zeros and returns the number of zeros removed (double).
|
||||
FMT_INLINE auto remove_trailing_zeros(uint64_t& n) noexcept -> int {
|
||||
FMT_ASSERT(n != 0, "");
|
||||
|
||||
// This magic number is ceil(2^90 / 10^8).
|
||||
constexpr uint64_t magic_number = 12379400392853802749ull;
|
||||
auto nm = umul128(n, magic_number);
|
||||
|
||||
// Is n is divisible by 10^8?
|
||||
if ((nm.high() & ((1ull << (90 - 64)) - 1)) == 0 && nm.low() < magic_number) {
|
||||
constexpr uint32_t ten_pow_8 = 100000000u;
|
||||
if ((n % ten_pow_8) == 0) {
|
||||
// If yes, work with the quotient...
|
||||
auto n32 = static_cast<uint32_t>(nm.high() >> (90 - 64));
|
||||
auto n32 = static_cast<uint32_t>(n / ten_pow_8);
|
||||
// ... and use the 32 bit variant of the function
|
||||
int s = remove_trailing_zeros(n32, 8);
|
||||
int num_zeros = remove_trailing_zeros(n32, 8);
|
||||
n = n32;
|
||||
return s;
|
||||
return num_zeros;
|
||||
}
|
||||
|
||||
// If n is not divisible by 10^8, work with n itself.
|
||||
@ -1210,7 +1214,7 @@ FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
|
||||
|
||||
// The main algorithm for shorter interval case
|
||||
template <typename T>
|
||||
FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) noexcept {
|
||||
FMT_INLINE auto shorter_interval_case(int exponent) noexcept -> decimal_fp<T> {
|
||||
decimal_fp<T> ret_value;
|
||||
// Compute k and beta
|
||||
const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);
|
||||
@ -1454,8 +1458,8 @@ FMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
|
||||
auto out = appender(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<char>{parse_context<char>(fmt), {out, args, loc}});
|
||||
parse_format_string(fmt,
|
||||
format_handler<>{parse_context<>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
template <typename T> struct span {
|
||||
@ -1546,10 +1550,11 @@ template <typename F> class glibc_file : public file_base<F> {
|
||||
|
||||
void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }
|
||||
|
||||
bool needs_flush() const {
|
||||
auto needs_flush() const -> bool {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
char* end = this->file_->_IO_write_end;
|
||||
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
|
||||
auto size = max_of<ptrdiff_t>(this->file_->_IO_write_ptr - end, 0);
|
||||
return memchr(end, '\n', static_cast<size_t>(size));
|
||||
}
|
||||
|
||||
void flush() { fflush_unlocked(this->file_); }
|
||||
@ -1573,7 +1578,7 @@ template <typename F> class apple_file : public file_base<F> {
|
||||
void init_buffer() {
|
||||
if (this->file_->_p) return;
|
||||
// Force buffer initialization by placing and removing a char in a buffer.
|
||||
putc_unlocked(0, this->file_);
|
||||
if (!FMT_CLANG_ANALYZER) putc_unlocked(0, this->file_);
|
||||
--this->file_->_p;
|
||||
++this->file_->_w;
|
||||
}
|
||||
@ -1594,7 +1599,7 @@ template <typename F> class apple_file : public file_base<F> {
|
||||
this->file_->_w -= size;
|
||||
}
|
||||
|
||||
bool needs_flush() const {
|
||||
auto needs_flush() const -> bool {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
return memchr(this->file_->_p + this->file_->_w, '\n',
|
||||
to_unsigned(-this->file_->_w));
|
||||
|
||||
819
3rdparty/fmt/include/fmt/format.h
vendored
819
3rdparty/fmt/include/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
3
3rdparty/fmt/include/fmt/os.h
vendored
3
3rdparty/fmt/include/fmt/os.h
vendored
@ -29,7 +29,8 @@
|
||||
# if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
|
||||
defined(__linux__)) && \
|
||||
(!defined(WINAPI_FAMILY) || \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) && \
|
||||
!defined(__wasm__)
|
||||
# include <fcntl.h> // for O_RDONLY
|
||||
# define FMT_USE_FCNTL 1
|
||||
# else
|
||||
|
||||
4
3rdparty/fmt/include/fmt/ostream.h
vendored
4
3rdparty/fmt/include/fmt/ostream.h
vendored
@ -33,8 +33,8 @@
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// Generate a unique explicit instantion in every translation unit using a tag
|
||||
// type in an anonymous namespace.
|
||||
// Generate a unique explicit instantiation in every translation unit using a
|
||||
// tag type in an anonymous namespace.
|
||||
namespace {
|
||||
struct file_access_tag {};
|
||||
} // namespace
|
||||
|
||||
59
3rdparty/fmt/include/fmt/printf.h
vendored
59
3rdparty/fmt/include/fmt/printf.h
vendored
@ -9,7 +9,7 @@
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#ifndef FMT_MODULE
|
||||
# include <algorithm> // std::max
|
||||
# include <algorithm> // std::find
|
||||
# include <limits> // std::numeric_limits
|
||||
#endif
|
||||
|
||||
@ -18,10 +18,6 @@
|
||||
FMT_BEGIN_NAMESPACE
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
template <typename T> struct printf_formatter {
|
||||
printf_formatter() = delete;
|
||||
};
|
||||
|
||||
template <typename Char> class basic_printf_context {
|
||||
private:
|
||||
basic_appender<Char> out_;
|
||||
@ -33,8 +29,6 @@ template <typename Char> class basic_printf_context {
|
||||
|
||||
public:
|
||||
using char_type = Char;
|
||||
using parse_context_type = parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
enum { builtin_types = 1 };
|
||||
|
||||
/// Constructs a `printf_context` object. References to the arguments are
|
||||
@ -46,7 +40,7 @@ template <typename Char> class basic_printf_context {
|
||||
auto out() -> basic_appender<Char> { return out_; }
|
||||
void advance_to(basic_appender<Char>) {}
|
||||
|
||||
auto locale() -> detail::locale_ref { return {}; }
|
||||
auto locale() -> locale_ref { return {}; }
|
||||
|
||||
auto arg(int id) const -> basic_format_arg<basic_printf_context> {
|
||||
return args_.get(id);
|
||||
@ -74,10 +68,9 @@ inline auto find<false, char>(const char* first, const char* last, char value,
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <bool IS_SIGNED> struct int_checker {
|
||||
template <typename T> static auto fits_in_int(T value) -> bool {
|
||||
unsigned max = to_unsigned(max_value<int>());
|
||||
return value <= max;
|
||||
return value <= to_unsigned(max_value<int>());
|
||||
}
|
||||
inline static auto fits_in_int(bool) -> bool { return true; }
|
||||
};
|
||||
@ -95,7 +88,7 @@ struct printf_precision_handler {
|
||||
auto operator()(T value) -> int {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
report_error("number is too big");
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
return max_of(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
@ -410,7 +403,9 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
arg_index = parse_ctx.next_arg_id();
|
||||
else
|
||||
parse_ctx.check_arg_id(--arg_index);
|
||||
return detail::get_arg(context, arg_index);
|
||||
auto arg = context.arg(arg_index);
|
||||
if (!arg) report_error("argument not found");
|
||||
return arg;
|
||||
};
|
||||
|
||||
const Char* start = parse_ctx.begin();
|
||||
@ -571,15 +566,19 @@ inline auto vsprintf(basic_string_view<Char> fmt,
|
||||
*
|
||||
* std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
|
||||
return vsprintf(detail::to_string_view(fmt),
|
||||
fmt::make_format_args<basic_printf_context<Char>>(args...));
|
||||
template <typename... T>
|
||||
inline auto sprintf(string_view fmt, const T&... args) -> std::string {
|
||||
return vsprintf(fmt, make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED auto sprintf(basic_string_view<wchar_t> fmt, const T&... args)
|
||||
-> std::wstring {
|
||||
return vsprintf(fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args) -> int {
|
||||
auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args) -> int {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vprintf(buf, fmt, args);
|
||||
size_t size = buf.size();
|
||||
@ -596,17 +595,14 @@ inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
*
|
||||
* fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
|
||||
return vfprintf(f, detail::to_string_view(fmt),
|
||||
make_printf_args<Char>(args...));
|
||||
template <typename... T>
|
||||
inline auto fprintf(std::FILE* f, string_view fmt, const T&... args) -> int {
|
||||
return vfprintf(f, fmt, make_printf_args(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_DEPRECATED inline auto vprintf(basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args)
|
||||
-> int {
|
||||
return vfprintf(stdout, fmt, args);
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED auto fprintf(std::FILE* f, basic_string_view<wchar_t> fmt,
|
||||
const T&... args) -> int {
|
||||
return vfprintf(f, fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,11 +617,6 @@ template <typename... T>
|
||||
inline auto printf(string_view fmt, const T&... args) -> int {
|
||||
return vfprintf(stdout, fmt, make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED inline auto printf(basic_string_view<wchar_t> fmt,
|
||||
const T&... args) -> int {
|
||||
return vfprintf(stdout, fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
48
3rdparty/fmt/include/fmt/ranges.h
vendored
48
3rdparty/fmt/include/fmt/ranges.h
vendored
@ -11,7 +11,6 @@
|
||||
#ifndef FMT_MODULE
|
||||
# include <initializer_list>
|
||||
# include <iterator>
|
||||
# include <string>
|
||||
# include <tuple>
|
||||
# include <type_traits>
|
||||
# include <utility>
|
||||
@ -31,7 +30,7 @@ template <typename T> class is_map {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@ -40,17 +39,16 @@ template <typename T> class is_set {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
|
||||
};
|
||||
|
||||
// C array overload
|
||||
template <typename T, std::size_t N>
|
||||
template <typename T, size_t N>
|
||||
auto range_begin(const T (&arr)[N]) -> const T* {
|
||||
return arr;
|
||||
}
|
||||
template <typename T, std::size_t N>
|
||||
auto range_end(const T (&arr)[N]) -> const T* {
|
||||
template <typename T, size_t N> auto range_end(const T (&arr)[N]) -> const T* {
|
||||
return arr + N;
|
||||
}
|
||||
|
||||
@ -120,7 +118,7 @@ template <typename T> class is_tuple_like_ {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@ -154,7 +152,7 @@ using tuple_index_sequence = make_index_sequence<std::tuple_size<T>::value>;
|
||||
template <typename T, typename C, bool = is_tuple_like_<T>::value>
|
||||
class is_tuple_formattable_ {
|
||||
public:
|
||||
static constexpr const bool value = false;
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||
template <size_t... Is>
|
||||
@ -170,7 +168,7 @@ template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||
C>::value)...>{}));
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
decltype(check(tuple_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
@ -208,7 +206,7 @@ template <typename Char, typename... T>
|
||||
using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
|
||||
|
||||
using std::get;
|
||||
template <typename Tuple, typename Char, std::size_t... Is>
|
||||
template <typename Tuple, typename Char, size_t... Is>
|
||||
auto get_formatters(index_sequence<Is...>)
|
||||
-> result_t<Char, decltype(get<Is>(std::declval<Tuple>()))...>;
|
||||
} // namespace tuple
|
||||
@ -219,7 +217,7 @@ template <typename R> struct range_reference_type_impl {
|
||||
using type = decltype(*detail::range_begin(std::declval<R&>()));
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N> struct range_reference_type_impl<T[N]> {
|
||||
template <typename T, size_t N> struct range_reference_type_impl<T[N]> {
|
||||
using type = T&;
|
||||
};
|
||||
|
||||
@ -281,14 +279,15 @@ template <typename FormatContext> struct format_tuple_element {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T> struct is_tuple_like {
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename C> struct is_tuple_formattable {
|
||||
static constexpr const bool value =
|
||||
detail::is_tuple_formattable_<T, C>::value;
|
||||
static constexpr bool value = detail::is_tuple_formattable_<T, C>::value;
|
||||
};
|
||||
|
||||
template <typename Tuple, typename Char>
|
||||
@ -343,8 +342,9 @@ struct formatter<Tuple, Char,
|
||||
}
|
||||
};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
detail::is_range_<T>::value && !detail::has_to_string_view<T>::value;
|
||||
};
|
||||
|
||||
@ -368,6 +368,7 @@ template <typename P1, typename... Pn>
|
||||
struct conjunction<P1, Pn...>
|
||||
: conditional_t<bool(P1::value), conjunction<Pn...>, P1> {};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char, typename Enable = void>
|
||||
struct range_formatter;
|
||||
|
||||
@ -670,7 +671,8 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||
FMT_EXPORT
|
||||
template <typename Tuple, typename Char> struct tuple_join_view : detail::view {
|
||||
const Tuple& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
@ -685,15 +687,15 @@ template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
||||
#endif
|
||||
|
||||
template <typename Char, typename Tuple>
|
||||
struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||
template <typename Tuple, typename Char>
|
||||
struct formatter<tuple_join_view<Tuple, Char>, Char,
|
||||
enable_if_t<is_tuple_like<Tuple>::value>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return do_parse(ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const tuple_join_view<Char, Tuple>& value,
|
||||
auto format(const tuple_join_view<Tuple, Char>& value,
|
||||
FormatContext& ctx) const -> typename FormatContext::iterator {
|
||||
return do_format(value, ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
@ -725,14 +727,14 @@ struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto do_format(const tuple_join_view<Char, Tuple>&, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Tuple, Char>&, FormatContext& ctx,
|
||||
std::integral_constant<size_t, 0>) const ->
|
||||
typename FormatContext::iterator {
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, size_t N>
|
||||
auto do_format(const tuple_join_view<Char, Tuple>& value, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Tuple, Char>& value, FormatContext& ctx,
|
||||
std::integral_constant<size_t, N>) const ->
|
||||
typename FormatContext::iterator {
|
||||
using std::get;
|
||||
@ -754,7 +756,7 @@ template <typename T> class is_container_adaptor_like {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@ -825,7 +827,7 @@ auto join(Range&& r, string_view sep)
|
||||
*/
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
FMT_CONSTEXPR auto join(const Tuple& tuple, string_view sep)
|
||||
-> tuple_join_view<char, Tuple> {
|
||||
-> tuple_join_view<Tuple, char> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
|
||||
425
3rdparty/fmt/include/fmt/std.h
vendored
425
3rdparty/fmt/include/fmt/std.h
vendored
@ -15,15 +15,13 @@
|
||||
# include <atomic>
|
||||
# include <bitset>
|
||||
# include <complex>
|
||||
# include <cstdlib>
|
||||
# include <exception>
|
||||
# include <functional>
|
||||
# include <functional> // std::reference_wrapper
|
||||
# include <memory>
|
||||
# include <thread>
|
||||
# include <type_traits>
|
||||
# include <typeinfo>
|
||||
# include <utility>
|
||||
# include <vector>
|
||||
# include <typeinfo> // std::type_info
|
||||
# include <utility> // std::make_index_sequence
|
||||
|
||||
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
|
||||
# if FMT_CPLUSPLUS >= 201703L
|
||||
@ -62,27 +60,26 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
|
||||
#ifndef FMT_CPP_LIB_FILESYSTEM
|
||||
# ifdef __cpp_lib_filesystem
|
||||
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
|
||||
# else
|
||||
# define FMT_CPP_LIB_FILESYSTEM 0
|
||||
# endif
|
||||
#ifdef FMT_CPP_LIB_FILESYSTEM
|
||||
// Use the provided definition.
|
||||
#elif defined(__cpp_lib_filesystem)
|
||||
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
|
||||
#else
|
||||
# define FMT_CPP_LIB_FILESYSTEM 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_CPP_LIB_VARIANT
|
||||
# ifdef __cpp_lib_variant
|
||||
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
|
||||
# else
|
||||
# define FMT_CPP_LIB_VARIANT 0
|
||||
# endif
|
||||
#ifdef FMT_CPP_LIB_VARIANT
|
||||
// Use the provided definition.
|
||||
#elif defined(__cpp_lib_variant)
|
||||
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
|
||||
#else
|
||||
# define FMT_CPP_LIB_VARIANT 0
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
#if FMT_CPP_LIB_FILESYSTEM
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename PathChar>
|
||||
auto get_path_string(const std::filesystem::path& p,
|
||||
@ -111,8 +108,168 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (has_to_string_view<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_CPP_LIB_VARIANT
|
||||
|
||||
template <typename> struct is_variant_like_ : std::false_type {};
|
||||
template <typename... Types>
|
||||
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
|
||||
|
||||
template <typename Variant, typename Char> class is_variant_formattable {
|
||||
template <size_t... Is>
|
||||
static auto check(std::index_sequence<Is...>) -> std::conjunction<
|
||||
is_formattable<std::variant_alternative_t<Is, Variant>, Char>...>;
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(check(
|
||||
std::make_index_sequence<std::variant_size<Variant>::value>()))::value;
|
||||
};
|
||||
|
||||
#endif // FMT_CPP_LIB_VARIANT
|
||||
|
||||
#if FMT_USE_RTTI
|
||||
|
||||
template <typename OutputIt>
|
||||
auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
}
|
||||
return detail::write_bytes<char>(out, demangled_name_view);
|
||||
# elif FMT_MSC_VERSION
|
||||
const string_view demangled_name(ti.name());
|
||||
for (size_t i = 0; i < demangled_name.size(); ++i) {
|
||||
auto sub = demangled_name;
|
||||
sub.remove_prefix(i);
|
||||
if (sub.starts_with("enum ")) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("class ") || sub.starts_with("union ")) {
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("struct ")) {
|
||||
i += 6;
|
||||
continue;
|
||||
}
|
||||
if (*sub.begin() != ' ') *out++ = *sub.begin();
|
||||
}
|
||||
return out;
|
||||
# else
|
||||
return detail::write_bytes<char>(out, string_view(ti.name()));
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // FMT_USE_RTTI
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_flip : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> struct is_bit_reference_like {
|
||||
static constexpr bool value = std::is_convertible<T, bool>::value &&
|
||||
std::is_nothrow_assignable<T, bool>::value &&
|
||||
has_flip<T>::value;
|
||||
};
|
||||
|
||||
// Workaround for libc++ incompatibility with C++ standard.
|
||||
// According to the Standard, `bitset::operator[] const` returns bool.
|
||||
#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD)
|
||||
template <typename C>
|
||||
struct is_bit_reference_like<std::__bit_const_reference<C>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_format_as : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_format_as<T, void_t<decltype(format_as(std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_format_as_member : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_format_as_member<
|
||||
T, void_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
|
||||
#if FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
class path : public std::filesystem::path {
|
||||
public:
|
||||
auto display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{}"), base);
|
||||
}
|
||||
auto system_string() const -> std::string { return string(); }
|
||||
|
||||
auto generic_display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{:g}"), base);
|
||||
}
|
||||
auto generic_system_string() const -> std::string { return generic_string(); }
|
||||
};
|
||||
|
||||
template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
private:
|
||||
format_specs specs_;
|
||||
@ -162,39 +319,20 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
}
|
||||
};
|
||||
|
||||
class path : public std::filesystem::path {
|
||||
public:
|
||||
auto display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{}"), base);
|
||||
}
|
||||
auto system_string() const -> std::string { return string(); }
|
||||
|
||||
auto generic_display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{:g}"), base);
|
||||
}
|
||||
auto generic_system_string() const -> std::string { return generic_string(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif // FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <std::size_t N, typename Char>
|
||||
template <size_t N, typename Char>
|
||||
struct formatter<std::bitset<N>, Char>
|
||||
: nested_formatter<basic_string_view<Char>, Char> {
|
||||
private:
|
||||
// Functor because C++11 doesn't support generic lambdas.
|
||||
// This is a functor because C++11 doesn't support generic lambdas.
|
||||
struct writer {
|
||||
const std::bitset<N>& bs;
|
||||
|
||||
template <typename OutputIt>
|
||||
FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
|
||||
for (auto pos = N; pos > 0; --pos) {
|
||||
for (auto pos = N; pos > 0; --pos)
|
||||
out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
@ -209,10 +347,8 @@ struct formatter<std::bitset<N>, Char>
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#ifdef __cpp_lib_optional
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::optional<T>, Char,
|
||||
std::enable_if_t<is_formattable<T, Char>::value>> {
|
||||
@ -251,30 +387,9 @@ struct formatter<std::optional<T>, Char,
|
||||
return detail::write(out, ')');
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_optional
|
||||
|
||||
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (has_to_string_view<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_expected
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename T, typename E, typename Char>
|
||||
struct formatter<std::expected<T, E>, Char,
|
||||
std::enable_if_t<(std::is_void<T>::value ||
|
||||
@ -301,11 +416,9 @@ struct formatter<std::expected<T, E>, Char,
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_expected
|
||||
|
||||
#ifdef __cpp_lib_source_location
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct formatter<std::source_location> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
|
||||
|
||||
@ -323,42 +436,12 @@ template <> struct formatter<std::source_location> {
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#if FMT_CPP_LIB_VARIANT
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
using variant_index_sequence =
|
||||
std::make_index_sequence<std::variant_size<T>::value>;
|
||||
|
||||
template <typename> struct is_variant_like_ : std::false_type {};
|
||||
template <typename... Types>
|
||||
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
|
||||
|
||||
// formattable element check.
|
||||
template <typename T, typename C> class is_variant_formattable_ {
|
||||
template <std::size_t... Is>
|
||||
static std::conjunction<
|
||||
is_formattable<std::variant_alternative_t<Is, T>, C>...>
|
||||
check(std::index_sequence<Is...>);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
decltype(check(variant_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_variant_like {
|
||||
static constexpr const bool value = detail::is_variant_like_<T>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename C> struct is_variant_formattable {
|
||||
static constexpr const bool value =
|
||||
detail::is_variant_formattable_<T, C>::value;
|
||||
static constexpr bool value = detail::is_variant_like_<T>::value;
|
||||
};
|
||||
|
||||
template <typename Char> struct formatter<std::monostate, Char> {
|
||||
@ -374,10 +457,10 @@ template <typename Char> struct formatter<std::monostate, Char> {
|
||||
};
|
||||
|
||||
template <typename Variant, typename Char>
|
||||
struct formatter<
|
||||
Variant, Char,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
|
||||
struct formatter<Variant, Char,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
is_variant_like<Variant>,
|
||||
detail::is_variant_formattable<Variant, Char>>>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
@ -402,10 +485,9 @@ struct formatter<
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_CPP_LIB_VARIANT
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct formatter<std::error_code> {
|
||||
private:
|
||||
format_specs specs_;
|
||||
@ -459,101 +541,29 @@ template <> struct formatter<std::error_code> {
|
||||
};
|
||||
|
||||
#if FMT_USE_RTTI
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt>
|
||||
auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
std::size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
}
|
||||
return detail::write_bytes<Char>(out, demangled_name_view);
|
||||
# elif FMT_MSC_VERSION
|
||||
const string_view demangled_name(ti.name());
|
||||
for (std::size_t i = 0; i < demangled_name.size(); ++i) {
|
||||
auto sub = demangled_name;
|
||||
sub.remove_prefix(i);
|
||||
if (sub.starts_with("enum ")) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("class ") || sub.starts_with("union ")) {
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("struct ")) {
|
||||
i += 6;
|
||||
continue;
|
||||
}
|
||||
if (*sub.begin() != ' ') *out++ = *sub.begin();
|
||||
}
|
||||
return out;
|
||||
# else
|
||||
return detail::write_bytes<Char>(out, string_view(ti.name()));
|
||||
# endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
|
||||
> {
|
||||
template <> struct formatter<std::type_info> {
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
auto format(const std::type_info& ti, Context& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return detail::write_demangled_name<Char>(ctx.out(), ti);
|
||||
return detail::write_demangled_name(ctx.out(), ti);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif // FMT_USE_RTTI
|
||||
|
||||
template <typename T, typename Char>
|
||||
template <typename T>
|
||||
struct formatter<
|
||||
T, Char, // DEPRECATED! Mixing code unit types.
|
||||
T, char,
|
||||
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
|
||||
private:
|
||||
bool with_typename_ = false;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
|
||||
auto it = ctx.begin();
|
||||
auto end = ctx.end();
|
||||
if (it == end || *it == '}') return it;
|
||||
@ -570,43 +580,15 @@ struct formatter<
|
||||
auto out = ctx.out();
|
||||
#if FMT_USE_RTTI
|
||||
if (with_typename_) {
|
||||
out = detail::write_demangled_name<Char>(out, typeid(ex));
|
||||
out = detail::write_demangled_name(out, typeid(ex));
|
||||
*out++ = ':';
|
||||
*out++ = ' ';
|
||||
}
|
||||
#endif
|
||||
return detail::write_bytes<Char>(out, string_view(ex.what()));
|
||||
return detail::write_bytes<char>(out, string_view(ex.what()));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_flip : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> struct is_bit_reference_like {
|
||||
static constexpr const bool value =
|
||||
std::is_convertible<T, bool>::value &&
|
||||
std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
|
||||
};
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
|
||||
// Workaround for libc++ incompatibility with C++ standard.
|
||||
// According to the Standard, `bitset::operator[] const` returns bool.
|
||||
template <typename C>
|
||||
struct is_bit_reference_like<std::__bit_const_reference<C>> {
|
||||
static constexpr const bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// We can't use std::vector<bool, Allocator>::reference and
|
||||
// std::bitset<N>::reference because the compiler can't deduce Allocator and N
|
||||
// in partial specialization.
|
||||
@ -621,14 +603,6 @@ struct formatter<BitRef, Char,
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::atomic<T>, Char,
|
||||
enable_if_t<is_formattable<T, Char>::value>>
|
||||
@ -715,7 +689,11 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::reference_wrapper<T>, Char,
|
||||
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
|
||||
// Guard against format_as because reference_wrapper is
|
||||
// implicitly convertible to T&.
|
||||
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value &&
|
||||
!detail::has_format_as<T>::value &&
|
||||
!detail::has_format_as_member<T>::value>>
|
||||
: formatter<remove_cvref_t<T>, Char> {
|
||||
template <typename FormatContext>
|
||||
auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
|
||||
@ -725,4 +703,5 @@ struct formatter<std::reference_wrapper<T>, Char,
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_STD_H_
|
||||
|
||||
73
3rdparty/fmt/include/fmt/xchar.h
vendored
73
3rdparty/fmt/include/fmt/xchar.h
vendored
@ -55,6 +55,16 @@ inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
basic_format_args<buffered_context<Char>> args,
|
||||
locale_ref loc = {}) {
|
||||
static_assert(!std::is_same<Char, char>::value, "");
|
||||
auto out = basic_appender<Char>(buf);
|
||||
parse_format_string(
|
||||
fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
@ -112,10 +122,6 @@ inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
|
||||
return {{s}};
|
||||
}
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
|
||||
#endif
|
||||
|
||||
template <typename... T>
|
||||
constexpr auto make_wformat_args(T&... args)
|
||||
-> decltype(fmt::make_format_args<wformat_context>(args...)) {
|
||||
@ -151,13 +157,13 @@ auto join(std::initializer_list<T> list, wstring_view sep)
|
||||
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
|
||||
-> tuple_join_view<wchar_t, Tuple> {
|
||||
-> tuple_join_view<Tuple, wchar_t> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto vformat(basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, fmt, args);
|
||||
@ -187,24 +193,20 @@ auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat(const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
template <typename S, typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat(locale_ref loc, const S& fmt,
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args,
|
||||
detail::locale_ref(loc));
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args, loc);
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename... T,
|
||||
template <typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto format(const Locale& loc, const S& fmt, T&&... args)
|
||||
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||
inline auto format(locale_ref loc, const S& fmt, T&&... args)
|
||||
-> std::basic_string<Char> {
|
||||
return vformat(loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
@ -215,7 +217,7 @@ template <typename OutputIt, typename S,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
auto vformat_to(OutputIt out, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args) -> OutputIt {
|
||||
basic_format_args<buffered_context<Char>> args) -> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args);
|
||||
return detail::get_iterator(buf, out);
|
||||
@ -231,27 +233,24 @@ inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename OutputIt, typename... Args,
|
||||
template <typename S, typename OutputIt, typename... Args,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to(OutputIt out, locale_ref loc, const S& fmt,
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
|
||||
vformat_to(buf, detail::to_string_view(fmt), args, loc);
|
||||
return detail::get_iterator(buf, out);
|
||||
}
|
||||
|
||||
template <typename Locale, typename OutputIt, typename S, typename... T,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
|
||||
detail::is_locale<Locale>::value &&
|
||||
detail::is_exotic_char<Char>::value>
|
||||
inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
T&&... args) ->
|
||||
typename std::enable_if<enable, OutputIt>::type {
|
||||
inline auto format_to(OutputIt out, locale_ref loc, const S& fmt, T&&... args)
|
||||
-> typename std::enable_if<enable, OutputIt>::type {
|
||||
return vformat_to(out, loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
@ -260,7 +259,7 @@ template <typename OutputIt, typename Char, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
|
||||
@ -331,18 +330,6 @@ inline auto format(text_style ts, wformat_string<T...> fmt, T&&... args)
|
||||
return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(std::FILE* f, text_style ts, wformat_string<T...> fmt,
|
||||
const T&... args) {
|
||||
vprint(f, ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(text_style ts, wformat_string<T...> fmt,
|
||||
const T&... args) {
|
||||
return print(stdout, ts, fmt, args...);
|
||||
}
|
||||
|
||||
inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
|
||||
auto buffer = basic_memory_buffer<wchar_t>();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
|
||||
2
3rdparty/fmt/src/fmt.cc
vendored
2
3rdparty/fmt/src/fmt.cc
vendored
@ -50,6 +50,8 @@ module;
|
||||
# include <limits.h>
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
#endif
|
||||
#include <cerrno>
|
||||
|
||||
17
3rdparty/fmt/src/format.cc
vendored
17
3rdparty/fmt/src/format.cc
vendored
@ -8,6 +8,12 @@
|
||||
#include "fmt/format-inl.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template FMT_API auto dragonbox::to_decimal(float x) noexcept
|
||||
@ -15,12 +21,6 @@ template FMT_API auto dragonbox::to_decimal(float x) noexcept
|
||||
template FMT_API auto dragonbox::to_decimal(double x) noexcept
|
||||
-> dragonbox::decimal_fp<double>;
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
// DEPRECATED! locale_ref in the detail namespace
|
||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||
#endif
|
||||
|
||||
// Explicit instantiations for char.
|
||||
|
||||
template FMT_API auto thousands_sep_impl(locale_ref)
|
||||
@ -30,16 +30,13 @@ template FMT_API auto decimal_point_impl(locale_ref) -> char;
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<char>::append(const char*, const char*);
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void vformat_to(buffer<char>&, string_view,
|
||||
typename vformat_args<>::type, locale_ref);
|
||||
|
||||
// Explicit instantiations for wchar_t.
|
||||
|
||||
template FMT_API auto thousands_sep_impl(locale_ref)
|
||||
-> thousands_sep_result<wchar_t>;
|
||||
template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
20
3rdparty/fmt/src/os.cc
vendored
20
3rdparty/fmt/src/os.cc
vendored
@ -66,14 +66,14 @@ using rwresult = int;
|
||||
|
||||
// On Windows the count argument to read and write is unsigned, so convert
|
||||
// it from size_t preventing integer overflow.
|
||||
inline unsigned convert_rwcount(std::size_t count) {
|
||||
inline unsigned convert_rwcount(size_t count) {
|
||||
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
|
||||
}
|
||||
#elif FMT_USE_FCNTL
|
||||
// Return type of read and write functions.
|
||||
using rwresult = ssize_t;
|
||||
|
||||
inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
||||
inline auto convert_rwcount(size_t count) -> size_t { return count; }
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
@ -185,7 +185,7 @@ void buffered_file::close() {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
||||
}
|
||||
|
||||
int buffered_file::descriptor() const {
|
||||
auto buffered_file::descriptor() const -> int {
|
||||
#ifdef FMT_HAS_SYSTEM
|
||||
// fileno is a macro on OpenBSD.
|
||||
# ifdef fileno
|
||||
@ -240,7 +240,7 @@ void file::close() {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
||||
}
|
||||
|
||||
long long file::size() const {
|
||||
auto file::size() const -> long long {
|
||||
# ifdef _WIN32
|
||||
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
|
||||
// is less than 0x0500 as is the case with some default MinGW builds.
|
||||
@ -251,7 +251,7 @@ long long file::size() const {
|
||||
if (size_lower == INVALID_FILE_SIZE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != NO_ERROR)
|
||||
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
|
||||
FMT_THROW(windows_error(error, "cannot get file size"));
|
||||
}
|
||||
unsigned long long long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
@ -266,7 +266,7 @@ long long file::size() const {
|
||||
# endif
|
||||
}
|
||||
|
||||
std::size_t file::read(void* buffer, std::size_t count) {
|
||||
auto file::read(void* buffer, size_t count) -> size_t {
|
||||
rwresult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0)
|
||||
@ -274,7 +274,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
auto file::write(const void* buffer, size_t count) -> size_t {
|
||||
rwresult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0)
|
||||
@ -282,7 +282,7 @@ std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
file file::dup(int fd) {
|
||||
auto file::dup(int fd) -> file {
|
||||
// Don't retry as dup doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
||||
int new_fd = FMT_POSIX_CALL(dup(fd));
|
||||
@ -308,7 +308,7 @@ void file::dup2(int fd, std::error_code& ec) noexcept {
|
||||
if (result == -1) ec = std::error_code(errno, std::generic_category());
|
||||
}
|
||||
|
||||
buffered_file file::fdopen(const char* mode) {
|
||||
auto file::fdopen(const char* mode) -> buffered_file {
|
||||
// Don't retry as fdopen doesn't return EINTR.
|
||||
# if defined(__MINGW32__) && defined(_POSIX_)
|
||||
FILE* f = ::fdopen(fd_, mode);
|
||||
@ -355,7 +355,7 @@ pipe::pipe() {
|
||||
}
|
||||
|
||||
# if !defined(__MSDOS__)
|
||||
long getpagesize() {
|
||||
auto getpagesize() -> long {
|
||||
# ifdef _WIN32
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user