Skip to content

Commit 50d59ba

Browse files
committed
Upgrade fmt to 11.2.0
1 parent 26c5bd8 commit 50d59ba

File tree

10 files changed

+461
-418
lines changed

10 files changed

+461
-418
lines changed

thirdparty/fmt/include/fmt/base.h

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#endif
2222

2323
// The fmt library version in the form major * 10000 + minor * 100 + patch.
24-
#define FMT_VERSION 110103
24+
#define FMT_VERSION 110200
2525

2626
// Detect compiler versions.
2727
#if defined(__clang__) && !defined(__ibmxl__)
@@ -209,20 +209,6 @@
209209
# define FMT_DEPRECATED /* deprecated */
210210
#endif
211211

212-
#ifdef FMT_ALWAYS_INLINE
213-
// Use the provided definition.
214-
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
215-
# define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
216-
#else
217-
# define FMT_ALWAYS_INLINE inline
218-
#endif
219-
// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
220-
#ifdef NDEBUG
221-
# define FMT_INLINE FMT_ALWAYS_INLINE
222-
#else
223-
# define FMT_INLINE inline
224-
#endif
225-
226212
#if FMT_GCC_VERSION || FMT_CLANG_VERSION
227213
# define FMT_VISIBILITY(value) __attribute__((visibility(value)))
228214
#else
@@ -249,6 +235,28 @@
249235
# define FMT_MSC_WARNING(...)
250236
#endif
251237

238+
// Enable minimal optimizations for more compact code in debug mode.
239+
FMT_PRAGMA_GCC(push_options)
240+
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
241+
FMT_PRAGMA_GCC(optimize("Og"))
242+
# define FMT_GCC_OPTIMIZED
243+
#endif
244+
FMT_PRAGMA_CLANG(diagnostic push)
245+
246+
#ifdef FMT_ALWAYS_INLINE
247+
// Use the provided definition.
248+
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
249+
# define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
250+
#else
251+
# define FMT_ALWAYS_INLINE inline
252+
#endif
253+
// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
254+
#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED)
255+
# define FMT_INLINE FMT_ALWAYS_INLINE
256+
#else
257+
# define FMT_INLINE inline
258+
#endif
259+
252260
#ifndef FMT_BEGIN_NAMESPACE
253261
# define FMT_BEGIN_NAMESPACE \
254262
namespace fmt { \
@@ -294,15 +302,8 @@
294302
#endif
295303

296304
#define FMT_APPLY_VARIADIC(expr) \
297-
using ignore = int[]; \
298-
(void)ignore { 0, (expr, 0)... }
299-
300-
// Enable minimal optimizations for more compact code in debug mode.
301-
FMT_PRAGMA_GCC(push_options)
302-
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
303-
FMT_PRAGMA_GCC(optimize("Og"))
304-
#endif
305-
FMT_PRAGMA_CLANG(diagnostic push)
305+
using unused = int[]; \
306+
(void)unused { 0, (expr, 0)... }
306307

307308
FMT_BEGIN_NAMESPACE
308309

@@ -325,8 +326,8 @@ using underlying_t = typename std::underlying_type<T>::type;
325326
template <typename T> using decay_t = typename std::decay<T>::type;
326327
using nullptr_t = decltype(nullptr);
327328

328-
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
329-
// A workaround for gcc 4.9 to make void_t work in a SFINAE context.
329+
#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION
330+
// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context.
330331
template <typename...> struct void_t_impl {
331332
using type = void;
332333
};
@@ -526,20 +527,20 @@ template <typename Char> class basic_string_view {
526527

527528
constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
528529

529-
/// Constructs a string reference object from a C string and a size.
530+
/// Constructs a string view object from a C string and a size.
530531
constexpr basic_string_view(const Char* s, size_t count) noexcept
531532
: data_(s), size_(count) {}
532533

533534
constexpr basic_string_view(nullptr_t) = delete;
534535

535-
/// Constructs a string reference object from a C string.
536+
/// Constructs a string view object from a C string.
536537
#if FMT_GCC_VERSION
537538
FMT_ALWAYS_INLINE
538539
#endif
539540
FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
540-
#if FMT_HAS_BUILTIN(__buitin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
541-
if (std::is_same<Char, char>::value) {
542-
size_ = __builtin_strlen(detail::narrow(s));
541+
#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
542+
if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
543+
size_ = __builtin_strlen(detail::narrow(s)); // strlen is not costexpr.
543544
return;
544545
}
545546
#endif
@@ -548,7 +549,7 @@ template <typename Char> class basic_string_view {
548549
size_ = len;
549550
}
550551

551-
/// Constructs a string reference from a `std::basic_string` or a
552+
/// Constructs a string view from a `std::basic_string` or a
552553
/// `std::basic_string_view` object.
553554
template <typename S,
554555
FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
@@ -585,7 +586,6 @@ template <typename Char> class basic_string_view {
585586
return starts_with(basic_string_view<Char>(s));
586587
}
587588

588-
// Lexicographically compare this string reference to other.
589589
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
590590
int result =
591591
detail::compare(data_, other.data_, min_of(size_, other.size_));
@@ -616,7 +616,7 @@ template <typename Char> class basic_string_view {
616616

617617
using string_view = basic_string_view<char>;
618618

619-
/// Specifies if `T` is an extended character type. Can be specialized by users.
619+
// DEPRECATED! Will be merged with is_char and moved to detail.
620620
template <typename T> struct is_xchar : std::false_type {};
621621
template <> struct is_xchar<wchar_t> : std::true_type {};
622622
template <> struct is_xchar<char16_t> : std::true_type {};
@@ -625,7 +625,7 @@ template <> struct is_xchar<char32_t> : std::true_type {};
625625
template <> struct is_xchar<char8_t> : std::true_type {};
626626
#endif
627627

628-
// DEPRECATED! Will be replaced with an alias to prevent specializations.
628+
// Specifies if `T` is a character (code unit) type.
629629
template <typename T> struct is_char : is_xchar<T> {};
630630
template <> struct is_char<char> : std::true_type {};
631631

@@ -740,7 +740,7 @@ class basic_specs {
740740
};
741741

742742
unsigned data_ = 1 << fill_size_shift;
743-
static_assert(sizeof(data_) * CHAR_BIT >= 18, "");
743+
static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, "");
744744

745745
// Character (code unit) type is erased to prevent template bloat.
746746
char fill_data_[max_fill_size] = {' '};
@@ -1032,6 +1032,11 @@ enum {
10321032

10331033
struct view {};
10341034

1035+
template <typename T, typename Enable = std::true_type>
1036+
struct is_view : std::false_type {};
1037+
template <typename T>
1038+
struct is_view<T, bool_constant<sizeof(T) != 0>> : std::is_base_of<view, T> {};
1039+
10351040
template <typename Char, typename T> struct named_arg;
10361041
template <typename T> struct is_named_arg : std::false_type {};
10371042
template <typename T> struct is_static_named_arg : std::false_type {};
@@ -1064,13 +1069,24 @@ template <typename Char> struct named_arg_info {
10641069
int id;
10651070
};
10661071

1072+
// named_args is non-const to suppress a bogus -Wmaybe-uninitalized in gcc 13.
1073+
template <typename Char>
1074+
FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
1075+
int named_arg_index,
1076+
basic_string_view<Char> arg_name) {
1077+
for (int i = 0; i < named_arg_index; ++i) {
1078+
if (named_args[i].name == arg_name) report_error("duplicate named arg");
1079+
}
1080+
}
1081+
10671082
template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
10681083
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
10691084
++arg_index;
10701085
}
10711086
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
10721087
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
10731088
int& named_arg_index, const T& arg) {
1089+
check_for_duplicate<Char>(named_args, named_arg_index, arg.name);
10741090
named_args[named_arg_index++] = {arg.name, arg_index++};
10751091
}
10761092

@@ -1084,12 +1100,13 @@ template <typename T, typename Char,
10841100
FMT_ENABLE_IF(is_static_named_arg<T>::value)>
10851101
FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
10861102
int& arg_index, int& named_arg_index) {
1103+
check_for_duplicate<Char>(named_args, named_arg_index, T::name);
10871104
named_args[named_arg_index++] = {T::name, arg_index++};
10881105
}
10891106

10901107
// To minimize the number of types we need to deal with, long is translated
10911108
// either to int or to long long depending on its size.
1092-
enum { long_short = sizeof(long) == sizeof(int) };
1109+
enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };
10931110
using long_type = conditional_t<long_short, int, long long>;
10941111
using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
10951112

@@ -1706,7 +1723,17 @@ class format_string_checker {
17061723
-> const Char* {
17071724
context_.advance_to(begin);
17081725
if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
1709-
while (begin != end && *begin != '}') ++begin;
1726+
1727+
// If id is out of range, it means we do not know the type and cannot parse
1728+
// the format at compile time. Instead, skip over content until we finish
1729+
// the format spec, accounting for any nested replacements.
1730+
for (int bracket_count = 0;
1731+
begin != end && (bracket_count > 0 || *begin != '}'); ++begin) {
1732+
if (*begin == '{')
1733+
++bracket_count;
1734+
else if (*begin == '}')
1735+
--bracket_count;
1736+
}
17101737
return begin;
17111738
}
17121739

@@ -2263,15 +2290,15 @@ template <> struct is_output_iterator<appender, char> : std::true_type {};
22632290
template <typename It, typename T>
22642291
struct is_output_iterator<
22652292
It, T,
2266-
void_t<decltype(*std::declval<decay_t<It>&>()++ = std::declval<T>())>>
2267-
: std::true_type {};
2293+
enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
2294+
T>::value>> : std::true_type {};
22682295

22692296
#ifndef FMT_USE_LOCALE
22702297
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
22712298
#endif
22722299

22732300
// A type-erased reference to an std::locale to avoid a heavy <locale> include.
2274-
struct locale_ref {
2301+
class locale_ref {
22752302
#if FMT_USE_LOCALE
22762303
private:
22772304
const void* locale_; // A type-erased pointer to std::locale.
@@ -2283,6 +2310,7 @@ struct locale_ref {
22832310
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
22842311
#endif // FMT_USE_LOCALE
22852312

2313+
public:
22862314
template <typename Locale> auto get() const -> Locale;
22872315
};
22882316

@@ -2702,7 +2730,7 @@ template <typename... T> struct fstring {
27022730
template <size_t N>
27032731
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {
27042732
using namespace detail;
2705-
static_assert(count<(std::is_base_of<view, remove_reference_t<T>>::value &&
2733+
static_assert(count<(is_view<remove_cvref_t<T>>::value &&
27062734
std::is_reference<T>::value)...>() == 0,
27072735
"passing views as lvalues is disallowed");
27082736
if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
@@ -2729,9 +2757,9 @@ template <typename... T> struct fstring {
27292757
std::is_same<typename S::char_type, char>::value)>
27302758
FMT_ALWAYS_INLINE fstring(const S&) : str(S()) {
27312759
FMT_CONSTEXPR auto sv = string_view(S());
2732-
FMT_CONSTEXPR int ignore =
2760+
FMT_CONSTEXPR int unused =
27332761
(parse_format_string(sv, checker(sv, arg_pack())), 0);
2734-
detail::ignore_unused(ignore);
2762+
detail::ignore_unused(unused);
27352763
}
27362764
fstring(runtime_format_string<> fmt) : str(fmt.str) {}
27372765

0 commit comments

Comments
 (0)