2121#endif
2222
2323// The fmt library version in the form major * 10000 + minor * 100 + patch.
24- #define FMT_VERSION 110201
24+ #define FMT_VERSION 120101
2525
2626// Detect compiler versions.
2727#if defined(__clang__) && !defined(__ibmxl__)
114114#endif
115115
116116// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.
117- #if !defined(__cpp_lib_is_constant_evaluated)
117+ #ifdef FMT_USE_CONSTEVAL
118+ // Use the provided definition.
119+ #elif !defined(__cpp_lib_is_constant_evaluated)
118120# define FMT_USE_CONSTEVAL 0
119121#elif FMT_CPLUSPLUS < 201709L
120122# define FMT_USE_CONSTEVAL 0
231233FMT_PRAGMA_GCC (push_options)
232234#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
233235FMT_PRAGMA_GCC (optimize(" Og" ))
234- # define FMT_GCC_OPTIMIZED
235236#endif
236237FMT_PRAGMA_CLANG (diagnostic push)
238+ FMT_PRAGMA_GCC(diagnostic push)
237239
238240#ifdef FMT_ALWAYS_INLINE
239241// Use the provided definition.
@@ -243,7 +245,7 @@ FMT_PRAGMA_CLANG(diagnostic push)
243245# define FMT_ALWAYS_INLINE inline
244246#endif
245247// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
246- #if defined( NDEBUG) || defined(FMT_GCC_OPTIMIZED)
248+ #ifdef NDEBUG
247249# define FMT_INLINE FMT_ALWAYS_INLINE
248250#else
249251# define FMT_INLINE inline
@@ -252,7 +254,7 @@ FMT_PRAGMA_CLANG(diagnostic push)
252254#ifndef FMT_BEGIN_NAMESPACE
253255# define FMT_BEGIN_NAMESPACE \
254256 namespace fmt { \
255- inline namespace v11 {
257+ inline namespace v12 {
256258# define FMT_END_NAMESPACE \
257259 } \
258260 }
@@ -414,8 +416,12 @@ inline auto map(int128_opt) -> monostate { return {}; }
414416inline auto map (uint128_opt) -> monostate { return {}; }
415417#endif
416418
417- #ifndef FMT_USE_BITINT
418- # define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1500 )
419+ #ifdef FMT_USE_BITINT
420+ // Use the provided definition.
421+ #elif FMT_CLANG_VERSION >= 1500 && !defined(__CUDACC__)
422+ # define FMT_USE_BITINT 1
423+ #else
424+ # define FMT_USE_BITINT 0
419425#endif
420426
421427#if FMT_USE_BITINT
@@ -458,8 +464,10 @@ enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
458464static_assert (!FMT_UNICODE || use_utf8,
459465 " Unicode support requires compiling with /utf-8" );
460466
461- template <typename T> constexpr const char * narrow (const T*) { return nullptr ; }
462- constexpr FMT_ALWAYS_INLINE const char * narrow (const char * s) { return s; }
467+ template <typename T> constexpr auto narrow (T*) -> char* { return nullptr ; }
468+ constexpr FMT_ALWAYS_INLINE auto narrow (const char * s) -> const char* {
469+ return s;
470+ }
463471
464472template <typename Char>
465473FMT_CONSTEXPR auto compare (const Char* s1, const Char* s2, size_t n) -> int {
@@ -762,7 +770,7 @@ class basic_specs {
762770 (static_cast <unsigned >(p) << precision_shift);
763771 }
764772
765- constexpr bool dynamic () const {
773+ constexpr auto dynamic () const -> bool {
766774 return (data_ & (width_mask | precision_mask)) != 0 ;
767775 }
768776
@@ -916,9 +924,15 @@ class locale_ref {
916924 constexpr locale_ref () : locale_(nullptr ) {}
917925
918926 template <typename Locale, FMT_ENABLE_IF(sizeof (Locale::collate) != 0 )>
919- locale_ref (const Locale& loc);
927+ locale_ref (const Locale& loc) : locale_(&loc) {
928+ // Check if std::isalpha is found via ADL to reduce the chance of misuse.
929+ detail::ignore_unused (sizeof (isalpha (' x' , loc)));
930+ }
920931
921932 inline explicit operator bool () const noexcept { return locale_ != nullptr ; }
933+ #else
934+ public:
935+ inline explicit operator bool () const noexcept { return false ; }
922936#endif // FMT_USE_LOCALE
923937
924938 public:
@@ -1071,11 +1085,11 @@ template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
10711085 return (B1 ? 1 : 0 ) + count<B2, Tail...>();
10721086}
10731087
1074- template <typename ... Args > constexpr auto count_named_args () -> int {
1075- return count<is_named_arg<Args >::value...>();
1088+ template <typename ... T > constexpr auto count_named_args () -> int {
1089+ return count<is_named_arg<T >::value...>();
10761090}
1077- template <typename ... Args > constexpr auto count_static_named_args () -> int {
1078- return count<is_static_named_arg<Args >::value...>();
1091+ template <typename ... T > constexpr auto count_static_named_args () -> int {
1092+ return count<is_static_named_arg<T >::value...>();
10791093}
10801094
10811095template <typename Char> struct named_arg_info {
@@ -1839,15 +1853,19 @@ template <typename T> class buffer {
18391853#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940
18401854 FMT_CONSTEXPR20
18411855#endif
1842- void
1843- append (const U* begin, const U* end) {
1856+ void append (const U* begin, const U* end) {
18441857 while (begin != end) {
1858+ auto size = size_;
1859+ auto free_cap = capacity_ - size;
18451860 auto count = to_unsigned (end - begin);
1846- try_reserve (size_ + count);
1847- auto free_cap = capacity_ - size_;
1848- if (free_cap < count) count = free_cap;
1861+ if (free_cap < count) {
1862+ grow_ (*this , size + count);
1863+ size = size_;
1864+ free_cap = capacity_ - size;
1865+ count = count < free_cap ? count : free_cap;
1866+ }
18491867 // A loop is faster than memcpy on small sizes.
1850- T* out = ptr_ + size_ ;
1868+ T* out = ptr_ + size ;
18511869 for (size_t i = 0 ; i < count; ++i) out[i] = begin[i];
18521870 size_ += count;
18531871 begin += count;
@@ -2243,8 +2261,11 @@ template <typename Context> class value {
22432261 : pointer(const_cast <const void *>(x)) {}
22442262 FMT_INLINE value (nullptr_t ) : pointer(nullptr ) {}
22452263
2246- template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
2247- std::is_member_pointer<T>::value)>
2264+ template <typename T,
2265+ FMT_ENABLE_IF (
2266+ (std::is_pointer<T>::value ||
2267+ std::is_member_pointer<T>::value) &&
2268+ !std::is_void<typename std::remove_pointer<T>::type>::value)>
22482269 value (const T&) {
22492270 // Formatting of arbitrary pointers is disallowed. If you want to format a
22502271 // pointer cast it to `void*` or `const void*`. In particular, this forbids
@@ -2289,7 +2310,7 @@ template <typename Context> class value {
22892310 template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>
22902311 FMT_CONSTEXPR value (const T&, custom_tag) {
22912312 // Cannot format an argument; to make type T formattable provide a
2292- // formatter<T> specialization: https://fmt.dev/latest/api.html #udt.
2313+ // formatter<T> specialization: https://fmt.dev/latest/api#udt.
22932314 type_is_unformattable_for<T, char_type> _;
22942315 }
22952316
@@ -2328,10 +2349,10 @@ template <typename> constexpr auto encode_types() -> unsigned long long {
23282349 return 0 ;
23292350}
23302351
2331- template <typename Context, typename Arg , typename ... Args >
2352+ template <typename Context, typename First , typename ... T >
23322353constexpr auto encode_types () -> unsigned long long {
2333- return static_cast <unsigned >(stored_type_constant<Arg , Context>::value) |
2334- (encode_types<Context, Args ...>() << packed_arg_bits);
2354+ return static_cast <unsigned >(stored_type_constant<First , Context>::value) |
2355+ (encode_types<Context, T ...>() << packed_arg_bits);
23352356}
23362357
23372358template <typename Context, typename ... T, size_t NUM_ARGS = sizeof ...(T)>
@@ -2369,8 +2390,8 @@ struct named_arg_store {
23692390 }
23702391
23712392 named_arg_store (const named_arg_store& rhs) = delete ;
2372- named_arg_store& operator =(const named_arg_store& rhs) = delete ;
2373- named_arg_store& operator =(named_arg_store&& rhs) = delete ;
2393+ auto operator =(const named_arg_store& rhs) -> named_arg_store& = delete ;
2394+ auto operator =(named_arg_store&& rhs) -> named_arg_store& = delete ;
23742395 operator const arg_t <Context, NUM_ARGS>*() const { return args + 1 ; }
23752396};
23762397
@@ -2739,7 +2760,9 @@ template <typename... T> struct fstring {
27392760 static_assert (count<(is_view<remove_cvref_t <T>>::value &&
27402761 std::is_reference<T>::value)...>() == 0 ,
27412762 " passing views as lvalues is disallowed" );
2742- if (FMT_USE_CONSTEVAL) parse_format_string<char >(s, checker (s, arg_pack ()));
2763+ #if FMT_USE_CONSTEVAL
2764+ parse_format_string<char >(s, checker (s, arg_pack ()));
2765+ #endif
27432766#ifdef FMT_ENFORCE_COMPILE_STRING
27442767 static_assert (
27452768 FMT_USE_CONSTEVAL && sizeof (s) != 0 ,
@@ -2824,6 +2847,10 @@ using vargs =
28242847 * **Example**:
28252848 *
28262849 * fmt::print("The answer is {answer}.", fmt::arg("answer", 42));
2850+ *
2851+ * Named arguments passed with `fmt::arg` are not supported
2852+ * in compile-time checks, but `"answer"_a=42` are compile-time checked in
2853+ * sufficiently new compilers. See `operator""_a()`.
28272854 */
28282855template <typename Char, typename T>
28292856inline auto arg (const Char* name, const T& arg) -> detail::named_arg<Char, T> {
@@ -2981,6 +3008,7 @@ FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
29813008 return fmt::println (stdout, fmt, static_cast <T&&>(args)...);
29823009}
29833010
3011+ FMT_PRAGMA_GCC (diagnostic pop)
29843012FMT_PRAGMA_CLANG(diagnostic pop)
29853013FMT_PRAGMA_GCC(pop_options)
29863014FMT_END_EXPORT
0 commit comments