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