-
Enabled compile-time format string check by default. For example (godbolt):
#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+) becaused
is not a valid format specifier for a string.To pass a runtime string wrap it in
fmt::runtime
:fmt::print(fmt::runtime("{:d}"), "I am not a number");
-
Added compile-time formatting (#2019, #2044, #2056, #2072, #2075, #2078, #2129, #2326). For example (godbolt):
#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).
-
Optimized handling of format specifiers during format string compilation. For example, hexadecimal formatting (
"{:x}"
) is now 3-7x faster than before when usingformat_to
with format string compilation and a stack-allocated buffer (#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 theFMT_COMPILE
macro (#2043, #2242):#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).
-
Format string compilation now requires
format
functions offormatter
specializations for user-defined types to beconst
: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, #2281). For example:
#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).
-
Added format string compilation support to
fmt::print
(#2280, #2304). Thanks @alexezeder (Alexey Ochapov). -
Added initial support for compiling {fmt} as a C++20 module (#2235, #2240, #2260, #2282, #2283, #2288, #2298, #2306, #2307, #2309, #2318, #2324, #2332, #2340). Thanks @DanielaE (Daniela Engert).
-
Made symbols private by default reducing shared library size (#2301). For example there was a ~15% reported reduction on one platform. Thanks @sergiud (Sergiu Deitsch).
-
Optimized includes making the result of preprocessing
fmt/format.h
~20% smaller with libstdc++/C++20 and slightly improving build times (#1998). -
Added support of ranges with non-const
begin
/end
(#1953). Thanks @kitegi (sarah). -
Added support of
std::byte
and other formattable types tofmt::join
(#1981, #2040, #2050, #2262). For example:#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).
-
Implemented the default format for
std::chrono::system_clock
(#2319, #2345). For example:#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.
-
Made more chrono specifiers locale independent by default. Use the
'L'
specifier to get localized formatting. For example:#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, #2349, #2350). Thanks @phprus (Vladislav Shchapov).
-
Deprecated
fmt/locale.h
moving the formatting functions that take a locale tofmt/format.h
(char
) andfmt/xchar
(other overloads). This doesn't introduce a dependency on<locale>
so there is virtually no compile time effect. -
Made parameter order in
vformat_to
consistent withformat_to
(#2327). -
Added support for time points with arbitrary durations (#2208). For example:
#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".
-
Formatting floating-point numbers no longer produces trailing zeros by default for consistency with
std::format
. For example:#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'sstr.format
. -
The
'L'
specifier for locale-specific numeric formatting can now be combined with presentation specifiers as instd::format
. For example:#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, #2310). Thanks @Liedtke (Matthias Liedtke). -
Made the hexfloat formatting use the right alignment by default (#2308, #2317). Thanks @Liedtke (Matthias Liedtke).
-
Removed the deprecated numeric alignment (
'='
). Use the'0'
specifier instead. -
Removed the deprecated
fmt/posix.h
header that has been replaced withfmt/os.h
. -
Removed the deprecated
format_to_n_context
,format_to_n_args
andmake_format_to_n_args
. They have been replaced withformat_context
,format_args
andmake_format_args
respectively. -
Moved
wchar_t
-specific functions and types tofmt/xchar.h
. You can defineFMT_DEPRECATED_INCLUDE_XCHAR
to automatically includefmt/xchar.h
fromfmt/format.h
but this will be disabled in the next major release. -
Fixed handling of the
'+'
specifier in localized formatting (#2133). -
Added support for the
's'
format specifier that gives textual representation ofbool
(#2094, #2109). For example:#include <fmt/core.h> int main() { fmt::print("{:s}", true); }
prints "true". Thanks @powercoderlol (Ivan Polyakov).
-
Made
fmt::ptr
work with function pointers (#2131). For example:#include <fmt/format.h> int main() { fmt::print("My main: {}\n", fmt::ptr(main)); }
Thanks @mikecrowe (Mike Crowe).
-
Fixed
fmt::formatted_size
with format string compilation (#2141, #2161). Thanks @alexezeder (Alexey Ochapov). -
Fixed handling of empty format strings during format string compilation (#2042):
auto s = fmt::format(FMT_COMPILE(""));
Thanks @alexezeder (Alexey Ochapov).
-
Fixed handling of enums in
fmt::to_string
(#2036). -
Improved width computation (#2033, #2091). For example:
#include <fmt/core.h> int main() { fmt::print("{:-<10}{}\n", "你好", "世界"); fmt::print("{:-<10}{}\n", "hello", "world"); }
prints
on a modern terminal.
-
The experimental fast output stream (
fmt::ostream
) is now truncated by default for consistency withfopen
(#2018). For example:#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 tofmt::output_file
. -
Fixed moving of
fmt::ostream
that holds buffered data (#2197, #2198). Thanks @vtta. -
Replaced the
fmt::system_error
exception with a function of the same name that constructsstd::system_error
(#2266). -
Replaced the
fmt::windows_error
exception with a function of the same name that constructsstd::system_error
with the category returned byfmt::system_category()
(#2274, #2275). The latter is similar tostd::sytem_category
but correctly handles UTF-8. Thanks @phprus (Vladislav Shchapov). -
Replaced
fmt::error_code
withstd::error_code
and made it formattable (#2269, #2270, #2273). Thanks @phprus (Vladislav Shchapov). -
Added speech synthesis support (#2206).
-
Made
format_to
work with a memory buffer that has a custom allocator (#2300). Thanks @voxmea. -
Added
Allocator::max_size
support tobasic_memory_buffer
. (#1960). Thanks @phprus (Vladislav Shchapov). -
Added wide string support to
fmt::join
(#2236). Thanks @crbrz. -
Made iterators passed to
formatter
specializations via a format context satisfy C++20std::output_iterator
requirements (#2156, #2158, #2195, #2204). Thanks @randomnetcat (Jason Cobb). -
Optimized the
printf
implementation (#1982, #1984, #2016, #2164). Thanks @rimathia and @moiwi. -
Improved detection of
constexpr
char_traits
(#2246, #2257). Thanks @phprus (Vladislav Shchapov). -
Fixed writing to
stdout
when it is redirected toNUL
on Windows (#2080). -
Fixed exception propagation from iterators (#2097).
-
Improved
strftime
error handling (#2238, #2244). Thanks @yumeyao. -
Stopped using deprecated GCC UDL template extension.
-
Added
fmt/args.h
to the install target (#2096). -
Error messages are now passed to assert when exceptions are disabled (#2145). Thanks @NobodyXu (Jiahao XU).
-
Added the
FMT_MASTER_PROJECT
CMake option to control build and install targets when {fmt} is included viaadd_subdirectory
(#2098, #2100). Thanks @randomizedthinking. -
Improved build configuration (#2026, #2122). Thanks @luncliff (Park DongHa) and @ibaned (Dan Ibanez).
-
Fixed various warnings and compilation issues (#1947, #1959, #1963, #1965, #1966, #1974, #1975, #1990, #2000, #2001, #2002, #2004, #2006, #2009, #2010, #2038, #2039, #2047, #2053, #2059, #2065, #2067, #2068, #2073, #2103 #2105 #2106, #2107, #2116 #2117, #2118 #2119, #2127, #2128, #2140, #2142, #2143, #2144, #2147, #2148, #2149, #2152, #2160, #2170, #2175, #2176, #2177, #2178, #2179, #2180, #2181, #2183, #2184, #2185, #2186, #2187, #2190, #2192, #2194, #2205, #2210, #2211, #2215, #2216, #2218, #2220, #2228, #2229, #2230, #2233, #2239, #2248, #2252, #2253, #2255, #2261, #2278, #2284, #2287, #2289, #2290, #2293, #2295, #2296, #2297, #2311, #2313, #2315, #2320, #2321, #2323, #2328, #2329, #2333, #2338, #2341). Thanks @darklukee, @fagg (Ashton Fagg), @killerbot242 (Lieven de Cock), @jgopel (Jonathan Gopel), @yeswalrus (Walter Gray), @Finkman, @HazardyKnusperkeks (Björn Schäpers), @dkavolis (Daumantas Kavolis) @concatime (Issam Maghni), @chronoxor (Ivan Shynkarenka), @summivox (Yin Zhong), @yNeo, @Apache-HB (Elliot), @alexezeder (Alexey Ochapov), @toojays (John Steele Scott), @Brainy0207, @vadz (VZ), @imsherlock (Ryan Sherlock), @phprus (Vladislav Shchapov), @white238 (Chris White), @yafshar (Yaser Afshar), @BillyDonahue (Billy Donahue), @jstaahl, @denchat, @DanielaE (Daniela Engert), @ilyakurdyukov (Ilya Kurdyukov), @ilmai, @JessyDL (Jessy De Lannoit), @sergiud (Sergiu Deitsch), @mwinterb, @sven-herrmann, @jmelas (John Melas), @twoixter (Jose Miguel Pérez), @crbrz, @upsj (Tobias Ribizel).
-
Improved documentation (#1986, #2051, #2057, #2081, #2084, #2312). Thanks @imba-tjd (谭九鼎), @0x416c69 (AlιAѕѕaѕѕιN), @mordante.
-
Continuous integration and test improvements (#1969, #1991, #2020, #2110, #2114, #2196, #2217, #2247, #2256, #2336, #2346). Thanks @jgopel (Jonathan Gopel), @alexezeder (Alexey Ochapov) and @DanielaE (Daniela Engert).