A modern formatting library
Added support for the %j
specifier (the number of days) for std::chrono::duration
(https://github.com/fmtlib/fmt/issues/3643, https://github.com/fmtlib/fmt/pull/3732). Thanks @intelfx.
Added support for the chrono suffix for days and changed the suffix for minutes from "m" to the correct "min" (https://github.com/fmtlib/fmt/issues/3662, https://github.com/fmtlib/fmt/pull/3664). For example (godbolt):
#include <fmt/chrono.h>
int main() {
fmt::print("{}\n", std::chrono::days(42)); // prints "42d"
}
Thanks @Richardk2n.
Fixed an overflow in std::chrono::time_point
formatting with large dates (https://github.com/fmtlib/fmt/issues/3725, https://github.com/fmtlib/fmt/pull/3727). Thanks @cschreib.
Added a formatter for std::source_location
(https://github.com/fmtlib/fmt/pull/3730). For example (godbolt):
#include <source_location>
#include <fmt/std.h>
int main() {
fmt::print("{}\n", std::source_location::current());
}
prints
/app/example.cpp:5:51: int main()
Thanks @felix642.
Added a formatter for std::bitset
(https://github.com/fmtlib/fmt/pull/3660). For example (godbolt):
#include <bitset>
#include <fmt/std.h>
int main() {
fmt::print("{}\n", std::bitset<6>(42)); // prints "101010"
}
Thanks @muggenhor.
Added an experimental nested_formatter
that provides an easy way of applying a formatter to one or more subobjects while automatically handling width, fill and alignment. For example:
#include <fmt/format.h>
struct point {
double x, y;
};
template <>
struct fmt::formatter<point> : nested_formatter<double> {
auto format(point p, format_context& ctx) const {
return write_padded(ctx, [=](auto out) {
return format_to(out, "({}, {})", nested(p.x), nested(p.y));
});
}
};
int main() {
fmt::print("[{:>20.2f}]", point{1, 2});
}
prints
[ (1.00, 2.00)]
Added the generic representation (g
) to std::filesystem::path
(https://github.com/fmtlib/fmt/issues/3715, https://github.com/fmtlib/fmt/pull/3729). For example:
#include <filesystem>
#include <fmt/std.h>
int main() {
fmt::print("{:g}\n", std::filesystem::path("C:\\foo"));
}
prints "C:/foo"
on Windows.
Thanks @js324.
Made format_as
work with references (https://github.com/fmtlib/fmt/pull/3739). Thanks @tchaikov.
Fixed formatting of invalid UTF-8 with precision (https://github.com/fmtlib/fmt/issues/3284).
Fixed an inconsistency between fmt::to_string
and fmt::format
(https://github.com/fmtlib/fmt/issues/3684).
Disallowed unsafe uses of fmt::styled
(https://github.com/fmtlib/fmt/issues/3625):
auto s = fmt::styled(std::string("dangle"), fmt::emphasis::bold);
fmt::print("{}\n", s); // compile error
Pass fmt::styled(...)
as a parameter instead.
Added a null check when formatting a C string with the s
specifier (https://github.com/fmtlib/fmt/issues/3706).
Disallowed the c
specifier for bool
(https://github.com/fmtlib/fmt/issues/3726, https://github.com/fmtlib/fmt/pull/3734). Thanks @js324.
Made the default formatting unlocalized in fmt::ostream_formatter
for consistency with the rest of the library (https://github.com/fmtlib/fmt/issues/3460).
Fixed localized formatting in bases other than decimal (https://github.com/fmtlib/fmt/issues/3693, https://github.com/fmtlib/fmt/pull/3750). Thanks @js324.
Fixed a performance regression in experimental fmt::ostream::print
(https://github.com/fmtlib/fmt/issues/3674).
Added synchronization with the underlying output stream when writing to the Windows console (https://github.com/fmtlib/fmt/pull/3668, https://github.com/fmtlib/fmt/issues/3688, https://github.com/fmtlib/fmt/pull/3689). Thanks @Roman-Koshelev and @dimztimz.
Changed to only export format_error
when {fmt} is built as a shared library (https://github.com/fmtlib/fmt/issues/3626, https://github.com/fmtlib/fmt/pull/3627). Thanks @phprus.
Made fmt::streamed
constexpr
. (https://github.com/fmtlib/fmt/pull/3650). Thanks @muggenhor.
Enabled consteval
on older versions of MSVC (https://github.com/fmtlib/fmt/pull/3757). Thanks @phprus.
Added an option to build without wchar_t
support on Windows (https://github.com/fmtlib/fmt/issues/3631, https://github.com/fmtlib/fmt/pull/3636). Thanks @glebm.
Improved build and CI configuration (https://github.com/fmtlib/fmt/pull/3679, https://github.com/fmtlib/fmt/issues/3701, https://github.com/fmtlib/fmt/pull/3702, https://github.com/fmtlib/fmt/pull/3749). Thanks @jcar87, @pklima and @tchaikov.
Fixed various warnings, compilation and test issues (https://github.com/fmtlib/fmt/issues/3607, https://github.com/fmtlib/fmt/pull/3610, https://github.com/fmtlib/fmt/pull/3624, https://github.com/fmtlib/fmt/pull/3630, https://github.com/fmtlib/fmt/pull/3634, https://github.com/fmtlib/fmt/pull/3638, https://github.com/fmtlib/fmt/issues/3645, https://github.com/fmtlib/fmt/issues/3646, https://github.com/fmtlib/fmt/pull/3647, https://github.com/fmtlib/fmt/pull/3652, https://github.com/fmtlib/fmt/issues/3654, https://github.com/fmtlib/fmt/pull/3663, https://github.com/fmtlib/fmt/issues/3670, https://github.com/fmtlib/fmt/pull/3680, https://github.com/fmtlib/fmt/issues/3694, https://github.com/fmtlib/fmt/pull/3695, https://github.com/fmtlib/fmt/pull/3699, https://github.com/fmtlib/fmt/issues/3705, https://github.com/fmtlib/fmt/issues/3710, https://github.com/fmtlib/fmt/issues/3712, https://github.com/fmtlib/fmt/pull/3713, https://github.com/fmtlib/fmt/issues/3714, https://github.com/fmtlib/fmt/pull/3716, https://github.com/fmtlib/fmt/pull/3723, https://github.com/fmtlib/fmt/issues/3738, https://github.com/fmtlib/fmt/issues/3740, https://github.com/fmtlib/fmt/pull/3741, https://github.com/fmtlib/fmt/pull/3743, https://github.com/fmtlib/fmt/issues/3745, https://github.com/fmtlib/fmt/pull/3747, https://github.com/fmtlib/fmt/pull/3748, https://github.com/fmtlib/fmt/pull/3751, https://github.com/fmtlib/fmt/pull/3754, https://github.com/fmtlib/fmt/pull/3755, https://github.com/fmtlib/fmt/issues/3760, https://github.com/fmtlib/fmt/pull/3762, https://github.com/fmtlib/fmt/issues/3763, https://github.com/fmtlib/fmt/pull/3764, https://github.com/fmtlib/fmt/issues/3774, https://github.com/fmtlib/fmt/pull/3779). Thanks @danakj, @vinayyadav3016, @cyyever, @phprus, @qimiko, @saschasc, @gsjaardema, @lazka, @Zhaojun-Liu, @carlsmedstad, @hotwatermorning, @cptFracassa, @kuguma, @PeterJohnson, @H1X4Dev, @asantoni, @eltociear, @msimberg, @tchaikov, @waywardmonkeys.
Improved documentation and README (https://github.com/fmtlib/fmt/issues/2086, https://github.com/fmtlib/fmt/issues/3637, https://github.com/fmtlib/fmt/pull/3642, https://github.com/fmtlib/fmt/pull/3653, https://github.com/fmtlib/fmt/pull/3655, https://github.com/fmtlib/fmt/pull/3661, https://github.com/fmtlib/fmt/issues/3673, https://github.com/fmtlib/fmt/pull/3677, https://github.com/fmtlib/fmt/pull/3737, https://github.com/fmtlib/fmt/issues/3742, https://github.com/fmtlib/fmt/pull/3744). Thanks @idzm, @perlun, @joycebrum, @fennewald, @reinhardt1053, @GeorgeLS.
Updated CI dependencies (https://github.com/fmtlib/fmt/pull/3615, https://github.com/fmtlib/fmt/pull/3622, https://github.com/fmtlib/fmt/pull/3623, https://github.com/fmtlib/fmt/pull/3666, https://github.com/fmtlib/fmt/pull/3696, https://github.com/fmtlib/fmt/pull/3697, https://github.com/fmtlib/fmt/pull/3759, https://github.com/fmtlib/fmt/pull/3782).
Added formatters for std::atomic
and atomic_flag
(#3574, #3594). Thanks @wangzw (Zhanwei Wang) and @AlexGuteniev (Alex Guteniev).
Fixed an error about partial specialization of formatter<string>
after instantiation when compiled with gcc and C++20 (#3584).
Fixed compilation as a C++20 module with gcc and clang (#3587, #3597, #3605). Thanks @MathewBensonCode (Mathew Benson).
Made fmt::to_string
work with types that have format_as
overloads (#3575). Thanks @phprus (Vladislav Shchapov).
Made formatted_size
work with integral format specifiers at compile time (#3591). Thanks @elbeno (Ben Deane).
Fixed a warning about the no_unique_address
attribute on clang-cl (#3599). Thanks @lukester1975.
Improved compatibility with the legacy GBK encoding (#3598, #3599). Thanks @YuHuanTin.
Added OpenSSF Scorecard analysis (#3530, #3571). Thanks @joycebrum (Joyce).
Updated CI dependencies (#3591, #3592, #3593, #3602).
formatted_size
with FMT_COMPILE
and format specs by @elbeno in https://github.com/fmtlib/fmt/pull/3588
FMT_NO_UNIQUE_ADDRESS
warning with clang-cl. by @lukester1975 in https://github.com/fmtlib/fmt/pull/3600
atomic_flag
formatting by @AlexGuteniev in https://github.com/fmtlib/fmt/pull/3594
Optimized format string compilation resulting in up to 40% speed up in compiled format_to
and ~4x speed up in compiled format_to_n
on a concatenation benchmark (#3133, #3484).
{fmt} 10.0:
---------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------
BM_format_to 78.9 ns 78.9 ns 8881746
BM_format_to_n 568 ns 568 ns 1232089
{fmt} 10.1:
---------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------
BM_format_to 54.9 ns 54.9 ns 12727944
BM_format_to_n 133 ns 133 ns 5257795
Optimized storage of an empty allocator in basic_memory_buffer
(#3485). Thanks @Minty-Meeo.
Added formatters for proxy references to elements of std::vector<bool>
and std::bitset<N>
(#3567, #3570). For example (godbolt):
#include <vector>
#include <fmt/std.h>
int main() {
auto v = std::vector<bool>{true};
fmt::print("{}", v[0]);
}
Thanks @phprus (Vladislav Shchapov) and @felix642 (Félix-Antoine Constantin).
Fixed an ambiguous formatter specialization for containers that look like container adaptors such as boost::flat_set
(#3556, #3561). Thanks @5chmidti.
Fixed compilation when formatting durations not convertible from std::chrono::seconds
(#3430). Thanks @patlkli (Patrick Geltinger).
Made the formatter
specialization for char*
const-correct (#3432). Thanks @timsong-cpp.
Made {}
and {:}
handled consistently during compile-time checks (#3526).
Disallowed passing temporaries to make_format_args
to improve API safety by preventing dangling references.
Improved the compile-time error for unformattable types (#3478). Thanks @BRevzin (Barry Revzin).
Improved the floating-point formatter (#3448, #3450). Thanks @florimond-collette (Florimond Collette).
Fixed handling of precision for long double
larger than 64 bits. (#3539, #3564).
Made floating-point and chrono tests less platform-dependent (#3337, #3433, #3434). Thanks @phprus (Vladislav Shchapov).
Removed the remnants of the Grisu floating-point formatter that has been replaced by Dragonbox in earlier versions.
Added throw_format_error
to the public API (#3551). Thanks @mjerabek (Martin Jeřábek).
Made FMT_THROW
assert even if assertions are disabled when compiling with exceptions disabled (#3418, #3439). Thanks @BRevzin (Barry Revzin).
Added support for the ?
format specifier to std::filesystem::path
and made the default unescaped for consistency with strings.
Made format_as
and std::filesystem::path
formatter work with exotic code unit types. (#3457, #3476). Thanks @gix (Nico Rieck), @hmbj (Hans-Martin B. Jensen).
Deprecated the wide stream overload of printf
.
Removed unused basic_printf_parse_context
.
Improved RTTI detection used when formatting exceptions (#3468). Thanks @danakj (Dana Jansens).
Improved compatibility with VxWorks7 (#3467). Thanks @wenshan1 (Bin Lan).
Improved documentation (#3174, #3423, #3454, #3458, #3461, #3487, #3515). Thanks @zencatalyst (Kasra Hashemi), @rlalik, @mikecrowe (Mike Crowe).
Improved build and CI configurations (#3449, #3451, #3452, #3453, #3459, #3481, #3486, #3489, #3496, #3517, #3523, #3563). Thanks @joycebrum (Joyce), @glebm (Gleb Mazovetskiy), @phprus (Vladislav Shchapov), @petrmanek (Petr Mánek), @setoye (Alta), @abouvier (Alexandre Bouvier).
Fixed various warnings and compilation issues (#3408, #3424, #3444, #3446, #3475, #3482, #3492, #3493, #3508, #3509, #3533, #3542, #3543, #3540, #3544, #3548, #3549, #3550, #3552). Thanks @adesitter (Arnaud Desitter), @hmbj (Hans-Martin B. Jensen), @Minty-Meeo, @phprus (Vladislav Shchapov), @TobiSchluter (Tobias Schlüter), @kieranclancy (Kieran Clancy), @alexeedm (Dmitry Alexeev), @jurihock (Jürgen Hock), @Ozomahtli, @razaqq.
cmake --install
when included as a subproject by @petrmanek in https://github.com/fmtlib/fmt/pull/3496
Replaced Grisu with a new floating-point formatting algorithm for given precision (#3262, #2750, #3269, #3276). The new algorithm is based on Dragonbox already used for the shortest representation and gives substantial performance improvement:
Red: new algorithm
Green: new algorithm with `FMT_USE_FULL_CACHE_DRAGONBOX` defined to 1
Blue: old algorithm
Thanks @jk-jeon (Junekey Jeon).
Replaced snprintf
-based hex float formatter with an internal implementation (#3179, #3203). This removes the last usage of s(n)printf
in {fmt}. Thanks @phprus (Vladislav Shchapov).
Fixed alignment of floating-point numbers with localization (#3263, #3272). Thanks @ShawnZhong (Shawn Zhong).
Made handling of #
consistent with std::format
.
Improved C++20 module support (#3134, #3254, #3386, #3387, #3388, #3392, #3397, #3399, #3400). Thanks @laitingsheng (Tinson Lai), @Orvid (Orvid King), @DanielaE (Daniela Engert). Switched to the modules CMake library which allows building {fmt} as a C++20 module with clang:
CXX=clang++ cmake -DFMT_MODULE=ON .
make
Made format_as
work with any user-defined type and not just enums. For example (godbolt):
#include <fmt/format.h>
struct floaty_mc_floatface {
double value;
};
auto format_as(floaty_mc_floatface f) { return f.value; }
int main() {
fmt::print("{:8}\n", floaty_mc_floatface{0.42}); // prints " 0.42"
}
Removed deprecated implicit conversions for enums and conversions to primitive types for compatibility with std::format
and to prevent potential ODR violations. Use format_as
instead.
Added support for fill, align and width to the time point formatter (#3237, #3260, #3275). For example (godbolt):
#include <fmt/chrono.h>
int main() {
// prints " 2023"
fmt::print("{:>8%Y}\n", std::chrono::system_clock::now());
}
Thanks @ShawnZhong (Shawn Zhong).
Implemented formatting of subseconds (#2207, #3117, #3115, #3143, #3144, #3349). For example (godbolt):
#include <fmt/chrono.h>
int main() {
// prints 01.234567
fmt::print("{:%S}\n", std::chrono::microseconds(1234567));
}
Thanks @patrickroocks (Patrick Roocks) @phprus (Vladislav Shchapov), @BRevzin (Barry Revzin).
Added precision support to %S
(#3148). Thanks @SappyJoy (Stepan Ponomaryov)
Added support for std::utc_time
(#3098, #3110). Thanks @patrickroocks (Patrick Roocks).
Switched formatting of std::chrono::system_clock
from local time to UTC for compatibility with the standard (#3199, #3230). Thanks @ned14 (Niall Douglas).
Added support for %Ez
and %Oz
to chrono formatters. (#3220, #3222). Thanks @phprus (Vladislav Shchapov).
Improved validation of format specifiers for std::chrono::duration
(#3219, #3232). Thanks @ShawnZhong (Shawn Zhong).
Fixed formatting of time points before the epoch (#3117, #3261). For example (godbolt):
#include <fmt/chrono.h>
int main() {
auto t = std::chrono::system_clock::from_time_t(0) -
std::chrono::milliseconds(250);
fmt::print("{:%S}\n", t); // prints 59.750000000
}
Thanks @ShawnZhong (Shawn Zhong).
Experimental: implemented glibc extension for padding seconds, minutes and hours (#2959, #3271). Thanks @ShawnZhong (Shawn Zhong).
Added a formatter for std::exception
(#2977, #3012, #3062, #3076, #3119). For example (godbolt):
#include <fmt/std.h>
#include <vector>
int main() {
try {
std::vector<bool>().at(0);
} catch(const std::exception& e) {
fmt::print("{}", e);
}
}
prints:
vector<bool>::_M_range_check: __n (which is 0) >= this->size() (which is 0)
on libstdc++. Thanks @zach2good (Zach Toogood) and @phprus (Vladislav Shchapov).
Moved std::error_code
formatter from fmt/os.h
to fmt/std.h
. (#3125). Thanks @phprus (Vladislav Shchapov).
Added formatters for standard container adapters: std::priority_queue
, std::queue
and std::stack
(#3215, #3279). For example (godbolt):
#include <fmt/ranges.h>
#include <stack>
#include <vector>
int main() {
auto s = std::stack<bool, std::vector<bool>>();
for (auto b: {true, false, true}) s.push(b);
fmt::print("{}\n", s); // prints [true, false, true]
}
Thanks @ShawnZhong (Shawn Zhong).
Added a formatter for std::optional
to fmt/std.h
. Thanks @tom-huntington.
Fixed formatting of valueless by exception variants (#3347). Thanks @TheOmegaCarrot.
Made fmt::ptr
accept unique_ptr
with a custom deleter (#3177). Thanks @hmbj (Hans-Martin B. Jensen).
Fixed formatting of noncopyable ranges and nested ranges of chars (#3158 #3286, #3290). Thanks @BRevzin (Barry Revzin).
Fixed issues with formatting of paths and ranges of paths (#3319, #3321 #3322). Thanks @phprus (Vladislav Shchapov).
Improved handling of invalid Unicode in paths.
Enabled compile-time checks on Apple clang 14 and later (#3331). Thanks @cloyce (Cloyce D. Spradling).
Improved compile-time checks of named arguments (#3105, #3214). Thanks @rbrich (Radek Brich).
Fixed formatting when both alignment and 0
are given (#3236, #3248). Thanks @ShawnZhong (Shawn Zhong).
Improved Unicode support in the experimental file API on Windows (#3234, #3293). Thanks @Fros1er (Froster).
Unified UTF transcoding (#3416). Thanks @phprus (Vladislav Shchapov).
Added support for UTF-8 digit separators via an experimental locale facet (#1861). For example (godbolt):
auto loc = std::locale(
std::locale(), new fmt::format_facet<std::locale>("’"));
auto s = fmt::format(loc, "{:L}", 1000);
where ’
is U+2019 used as a digit separator in the de_CH locale.
Added an overload of formatted_size
that takes a locale (#3084, #3087). Thanks @gerboengels.
Removed the deprecated FMT_DEPRECATED_OSTREAM
.
Fixed a UB when using a null std::string_view
with fmt::to_string
or format string compilation (#3241, #3244). Thanks @phprus (Vladislav Shchapov).
Added starts_with
to the fallback string_view
implementation (#3080). Thanks @phprus (Vladislav Shchapov).
Added fmt::basic_format_string::get()
for compatibility with basic_format_string
(#3111). Thanks @huangqinjin.
Added println
for compatibility with C++23 (#3267). Thanks @ShawnZhong (Shawn Zhong).
Renamed the FMT_EXPORT
macro for shared library usage to FMT_LIB_EXPORT
.
Improved documentation (#3108, #3169, #3243). #3404). Thanks @Cleroth and @Vertexwahn.
Improved build configuration and tests (#3118, #3120, #3188, #3189, #3198, #3205, #3207, #3210, #3240, #3256, #3264, #3299, #3302, #3312, #3317, #3328, #3333, #3369, #3373, #3395, #3406, #3411). Thanks @dimztimz (Dimitrij Mijoski), @phprus (Vladislav Shchapov), @DavidKorczynski, @ChrisThrasher (Chris Thrasher), @FrancoisCarouge (François Carouge), @kennyweiss (Kenny Weiss), @luzpaz, @codeinred (Alecto Irene Perez), @Mixaill (Mikhail Paulyshka), @joycebrum (Joyce), @kevinhwang (Kevin Hwang), @Vertexwahn.
Fixed a regression in handling empty format specifiers after a colon ({:}
) (#3086). Thanks @oxidase (Michael Krasnyk).
Worked around a broken implementation of std::is_constant_evaluated
in some versions of libstdc++ on clang (#3247, #3281). Thanks @phprus (Vladislav Shchapov).
Fixed formatting of volatile variables (#3068).
Fixed various warnings and compilation issues (#3057, #3066, #3072, #3082, #3091, #3092, #3093, #3095, #3096, #3097, #3128, #3129, #3137, #3139, #3140, #3142, #3149, #3150, #3154, #3163, #3178, #3184, #3196, #3204, #3206, #3208, #3213, #3216, #3224, #3226, #3228, #3229, #3259, #3274, #3287, #3288, #3292, #3295, #3296, #3298, #3325, #3326, #3334, #3342, #3343, #3351, #3352, #3362, #3365, #3366, #3374, #3377, #3378, #3381, #3398, #3413, #3415). Thanks @phprus (Vladislav Shchapov), @gsjaardema (Greg Sjaardema), @NewbieOrange, @EngineLessCC (VivyaCC), @asmaloney (Andy Maloney), @HazardyKnusperkeks (Björn Schäpers), @sergiud (Sergiu Deitsch), @Youw (Ihor Dutchak), @thesmurph, @czudziakm (Maksymilian Czudziak), @Roman-Koshelev, @chronoxor (Ivan Shynkarenka), @ShawnZhong (Shawn Zhong), @russelltg (Russell Greene), @glebm (Gleb Mazovetskiy), @tmartin-gh, @Zhaojun-Liu (June Liu), @louiswins (Louis Wilson), @mogemimi.
uint
as a type name by @Youw in https://github.com/fmtlib/fmt/pull/3137
target_compile_features
to specify C++ standard requirement by @ChrisThrasher in https://github.com/fmtlib/fmt/pull/3205
println
by @ShawnZhong in https://github.com/fmtlib/fmt/pull/3267
write_floating_seconds
: Fall back to ::round
by @glebm in https://github.com/fmtlib/fmt/pull/3343
vfprintf
clashes with the identically named declaration in 'st… by @DanielaE in https://github.com/fmtlib/fmt/pull/3400
FMT_STRING
for format_to()
call with clang-cl by @mogemimi in https://github.com/fmtlib/fmt/pull/3413
Full Changelog: https://github.com/fmtlib/fmt/compare/9.1.0...10.0.0
fmt::formatted_size
now works at compile time (#3026). For example (godbolt):
#include <fmt/compile.h>
int main() {
using namespace fmt::literals;
constexpr size_t n = fmt::formatted_size("{}"_cf, 42);
fmt::print("{}\n", n); // prints 2
}
Thanks @marksantaniello (Mark Santaniello).
Fixed handling of invalid UTF-8 (#3038, #3044, #3056). Thanks @phprus (Vladislav Shchapov) and @skeeto (Christopher Wellons).
Improved Unicode support in ostream
overloads of print
(#2994, #3001, #3025). Thanks @dimztimz (Dimitrij Mijoski).
Fixed handling of the sign specifier in localized formatting on systems with 32-bit wchar_t
(#3041).
Added support for wide streams to fmt::streamed
(#2994). Thanks @phprus (Vladislav Shchapov).
Added the n
specifier that disables the output of delimiters when formatting ranges (#2981, #2983). For example (godbolt):
#include <fmt/ranges.h>
#include <vector>
int main() {
auto v = std::vector{1, 2, 3};
fmt::print("{:n}\n", v); // prints 1, 2, 3
}
Thanks @BRevzin (Barry Revzin).
Worked around problematic std::string_view
constructors introduced in C++23 (#3030, #3050). Thanks @strega-nil-ms (nicole mazzuca).
Improve handling (exclusion) of recursive ranges (#2968, #2974). Thanks @Dani-Hub (Daniel Krügler).
Improved error reporting in format string compilation (#3055).
Improved the implementation of Dragonbox, the algorithm used for the default floating-point formatting (#2984). Thanks @jk-jeon (Junekey Jeon).
Fixed issues with floating-point formatting on exotic platforms.
Improved the implementation of chrono formatting (#3010). Thanks @phprus (Vladislav Shchapov).
Improved documentation (#2966, #3009, #3020, #3037). Thanks @mwinterb, @jcelerier (Jean-Michaël Celerier) and @remiburtin (Rémi Burtin).
Improved build configuration (#2991, #2995, #3004, #3007, #3040). Thanks @dimztimz (Dimitrij Mijoski) and @hwhsu1231 (Haowei Hsu).
Fixed various warnings and compilation issues (#2969, #2971, #2975, #2982, #2985, #2988, #3000, #3006, #3014, #3015, #3021, #3023, #3024, #3029, #3043, #3052, #3053, #3054). Thanks @h-friederich (Hannes Friederich), @dimztimz (Dimitrij Mijoski), @olupton (Olli Lupton), @bernhardmgruber (Bernhard Manfred Gruber), @phprus (Vladislav Shchapov).
Full Changelog: https://github.com/fmtlib/fmt/compare/9.0.0...9.1.0
Switched to the internal floating point formatter for all decimal presentation formats. In particular this results in consistent rounding on all platforms and removing the s[n]printf
fallback for decimal FP formatting.
Compile-time floating point formatting no longer requires the header-only mode. For example (godbolt):
#include <array>
#include <fmt/compile.h>
consteval auto compile_time_dtoa(double 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_dtoa(0.42);
works with the default settings.
Improved the implementation of Dragonbox, the algorithm used for the default floating-point formatting (#2713, #2750). Thanks @jk-jeon (Junekey Jeon).
Made fmt::to_string
work with __float128
. This uses the internal FP formatter and works even on system without __float128
support in [s]printf
.
Disabled automatic std::ostream
insertion operator (operator<<
) discovery when fmt/ostream.h
is included to prevent ODR violations. You can get the old behavior by defining FMT_DEPRECATED_OSTREAM
but this will be removed in the next major release. Use fmt::streamed
or fmt::ostream_formatter
to enable formatting via std::ostream
instead.
Added fmt::ostream_formatter
that can be used to write formatter
specializations that perform formatting via std::ostream
. For example (godbolt):
#include <fmt/ostream.h>
struct date {
int year, month, day;
friend std::ostream& operator<<(std::ostream& os, const date& d) {
return os << d.year << '-' << d.month << '-' << d.day;
}
};
template <> struct fmt::formatter<date> : ostream_formatter {};
std::string s = fmt::format("The date is {}", date{2012, 12, 9});
// s == "The date is 2012-12-9"
Added the fmt::streamed
function that takes an object and formats it via std::ostream
. For example (godbolt):
#include <thread>
#include <fmt/ostream.h>
int main() {
fmt::print("Current thread id: {}\n",
fmt::streamed(std::this_thread::get_id()));
}
Note that fmt/std.h
provides a formatter
specialization for std::thread::id
so you don't need to format it via std::ostream
.
Deprecated implicit conversions of unscoped enums to integers for consistency with scoped enums.
Added an argument-dependent lookup based format_as
extension API to simplify formatting of enums.
Added experimental std::variant
formatting support (#2941). For example (godbolt):
#include <variant>
#include <fmt/std.h>
int main() {
auto v = std::variant<int, std::string>(42);
fmt::print("{}\n", v);
}
prints:
variant(42)
Thanks @jehelset.
Added experimental std::filesystem::path
formatting support (#2865, #2902, #2917, #2918). For example (godbolt):
#include <filesystem>
#include <fmt/std.h>
int main() {
fmt::print("There is no place like {}.", std::filesystem::path("/home"));
}
prints:
There is no place like "/home".
Thanks @phprus (Vladislav Shchapov).
Added a std::thread::id
formatter to fmt/std.h
. For example (godbolt):
#include <thread>
#include <fmt/std.h>
int main() {
fmt::print("Current thread id: {}\n", std::this_thread::get_id());
}
Added fmt::styled
that applies a text style to an individual argument (#2793). For example (godbolt):
#include <fmt/chrono.h>
#include <fmt/color.h>
int main() {
auto now = std::chrono::system_clock::now();
fmt::print(
"[{}] {}: {}\n",
fmt::styled(now, fmt::emphasis::bold),
fmt::styled("error", fg(fmt::color::red)),
"something went wrong");
}
prints
Thanks @rbrugo (Riccardo Brugo).
Made fmt::print
overload for text styles correctly handle UTF-8 (#2681, #2701). Thanks @AlexGuteniev (Alex Guteniev).
Fixed Unicode handling when writing to an ostream.
Added support for nested specifiers to range formatting (#2673). For example (godbolt):
#include <vector>
#include <fmt/ranges.h>
int main() {
fmt::print("{::#x}\n", std::vector{10, 20, 30});
}
prints [0xa, 0x14, 0x1e]
.
Thanks @BRevzin (Barry Revzin).
Implemented escaping of wide strings in ranges (#2904). Thanks @phprus (Vladislav Shchapov).
Added support for ranges with begin
/ end
found via the argument-dependent lookup (#2807). Thanks @rbrugo (Riccardo Brugo).
Fixed formatting of certain kinds of ranges of ranges (#2787). Thanks @BRevzin (Barry Revzin).
Fixed handling of maps with element types other than std::pair
(#2944). Thanks @BrukerJWD (Jonathan W).
Made tuple formatter enabled only if elements are formattable (#2939, #2940). Thanks @jehelset.
Made fmt::join
compatible with format string compilation (#2719, #2720). Thanks @phprus (Vladislav Shchapov).
Made compile-time checks work with named arguments of custom types and std::ostream
print
overloads (#2816, #2817, #2819). Thanks @timsong-cpp.
Removed make_args_checked
because it is no longer needed for compile-time checks (#2760). Thanks @phprus (Vladislav Shchapov).
Removed the following deprecated APIs: _format
, arg_join
, the format_to
overload that takes a memory buffer, [v]fprintf
that takes an ostream
.
Removed the deprecated implicit conversion of [const] signed char*
and [const] unsigned char*
to C strings.
Removed the deprecated fmt/locale.h
.
Replaced the deprecated fileno()
with descriptor()
in buffered_file
.
Moved to_string_view
to the detail
namespace since it's an implementation detail.
Made access mode of a created file consistent with fopen
by setting S_IWGRP
and S_IWOTH
(#2733). Thanks @arogge (Andreas Rogge).
Removed a redundant buffer resize when formatting to std::ostream
(#2842, #2843). Thanks @jcelerier (Jean-Michaël Celerier).
Made precision computation for strings consistent with width (#2888).
Fixed handling of locale separators in floating point formatting (#2830).
Made sign specifiers work with __int128_t
(#2773).
Improved support for systems such as CHERI with extra data stored in pointers (#2932). Thanks @davidchisnall (David Chisnall).
Improved documentation (#2706, #2712, #2789, #2803, #2805, #2815, #2924). Thanks @BRevzin (Barry Revzin), @Pokechu22, @setoye (Alta), @rtobar, @rbrugo (Riccardo Brugo), @anoonD (cre), @leha-bot (Alex).
Improved build configuration (#2766, #2772, #2836, #2852, #2907, #2913, #2914). Thanks @kambala-decapitator (Andrey Filipenkov), @mattiasljungstrom (Mattias Ljungström), @kieselnb (Nick Kiesel), @nathannaveen, @Vertexwahn.
Fixed various warnings and compilation issues (#2408, #2507, #2697, #2715, #2717, #2722, #2724, #2725, #2726, #2728, #2732, #2738, #2742, #2744, #2745, #2746, #2754, #2755, #2757, #2758, #2761, #2762, #2763, #2765, #2769, #2770, #2771, #2777, #2779, #2782, #2783, #2794, #2796, #2797, #2801, #2802, #2808, #2818, #2819, #2829, #2835, #2848, #2860, #2861, #2882, #2886, #2891, #2892, #2895, #2896, #2903, #2906, #2908, #2909, #2920, #2922, #2927, #2929, #2936, #2937, #2938, #2951, #2954, #2957, #2958, #2960). Thanks @matrackif @Tobi823 (Tobias Hellmann), @ivan-volnov (Ivan Volnov), @VasiliPupkin256, @federico-busato (Federico), @barcharcraz (Charlie Barto), @jk-jeon (Junekey Jeon), @HazardyKnusperkeks (Björn Schäpers), @dalboris (Boris Dalstein), @seanm (Sean McBride), @gsjaardema (Greg Sjaardema), @timsong-cpp, @seanm (Sean McBride), @frithrah, @chronoxor (Ivan Shynkarenka), @Agga, @madmaxoft (Mattes D), @JurajX (Juraj), @phprus (Vladislav Shchapov), @Dani-Hub (Daniel Krügler).
make_args_checked
with make_format_args
by @phprus in https://github.com/fmtlib/fmt/pull/2760
-Wliteral-range
warning by @phprus in https://github.com/fmtlib/fmt/pull/2779
styled
in documentation by @rbrugo in https://github.com/fmtlib/fmt/pull/2805
begin
/end
by @rbrugo in https://github.com/fmtlib/fmt/pull/2807
/source-charset:utf-8
compile option. by @phprus in https://github.com/fmtlib/fmt/pull/2938
Full Changelog: https://github.com/fmtlib/fmt/compare/8.1.1...9.0.0
Restored ABI compatibility with version 8.0.x (#2695, #2696). Thanks @saraedum (Julian Rüth).
Fixed chrono formatting on big endian systems (#2698, #2699). Thanks @phprus (Vladislav Shchapov) and @xvitaly (Vitaly Zaitsev).
Fixed a linkage error with mingw (#2691, #2692). Thanks @rbberger (Richard Berger).
Optimized chrono formatting (#2500, #2537, #2541, #2544, #2550, #2551, #2576, #2577, #2586, #2591, #2594, #2602, #2617, #2628, #2633, #2670, #2671).
Processing of some specifiers such as %z
and %Y
is now up to 10-20 times faster, for example on GCC 11 with libstdc++:
----------------------------------------------------------------------------
Benchmark Before After
----------------------------------------------------------------------------
FMTFormatter_z 261 ns 26.3 ns
FMTFormatterCompile_z 246 ns 11.6 ns
FMTFormatter_Y 263 ns 26.1 ns
FMTFormatterCompile_Y 244 ns 10.5 ns
----------------------------------------------------------------------------
Thanks @phprus (Vladislav Shchapov) and @toughengineer (Pavel Novikov).
Implemented subsecond formatting for chrono durations (#2623). For example (godbolt):
#include <fmt/chrono.h>
int main() {
fmt::print("{:%S}", std::chrono::milliseconds(1234));
}
prints "01.234".
Thanks @matrackif.
Fixed handling of precision 0 when formatting chrono durations (#2587, #2588). Thanks @lukester1975.
Fixed an overflow on invalid inputs in the tm
formatter (#2564). Thanks @phprus (Vladislav Shchapov).
Added fmt::group_digits
that formats integers with a non-localized digit separator (comma) for groups of three digits. For example (godbolt):
#include <fmt/format.h>
int main() {
fmt::print("{} dollars", fmt::group_digits(1000000));
}
prints "1,000,000 dollars".
Added support for faint, conceal, reverse and blink text styles (#2394):
https://user-images.githubusercontent.com/576385/147710227-c68f5317-f8fa-42c3-9123-7c4ba3c398cb.mp4
Thanks @benit8 (Benoît Lormeau) and @data-man (Dmitry Atamanov).
Added experimental support for compile-time floating point formatting (#2426, #2470). It is currently limited to the header-only mode. Thanks @alexezeder (Alexey Ochapov).
Added UDL-based named argument support to compile-time format string checks (#2640, #2649). For example (godbolt):
#include <fmt/format.h>
int main() {
using namespace fmt::literals;
fmt::print("{answer:s}", "answer"_a=42);
}
gives a compile-time error on compilers with C++20 consteval
and non-type template parameter support (gcc 10+) because s
is not a valid format specifier for an integer.
Thanks @alexezeder (Alexey Ochapov).
Implemented escaping of string range elements. For example (godbolt):
#include <fmt/ranges.h>
#include <vector>
int main() {
fmt::print("{}", std::vector<std::string>{"\naan"});
}
is now printed as:
["\naan"]
instead of:
["
aan"]
Switched to JSON-like representation of maps and sets for consistency with Python's str.format
. For example (godbolt):
#include <fmt/ranges.h>
#include <map>
int main() {
fmt::print("{}", std::map<std::string, int>{{"answer", 42}});
}
is now printed as:
{"answer": 42}
Extended fmt::join
to support C++20-only ranges (#2549). Thanks @BRevzin (Barry Revzin).
Optimized handling of non-const-iterable ranges and implemented initial support for non-const-formattable types.
Disabled implicit conversions of scoped enums to integers that was accidentally introduced in earlier versions (#1841).
Deprecated implicit conversion of [const] signed char*
and [const] unsigned char*
to C strings.
Deprecated _format
, a legacy UDL-based format API (#2646). Thanks @alexezeder (Alexey Ochapov).
Marked format
, formatted_size
and to_string
as [[nodiscard]]
(#2612). @0x8000-0000 (Florin Iucha).
Added missing diagnostic when trying to format function and member pointers as well as objects convertible to pointers which is explicitly disallowed (#2598, #2609, #2610). Thanks @AlexGuteniev (Alex Guteniev).
Optimized writing to a contiguous buffer with format_to_n
(#2489). Thanks @Roman-Koshelev.
Optimized writing to non-char
buffers (#2477). Thanks @Roman-Koshelev.
Decimal point is now localized when using the L
specifier.
Improved floating point formatter implementation (#2498, #2499). Thanks @Roman-Koshelev.
Fixed handling of very large precision in fixed format (#2616).
Made a table of cached powers used in FP formatting static (#2509). Thanks @jk-jeon (Junekey Jeon).
Resolved a lookup ambiguity with C++20 format-related functions due to ADL (#2639, #2641). Thanks @mkurdej (Marek Kurdej).
Removed unnecessary inline namespace qualification (#2642, #2643). Thanks @mkurdej (Marek Kurdej).
Implemented argument forwarding in format_to_n
(#2462, #2463). Thanks @owent (WenTao Ou).
Fixed handling of implicit conversions in fmt::to_string
and format string compilation (#2565).
Changed the default access mode of files created by fmt::output_file
to -rw-r--r--
for consistency with fopen
(#2530).
Make fmt::ostream::flush
public (#2435).
Improved C++14/17 attribute detection (#2615). Thanks @AlexGuteniev (Alex Guteniev).
Improved consteval
detection for MSVC (#2559). Thanks @DanielaE (Daniela Engert).
Improved documentation (#2406, #2446, #2493, #2513, #2515, #2522, #2562, #2575, #2606, #2620, #2676). Thanks @sobolevn (Nikita Sobolev), @UnePierre (Max FERGER), @zhsj, @phprus (Vladislav Shchapov), @ericcurtin (Eric Curtin), @Lounarok.
Improved fuzzers and added a fuzzer for chrono timepoint formatting (#2461, #2469). @pauldreik (Paul Dreik),
Added the FMT_SYSTEM_HEADERS
CMake option setting which marks {fmt}'s headers as system. It can be used to suppress warnings (#2644, #2651). Thanks @alexezeder (Alexey Ochapov).
Added the Bazel build system support (#2505, #2516). Thanks @Vertexwahn.
Improved build configuration and tests (#2437, #2558, #2648, #2650, #2663, #2677). Thanks @DanielaE (Daniela Engert), @alexezeder (Alexey Ochapov), @phprus (Vladislav Shchapov).
Fixed various warnings and compilation issues (#2353, #2356, #2399, #2408, #2414, #2427, #2432, #2442, #2434, #2439, #2447, #2450, #2455, #2465, #2472, #2474, #2476, #2478, #2479, #2481, #2482, #2483, #2490, #2491, #2510, #2518, #2528, #2529, #2539, #2540, #2545, #2555, #2557, #2570, #2573, #2582, #2605, #2611, #2647, #2627, #2630, #2635, #2638, #2653, #2654, #2661, #2664, #2684). Thanks @DanielaE (Daniela Engert), @mwinterb, @cdacamar (Cameron DaCamara), @TrebledJ (Johnathan), @bodomartin (brm), @cquammen (Cory Quammen), @white238 (Chris White), @mmarkeloff (Max), @palacaze (Pierre-Antoine Lacaze), @jcelerier (Jean-Michaël Celerier), @mborn-adi (Mathias Born), @BrukerJWD (Jonathan W), @spyridon97 (Spiros Tsalikis), @phprus (Vladislav Shchapov), @oliverlee (Oliver Lee), @joshessman-llnl (Josh Essman), @akohlmey (Axel Kohlmeyer), @timkalu, @olupton (Olli Lupton), @Acretock, @alexezeder (Alexey Ochapov), @andrewcorrigan (Andrew Corrigan), @lucpelletier, @HazardyKnusperkeks (Björn Schäpers).
Fixed the version number in the inline namespace (#2374).
Added a missing presentation type check for std::string
(#2402).
Fixed a linkage error when mixing code built with clang and gcc (#2377).
Fixed documentation issues (#2396, #2403, #2406). Thanks @mkurdej (Marek Kurdej).
Removed dead code in FP formatter ( #2398). Thanks @javierhonduco (Javier Honduvilla Coto).
Fixed various warnings and compilation issues (#2351, #2359, #2365, #2368, #2370, #2376, #2381, #2382, #2386, #2389, #2395, #2397, #2400 #2401, #2407). Thanks @zx2c4 (Jason A. Donenfeld), @AidanSun05 (Aidan Sun), @mattiasljungstrom (Mattias Ljungström), @joemmett (Jonathan Emmett), @erengy (Eren Okka), @patlkli (Patrick Geltinger), @gsjaardema (Greg Sjaardema), @phprus (Vladislav Shchapov).