Skip to content

Commit 7ddfafe

Browse files
authored
Update fmtlib from 11.1.2 to 11.2.0 (#7149)
1 parent f17dc18 commit 7ddfafe

File tree

11 files changed

+479
-429
lines changed

11 files changed

+479
-429
lines changed

3rdparty/exported/fmt/base.h

Lines changed: 80 additions & 49 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 110102
24+
#define FMT_VERSION 110200
2525

2626
// Detect compiler versions.
2727
#if defined(__clang__) && !defined(__ibmxl__)
@@ -96,9 +96,9 @@
9696
// Detect C++14 relaxed constexpr.
9797
#ifdef FMT_USE_CONSTEXPR
9898
// Use the provided definition.
99-
#elif FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L
100-
// GCC only allows throw in constexpr since version 6:
101-
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371.
99+
#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L
100+
// GCC only allows constexpr member functions in non-literal types since 7.2:
101+
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297.
102102
# define FMT_USE_CONSTEXPR 1
103103
#elif FMT_ICC_VERSION
104104
# define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628
@@ -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__)
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

@@ -739,13 +739,15 @@ class basic_specs {
739739
max_fill_size = 4
740740
};
741741

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

744745
// Character (code unit) type is erased to prevent template bloat.
745746
char fill_data_[max_fill_size] = {' '};
746747

747748
FMT_CONSTEXPR void set_fill_size(size_t size) {
748-
data_ = (data_ & ~fill_size_mask) | (size << fill_size_shift);
749+
data_ = (data_ & ~fill_size_mask) |
750+
(static_cast<unsigned>(size) << fill_size_shift);
749751
}
750752

751753
public:
@@ -1030,6 +1032,11 @@ enum {
10301032

10311033
struct view {};
10321034

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+
10331040
template <typename Char, typename T> struct named_arg;
10341041
template <typename T> struct is_named_arg : std::false_type {};
10351042
template <typename T> struct is_static_named_arg : std::false_type {};
@@ -1062,13 +1069,24 @@ template <typename Char> struct named_arg_info {
10621069
int id;
10631070
};
10641071

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+
10651082
template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
10661083
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
10671084
++arg_index;
10681085
}
10691086
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
10701087
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
10711088
int& named_arg_index, const T& arg) {
1089+
check_for_duplicate<Char>(named_args, named_arg_index, arg.name);
10721090
named_args[named_arg_index++] = {arg.name, arg_index++};
10731091
}
10741092

@@ -1082,12 +1100,13 @@ template <typename T, typename Char,
10821100
FMT_ENABLE_IF(is_static_named_arg<T>::value)>
10831101
FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
10841102
int& arg_index, int& named_arg_index) {
1103+
check_for_duplicate<Char>(named_args, named_arg_index, T::name);
10851104
named_args[named_arg_index++] = {T::name, arg_index++};
10861105
}
10871106

10881107
// To minimize the number of types we need to deal with, long is translated
10891108
// either to int or to long long depending on its size.
1090-
enum { long_short = sizeof(long) == sizeof(int) };
1109+
enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };
10911110
using long_type = conditional_t<long_short, int, long long>;
10921111
using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
10931112

@@ -1119,7 +1138,7 @@ using use_formatter =
11191138
bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||
11201139
std::is_union<T>::value || std::is_array<T>::value) &&
11211140
!has_to_string_view<T>::value && !is_named_arg<T>::value &&
1122-
!use_format_as<T>::value && !use_format_as_member<T>::value>;
1141+
!use_format_as<T>::value && !use_format_as_member<U>::value>;
11231142

11241143
template <typename Char, typename T, typename U = remove_const_t<T>>
11251144
auto has_formatter_impl(T* p, buffered_context<Char>* ctx = nullptr)
@@ -1704,7 +1723,17 @@ class format_string_checker {
17041723
-> const Char* {
17051724
context_.advance_to(begin);
17061725
if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
1707-
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+
}
17081737
return begin;
17091738
}
17101739

@@ -2261,15 +2290,15 @@ template <> struct is_output_iterator<appender, char> : std::true_type {};
22612290
template <typename It, typename T>
22622291
struct is_output_iterator<
22632292
It, T,
2264-
void_t<decltype(*std::declval<decay_t<It>&>()++ = std::declval<T>())>>
2265-
: std::true_type {};
2293+
enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
2294+
T>::value>> : std::true_type {};
22662295

22672296
#ifndef FMT_USE_LOCALE
22682297
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
22692298
#endif
22702299

22712300
// A type-erased reference to an std::locale to avoid a heavy <locale> include.
2272-
struct locale_ref {
2301+
class locale_ref {
22732302
#if FMT_USE_LOCALE
22742303
private:
22752304
const void* locale_; // A type-erased pointer to std::locale.
@@ -2281,6 +2310,7 @@ struct locale_ref {
22812310
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
22822311
#endif // FMT_USE_LOCALE
22832312

2313+
public:
22842314
template <typename Locale> auto get() const -> Locale;
22852315
};
22862316

@@ -2654,6 +2684,7 @@ class context {
26542684
FMT_CONSTEXPR auto arg_id(string_view name) const -> int {
26552685
return args_.get_id(name);
26562686
}
2687+
auto args() const -> const format_args& { return args_; }
26572688

26582689
// Returns an iterator to the beginning of the output range.
26592690
FMT_CONSTEXPR auto out() const -> iterator { return out_; }
@@ -2699,7 +2730,7 @@ template <typename... T> struct fstring {
26992730
template <size_t N>
27002731
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {
27012732
using namespace detail;
2702-
static_assert(count<(std::is_base_of<view, remove_reference_t<T>>::value &&
2733+
static_assert(count<(is_view<remove_cvref_t<T>>::value &&
27032734
std::is_reference<T>::value)...>() == 0,
27042735
"passing views as lvalues is disallowed");
27052736
if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
@@ -2726,9 +2757,9 @@ template <typename... T> struct fstring {
27262757
std::is_same<typename S::char_type, char>::value)>
27272758
FMT_ALWAYS_INLINE fstring(const S&) : str(S()) {
27282759
FMT_CONSTEXPR auto sv = string_view(S());
2729-
FMT_CONSTEXPR int ignore =
2760+
FMT_CONSTEXPR int unused =
27302761
(parse_format_string(sv, checker(sv, arg_pack())), 0);
2731-
detail::ignore_unused(ignore);
2762+
detail::ignore_unused(unused);
27322763
}
27332764
fstring(runtime_format_string<> fmt) : str(fmt.str) {}
27342765

0 commit comments

Comments
 (0)