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