7.1.0
-
Switched from Grisu3 to Dragonbox for the default floating-point formatting which gives the shortest decimal representation with round-trip guarantee and correct rounding (#1882, #1887, #1894). This makes {fmt} up to 20-30x faster than common implementations of
std::ostringstream
andsprintf
on dtoa-benchmark and faster than double-conversion and Ryū:It is possible to get even better performance at the cost of larger binary size by compiling with the
FMT_USE_FULL_CACHE_DRAGONBOX
macro set to 1. Thanks @jk-jeon (Junekey Jeon). -
Added an experimental unsynchronized file output API which, together with format string compilation, can give 5-9 times speed up compared to fprintf on common platforms (godbolt):
#include <fmt/os.h> int main() { auto f = fmt::output_file("guide"); f.print("The answer is {}.", 42); }
-
Added a formatter for
std::chrono::time_point<system_clock>
(#1819, #1837). For example (godbolt):#include <fmt/chrono.h> int main() { auto now = std::chrono::system_clock::now(); fmt::print("The time is {:%H:%M:%S}.\n", now); }
Thanks @adamburgess (Adam Burgess).
-
Added support for ranges with non-const
begin
/end
tofmt::join
(#1784, #1786). For example (godbolt):#include <fmt/ranges.h> #include <range/v3/view/filter.hpp> int main() { using std::literals::string_literals::operator""s; auto strs = std::array{"a"s, "bb"s, "ccc"s}; auto range = strs | ranges::views::filter( [] (const std::string &x) { return x.size() != 2; } ); fmt::print("{}\n", fmt::join(range, "")); }
prints "accc". Thanks @tonyelewis (Tony E Lewis).
-
Added a
memory_buffer::append
overload that takes a range (#1806). Thanks @BRevzin (Barry Revzin). -
Improved handling of single code units in
FMT_COMPILE
. For example:#include <fmt/compile.h> char* f(char* buf) { return fmt::format_to(buf, FMT_COMPILE("x{}"), 42); }
compiles to just (godbolt):
_Z1fPc: movb $120, (%rdi) xorl %edx, %edx cmpl $42, _ZN3fmt2v76detail10basic_dataIvE23zero_or_powers_of_10_32E+8(%rip) movl $3, %eax seta %dl subl %edx, %eax movzwl _ZN3fmt2v76detail10basic_dataIvE6digitsE+84(%rip), %edx cltq addq %rdi, %rax movw %dx, -2(%rax) ret
Here a single
mov
instruction writes'x'
($120
) to the output buffer. -
Added dynamic width support to format string compilation (#1809).
-
Improved error reporting for unformattable types: now you'll get the type name directly in the error message instead of the note:
#include <fmt/core.h> struct how_about_no {}; int main() { fmt::print("{}", how_about_no()); }
Error (godbolt):
fmt/core.h:1438:3: error: static_assert failed due to requirement 'fmt::v7::formattable<how_about_no>()' "Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt" ...
-
Added the make_args_checked function template that allows you to write formatting functions with compile-time format string checks and avoid binary code bloat (godbolt):
void vlog(const char* file, int line, fmt::string_view format, fmt::format_args args) { fmt::print("{}: {}: ", file, line); fmt::vprint(format, args); } template <typename S, typename... Args> void log(const char* file, int line, const S& format, Args&&... args) { vlog(file, line, format, fmt::make_args_checked<Args...>(format, args...)); } #define MY_LOG(format, ...) \ log(__FILE__, __LINE__, FMT_STRING(format), __VA_ARGS__) MY_LOG("invalid squishiness: {}", 42);
-
Replaced
snprintf
fallback with a faster internal IEEE 754float
anddouble
formatter for arbitrary precision. For example (godbolt):#include <fmt/core.h> int main() { fmt::print("{:.500}\n", 4.9406564584124654E-324); }
prints
4.9406564584124654417656879286822137236505980261432476442558568250067550727020875186529983636163599237979656469544571773092665671035593979639877479601078187812630071319031140452784581716784898210368871863605699873072305000638740915356498438731247339727316961514003171538539807412623856559117102665855668676818703956031062493194527159149245532930545654440112748012970999954193198940908041656332452475714786901472678015935523861155013480352649347201937902681071074917033322268447533357208324319360923829e-324
. -
Made
format_to_n
andformatted_size
part of the core API (godbolt):#include <fmt/core.h> int main() { char buffer[10]; auto result = fmt::format_to_n(buffer, sizeof(buffer), "{}", 42); }
-
Added
fmt::format_to_n
overload with format string compilation (#1764, #1767, #1869). For example (godbolt):#include <fmt/compile.h> int main() { char buffer[8]; fmt::format_to_n(buffer, sizeof(buffer), FMT_COMPILE("{}"), 42); }
Thanks @Kurkin (Dmitry Kurkin), @alexezeder (Alexey Ochapov).
-
Added
fmt::format_to
overload that taketext_style
(#1593, #1842, #1843). For example (godbolt):#include <fmt/color.h> int main() { std::string out; fmt::format_to(std::back_inserter(out), fmt::emphasis::bold | fg(fmt::color::red), "The answer is {}.", 42); }
Thanks @Naios (Denis Blank).
-
Made the
#
specifier emit trailing zeros in addition to the decimal point (#1797). For example (godbolt):#include <fmt/core.h> int main() { fmt::print("{:#.2g}", 0.5); }
prints
0.50
. -
Changed the default floating point format to not include
.0
for consistency withstd::format
andstd::to_chars
(#1893, #1943). It is possible to get the decimal point and trailing zero with the#
specifier. -
Fixed an issue with floating-point formatting that could result in addition of a non-significant trailing zero in rare cases e.g.
1.00e-34
instead of1.0e-34
(#1873, #1917). -
Made
fmt::to_string
fallback onostream
insertion operator if theformatter
specialization is not provided (#1815, #1829). Thanks @alexezeder (Alexey Ochapov). -
Added support for the append mode to the experimental file API and improved
fcntl.h
detection. (#1847, #1848). Thanks @t-wiser. -
Fixed handling of types that have both an implicit conversion operator and an overloaded
ostream
insertion operator (#1766). -
Fixed a slicing issue in an internal iterator type (#1822). Thanks @BRevzin (Barry Revzin).
-
Fixed an issue in locale-specific integer formatting (#1927).
-
Improved
FMT_ALWAYS_INLINE
(#1878). Thanks @jk-jeon (Junekey Jeon). -
Removed dependency on
windows.h
(#1900). Thanks @bernd5 (Bernd Baumanns). -
Optimized counting of decimal digits on MSVC (#1890). Thanks @mwinterb.
-
Improved documentation (#1772, #1775, #1792, #1838, #1888, #1918, #1939). Thanks @leolchat (Léonard Gérard), @pepsiman (Malcolm Parsons), @Klaim (Joël Lamotte), @ravijanjam (Ravi J), @francesco-st, @udnaan (Adnan).
-
Added the
FMT_REDUCE_INT_INSTANTIATIONS
CMake option that reduces the binary code size at the cost of some integer formatting performance. This can be useful for extremely memory-constrained embedded systems (#1778, #1781). Thanks @kammce (Khalil Estell). -
Added the
FMT_USE_INLINE_NAMESPACES
macro to control usage of inline namespaces (#1945). Thanks @darklukee. -
Improved build configuration (#1760, #1770, #1779, #1783, #1823). Thanks @dvetutnev (Dmitriy Vetutnev), @xvitaly (Vitaly Zaitsev), @tambry (Raul Tambre), @medithe, @martinwuehrer (Martin Wührer).
-
Fixed various warnings and compilation issues (#1790, #1802, #1808, #1810, #1811, #1812, #1814, #1816, #1817, #1818, #1825, #1836, #1855, #1856, #1860, #1877, #1879, #1880, #1896, #1897, #1898, #1904, #1908, #1911, #1912, #1928, #1929, #1935 #1937, #1942, #1949). Thanks @TheQwertiest, @medithe, @martinwuehrer (Martin Wührer), @n16h7hunt3r, @Othereum (Seokjin Lee), @gsjaardema (Greg Sjaardema), @AlexanderLanin (Alexander Lanin), @gcerretani (Giovanni Cerretani), @chronoxor (Ivan Shynkarenka), @noizefloor (Jan Schwers), @akohlmey (Axel Kohlmeyer), @jk-jeon (Junekey Jeon), @rimathia, @rglarix (Riccardo Ghetta (larix)), @moiwi, @heckad (Kazantcev Andrey), @MarcDirven. @BartSiwek (Bart Siwek), @darklukee.