README.rst (20274B)
1 .. image:: https://user-images.githubusercontent.com/ 2 576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png 3 :width: 25% 4 :alt: {fmt} 5 6 .. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg 7 :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux 8 9 .. image:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg 10 :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos 11 12 .. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg 13 :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows 14 15 .. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg 16 :alt: fmt is continuously fuzzed at oss-fuzz 17 :target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\ 18 colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\ 19 Summary&q=proj%3Dfmt&can=1 20 21 .. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg 22 :alt: Ask questions at StackOverflow with the tag fmt 23 :target: https://stackoverflow.com/questions/tagged/fmt 24 25 .. image:: https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge 26 :target: https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt 27 28 **{fmt}** is an open-source formatting library providing a fast and safe 29 alternative to C stdio and C++ iostreams. 30 31 If you like this project, please consider donating to one of the funds that 32 help victims of the war in Ukraine: https://www.stopputin.net/. 33 34 `Documentation <https://fmt.dev>`__ 35 36 `Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>`__ 37 38 Q&A: ask questions on `StackOverflow with the tag fmt 39 <https://stackoverflow.com/questions/tagged/fmt>`_. 40 41 Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_. 42 43 Features 44 -------- 45 46 * Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments 47 for localization 48 * Implementation of `C++20 std::format 49 <https://en.cppreference.com/w/cpp/utility/format>`__ 50 * `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's 51 `format <https://docs.python.org/3/library/stdtypes.html#str.format>`_ 52 * Fast IEEE 754 floating-point formatter with correct rounding, shortness and 53 round-trip guarantees using the `Dragonbox <https://github.com/jk-jeon/dragonbox>`_ 54 algorithm 55 * Portable Unicode support 56 * Safe `printf implementation 57 <https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX 58 extension for positional arguments 59 * Extensibility: `support for user-defined types 60 <https://fmt.dev/latest/api.html#formatting-user-defined-types>`_ 61 * High performance: faster than common standard library implementations of 62 ``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_ 63 and `Converting a hundred million integers to strings per second 64 <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_ 65 * Small code size both in terms of source code with the minimum configuration 66 consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``, 67 and compiled code; see `Compile time and code bloat`_ 68 * Reliability: the library has an extensive set of `tests 69 <https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed 70 <https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20 71 Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>`_ 72 * Safety: the library is fully type-safe, errors in format strings can be 73 reported at compile time, automatic memory management prevents buffer overflow 74 errors 75 * Ease of use: small self-contained code base, no external dependencies, 76 permissive MIT `license 77 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_ 78 * `Portability <https://fmt.dev/latest/index.html#portability>`_ with 79 consistent output across platforms and support for older compilers 80 * Clean warning-free codebase even on high warning levels such as 81 ``-Wall -Wextra -pedantic`` 82 * Locale independence by default 83 * Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro 84 85 See the `documentation <https://fmt.dev>`_ for more details. 86 87 Examples 88 -------- 89 90 **Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_) 91 92 .. code:: c++ 93 94 #include <fmt/core.h> 95 96 int main() { 97 fmt::print("Hello, world!\n"); 98 } 99 100 **Format a string** (`run <https://godbolt.org/z/oK8h33>`_) 101 102 .. code:: c++ 103 104 std::string s = fmt::format("The answer is {}.", 42); 105 // s == "The answer is 42." 106 107 **Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_) 108 109 .. code:: c++ 110 111 std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy"); 112 // s == "I'd rather be happy than right." 113 114 **Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_) 115 116 .. code:: c++ 117 118 #include <fmt/chrono.h> 119 120 int main() { 121 using namespace std::literals::chrono_literals; 122 fmt::print("Default format: {} {}\n", 42s, 100ms); 123 fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s); 124 } 125 126 Output:: 127 128 Default format: 42s 100ms 129 strftime-like format: 03:15:30 130 131 **Print a container** (`run <https://godbolt.org/z/MxM1YqjE7>`_) 132 133 .. code:: c++ 134 135 #include <vector> 136 #include <fmt/ranges.h> 137 138 int main() { 139 std::vector<int> v = {1, 2, 3}; 140 fmt::print("{}\n", v); 141 } 142 143 Output:: 144 145 [1, 2, 3] 146 147 **Check a format string at compile time** 148 149 .. code:: c++ 150 151 std::string s = fmt::format("{:d}", "I am not a number"); 152 153 This gives a compile-time error in C++20 because ``d`` is an invalid format 154 specifier for a string. 155 156 **Write a file from a single thread** 157 158 .. code:: c++ 159 160 #include <fmt/os.h> 161 162 int main() { 163 auto out = fmt::output_file("guide.txt"); 164 out.print("Don't {}", "Panic"); 165 } 166 167 This can be `5 to 9 times faster than fprintf 168 <http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_. 169 170 **Print with colors and text styles** 171 172 .. code:: c++ 173 174 #include <fmt/color.h> 175 176 int main() { 177 fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, 178 "Hello, {}!\n", "world"); 179 fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | 180 fmt::emphasis::underline, "Hello, {}!\n", "мир"); 181 fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, 182 "Hello, {}!\n", "世界"); 183 } 184 185 Output on a modern terminal: 186 187 .. image:: https://user-images.githubusercontent.com/ 188 576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png 189 190 Benchmarks 191 ---------- 192 193 Speed tests 194 ~~~~~~~~~~~ 195 196 ================= ============= =========== 197 Library Method Run Time, s 198 ================= ============= =========== 199 libc printf 0.91 200 libc++ std::ostream 2.49 201 {fmt} 9.1 fmt::print 0.74 202 Boost Format 1.80 boost::format 6.26 203 Folly Format folly::format 1.87 204 ================= ============= =========== 205 206 {fmt} is the fastest of the benchmarked methods, ~20% faster than ``printf``. 207 208 The above results were generated by building ``tinyformat_test.cpp`` on macOS 209 12.6.1 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the 210 best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` 211 or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for 212 further details refer to the `source 213 <https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_. 214 215 {fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on 216 IEEE754 ``float`` and ``double`` formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_) 217 and faster than `double-conversion <https://github.com/google/double-conversion>`_ and 218 `ryu <https://github.com/ulfjack/ryu>`_: 219 220 .. image:: https://user-images.githubusercontent.com/576385/ 221 95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png 222 :target: https://fmt.dev/unknown_mac64_clang12.0.html 223 224 Compile time and code bloat 225 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 227 The script `bloat-test.py 228 <https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_ 229 from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_ 230 tests compile time and code bloat for nontrivial projects. 231 It generates 100 translation units and uses ``printf()`` or its alternative 232 five times in each to simulate a medium-sized project. The resulting 233 executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), 234 macOS Sierra, best of three) is shown in the following tables. 235 236 **Optimized build (-O3)** 237 238 ============= =============== ==================== ================== 239 Method Compile Time, s Executable size, KiB Stripped size, KiB 240 ============= =============== ==================== ================== 241 printf 2.6 29 26 242 printf+string 16.4 29 26 243 iostreams 31.1 59 55 244 {fmt} 19.0 37 34 245 Boost Format 91.9 226 203 246 Folly Format 115.7 101 88 247 ============= =============== ==================== ================== 248 249 As you can see, {fmt} has 60% less overhead in terms of resulting binary code 250 size compared to iostreams and comes pretty close to ``printf``. Boost Format 251 and Folly Format have the largest overheads. 252 253 ``printf+string`` is the same as ``printf`` but with an extra ``<string>`` 254 include to measure the overhead of the latter. 255 256 **Non-optimized build** 257 258 ============= =============== ==================== ================== 259 Method Compile Time, s Executable size, KiB Stripped size, KiB 260 ============= =============== ==================== ================== 261 printf 2.2 33 30 262 printf+string 16.0 33 30 263 iostreams 28.3 56 52 264 {fmt} 18.2 59 50 265 Boost Format 54.1 365 303 266 Folly Format 79.9 445 430 267 ============= =============== ==================== ================== 268 269 ``libc``, ``lib(std)c++``, and ``libfmt`` are all linked as shared libraries to 270 compare formatting function overhead only. Boost Format is a 271 header-only library so it doesn't provide any linkage options. 272 273 Running the tests 274 ~~~~~~~~~~~~~~~~~ 275 276 Please refer to `Building the library`__ for instructions on how to build 277 the library and run the unit tests. 278 279 __ https://fmt.dev/latest/usage.html#building-the-library 280 281 Benchmarks reside in a separate repository, 282 `format-benchmarks <https://github.com/fmtlib/format-benchmark>`_, 283 so to run the benchmarks you first need to clone this repository and 284 generate Makefiles with CMake:: 285 286 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git 287 $ cd format-benchmark 288 $ cmake . 289 290 Then you can run the speed test:: 291 292 $ make speed-test 293 294 or the bloat test:: 295 296 $ make bloat-test 297 298 Migrating code 299 -------------- 300 301 `clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`_ v17 (not yet 302 released) provides the `modernize-use-std-print 303 <https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html>`_ 304 check that is capable of converting occurrences of ``printf`` and 305 ``fprintf`` to ``fmt::print`` if configured to do so. (By default it 306 converts to ``std::print``.) 307 308 Projects using this library 309 --------------------------- 310 311 * `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform 312 real-time strategy game 313 314 * `AMPL/MP <https://github.com/ampl/mp>`_: 315 an open-source library for mathematical programming 316 317 * `Aseprite <https://github.com/aseprite/aseprite>`_: 318 animated sprite editor & pixel art tool 319 320 * `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft 321 operations suite 322 323 * `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform 324 325 * `Celestia <https://celestia.space/>`_: real-time 3D visualization of space 326 327 * `Ceph <https://ceph.com/>`_: a scalable distributed storage system 328 329 * `ccache <https://ccache.dev/>`_: a compiler cache 330 331 * `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: an analytical database 332 management system 333 334 * `Contour <https://github.com/contour-terminal/contour/>`_: a modern terminal emulator 335 336 * `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater 337 vehicle 338 339 * `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox 340 for nonlinear dynamical systems (MIT) 341 342 * `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus 343 (Lyft) 344 345 * `FiveM <https://fivem.net/>`_: a modification framework for GTA V 346 347 * `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style 348 logging library with latency in nanoseconds 349 350 * `Folly <https://github.com/facebook/folly>`_: Facebook open-source library 351 352 * `GemRB <https://gemrb.org/>`_: a portable open-source implementation of 353 Bioware’s Infinity Engine 354 355 * `Grand Mountain Adventure 356 <https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_: 357 a beautiful open-world ski & snowboarding game 358 359 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_: 360 Player vs Player Gaming Network with tweaks 361 362 * `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server 363 engine 364 365 * `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows 366 367 * `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software 368 369 * `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node 370 371 * `libunicode <https://github.com/contour-terminal/libunicode/>`_: a modern C++17 Unicode library 372 373 * `MariaDB <https://mariadb.org/>`_: relational database management system 374 375 * `Microsoft Verona <https://github.com/microsoft/verona>`_: 376 research programming language for concurrent ownership 377 378 * `MongoDB <https://mongodb.com/>`_: distributed document database 379 380 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to 381 generate randomized datasets 382 383 * `OpenSpace <https://openspaceproject.com/>`_: an open-source 384 astrovisualization framework 385 386 * `PenUltima Online (POL) <https://www.polserver.com/>`_: 387 an MMO server, compatible with most Ultima Online clients 388 389 * `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine 390 learning library 391 392 * `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance, 393 associative database 394 395 * `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library 396 397 * `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify 398 navigation, and executing complex multi-line terminal command sequences 399 400 * `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster 401 proxy 402 403 * `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement 404 for mission-critical systems written in C++ 405 406 * `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client 407 library 408 409 * `Salesforce Analytics Cloud 410 <https://www.salesforce.com/analytics-cloud/overview/>`_: 411 business intelligence software 412 413 * `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store 414 that can handle 1 million transactions per second on a single server 415 416 * `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++ 417 framework for high-performance server applications on modern hardware 418 419 * `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library 420 421 * `Stellar <https://www.stellar.org/>`_: financial platform 422 423 * `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator 424 425 * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source 426 MMORPG framework 427 428 * `🐙 userver framework <https://userver.tech/>`_: open-source asynchronous 429 framework with a rich set of abstractions and database drivers 430 431 * `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows 432 terminal 433 434 `More... <https://github.com/search?q=fmtlib&type=Code>`_ 435 436 If you are aware of other projects using this library, please let me know 437 by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an 438 `issue <https://github.com/fmtlib/fmt/issues>`_. 439 440 Motivation 441 ---------- 442 443 So why yet another formatting library? 444 445 There are plenty of methods for doing this task, from standard ones like 446 the printf family of function and iostreams to Boost Format and FastFormat 447 libraries. The reason for creating a new library is that every existing 448 solution that I found either had serious issues or didn't provide 449 all the features I needed. 450 451 printf 452 ~~~~~~ 453 454 The good thing about ``printf`` is that it is pretty fast and readily available 455 being a part of the C standard library. The main drawback is that it 456 doesn't support user-defined types. ``printf`` also has safety issues although 457 they are somewhat mitigated with `__attribute__ ((format (printf, ...)) 458 <https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC. 459 There is a POSIX extension that adds positional arguments required for 460 `i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_ 461 to ``printf`` but it is not a part of C99 and may not be available on some 462 platforms. 463 464 iostreams 465 ~~~~~~~~~ 466 467 The main issue with iostreams is best illustrated with an example: 468 469 .. code:: c++ 470 471 std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n"; 472 473 which is a lot of typing compared to printf: 474 475 .. code:: c++ 476 477 printf("%.2f\n", 1.23456); 478 479 Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams 480 don't support positional arguments by design. 481 482 The good part is that iostreams support user-defined types and are safe although 483 error handling is awkward. 484 485 Boost Format 486 ~~~~~~~~~~~~ 487 488 This is a very powerful library that supports both ``printf``-like format 489 strings and positional arguments. Its main drawback is performance. According to 490 various benchmarks, it is much slower than other methods considered here. Boost 491 Format also has excessive build times and severe code bloat issues (see 492 `Benchmarks`_). 493 494 FastFormat 495 ~~~~~~~~~~ 496 497 This is an interesting library that is fast, safe, and has positional arguments. 498 However, it has significant limitations, citing its author: 499 500 Three features that have no hope of being accommodated within the 501 current design are: 502 503 * Leading zeros (or any other non-space padding) 504 * Octal/hexadecimal encoding 505 * Runtime width/alignment specification 506 507 It is also quite big and has a heavy dependency, STLSoft, which might be too 508 restrictive for using it in some projects. 509 510 Boost Spirit.Karma 511 ~~~~~~~~~~~~~~~~~~ 512 513 This is not a formatting library but I decided to include it here for 514 completeness. As iostreams, it suffers from the problem of mixing verbatim text 515 with arguments. The library is pretty fast, but slower on integer formatting 516 than ``fmt::format_to`` with format string compilation on Karma's own benchmark, 517 see `Converting a hundred million integers to strings per second 518 <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_. 519 520 License 521 ------- 522 523 {fmt} is distributed under the MIT `license 524 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_. 525 526 Documentation License 527 --------------------- 528 529 The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_ 530 section in the documentation is based on the one from Python `string module 531 documentation <https://docs.python.org/3/library/string.html#module-string>`_. 532 For this reason, the documentation is distributed under the Python Software 533 Foundation license available in `doc/python-license.txt 534 <https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_. 535 It only applies if you distribute the documentation of {fmt}. 536 537 Maintainers 538 ----------- 539 540 The {fmt} library is maintained by Victor Zverovich (`vitaut 541 <https://github.com/vitaut>`_) with contributions from many other people. 542 See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and 543 `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names. 544 Let us know if your contribution is not listed or mentioned incorrectly and 545 we'll make it right.