C++ Format v7.1.0 Release Notes
Release Date: 2020-10-26 // over 3 years ago-
- Switched from
Grisu3 <https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf>
_ toDragonbox <https://github.com/jk-jeon/dragonbox>
_ for the default floating-point formatting which gives the shortest decimal representation with round-trip guarantee and correct rounding (#1882 <https://github.com/fmtlib/fmt/pull/1882>
,#1887 <https://github.com/fmtlib/fmt/pull/1887>
,#1894 <https://github.com/fmtlib/fmt/pull/1894>
). This makes {fmt} up to 20-30x faster than common implementations ofstd::ostringstream
andsprintf
ondtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>
and faster than double-conversion and Ryū:
.. image:: https://user-images.githubusercontent.com/576385/ 95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png
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) <https://github.com/jk-jeon>
_.- ➕ Added an experimental unsynchronized file output API which, together with
format string compilation <https://fmt.dev/latest/api.html#compile-api>
, can give5-9 times speed up compared to fprintf <https://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>
on common platforms (godbolt <https://godbolt.org/z/nsTcG8>
__):
.. code:: c++
#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 <https://github.com/fmtlib/fmt/issues/1819>
,#1837 <https://github.com/fmtlib/fmt/pull/1837>
). For example (godbolt <https://godbolt.org/z/c4M6fh>
__):
.. code:: c++
#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) <https://github.com/adamburgess>
_.- ➕ Added support for ranges with non-const
begin
/end
tofmt::join
(#1784 <https://github.com/fmtlib/fmt/issues/1784>
,#1786 <https://github.com/fmtlib/fmt/pull/1786>
). For example (godbolt <https://godbolt.org/z/jP63Tv>
__):
.. code:: c++
#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) <https://github.com/tonyelewis>
_.➕ Added a
memory_buffer::append
overload that takes a range (#1806 <https://github.com/fmtlib/fmt/pull/1806>
). Thanks@BRevzin (Barry Revzin) <https://github.com/BRevzin>
.👌 Improved handling of single code units in
FMT_COMPILE
. For example:
.. code:: c++
#include <fmt/compile.h> char* f(char* buf) { return fmt::format_to(buf, FMT_COMPILE("x{}"), 42); }
compiles to just (
godbolt <https://godbolt.org/z/5vncz3>
__):.. code:: asm
_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 <https://github.com/fmtlib/fmt/issues/1809>
_).👌 Improved error reporting for unformattable types: now you'll get the type name directly in the error message instead of the note:
.. code:: c++
#include <fmt/core.h> struct how_about_no {}; int main() { fmt::print("{}", how_about_no()); }
Error (
godbolt <https://godbolt.org/z/GoxM4e>
__):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 <https://fmt.dev/7.1.0/api.html#argument-lists>
_ function template that allows you to write formatting functions with compile-time format string checks and avoid binary code bloat (godbolt <https://godbolt.org/z/PEf9qr>
__):
.. code:: c++
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 <https://godbolt.org/z/dPhWvj>
__):
.. code:: c++
#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 thecore API <https://fmt.dev/latest/api.html#core-api>
__ (godbolt <https://godbolt.org/z/sPjY1K>
__):
.. code:: c++
#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 <https://github.com/fmtlib/fmt/issues/1764>
,#1767 <https://github.com/fmtlib/fmt/pull/1767>
,#1869 <https://github.com/fmtlib/fmt/pull/1869>
). For example (godbolt <https://godbolt.org/z/93h86q>
_):
.. code:: c++
#include <fmt/compile.h> int main() { char buffer[8]; fmt::format_to_n(buffer, sizeof(buffer), FMT_COMPILE("{}"), 42); }
Thanks
@Kurkin (Dmitry Kurkin) <https://github.com/Kurkin>
,@alexezeder (Alexey Ochapov) <https://github.com/alexezeder>
.- Added
fmt::format_to
overload that taketext_style
(#1593 <https://github.com/fmtlib/fmt/issues/1593>
,#1842 <https://github.com/fmtlib/fmt/issues/1842>
,#1843 <https://github.com/fmtlib/fmt/pull/1843>
). For example (godbolt <https://godbolt.org/z/91153r>
_):
.. code:: c++
#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) <https://github.com/Naios>
_.- Made the
'#'
specifier emit trailing zeros in addition to the decimal point (#1797 <https://github.com/fmtlib/fmt/issues/1797>
). For example (godbolt <https://godbolt.org/z/bhdcW9>
_):
.. code:: c++
#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 <https://github.com/fmtlib/fmt/issues/1893>
,#1943 <https://github.com/fmtlib/fmt/issues/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 <https://github.com/fmtlib/fmt/issues/1873>
,#1917 <https://github.com/fmtlib/fmt/issues/1917>
).Made
fmt::to_string
fallback onostream
insertion operator if theformatter
specialization is not provided (#1815 <https://github.com/fmtlib/fmt/issues/1815>
,#1829 <https://github.com/fmtlib/fmt/pull/1829>
). Thanks@alexezeder (Alexey Ochapov) <https://github.com/alexezeder>
_.➕ Added support for the append mode to the experimental file API and improved
fcntl.h
detection. (#1847 <https://github.com/fmtlib/fmt/pull/1847>
,#1848 <https://github.com/fmtlib/fmt/pull/1848>
). Thanks@t-wiser <https://github.com/t-wiser>
_.🛠 Fixed handling of types that have both an implicit conversion operator and an overloaded
ostream
insertion operator (#1766 <https://github.com/fmtlib/fmt/issues/1766>
_).🛠 Fixed a slicing issue in an internal iterator type (
#1822 <https://github.com/fmtlib/fmt/pull/1822>
). Thanks@BRevzin (Barry Revzin) <https://github.com/BRevzin>
.🛠 Fixed an issue in locale-specific integer formatting (
#1927 <https://github.com/fmtlib/fmt/issues/1927>
_).🛠 Fixed handling of exotic code unit types (
#1870 <https://github.com/fmtlib/fmt/issues/1870>
,#1932 <https://github.com/fmtlib/fmt/issues/1932>
).Improved
FMT_ALWAYS_INLINE
(#1878 <https://github.com/fmtlib/fmt/pull/1878>
). Thanks@jk-jeon (Junekey Jeon) <https://github.com/jk-jeon>
.✂ Removed dependency on
windows.h
(#1900 <https://github.com/fmtlib/fmt/pull/1900>
). Thanks@bernd5 (Bernd Baumanns) <https://github.com/bernd5>
.⚡️ Optimized counting of decimal digits on MSVC (
#1890 <https://github.com/fmtlib/fmt/pull/1890>
). Thanks@mwinterb <https://github.com/mwinterb>
.👌 Improved documentation (
#1772 <https://github.com/fmtlib/fmt/issues/1772>
,#1775 <https://github.com/fmtlib/fmt/pull/1775>
,#1792 <https://github.com/fmtlib/fmt/pull/1792>
,#1838 <https://github.com/fmtlib/fmt/pull/1838>
,#1888 <https://github.com/fmtlib/fmt/pull/1888>
,#1918 <https://github.com/fmtlib/fmt/pull/1918>
,#1939 <https://github.com/fmtlib/fmt/pull/1939>
). Thanks@leolchat (Léonard Gérard) <https://github.com/leolchat>
,@pepsiman (Malcolm Parsons) <https://github.com/pepsiman>
,@Klaim (Joël Lamotte) <https://github.com/Klaim>
,@ravijanjam (Ravi J) <https://github.com/ravijanjam>
,@francesco-st <https://github.com/francesco-st>
,@udnaan (Adnan) <https://github.com/udnaan>
_.⬇️ 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 <https://github.com/fmtlib/fmt/issues/1778>
,#1781 <https://github.com/fmtlib/fmt/pull/1781>
). Thanks@kammce (Khalil Estell) <https://github.com/kammce>
_.👉 Added the
FMT_USE_INLINE_NAMESPACES
macro to control usage of inline namespaces (#1945 <https://github.com/fmtlib/fmt/pull/1945>
). Thanks@darklukee <https://github.com/darklukee>
.👌 Improved build configuration (
#1760 <https://github.com/fmtlib/fmt/pull/1760>
,#1770 <https://github.com/fmtlib/fmt/pull/1770>
,#1779 <https://github.com/fmtlib/fmt/issues/1779>
,#1783 <https://github.com/fmtlib/fmt/pull/1783>
,#1823 <https://github.com/fmtlib/fmt/pull/1823>
). Thanks@dvetutnev (Dmitriy Vetutnev) <https://github.com/dvetutnev>
,@xvitaly (Vitaly Zaitsev) <https://github.com/xvitaly>
,@tambry (Raul Tambre) <https://github.com/tambry>
,@medithe <https://github.com/medithe>
,@martinwuehrer (Martin Wührer) <https://github.com/martinwuehrer>
.🛠 Fixed various warnings and compilation issues (
#1790 <https://github.com/fmtlib/fmt/pull/1790>
,#1802 <https://github.com/fmtlib/fmt/pull/1802>
,#1808 <https://github.com/fmtlib/fmt/pull/1808>
,#1810 <https://github.com/fmtlib/fmt/issues/1810>
,#1811 <https://github.com/fmtlib/fmt/issues/1811>
,#1812 <https://github.com/fmtlib/fmt/pull/1812>
,#1814 <https://github.com/fmtlib/fmt/pull/1814>
,#1816 <https://github.com/fmtlib/fmt/pull/1816>
,#1817 <https://github.com/fmtlib/fmt/pull/1817>
,#1818 <https://github.com/fmtlib/fmt/pull/1818>
,#1825 <https://github.com/fmtlib/fmt/issues/1825>
,#1836 <https://github.com/fmtlib/fmt/pull/1836>
,#1855 <https://github.com/fmtlib/fmt/pull/1855>
,#1856 <https://github.com/fmtlib/fmt/pull/1856>
,#1860 <https://github.com/fmtlib/fmt/pull/1860>
,#1877 <https://github.com/fmtlib/fmt/pull/1877>
,#1879 <https://github.com/fmtlib/fmt/pull/1879>
,#1880 <https://github.com/fmtlib/fmt/pull/1880>
,#1896 <https://github.com/fmtlib/fmt/issues/1896>
,#1897 <https://github.com/fmtlib/fmt/pull/1897>
,#1898 <https://github.com/fmtlib/fmt/pull/1898>
,#1904 <https://github.com/fmtlib/fmt/issues/1904>
,#1908 <https://github.com/fmtlib/fmt/pull/1908>
,#1911 <https://github.com/fmtlib/fmt/issues/1911>
,#1912 <https://github.com/fmtlib/fmt/issues/1912>
,#1928 <https://github.com/fmtlib/fmt/issues/1928>
,#1929 <https://github.com/fmtlib/fmt/pull/1929>
,#1935 <https://github.com/fmtlib/fmt/issues/1935>
,#1937 <https://github.com/fmtlib/fmt/pull/1937>
,#1942 <https://github.com/fmtlib/fmt/pull/1942>
,#1949 <https://github.com/fmtlib/fmt/issues/1949>
). Thanks@TheQwertiest <https://github.com/TheQwertiest>
,@medithe <https://github.com/medithe>
,@martinwuehrer (Martin Wührer) <https://github.com/martinwuehrer>
,@n16h7hunt3r <https://github.com/n16h7hunt3r>
,@Othereum (Seokjin Lee) <https://github.com/Othereum>
,@gsjaardema (Greg Sjaardema) <https://github.com/gsjaardema>
,@AlexanderLanin (Alexander Lanin) <https://github.com/AlexanderLanin>
,@gcerretani (Giovanni Cerretani) <https://github.com/gcerretani>
,@chronoxor (Ivan Shynkarenka) <https://github.com/chronoxor>
,@noizefloor (Jan Schwers) <https://github.com/noizefloor>
,@akohlmey (Axel Kohlmeyer) <https://github.com/akohlmey>
,@jk-jeon (Junekey Jeon) <https://github.com/jk-jeon>
,@rimathia <https://github.com/rimathia>
,@rglarix (Riccardo Ghetta (larix)) <https://github.com/rglarix>
,@moiwi <https://github.com/moiwi>
,@heckad (Kazantcev Andrey) <https://github.com/heckad>
,@MarcDirven <https://github.com/MarcDirven>
.@BartSiwek (Bart Siwek) <https://github.com/BartSiwek>
,@darklukee <https://github.com/darklukee>
.
- Switched from