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