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