C++ Format v8.0.0 Release Notes

Release Date: 2021-06-21 // almost 3 years ago
    • 0️⃣ Enabled compile-time format string checks by default. For example (godbolt <https://godbolt.org/z/sMxcohGjz>__):

    .. code:: c++

     #include <fmt/core.h>
    
     int main() {
       fmt::print("{:d}", "I am not a number");
     }
    

    gives a compile-time error on compilers with C++20 consteval support (gcc 10+, clang 11+) because d is not a valid format specifier for a string.

    To pass a runtime string wrap it in fmt::runtime:

    .. code:: c++

     fmt::print(fmt::runtime("{:d}"), "I am not a number");
    
    • ➕ Added compile-time formatting (#2019 <https://github.com/fmtlib/fmt/pull/2019>, #2044 <https://github.com/fmtlib/fmt/pull/2044>, #2056 <https://github.com/fmtlib/fmt/pull/2056>, #2072 <https://github.com/fmtlib/fmt/pull/2072>, #2075 <https://github.com/fmtlib/fmt/pull/2075>, #2078 <https://github.com/fmtlib/fmt/issues/2078>, #2129 <https://github.com/fmtlib/fmt/pull/2129>, #2326 <https://github.com/fmtlib/fmt/pull/2326>). For example (godbolt <https://godbolt.org/z/Mxx9d89jM>__):

    .. code:: c++

     #include <fmt/compile.h>
    
     consteval auto compile_time_itoa(int value) -> std::array<char, 10> {
       auto result = std::array<char, 10>();
       fmt::format_to(result.data(), FMT_COMPILE("{}"), value);
       return result;
     }
    
     constexpr auto answer = compile_time_itoa(42);
    

    Most of the formatting functionality is available at compile time with a notable exception of floating-point numbers and pointers. Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • ⚡️ Optimized handling of format specifiers during format string compilation. For example, hexadecimal formatting ("{:x}") is now 3-7x faster than before when using format_to with format string compilation and a stack-allocated buffer (#1944 <https://github.com/fmtlib/fmt/issues/1944>_).

    Before (7.1.3)::

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    FMTCompileOld/0                         15.5 ns         15.5 ns     43302898
    FMTCompileOld/42                        16.6 ns         16.6 ns     43278267
    FMTCompileOld/273123                    18.7 ns         18.6 ns     37035861
    FMTCompileOld/9223372036854775807       19.4 ns         19.4 ns     35243000
    ----------------------------------------------------------------------------
    

    After (8.x)::

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    FMTCompileNew/0                         1.99 ns         1.99 ns    360523686
    FMTCompileNew/42                        2.33 ns         2.33 ns    279865664
    FMTCompileNew/273123                    3.72 ns         3.71 ns    190230315
    FMTCompileNew/9223372036854775807       5.28 ns         5.26 ns    130711631
    ----------------------------------------------------------------------------
    

    It is even faster than std::to_chars from libc++ compiled with clang on macOS::

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    ToChars/0                               4.42 ns         4.41 ns    160196630
    ToChars/42                              5.00 ns         4.98 ns    140735201
    ToChars/273123                          7.26 ns         7.24 ns     95784130
    ToChars/9223372036854775807             8.77 ns         8.75 ns     75872534
    ----------------------------------------------------------------------------
    

    In other cases, especially involving std::string construction, the speed up is usually lower because handling format specifiers takes a smaller fraction of the total time.

    • ➕ Added the _cf user-defined literal to represent a compiled format string. It can be used instead of the FMT_COMPILE macro (#2043 <https://github.com/fmtlib/fmt/pull/2043>, #2242 <https://github.com/fmtlib/fmt/pull/2242>):

    .. code:: c++

     #include <fmt/compile.h>
    
     using namespace fmt::literals;
     auto s = fmt::format(FMT_COMPILE("{}"), 42); // 🙁 not modern
     auto s = fmt::format("{}"_cf, 42);           // 🙂 modern as hell
    

    It requires compiler support for class types in non-type template parameters (a C++20 feature) which is available in GCC 9.3+. Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • Format string compilation now requires format functions of formatter specializations for user-defined types to be const:

    .. code:: c++

     template <> struct fmt::formatter<my_type>: formatter<string_view> {
       template <typename FormatContext>
       auto format(my_type obj, FormatContext& ctx) const {  // Note const here.
         // ...
       }
     };
    
    • ➕ Added UDL-based named argument support to format string compilation (#2243 <https://github.com/fmtlib/fmt/pull/2243>, #2281 <https://github.com/fmtlib/fmt/pull/2281>). For example:

    .. code:: c++

     #include <fmt/compile.h>
    
     using namespace fmt::literals;
     auto s = fmt::format(FMT_COMPILE("{answer}"), "answer"_a = 42);
    

    Here the argument named "answer" is resolved at compile time with no runtime overhead. Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • ➕ Added format string compilation support to fmt::print (#2280 <https://github.com/fmtlib/fmt/issues/2280>, #2304 <https://github.com/fmtlib/fmt/pull/2304>). Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • ➕ Added initial support for compiling {fmt} as a C++20 module (#2235 <https://github.com/fmtlib/fmt/pull/2235>, #2240 <https://github.com/fmtlib/fmt/pull/2240>, #2260 <https://github.com/fmtlib/fmt/pull/2260>, #2282 <https://github.com/fmtlib/fmt/pull/2282>, #2283 <https://github.com/fmtlib/fmt/pull/2283>, #2288 <https://github.com/fmtlib/fmt/pull/2288>, #2298 <https://github.com/fmtlib/fmt/pull/2298>, #2306 <https://github.com/fmtlib/fmt/pull/2306>, #2307 <https://github.com/fmtlib/fmt/pull/2307>, #2309 <https://github.com/fmtlib/fmt/pull/2309>, #2318 <https://github.com/fmtlib/fmt/pull/2318>, #2324 <https://github.com/fmtlib/fmt/pull/2324>, #2332 <https://github.com/fmtlib/fmt/pull/2332>, #2340 <https://github.com/fmtlib/fmt/pull/2340>). Thanks @DanielaE (Daniela Engert) <https://github.com/DanielaE>_.

    • 0️⃣ Made symbols private by default reducing shared library size (#2301 <https://github.com/fmtlib/fmt/pull/2301>). For example there was a ~15% reported reduction on one platform. Thanks @sergiud (Sergiu Deitsch) <https://github.com/sergiud>.

    • ⚡️ Optimized includes making the result of preprocessing fmt/format.h ~20% smaller with libstdc++/C++20 and slightly improving build times (#1998 <https://github.com/fmtlib/fmt/issues/1998>_).

    • ➕ Added support of ranges with non-const begin / end (#1953 <https://github.com/fmtlib/fmt/pull/1953>). Thanks @kitegi (sarah) <https://github.com/kitegi>.

    • ➕ Added support of std::byte and other formattable types to fmt::join (#1981 <https://github.com/fmtlib/fmt/issues/1981>, #2040 <https://github.com/fmtlib/fmt/issues/2040>, #2050 <https://github.com/fmtlib/fmt/pull/2050>, #2262 <https://github.com/fmtlib/fmt/issues/2262>). For example:

    .. code:: c++

     #include <fmt/format.h>
     #include <cstddef>
     #include <vector>
    
     int main() {
       auto bytes = std::vector{std::byte(4), std::byte(2)};
       fmt::print("{}", fmt::join(bytes, ""));
     }
    

    prints "42".

    Thanks @kamibo (Camille Bordignon) <https://github.com/kamibo>_.

    • 0️⃣ Implemented the default format for std::chrono::system_clock (#2319 <https://github.com/fmtlib/fmt/issues/2319>, #2345 <https://github.com/fmtlib/fmt/pull/2345>). For example:

    .. code:: c++

     #include <fmt/chrono.h>
    
     int main() {
       fmt::print("{}", std::chrono::system_clock::now());
     }
    

    prints "2021-06-18 15:22:00" (the output depends on the current date and time). Thanks @sunmy2019 <https://github.com/sunmy2019>_.

    • 0️⃣ Made more chrono specifiers locale independent by default. Use the 'L' specifier to get localized formatting. For example:

    .. code:: c++

     #include <fmt/chrono.h>
    
     int main() {
       std::locale::global(std::locale("ru_RU.UTF-8"));
       auto monday = std::chrono::weekday(1);
       fmt::print("{}\n", monday);   // prints "Mon"
       fmt::print("{:L}\n", monday); // prints "пн"
     }
    
    • 👌 Improved locale handling in chrono formatting (#2337 <https://github.com/fmtlib/fmt/issues/2337>, #2349 <https://github.com/fmtlib/fmt/pull/2349>, #2350 <https://github.com/fmtlib/fmt/pull/2350>). Thanks @phprus (Vladislav Shchapov) <https://github.com/phprus>.

    • 🗄 Deprecated fmt/locale.h moving the formatting functions that take a locale to fmt/format.h (char) and fmt/xchar (other overloads). This doesn't introduce a dependency on <locale> so there is virtually no compile time effect.

    • 🗄 Deprecated an undocumented format_to overload that takes basic_memory_buffer.

    • Made parameter order in vformat_to consistent with format_to (#2327 <https://github.com/fmtlib/fmt/issues/2327>_).

    • ➕ Added support for time points with arbitrary durations (#2208 <https://github.com/fmtlib/fmt/issues/2208>_). For example:

    .. code:: c++

     #include <fmt/chrono.h>
    
     int main() {
       using tp = std::chrono::time_point<
         std::chrono::system_clock, std::chrono::seconds>;
       fmt::print("{:%S}", tp(std::chrono::seconds(42)));
     }
    

    prints "42".

    • 0️⃣ Formatting floating-point numbers no longer produces trailing zeros by default for consistency with std::format. For example:

    .. code:: c++

     #include <fmt/core.h>
    
     int main() {
       fmt::print("{0:.3}", 1.1);
     }
    

    prints "1.1". Use the '#' specifier to keep trailing zeros.

    • ⬇️ Dropped a limit on the number of elements in a range and replaced {} with [] as range delimiters for consistency with Python's str.format.

    • The 'L' specifier for locale-specific numeric formatting can now be combined with presentation specifiers as in std::format. For example:

    .. code:: c++

     #include <fmt/core.h>
     #include <locale>
    
     int main() {
       std::locale::global(std::locale("fr_FR.UTF-8"));
       fmt::print("{0:.2Lf}", 0.42);
     }
    

    prints "0,42". The deprecated 'n' specifier has been removed.

    • Made the 0 specifier ignored for infinity and NaN (#2305 <https://github.com/fmtlib/fmt/issues/2305>, #2310 <https://github.com/fmtlib/fmt/pull/2310>). Thanks @Liedtke (Matthias Liedtke) <https://github.com/Liedtke>_.

    • 0️⃣ Made the hexfloat formatting use the right alignment by default (#2308 <https://github.com/fmtlib/fmt/issues/2308>, #2317 <https://github.com/fmtlib/fmt/pull/2317>). Thanks @Liedtke (Matthias Liedtke) <https://github.com/Liedtke>_.

    • ✂ Removed the deprecated numeric alignment ('='). Use the '0' specifier instead.

    • ✂ Removed the deprecated fmt/posix.h header that has been replaced with fmt/os.h.

    • Removed the deprecated format_to_n_context, format_to_n_args and make_format_to_n_args. They have been replaced with format_context, format_args` andmake_format_args`` respectively.

    • 🚚 Moved wchar_t-specific functions and types to fmt/xchar.h. You can define FMT_DEPRECATED_INCLUDE_XCHAR to automatically include fmt/xchar.h from fmt/format.h but this will be disabled in the next major release.

    • 🛠 Fixed handling of the '+' specifier in localized formatting (#2133 <https://github.com/fmtlib/fmt/issues/2133>_).

    • ➕ Added support for the 's' format specifier that gives textual representation of bool (#2094 <https://github.com/fmtlib/fmt/issues/2094>, #2109 <https://github.com/fmtlib/fmt/pull/2109>). For example:

    .. code:: c++

     #include <fmt/core.h>
    
     int main() {
       fmt::print("{:s}", true);
     }
    

    prints "true". Thanks @powercoderlol (Ivan Polyakov) <https://github.com/powercoderlol>_.

    • Made fmt::ptr work with function pointers (#2131 <https://github.com/fmtlib/fmt/pull/2131>_). For example:

    .. code:: c++

     #include <fmt/format.h>
    
     int main() {
       fmt::print("My main: {}\n", fmt::ptr(main));
     }
    

    Thanks @mikecrowe (Mike Crowe) <https://github.com/mikecrowe>_.

    • 👍 The undocumented support for specializing formatter for pointer types has been removed.

    • 🛠 Fixed fmt::formatted_size with format string compilation (#2141 <https://github.com/fmtlib/fmt/pull/2141>, #2161 <https://github.com/fmtlib/fmt/pull/2161>). Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • 🛠 Fixed handling of empty format strings during format string compilation (#2042 <https://github.com/fmtlib/fmt/issues/2042>_):

    .. code:: c++

     auto s = fmt::format(FMT_COMPILE(""));
    

    Thanks @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_.

    • 🛠 Fixed handling of enums in fmt::to_string (#2036 <https://github.com/fmtlib/fmt/issues/2036>_).

    • 👌 Improved width computation (#2033 <https://github.com/fmtlib/fmt/issues/2033>, #2091 <https://github.com/fmtlib/fmt/issues/2091>). For example:

    .. code:: c++

     #include <fmt/core.h>
    
     int main() {
       fmt::print("{:-<10}{}\n", "你好", "世界");
       fmt::print("{:-<10}{}\n", "hello", "world");
     }
    

    prints

    .. image:: https://user-images.githubusercontent.com/576385/ 119840373-cea3ca80-beb9-11eb-91e0-54266c48e181.png

    on a modern terminal.

    • The experimental fast output stream (fmt::ostream) is now truncated by default for consistency with fopen (#2018 <https://github.com/fmtlib/fmt/issues/2018>_). For example:

    .. code:: c++

     #include <fmt/os.h>
    
     int main() {
       fmt::ostream out1 = fmt::output_file("guide");
       out1.print("Zaphod");
       out1.close();
       fmt::ostream out2 = fmt::output_file("guide");
       out2.print("Ford");
     }
    

    writes "Ford" to the file "guide". To preserve the old file content if any pass fmt::file::WRONLY | fmt::file::CREATE flags to fmt::output_file.

    • 🛠 Fixed moving of fmt::ostream that holds buffered data (#2197 <https://github.com/fmtlib/fmt/issues/2197>, #2198 <https://github.com/fmtlib/fmt/pull/2198>). Thanks @vtta <https://github.com/vtta>_.

    • 👻 Replaced the fmt::system_error exception with a function of the same name that constructs std::system_error (#2266 <https://github.com/fmtlib/fmt/issues/2266>_).

    • 🏁 Replaced the fmt::windows_error exception with a function of the same name that constructs std::system_error with the category returned by fmt::system_category() (#2274 <https://github.com/fmtlib/fmt/issues/2274>, #2275 <https://github.com/fmtlib/fmt/pull/2275>). The latter is similar to std::sytem_category but correctly handles UTF-8. Thanks @phprus (Vladislav Shchapov) <https://github.com/phprus>_.

    • Replaced fmt::error_code with std::error_code and made it formattable (#2269 <https://github.com/fmtlib/fmt/issues/2269>, #2270 <https://github.com/fmtlib/fmt/pull/2270>, #2273 <https://github.com/fmtlib/fmt/pull/2273>). Thanks @phprus (Vladislav Shchapov) <https://github.com/phprus>.

    • ➕ Added speech synthesis support (#2206 <https://github.com/fmtlib/fmt/pull/2206>_).

    • Made format_to work with a memory buffer that has a custom allocator (#2300 <https://github.com/fmtlib/fmt/pull/2300>). Thanks @voxmea <https://github.com/voxmea>.

    • 👍 Added Allocator::max_size support to basic_memory_buffer. (#1960 <https://github.com/fmtlib/fmt/pull/1960>). Thanks @phprus (Vladislav Shchapov) <https://github.com/phprus>.

    • ➕ Added wide string support to fmt::join (#2236 <https://github.com/fmtlib/fmt/pull/2236>). Thanks @crbrz <https://github.com/crbrz>.

    • Made iterators passed to formatter specializations via a format context satisfy C++20 std::output_iterator requirements (#2156 <https://github.com/fmtlib/fmt/issues/2156>, #2158 <https://github.com/fmtlib/fmt/pull/2158>, #2195 <https://github.com/fmtlib/fmt/issues/2195>, #2204 <https://github.com/fmtlib/fmt/pull/2204>). Thanks @randomnetcat (Jason Cobb) <https://github.com/randomnetcat>_.

    • ⚡️ Optimized the printf implementation (#1982 <https://github.com/fmtlib/fmt/pull/1982>, #1984 <https://github.com/fmtlib/fmt/pull/1984>, #2016 <https://github.com/fmtlib/fmt/pull/2016>, #2164 <https://github.com/fmtlib/fmt/pull/2164>). Thanks @rimathia <https://github.com/rimathia>_ and @moiwi <https://github.com/moiwi>_.

    • 👌 Improved detection of constexpr char_traits (#2246 <https://github.com/fmtlib/fmt/pull/2246>, #2257 <https://github.com/fmtlib/fmt/pull/2257>). Thanks @phprus (Vladislav Shchapov) <https://github.com/phprus>_.

    • 🛠 Fixed writing to stdout when it is redirected to NUL on Windows (#2080 <https://github.com/fmtlib/fmt/issues/2080>_).

    • 🛠 Fixed exception propagation from iterators (#2097 <https://github.com/fmtlib/fmt/issues/2097>_).

    • 👌 Improved strftime error handling (#2238 <https://github.com/fmtlib/fmt/issues/2238>, #2244 <https://github.com/fmtlib/fmt/pull/2244>). Thanks @yumeyao <https://github.com/yumeyao>_.

    • 🗄 Stopped using deprecated GCC UDL template extension.

    • ➕ Added fmt/args.h to the install target (#2096 <https://github.com/fmtlib/fmt/issues/2096>_).

    • Error messages are now passed to assert when exceptions are disabled (#2145 <https://github.com/fmtlib/fmt/pull/2145>). Thanks @NobodyXu (Jiahao XU) <https://github.com/NobodyXu>.

    • Added the FMT_MASTER_PROJECT CMake option to control build and install targets when {fmt} is included via add_subdirectory (#2098 <https://github.com/fmtlib/fmt/issues/2098>, #2100 <https://github.com/fmtlib/fmt/pull/2100>). Thanks @randomizedthinking <https://github.com/randomizedthinking>_.

    • 👌 Improved build configuration (#2026 <https://github.com/fmtlib/fmt/pull/2026>, #2122 <https://github.com/fmtlib/fmt/pull/2122>). Thanks @luncliff (Park DongHa) <https://github.com/luncliff>_ and @ibaned (Dan Ibanez) <https://github.com/ibaned>_.

    • 🛠 Fixed various warnings and compilation issues (#1947 <https://github.com/fmtlib/fmt/issues/1947>, #1959 <https://github.com/fmtlib/fmt/pull/1959>, #1963 <https://github.com/fmtlib/fmt/pull/1963>, #1965 <https://github.com/fmtlib/fmt/pull/1965>, #1966 <https://github.com/fmtlib/fmt/issues/1966>, #1974 <https://github.com/fmtlib/fmt/pull/1974>, #1975 <https://github.com/fmtlib/fmt/pull/1975>, #1990 <https://github.com/fmtlib/fmt/pull/1990>, #2000 <https://github.com/fmtlib/fmt/issues/2000>, #2001 <https://github.com/fmtlib/fmt/pull/2001>, #2002 <https://github.com/fmtlib/fmt/issues/2002>, #2004 <https://github.com/fmtlib/fmt/issues/2004>, #2006 <https://github.com/fmtlib/fmt/pull/2006>, #2009 <https://github.com/fmtlib/fmt/pull/2009>, #2010 <https://github.com/fmtlib/fmt/pull/2010>, #2038 <https://github.com/fmtlib/fmt/issues/2038>, #2039 <https://github.com/fmtlib/fmt/issues/2039>, #2047 <https://github.com/fmtlib/fmt/issues/2047>, #2053 <https://github.com/fmtlib/fmt/pull/2053>, #2059 <https://github.com/fmtlib/fmt/issues/2059>, #2065 <https://github.com/fmtlib/fmt/pull/2065>, #2067 <https://github.com/fmtlib/fmt/pull/2067>, #2068 <https://github.com/fmtlib/fmt/pull/2068>, #2073 <https://github.com/fmtlib/fmt/pull/2073>, #2103 <https://github.com/fmtlib/fmt/issues/2103>, #2105 <https://github.com/fmtlib/fmt/issues/2105>, #2106 <https://github.com/fmtlib/fmt/pull/2106>, #2107 <https://github.com/fmtlib/fmt/pull/2107>, #2116 <https://github.com/fmtlib/fmt/issues/2116>, #2117 <https://github.com/fmtlib/fmt/pull/2117>, #2118 <https://github.com/fmtlib/fmt/issues/2118>, #2119 <https://github.com/fmtlib/fmt/pull/2119>, #2127 <https://github.com/fmtlib/fmt/issues/2127>, #2128 <https://github.com/fmtlib/fmt/pull/2128>, #2140 <https://github.com/fmtlib/fmt/issues/2140>, #2142 <https://github.com/fmtlib/fmt/issues/2142>, #2143 <https://github.com/fmtlib/fmt/pull/2143>, #2144 <https://github.com/fmtlib/fmt/pull/2144>, #2147 <https://github.com/fmtlib/fmt/issues/2147>, #2148 <https://github.com/fmtlib/fmt/issues/2148>, #2149 <https://github.com/fmtlib/fmt/issues/2149>, #2152 <https://github.com/fmtlib/fmt/pull/2152>, #2160 <https://github.com/fmtlib/fmt/pull/2160>, #2170 <https://github.com/fmtlib/fmt/issues/2170>, #2175 <https://github.com/fmtlib/fmt/issues/2175>, #2176 <https://github.com/fmtlib/fmt/issues/2176>, #2177 <https://github.com/fmtlib/fmt/pull/2177>, #2178 <https://github.com/fmtlib/fmt/issues/2178>, #2179 <https://github.com/fmtlib/fmt/pull/2179>, #2180 <https://github.com/fmtlib/fmt/issues/2180>, #2181 <https://github.com/fmtlib/fmt/issues/2181>, #2183 <https://github.com/fmtlib/fmt/pull/2183>, #2184 <https://github.com/fmtlib/fmt/issues/2184>, #2185 <https://github.com/fmtlib/fmt/issues/2185>, #2186 <https://github.com/fmtlib/fmt/pull/2186>, #2187 <https://github.com/fmtlib/fmt/pull/2187>, #2190 <https://github.com/fmtlib/fmt/pull/2190>, #2192 <https://github.com/fmtlib/fmt/pull/2192>, #2194 <https://github.com/fmtlib/fmt/pull/2194>, #2205 <https://github.com/fmtlib/fmt/pull/2205>, #2210 <https://github.com/fmtlib/fmt/issues/2210>, #2211 <https://github.com/fmtlib/fmt/pull/2211>, #2215 <https://github.com/fmtlib/fmt/pull/2215>, #2216 <https://github.com/fmtlib/fmt/pull/2216>, #2218 <https://github.com/fmtlib/fmt/pull/2218>, #2220 <https://github.com/fmtlib/fmt/pull/2220>, #2228 <https://github.com/fmtlib/fmt/issues/2228>, #2229 <https://github.com/fmtlib/fmt/pull/2229>, #2230 <https://github.com/fmtlib/fmt/pull/2230>, #2233 <https://github.com/fmtlib/fmt/issues/2233>, #2239 <https://github.com/fmtlib/fmt/pull/2239>, #2248 <https://github.com/fmtlib/fmt/issues/2248>, #2252 <https://github.com/fmtlib/fmt/issues/2252>, #2253 <https://github.com/fmtlib/fmt/pull/2253>, #2255 <https://github.com/fmtlib/fmt/pull/2255>, #2261 <https://github.com/fmtlib/fmt/issues/2261>, #2278 <https://github.com/fmtlib/fmt/issues/2278>, #2284 <https://github.com/fmtlib/fmt/issues/2284>, #2287 <https://github.com/fmtlib/fmt/pull/2287>, #2289 <https://github.com/fmtlib/fmt/pull/2289>, #2290 <https://github.com/fmtlib/fmt/pull/2290>, #2293 <https://github.com/fmtlib/fmt/pull/2293>, #2295 <https://github.com/fmtlib/fmt/issues/2295>, #2296 <https://github.com/fmtlib/fmt/pull/2296>, #2297 <https://github.com/fmtlib/fmt/pull/2297>, #2311 <https://github.com/fmtlib/fmt/issues/2311>, #2313 <https://github.com/fmtlib/fmt/pull/2313>, #2315 <https://github.com/fmtlib/fmt/pull/2315>, #2320 <https://github.com/fmtlib/fmt/issues/2320>, #2321 <https://github.com/fmtlib/fmt/pull/2321>, #2323 <https://github.com/fmtlib/fmt/pull/2323>, #2328 <https://github.com/fmtlib/fmt/issues/2328>, #2329 <https://github.com/fmtlib/fmt/pull/2329>, #2333 <https://github.com/fmtlib/fmt/pull/2333>, #2338 <https://github.com/fmtlib/fmt/pull/2338>, #2341 <https://github.com/fmtlib/fmt/pull/2341>). Thanks @darklukee <https://github.com/darklukee>, @fagg (Ashton Fagg) <https://github.com/fagg>, @killerbot242 (Lieven de Cock) <https://github.com/killerbot242>, @jgopel (Jonathan Gopel) <https://github.com/jgopel>, @yeswalrus (Walter Gray) <https://github.com/yeswalrus>, @Finkman <https://github.com/Finkman>, @HazardyKnusperkeks (Björn Schäpers) <https://github.com/HazardyKnusperkeks>, @dkavolis (Daumantas Kavolis) <https://github.com/dkavolis>, @concatime (Issam Maghni) <https://github.com/concatime>, @chronoxor (Ivan Shynkarenka) <https://github.com/chronoxor>, @summivox (Yin Zhong) <https://github.com/summivox>, @yNeo <https://github.com/yNeo>, @Apache-HB (Elliot) <https://github.com/Apache-HB>, @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>, @toojays (John Steele Scott) <https://github.com/toojays>, @Brainy0207 <https://github.com/Brainy0207>, @vadz (VZ) <https://github.com/vadz>, @imsherlock (Ryan Sherlock) <https://github.com/imsherlock>, @phprus (Vladislav Shchapov) <https://github.com/phprus>, @white238 (Chris White) <https://github.com/white238>, @yafshar (Yaser Afshar) <https://github.com/yafshar>, @BillyDonahue (Billy Donahue) <https://github.com/BillyDonahue>, @jstaahl <https://github.com/jstaahl>, @denchat <https://github.com/denchat>, @DanielaE (Daniela Engert) <https://github.com/DanielaE>, @ilyakurdyukov (Ilya Kurdyukov) <https://github.com/ilyakurdyukov>, @ilmai <https://github.com/ilmai>, @JessyDL (Jessy De Lannoit) <https://github.com/JessyDL>, @sergiud (Sergiu Deitsch) <https://github.com/sergiud>, @mwinterb <https://github.com/mwinterb>, @sven-herrmann <https://github.com/sven-herrmann>, @jmelas (John Melas) <https://github.com/jmelas>, @twoixter (Jose Miguel Pérez) <https://github.com/twoixter>, @crbrz <https://github.com/crbrz>, @upsj (Tobias Ribizel) <https://github.com/upsj>_.

    • 👌 Improved documentation (#1986 <https://github.com/fmtlib/fmt/issues/1986>, #2051 <https://github.com/fmtlib/fmt/pull/2051>, #2057 <https://github.com/fmtlib/fmt/issues/2057>, #2081 <https://github.com/fmtlib/fmt/pull/2081>, #2084 <https://github.com/fmtlib/fmt/issues/2084>, #2312 <https://github.com/fmtlib/fmt/pull/2312>). Thanks @imba-tjd (谭九鼎) <https://github.com/imba-tjd>, @0x416c69 (AlιAѕѕaѕѕιN) <https://github.com/0x416c69>, @mordante <https://github.com/mordante>_.

    • ✅ Continuous integration and test improvements (#1969 <https://github.com/fmtlib/fmt/issues/1969>, #1991 <https://github.com/fmtlib/fmt/pull/1991>, #2020 <https://github.com/fmtlib/fmt/pull/2020>, #2110 <https://github.com/fmtlib/fmt/pull/2110>, #2114 <https://github.com/fmtlib/fmt/pull/2114>, #2196 <https://github.com/fmtlib/fmt/issues/2196>, #2217 <https://github.com/fmtlib/fmt/pull/2217>, #2247 <https://github.com/fmtlib/fmt/pull/2247>, #2256 <https://github.com/fmtlib/fmt/pull/2256>, #2336 <https://github.com/fmtlib/fmt/pull/2336>, #2346 <https://github.com/fmtlib/fmt/pull/2346>). Thanks @jgopel (Jonathan Gopel) <https://github.com/jgopel>, @alexezeder (Alexey Ochapov) <https://github.com/alexezeder>_ and @DanielaE (Daniela Engert) <https://github.com/DanielaE>_.