2121#endif
2222
2323// The fmt library version in the form major * 10000 + minor * 100 + patch.
24- #define FMT_VERSION 110100
24+ #define FMT_VERSION 110103
2525
2626// Detect compiler versions.
2727#if defined(__clang__) && !defined(__ibmxl__)
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
161161# define FMT_CATCH (x ) if (false )
162162#endif
163163
164+ #ifdef FMT_NO_UNIQUE_ADDRESS
165+ // Use the provided definition.
166+ #elif FMT_CPLUSPLUS < 202002L
167+ // Not supported.
168+ #elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
169+ # define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
170+ // VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
171+ #elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
172+ # define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
173+ #endif
174+ #ifndef FMT_NO_UNIQUE_ADDRESS
175+ # define FMT_NO_UNIQUE_ADDRESS
176+ #endif
177+
164178#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
165179# define FMT_FALLTHROUGH [[fallthrough]]
166180#elif defined(__clang__)
285299
286300// Enable minimal optimizations for more compact code in debug mode.
287301FMT_PRAGMA_GCC (push_options)
288- #if !defined(__OPTIMIZE__) && !defined(__CUDACC__)
302+ #if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
289303FMT_PRAGMA_GCC (optimize(" Og" ))
290304#endif
291305FMT_PRAGMA_CLANG (diagnostic push)
@@ -725,13 +739,15 @@ class basic_specs {
725739 max_fill_size = 4
726740 };
727741
728- size_t data_ = 1 << fill_size_shift;
742+ unsigned data_ = 1 << fill_size_shift;
743+ static_assert (sizeof (data_) * CHAR_BIT >= 18 , " " );
729744
730745 // Character (code unit) type is erased to prevent template bloat.
731746 char fill_data_[max_fill_size] = {' ' };
732747
733748 FMT_CONSTEXPR void set_fill_size (size_t size) {
734- data_ = (data_ & ~fill_size_mask) | (size << fill_size_shift);
749+ data_ = (data_ & ~fill_size_mask) |
750+ (static_cast <unsigned >(size) << fill_size_shift);
735751 }
736752
737753 public:
@@ -828,6 +844,12 @@ class basic_specs {
828844 for (size_t i = 0 ; i < size; ++i)
829845 fill_data_[i & 3 ] = static_cast <char >(s[i]);
830846 }
847+
848+ FMT_CONSTEXPR void copy_fill_from (const basic_specs& specs) {
849+ set_fill_size (specs.fill_size ());
850+ for (size_t i = 0 ; i < max_fill_size; ++i)
851+ fill_data_[i] = specs.fill_data_ [i];
852+ }
831853};
832854
833855// Format specifiers for built-in and string types.
@@ -1099,7 +1121,7 @@ using use_formatter =
10991121 bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||
11001122 std::is_union<T>::value || std::is_array<T>::value) &&
11011123 !has_to_string_view<T>::value && !is_named_arg<T>::value &&
1102- !use_format_as<T>::value && !use_format_as_member<T >::value>;
1124+ !use_format_as<T>::value && !use_format_as_member<U >::value>;
11031125
11041126template <typename Char, typename T, typename U = remove_const_t <T>>
11051127auto has_formatter_impl (T* p, buffered_context<Char>* ctx = nullptr )
@@ -2256,9 +2278,7 @@ struct locale_ref {
22562278
22572279 public:
22582280 constexpr locale_ref () : locale_(nullptr ) {}
2259-
2260- template <typename Locale, FMT_ENABLE_IF(sizeof (Locale::collate) != 0 )>
2261- locale_ref (const Locale& loc);
2281+ template <typename Locale> locale_ref (const Locale& loc);
22622282
22632283 inline explicit operator bool () const noexcept { return locale_ != nullptr ; }
22642284#endif // FMT_USE_LOCALE
@@ -2604,10 +2624,11 @@ template <typename Context> class basic_format_args {
26042624};
26052625
26062626// A formatting context.
2607- class context : private detail ::locale_ref {
2627+ class context {
26082628 private:
26092629 appender out_;
26102630 format_args args_;
2631+ FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
26112632
26122633 public:
26132634 // / The character type for the output.
@@ -2623,7 +2644,7 @@ class context : private detail::locale_ref {
26232644 // / in the object so make sure they have appropriate lifetimes.
26242645 FMT_CONSTEXPR context (iterator out, format_args args,
26252646 detail::locale_ref loc = {})
2626- : locale_ref(loc), out_(out), args_(args) {}
2647+ : out_(out), args_(args), loc_(loc ) {}
26272648 context (context&&) = default ;
26282649 context (const context&) = delete ;
26292650 void operator =(const context&) = delete ;
@@ -2635,14 +2656,15 @@ class context : private detail::locale_ref {
26352656 FMT_CONSTEXPR auto arg_id (string_view name) const -> int {
26362657 return args_.get_id (name);
26372658 }
2659+ auto args () const -> const format_args& { return args_; }
26382660
26392661 // Returns an iterator to the beginning of the output range.
26402662 FMT_CONSTEXPR auto out () const -> iterator { return out_; }
26412663
26422664 // Advances the begin iterator to `it`.
26432665 FMT_CONSTEXPR void advance_to (iterator) {}
26442666
2645- FMT_CONSTEXPR auto locale () const -> detail::locale_ref { return * this ; }
2667+ FMT_CONSTEXPR auto locale () const -> detail::locale_ref { return loc_ ; }
26462668};
26472669
26482670template <typename Char = char > struct runtime_format_string {
@@ -2659,7 +2681,8 @@ template <typename Char = char> struct runtime_format_string {
26592681 */
26602682inline auto runtime (string_view s) -> runtime_format_string<> { return {{s}}; }
26612683
2662- // / A compile-time format string.
2684+ // / A compile-time format string. Use `format_string` in the public API to
2685+ // / prevent type deduction.
26632686template <typename ... T> struct fstring {
26642687 private:
26652688 static constexpr int num_static_named_args =
0 commit comments