comparison dep/fmt/README.md @ 343:1faa72660932

*: transfer back to cmake from autotools autotools just made lots of things more complicated than they should have and many things broke (i.e. translations)
author Paper <paper@paper.us.eu.org>
date Thu, 20 Jun 2024 05:56:06 -0400
parents
children
comparison
equal deleted inserted replaced
342:adb79bdde329 343:1faa72660932
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
11 alternative to C stdio and C++ iostreams.
12
13 If you like this project, please consider donating to one of the funds
14 that 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
20 Q&A: ask questions on [StackOverflow with the tag
21 fmt](https://stackoverflow.com/questions/tagged/fmt).
22
23 Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
24
25 # Features
26
27 - Simple [format API](https://fmt.dev/latest/api.html) 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.html) 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.html#printf-formatting)
41 including the POSIX extension for positional arguments
42 - Extensibility: [support for user-defined
43 types](https://fmt.dev/latest/api.html#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.rst)
62 - [Portability](https://fmt.dev/latest/index.html#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
70 See 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
79 int main() {
80 fmt::print("Hello, world!\n");
81 }
82 ```
83
84 **Format a string** ([run](https://godbolt.org/z/oK8h33))
85
86 ``` c++
87 std::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++
95 std::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
104 int 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
111 Output:
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
122 int main() {
123 std::vector<int> v = {1, 2, 3};
124 fmt::print("{}\n", v);
125 }
126 ```
127
128 Output:
129
130 [1, 2, 3]
131
132 **Check a format string at compile time**
133
134 ``` c++
135 std::string s = fmt::format("{:d}", "I am not a number");
136 ```
137
138 This gives a compile-time error in C++20 because `d` is an invalid
139 format specifier for a string.
140
141 **Write a file from a single thread**
142
143 ``` c++
144 #include <fmt/os.h>
145
146 int main() {
147 auto out = fmt::output_file("guide.txt");
148 out.print("Don't {}", "Panic");
149 }
150 ```
151
152 This can be [5 to 9 times faster than
153 fprintf](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
160 int 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
170 Output 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
189 The above results were generated by building `tinyformat_test.cpp` on
190 macOS 12.6.1 with `clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT`, and
191 taking 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
193 times 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
197 IEEE754 `float` and `double` formatting
198 ([dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark)) and faster
199 than [double-conversion](https://github.com/google/double-conversion)
200 and [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
206 The script
207 [bloat-test.py](https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py)
208 from [format-benchmark](https://github.com/fmtlib/format-benchmark)
209 tests compile time and code bloat for nontrivial projects. It generates
210 100 translation units and uses `printf()` or its alternative five times
211 in each to simulate a medium-sized project. The resulting executable
212 size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), macOS
213 Sierra, best of three) is shown in the following tables.
214
215 **Optimized build (-O3)**
216
217 | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
218 |---------------|-----------------|----------------------|--------------------|
219 | printf | 2.6 | 29 | 26 |
220 | printf+string | 16.4 | 29 | 26 |
221 | iostreams | 31.1 | 59 | 55 |
222 | {fmt} | 19.0 | 37 | 34 |
223 | Boost Format | 91.9 | 226 | 203 |
224 | Folly Format | 115.7 | 101 | 88 |
225
226 As you can see, {fmt} has 60% less overhead in terms of resulting binary
227 code size compared to iostreams and comes pretty close to `printf`.
228 Boost Format and Folly Format have the largest overheads.
229
230 `printf+string` is the same as `printf` but with an extra `<string>`
231 include to measure the overhead of the latter.
232
233 **Non-optimized build**
234
235 | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
236 |---------------|-----------------|----------------------|--------------------|
237 | printf | 2.2 | 33 | 30 |
238 | printf+string | 16.0 | 33 | 30 |
239 | iostreams | 28.3 | 56 | 52 |
240 | {fmt} | 18.2 | 59 | 50 |
241 | Boost Format | 54.1 | 365 | 303 |
242 | Folly Format | 79.9 | 445 | 430 |
243
244 `libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
245 to compare formatting function overhead only. Boost Format is a
246 header-only library so it doesn\'t provide any linkage options.
247
248 ## Running the tests
249
250 Please refer to [Building the
251 library](https://fmt.dev/latest/usage.html#building-the-library) for
252 instructions on how to build the library and run the unit tests.
253
254 Benchmarks reside in a separate repository,
255 [format-benchmarks](https://github.com/fmtlib/format-benchmark), so to
256 run the benchmarks you first need to clone this repository and generate
257 Makefiles with CMake:
258
259 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
260 $ cd format-benchmark
261 $ cmake .
262
263 Then you can run the speed test:
264
265 $ make speed-test
266
267 or the bloat test:
268
269 $ make bloat-test
270
271 # Migrating code
272
273 [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v17 (not yet
274 released) provides the
275 [modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
276 check that is capable of converting occurrences of `printf` and
277 `fprintf` to `fmt::print` if configured to do so. (By default it
278 converts to `std::print`.)
279
280 # Notable projects using this library
281
282 - [0 A.D.](https://play0ad.com/): a free, open-source, cross-platform
283 real-time strategy game
284 - [AMPL/MP](https://github.com/ampl/mp): an open-source library for
285 mathematical programming
286 - [Apple's FoundationDB](https://github.com/apple/foundationdb): an open-source,
287 distributed, transactional key-value store
288 - [Aseprite](https://github.com/aseprite/aseprite): animated sprite
289 editor & pixel art tool
290 - [AvioBook](https://www.aviobook.aero/en): a comprehensive aircraft
291 operations suite
292 - [Blizzard Battle.net](https://battle.net/): an online gaming
293 platform
294 - [Celestia](https://celestia.space/): real-time 3D visualization of
295 space
296 - [Ceph](https://ceph.com/): a scalable distributed storage system
297 - [ccache](https://ccache.dev/): a compiler cache
298 - [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
299 analytical database management system
300 - [Contour](https://github.com/contour-terminal/contour/): a modern
301 terminal emulator
302 - [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
303 underwater vehicle
304 - [Drake](https://drake.mit.edu/): a planning, control, and analysis
305 toolbox for nonlinear dynamical systems (MIT)
306 - [Envoy](https://lyft.github.io/envoy/): C++ L7 proxy and
307 communication bus (Lyft)
308 - [FiveM](https://fivem.net/): a modification framework for GTA V
309 - [fmtlog](https://github.com/MengRao/fmtlog): a performant
310 fmtlib-style logging library with latency in nanoseconds
311 - [Folly](https://github.com/facebook/folly): Facebook open-source
312 library
313 - [GemRB](https://gemrb.org/): a portable open-source implementation
314 of Bioware's Infinity Engine
315 - [Grand Mountain
316 Adventure](https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/):
317 a beautiful open-world ski & snowboarding game
318 - [HarpyWar/pvpgn](https://github.com/pvpgn/pvpgn-server): Player vs
319 Player Gaming Network with tweaks
320 - [KBEngine](https://github.com/kbengine/kbengine): an open-source
321 MMOG server engine
322 - [Keypirinha](https://keypirinha.com/): a semantic launcher for
323 Windows
324 - [Kodi](https://kodi.tv/) (formerly xbmc): home theater software
325 - [Knuth](https://kth.cash/): high-performance Bitcoin full-node
326 - [libunicode](https://github.com/contour-terminal/libunicode/): a
327 modern C++17 Unicode library
328 - [MariaDB](https://mariadb.org/): relational database management
329 system
330 - [Microsoft Verona](https://github.com/microsoft/verona): research
331 programming language for concurrent ownership
332 - [MongoDB](https://mongodb.com/): distributed document database
333 - [MongoDB Smasher](https://github.com/duckie/mongo_smasher): a small
334 tool to generate randomized datasets
335 - [OpenSpace](https://openspaceproject.com/): an open-source
336 astrovisualization framework
337 - [PenUltima Online (POL)](https://www.polserver.com/): an MMO server,
338 compatible with most Ultima Online clients
339 - [PyTorch](https://github.com/pytorch/pytorch): an open-source
340 machine learning library
341 - [quasardb](https://www.quasardb.net/): a distributed,
342 high-performance, associative database
343 - [Quill](https://github.com/odygrd/quill): asynchronous low-latency
344 logging library
345 - [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
346 simplify navigation, and executing complex multi-line terminal
347 command sequences
348 - [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
349 cluster proxy
350 - [redpanda](https://vectorized.io/redpanda): a 10x faster Kafka®
351 replacement for mission-critical systems written in C++
352 - [rpclib](http://rpclib.net/): a modern C++ msgpack-RPC server and
353 client library
354 - [Salesforce Analytics
355 Cloud](https://www.salesforce.com/analytics-cloud/overview/):
356 business intelligence software
357 - [Scylla](https://www.scylladb.com/): a Cassandra-compatible NoSQL
358 data store that can handle 1 million transactions per second on a
359 single server
360 - [Seastar](http://www.seastar-project.org/): an advanced, open-source
361 C++ framework for high-performance server applications on modern
362 hardware
363 - [spdlog](https://github.com/gabime/spdlog): super fast C++ logging
364 library
365 - [Stellar](https://www.stellar.org/): financial platform
366 - [Touch Surgery](https://www.touchsurgery.com/): surgery simulator
367 - [TrinityCore](https://github.com/TrinityCore/TrinityCore):
368 open-source MMORPG framework
369 - [🐙 userver framework](https://userver.tech/): open-source
370 asynchronous framework with a rich set of abstractions and database
371 drivers
372 - [Windows Terminal](https://github.com/microsoft/terminal): the new
373 Windows terminal
374
375 [More\...](https://github.com/search?q=fmtlib&type=Code)
376
377 If you are aware of other projects using this library, please let me
378 know by [email](mailto:victor.zverovich@gmail.com) or by submitting an
379 [issue](https://github.com/fmtlib/fmt/issues).
380
381 # Motivation
382
383 So why yet another formatting library?
384
385 There are plenty of methods for doing this task, from standard ones like
386 the printf family of function and iostreams to Boost Format and
387 FastFormat libraries. The reason for creating a new library is that
388 every existing solution that I found either had serious issues or
389 didn\'t provide all the features I needed.
390
391 ## printf
392
393 The good thing about `printf` is that it is pretty fast and readily
394 available being a part of the C standard library. The main drawback is
395 that it doesn\'t support user-defined types. `printf` also has safety
396 issues although they are somewhat mitigated with [\_\_attribute\_\_
397 ((format (printf,
398 \...))](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) in
399 GCC. There is a POSIX extension that adds positional arguments required
400 for
401 [i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization)
402 to `printf` but it is not a part of C99 and may not be available on some
403 platforms.
404
405 ## iostreams
406
407 The main issue with iostreams is best illustrated with an example:
408
409 ``` c++
410 std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
411 ```
412
413 which is a lot of typing compared to printf:
414
415 ``` c++
416 printf("%.2f\n", 1.23456);
417 ```
418
419 Matthew Wilson, the author of FastFormat, called this \"chevron hell\".
420 iostreams don\'t support positional arguments by design.
421
422 The good part is that iostreams support user-defined types and are safe
423 although error handling is awkward.
424
425 ## Boost Format
426
427 This is a very powerful library that supports both `printf`-like format
428 strings and positional arguments. Its main drawback is performance.
429 According to various benchmarks, it is much slower than other methods
430 considered here. Boost Format also has excessive build times and severe
431 code bloat issues (see [Benchmarks](#benchmarks)).
432
433 ## FastFormat
434
435 This is an interesting library that is fast, safe, and has positional
436 arguments. However, it has significant limitations, citing its author:
437
438 > Three features that have no hope of being accommodated within the
439 > current design are:
440 >
441 > - Leading zeros (or any other non-space padding)
442 > - Octal/hexadecimal encoding
443 > - Runtime width/alignment specification
444
445 It is also quite big and has a heavy dependency, STLSoft, which might be
446 too restrictive for using it in some projects.
447
448 ## Boost Spirit.Karma
449
450 This is not a formatting library but I decided to include it here for
451 completeness. As iostreams, it suffers from the problem of mixing
452 verbatim text with arguments. The library is pretty fast, but slower on
453 integer formatting than `fmt::format_to` with format string compilation
454 on Karma\'s own benchmark, see [Converting a hundred million integers to
455 strings per
456 second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html).
457
458 # License
459
460 {fmt} is distributed under the MIT
461 [license](https://github.com/fmtlib/fmt/blob/master/LICENSE).
462
463 # Documentation License
464
465 The [Format String Syntax](https://fmt.dev/latest/syntax.html) section
466 in the documentation is based on the one from Python [string module
467 documentation](https://docs.python.org/3/library/string.html#module-string).
468 For this reason, the documentation is distributed under the Python
469 Software Foundation license available in
470 [doc/python-license.txt](https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt).
471 It only applies if you distribute the documentation of {fmt}.
472
473 # Maintainers
474
475 The {fmt} library is maintained by Victor Zverovich
476 ([vitaut](https://github.com/vitaut)) with contributions from many other
477 people. See
478 [Contributors](https://github.com/fmtlib/fmt/graphs/contributors) and
479 [Releases](https://github.com/fmtlib/fmt/releases) for some of the
480 names. Let us know if your contribution is not listed or mentioned
481 incorrectly and we\'ll make it right.
482
483 # Security Policy
484
485 To report a security issue, please disclose it at [security
486 advisory](https://github.com/fmtlib/fmt/security/advisories/new).
487
488 This project is maintained by a team of volunteers on a
489 reasonable-effort basis. As such, please give us at least 90 days to
490 work on a fix before public exposure.