From 6f9710f63d718e2a9f39ba73c60ca7cd642664b7 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Thu, 13 Feb 2025 20:53:47 -0600 Subject: [PATCH] Update thirdparty/fmt to 11.1.3 --- thirdparty/fmt/CMakeLists.txt | 2 +- thirdparty/fmt/include/fmt/base.h | 53 ++++++++++++++------ thirdparty/fmt/include/fmt/chrono.h | 4 +- thirdparty/fmt/include/fmt/format-inl.h | 6 ++- thirdparty/fmt/include/fmt/format.h | 66 ++++++++++++------------- thirdparty/fmt/include/fmt/ostream.h | 2 +- thirdparty/fmt/include/fmt/ranges.h | 4 +- thirdparty/fmt/include/fmt/std.h | 9 ++-- thirdparty/fmt/include/fmt/xchar.h | 27 +++++----- 9 files changed, 102 insertions(+), 71 deletions(-) diff --git a/thirdparty/fmt/CMakeLists.txt b/thirdparty/fmt/CMakeLists.txt index dd4fb6810..f926d89eb 100644 --- a/thirdparty/fmt/CMakeLists.txt +++ b/thirdparty/fmt/CMakeLists.txt @@ -1,5 +1,5 @@ # Update from https://github.com/fmtlib/fmt -# fmt 11.1.0 +# fmt 11.1.3 # License: MIT with object code exception add_library(fmt INTERFACE) diff --git a/thirdparty/fmt/include/fmt/base.h b/thirdparty/fmt/include/fmt/base.h index 2266cb7cd..9eeeb2ce7 100644 --- a/thirdparty/fmt/include/fmt/base.h +++ b/thirdparty/fmt/include/fmt/base.h @@ -21,7 +21,7 @@ #endif // The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 110100 +#define FMT_VERSION 110103 // Detect compiler versions. #if defined(__clang__) && !defined(__ibmxl__) @@ -96,9 +96,9 @@ // Detect C++14 relaxed constexpr. #ifdef FMT_USE_CONSTEXPR // Use the provided definition. -#elif FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L -// GCC only allows throw in constexpr since version 6: -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371. +#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L +// GCC only allows constexpr member functions in non-literal types since 7.2: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297. # define FMT_USE_CONSTEXPR 1 #elif FMT_ICC_VERSION # define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628 @@ -161,6 +161,20 @@ # define FMT_CATCH(x) if (false) #endif +#ifdef FMT_NO_UNIQUE_ADDRESS +// Use the provided definition. +#elif FMT_CPLUSPLUS < 202002L +// Not supported. +#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address) +# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]] +// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485). +#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION +# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] +#endif +#ifndef FMT_NO_UNIQUE_ADDRESS +# define FMT_NO_UNIQUE_ADDRESS +#endif + #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough) # define FMT_FALLTHROUGH [[fallthrough]] #elif defined(__clang__) @@ -285,7 +299,7 @@ // Enable minimal optimizations for more compact code in debug mode. FMT_PRAGMA_GCC(push_options) -#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) +#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE) FMT_PRAGMA_GCC(optimize("Og")) #endif FMT_PRAGMA_CLANG(diagnostic push) @@ -725,13 +739,15 @@ class basic_specs { max_fill_size = 4 }; - size_t data_ = 1 << fill_size_shift; + unsigned data_ = 1 << fill_size_shift; + static_assert(sizeof(data_) * CHAR_BIT >= 18, ""); // Character (code unit) type is erased to prevent template bloat. char fill_data_[max_fill_size] = {' '}; FMT_CONSTEXPR void set_fill_size(size_t size) { - data_ = (data_ & ~fill_size_mask) | (size << fill_size_shift); + data_ = (data_ & ~fill_size_mask) | + (static_cast(size) << fill_size_shift); } public: @@ -828,6 +844,12 @@ class basic_specs { for (size_t i = 0; i < size; ++i) fill_data_[i & 3] = static_cast(s[i]); } + + FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) { + set_fill_size(specs.fill_size()); + for (size_t i = 0; i < max_fill_size; ++i) + fill_data_[i] = specs.fill_data_[i]; + } }; // Format specifiers for built-in and string types. @@ -1099,7 +1121,7 @@ using use_formatter = bool_constant<(std::is_class::value || std::is_enum::value || std::is_union::value || std::is_array::value) && !has_to_string_view::value && !is_named_arg::value && - !use_format_as::value && !use_format_as_member::value>; + !use_format_as::value && !use_format_as_member::value>; template > auto has_formatter_impl(T* p, buffered_context* ctx = nullptr) @@ -2256,9 +2278,7 @@ struct locale_ref { public: constexpr locale_ref() : locale_(nullptr) {} - - template - locale_ref(const Locale& loc); + template locale_ref(const Locale& loc); inline explicit operator bool() const noexcept { return locale_ != nullptr; } #endif // FMT_USE_LOCALE @@ -2604,10 +2624,11 @@ template class basic_format_args { }; // A formatting context. -class context : private detail::locale_ref { +class context { private: appender out_; format_args args_; + FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_; public: /// The character type for the output. @@ -2623,7 +2644,7 @@ class context : private detail::locale_ref { /// in the object so make sure they have appropriate lifetimes. FMT_CONSTEXPR context(iterator out, format_args args, detail::locale_ref loc = {}) - : locale_ref(loc), out_(out), args_(args) {} + : out_(out), args_(args), loc_(loc) {} context(context&&) = default; context(const context&) = delete; void operator=(const context&) = delete; @@ -2635,6 +2656,7 @@ class context : private detail::locale_ref { FMT_CONSTEXPR auto arg_id(string_view name) const -> int { return args_.get_id(name); } + auto args() const -> const format_args& { return args_; } // Returns an iterator to the beginning of the output range. FMT_CONSTEXPR auto out() const -> iterator { return out_; } @@ -2642,7 +2664,7 @@ class context : private detail::locale_ref { // Advances the begin iterator to `it`. FMT_CONSTEXPR void advance_to(iterator) {} - FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return *this; } + FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; } }; template struct runtime_format_string { @@ -2659,7 +2681,8 @@ template struct runtime_format_string { */ inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; } -/// A compile-time format string. +/// A compile-time format string. Use `format_string` in the public API to +/// prevent type deduction. template struct fstring { private: static constexpr int num_static_named_args = diff --git a/thirdparty/fmt/include/fmt/chrono.h b/thirdparty/fmt/include/fmt/chrono.h index abf3671e5..50c777c84 100644 --- a/thirdparty/fmt/include/fmt/chrono.h +++ b/thirdparty/fmt/include/fmt/chrono.h @@ -261,7 +261,7 @@ namespace detail { using utc_clock = std::chrono::utc_clock; #else struct utc_clock { - void to_sys(); + template void to_sys(T); }; #endif @@ -364,7 +364,7 @@ void write_codecvt(codecvt_result& out, string_view in, template auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) -> OutputIt { - if (detail::use_utf8 && loc != get_classic_locale()) { + if (const_check(detail::use_utf8) && loc != get_classic_locale()) { // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and // gcc-4. #if FMT_MSC_VERSION != 0 || \ diff --git a/thirdparty/fmt/include/fmt/format-inl.h b/thirdparty/fmt/include/fmt/format-inl.h index 38308bf2a..a5b79dbe4 100644 --- a/thirdparty/fmt/include/fmt/format-inl.h +++ b/thirdparty/fmt/include/fmt/format-inl.h @@ -84,7 +84,7 @@ using std::locale; using std::numpunct; using std::use_facet; -template > +template locale_ref::locale_ref(const Locale& loc) : locale_(&loc) { static_assert(std::is_same::value, ""); } @@ -134,7 +134,9 @@ FMT_FUNC auto write_loc(appender out, loc_value value, FMT_FUNC void report_error(const char* message) { #if FMT_USE_EXCEPTIONS - throw format_error(message); + // Use FMT_THROW instead of throw to avoid bogus unreachable code warnings + // from MSVC. + FMT_THROW(format_error(message)); #else fputs(message, stderr); abort(); diff --git a/thirdparty/fmt/include/fmt/format.h b/thirdparty/fmt/include/fmt/format.h index 9ee6d683e..4466b4f4d 100644 --- a/thirdparty/fmt/include/fmt/format.h +++ b/thirdparty/fmt/include/fmt/format.h @@ -151,20 +151,6 @@ FMT_END_NAMESPACE # endif // FMT_USE_EXCEPTIONS #endif // FMT_THROW -#ifdef FMT_NO_UNIQUE_ADDRESS -// Use the provided definition. -#elif FMT_CPLUSPLUS < 202002L -// Not supported. -#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address) -# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]] -// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485). -#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION -# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] -#endif -#ifndef FMT_NO_UNIQUE_ADDRESS -# define FMT_NO_UNIQUE_ADDRESS -#endif - // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of // integer formatter template instantiations to just one by only using the // largest integer type. This results in a reduction in binary size but will @@ -241,7 +227,9 @@ FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) { #if defined(FMT_USE_STRING_VIEW) template using std_string_view = std::basic_string_view; #else -template struct std_string_view {}; +template struct std_string_view { + operator basic_string_view() const; +}; #endif template struct string_literal { @@ -1217,7 +1205,7 @@ FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value, } template ::value)> + FMT_ENABLE_IF(!std::is_pointer>::value)> FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits) -> OutputIt { if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { @@ -1853,7 +1841,9 @@ template class digit_grouping { } public: - explicit digit_grouping(locale_ref loc, bool localized = true) { + template ::value)> + explicit digit_grouping(Locale loc, bool localized = true) { if (!localized) return; auto sep = thousands_sep(loc); grouping_ = sep.grouping; @@ -3653,6 +3643,12 @@ FMT_CONSTEXPR auto native_formatter::format( return write(ctx.out(), val, specs, ctx.locale()); } +// DEPRECATED! https://github.com/fmtlib/fmt/issues/4292. +template +struct is_locale : std::false_type {}; +template +struct is_locale> : std::true_type {}; + // DEPRECATED! template struct vformat_args { using type = basic_format_args>; @@ -3974,8 +3970,7 @@ template struct nested_formatter { write(basic_appender(buf)); auto specs = format_specs(); specs.width = width_; - specs.set_fill( - basic_string_view(specs_.fill(), specs_.fill_size())); + specs.copy_fill_from(specs_); specs.set_align(specs_.align()); return detail::write( ctx.out(), basic_string_view(buf.data(), buf.size()), specs); @@ -4135,41 +4130,46 @@ FMT_API void format_system_error(detail::buffer& out, int error_code, // Can be used to report errors from destructors. FMT_API void report_system_error(int error_code, const char* message) noexcept; -inline auto vformat(detail::locale_ref loc, string_view fmt, format_args args) +template ::value)> +inline auto vformat(const Locale& loc, string_view fmt, format_args args) -> std::string { auto buf = memory_buffer(); - detail::vformat_to(buf, fmt, args, loc); + detail::vformat_to(buf, fmt, args, detail::locale_ref(loc)); return {buf.data(), buf.size()}; } -template -FMT_INLINE auto format(detail::locale_ref loc, format_string fmt, - T&&... args) -> std::string { +template ::value)> +FMT_INLINE auto format(const Locale& loc, format_string fmt, T&&... args) + -> std::string { return vformat(loc, fmt.str, vargs{{args...}}); } -template ::value)> -auto vformat_to(OutputIt out, detail::locale_ref loc, string_view fmt, +auto vformat_to(OutputIt out, const Locale& loc, string_view fmt, format_args args) -> OutputIt { auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, fmt, args, loc); + detail::vformat_to(buf, fmt, args, detail::locale_ref(loc)); return detail::get_iterator(buf, out); } -template ::value)> -FMT_INLINE auto format_to(OutputIt out, detail::locale_ref loc, +template ::value&& + detail::is_locale::value)> +FMT_INLINE auto format_to(OutputIt out, const Locale& loc, format_string fmt, T&&... args) -> OutputIt { return fmt::vformat_to(out, loc, fmt.str, vargs{{args...}}); } -template -FMT_NODISCARD FMT_INLINE auto formatted_size(detail::locale_ref loc, +template ::value)> +FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc, format_string fmt, T&&... args) -> size_t { auto buf = detail::counting_buffer<>(); - detail::vformat_to(buf, fmt.str, vargs{{args...}}, loc); + detail::vformat_to(buf, fmt.str, vargs{{args...}}, + detail::locale_ref(loc)); return buf.count(); } diff --git a/thirdparty/fmt/include/fmt/ostream.h b/thirdparty/fmt/include/fmt/ostream.h index 5d893c921..71fd6c887 100644 --- a/thirdparty/fmt/include/fmt/ostream.h +++ b/thirdparty/fmt/include/fmt/ostream.h @@ -150,7 +150,7 @@ inline void vprint(std::ostream& os, string_view fmt, format_args args) { FMT_EXPORT template void print(std::ostream& os, format_string fmt, T&&... args) { fmt::vargs vargs = {{args...}}; - if (detail::use_utf8) return vprint(os, fmt.str, vargs); + if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs); auto buffer = memory_buffer(); detail::vformat_to(buffer, fmt.str, vargs); detail::write_buffer(os, buffer); diff --git a/thirdparty/fmt/include/fmt/ranges.h b/thirdparty/fmt/include/fmt/ranges.h index 118d24fe8..77d645f8e 100644 --- a/thirdparty/fmt/include/fmt/ranges.h +++ b/thirdparty/fmt/include/fmt/ranges.h @@ -527,7 +527,9 @@ struct formatter< template struct formatter< R, Char, - enable_if_t::value == range_format::map>> { + enable_if_t::value == range_format::map>, + detail::is_formattable_delayed>::value>> { private: using map_type = detail::maybe_const_range; using element_type = detail::uncvref_type; diff --git a/thirdparty/fmt/include/fmt/std.h b/thirdparty/fmt/include/fmt/std.h index b00e40225..54eb2c2a7 100644 --- a/thirdparty/fmt/include/fmt/std.h +++ b/thirdparty/fmt/include/fmt/std.h @@ -184,7 +184,8 @@ FMT_END_NAMESPACE FMT_BEGIN_NAMESPACE FMT_EXPORT template -struct formatter, Char> : nested_formatter { +struct formatter, Char> + : nested_formatter, Char> { private: // Functor because C++11 doesn't support generic lambdas. struct writer { @@ -204,7 +205,7 @@ struct formatter, Char> : nested_formatter { template auto format(const std::bitset& bs, FormatContext& ctx) const -> decltype(ctx.out()) { - return write_padded(ctx, writer{bs}); + return this->write_padded(ctx, writer{bs}); } }; @@ -695,9 +696,7 @@ template struct formatter, Char> { auto outer_specs = format_specs(); outer_specs.width = specs.width; - auto fill = specs.template fill(); - if (fill) - outer_specs.set_fill(basic_string_view(fill, specs.fill_size())); + outer_specs.copy_fill_from(specs); outer_specs.set_align(specs.align()); specs.width = 0; diff --git a/thirdparty/fmt/include/fmt/xchar.h b/thirdparty/fmt/include/fmt/xchar.h index 4cbda5421..9f7f889d6 100644 --- a/thirdparty/fmt/include/fmt/xchar.h +++ b/thirdparty/fmt/include/fmt/xchar.h @@ -191,9 +191,11 @@ auto format(const S& fmt, T&&... args) -> std::basic_string { fmt::make_format_args>(args...)); } -template , - FMT_ENABLE_IF(detail::is_exotic_char::value)> -inline auto vformat(detail::locale_ref loc, const S& fmt, +template , + FMT_ENABLE_IF(detail::is_locale::value&& + detail::is_exotic_char::value)> +inline auto vformat(const Locale& loc, const S& fmt, typename detail::vformat_args::type args) -> std::basic_string { auto buf = basic_memory_buffer(); @@ -202,10 +204,11 @@ inline auto vformat(detail::locale_ref loc, const S& fmt, return {buf.data(), buf.size()}; } -template , - FMT_ENABLE_IF(detail::is_exotic_char::value)> -inline auto format(detail::locale_ref loc, const S& fmt, T&&... args) + FMT_ENABLE_IF(detail::is_locale::value&& + detail::is_exotic_char::value)> +inline auto format(const Locale& loc, const S& fmt, T&&... args) -> std::basic_string { return vformat(loc, detail::to_string_view(fmt), fmt::make_format_args>(args...)); @@ -232,11 +235,12 @@ inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt { fmt::make_format_args>(args...)); } -template , FMT_ENABLE_IF(detail::is_output_iterator::value&& - detail::is_exotic_char::value)> -inline auto vformat_to(OutputIt out, detail::locale_ref loc, const S& fmt, + detail::is_locale::value&& + detail::is_exotic_char::value)> +inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt, typename detail::vformat_args::type args) -> OutputIt { auto&& buf = detail::get_buffer(out); @@ -244,11 +248,12 @@ inline auto vformat_to(OutputIt out, detail::locale_ref loc, const S& fmt, return detail::get_iterator(buf, out); } -template , bool enable = detail::is_output_iterator::value && + detail::is_locale::value && detail::is_exotic_char::value> -inline auto format_to(OutputIt out, detail::locale_ref loc, const S& fmt, +inline auto format_to(OutputIt out, const Locale& loc, const S& fmt, T&&... args) -> typename std::enable_if::type { return vformat_to(out, loc, detail::to_string_view(fmt),