xref: /fmt/
Name Date Size

..27-Apr.-20224 KiB

.clang-formatH A D18-Oct.-2021231

.github/H08-Apr.-20224 KiB

.gitignoreH A D18-Oct.-2021397

ChangeLog.rstH A D06-Jul.-2022201.3 KiB

CMakeLists.txtH A D07-Aug.-202213.9 KiB

CONTRIBUTING.mdH A D18-Oct.-2021710

doc/H05-Aug.-20224 KiB

include/fmt/H18-Oct.-20214 KiB

LICENSE.rstH A D18-Oct.-20211.4 KiB

README.rstH A D02-Aug.-202219.1 KiB

src/H01-Jun.-20224 KiB

support/H23-Jul.-20224 KiB

test/H14-Aug.-20224 KiB

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
26alternative to C stdio and C++ iostreams.
27
28If you like this project, please consider donating to one of the funds that
29help 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
35Q&A: ask questions on `StackOverflow with the tag fmt
36<https://stackoverflow.com/questions/tagged/fmt>`_.
37
38Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
39
40Features
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
80See the `documentation <https://fmt.dev>`_ for more details.
81
82Examples
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
121Output::
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
138Output::
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
148This gives a compile-time error in C++20 because ``d`` is an invalid format
149specifier 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
162This 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
180Output on a modern terminal:
181
182.. image:: https://user-images.githubusercontent.com/
183           576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
184
185Benchmarks
186----------
187
188Speed tests
189~~~~~~~~~~~
190
191================= ============= ===========
192Library           Method        Run Time, s
193================= ============= ===========
194libc              printf          1.04
195libc++            std::ostream    3.05
196{fmt} 6.1.1       fmt::print      0.75
197Boost Format 1.67 boost::format   7.24
198Folly Format      folly::format   2.23
199================= ============= ===========
200
201{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``.
202
203The above results were generated by building ``tinyformat_test.cpp`` on macOS
20410.14.6 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
205best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
206or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
207further 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
211floating-point formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
212and 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
219Compile time and code bloat
220~~~~~~~~~~~~~~~~~~~~~~~~~~~
221
222The script `bloat-test.py
223<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
224from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
225tests compile time and code bloat for nontrivial projects.
226It generates 100 translation units and uses ``printf()`` or its alternative
227five times in each to simulate a medium sized project.  The resulting
228executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
229macOS Sierra, best of three) is shown in the following tables.
230
231**Optimized build (-O3)**
232
233============= =============== ==================== ==================
234Method        Compile Time, s Executable size, KiB Stripped size, KiB
235============= =============== ==================== ==================
236printf                    2.6                   29                 26
237printf+string            16.4                   29                 26
238iostreams                31.1                   59                 55
239{fmt}                    19.0                   37                 34
240Boost Format             91.9                  226                203
241Folly Format            115.7                  101                 88
242============= =============== ==================== ==================
243
244As you can see, {fmt} has 60% less overhead in terms of resulting binary code
245size compared to iostreams and comes pretty close to ``printf``. Boost Format
246and Folly Format have the largest overheads.
247
248``printf+string`` is the same as ``printf`` but with extra ``<string>``
249include to measure the overhead of the latter.
250
251**Non-optimized build**
252
253============= =============== ==================== ==================
254Method        Compile Time, s Executable size, KiB Stripped size, KiB
255============= =============== ==================== ==================
256printf                    2.2                   33                 30
257printf+string            16.0                   33                 30
258iostreams                28.3                   56                 52
259{fmt}                    18.2                   59                 50
260Boost Format             54.1                  365                303
261Folly Format             79.9                  445                430
262============= =============== ==================== ==================
263
264``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to
265compare formatting function overhead only. Boost Format is a
266header-only library so it doesn't provide any linkage options.
267
268Running the tests
269~~~~~~~~~~~~~~~~~
270
271Please refer to `Building the library`__ for the instructions on how to build
272the library and run the unit tests.
273
274__ https://fmt.dev/latest/usage.html#building-the-library
275
276Benchmarks reside in a separate repository,
277`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
278so to run the benchmarks you first need to clone this repository and
279generate Makefiles with CMake::
280
281    $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
282    $ cd format-benchmark
283    $ cmake .
284
285Then you can run the speed test::
286
287    $ make speed-test
288
289or the bloat test::
290
291    $ make bloat-test
292    
293Migrating code
294--------------
295
296`clang-tidy-fmt <https://github.com/mikecrowe/clang-tidy-fmt>`_ provides clang
297tidy checks for converting occurrences of ``printf`` and ``fprintf`` to
298``fmt::print``.
299
300Projects 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
421If you are aware of other projects using this library, please let me know
422by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
423`issue <https://github.com/fmtlib/fmt/issues>`_.
424
425Motivation
426----------
427
428So why yet another formatting library?
429
430There are plenty of methods for doing this task, from standard ones like
431the printf family of function and iostreams to Boost Format and FastFormat
432libraries. The reason for creating a new library is that every existing
433solution that I found either had serious issues or didn't provide
434all the features I needed.
435
436printf
437~~~~~~
438
439The good thing about ``printf`` is that it is pretty fast and readily available
440being a part of the C standard library. The main drawback is that it
441doesn't support user-defined types. ``printf`` also has safety issues although
442they are somewhat mitigated with `__attribute__ ((format (printf, ...))
443<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
444There is a POSIX extension that adds positional arguments required for
445`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
446to ``printf`` but it is not a part of C99 and may not be available on some
447platforms.
448
449iostreams
450~~~~~~~~~
451
452The 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
458which is a lot of typing compared to printf:
459
460.. code:: c++
461
462    printf("%.2f\n", 1.23456);
463
464Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
465don't support positional arguments by design.
466
467The good part is that iostreams support user-defined types and are safe although
468error handling is awkward.
469
470Boost Format
471~~~~~~~~~~~~
472
473This is a very powerful library which supports both ``printf``-like format
474strings and positional arguments. Its main drawback is performance. According to
475various benchmarks, it is much slower than other methods considered here. Boost
476Format also has excessive build times and severe code bloat issues (see
477`Benchmarks`_).
478
479FastFormat
480~~~~~~~~~~
481
482This is an interesting library which is fast, safe and has positional arguments.
483However, 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
492It is also quite big and has a heavy dependency, STLSoft, which might be too
493restrictive for using it in some projects.
494
495Boost Spirit.Karma
496~~~~~~~~~~~~~~~~~~
497
498This is not really a formatting library but I decided to include it here for
499completeness. As iostreams, it suffers from the problem of mixing verbatim text
500with arguments. The library is pretty fast, but slower on integer formatting
501than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
502see `Converting a hundred million integers to strings per second
503<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
504
505License
506-------
507
508{fmt} is distributed under the MIT `license
509<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
510
511Documentation License
512---------------------
513
514The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
515section in the documentation is based on the one from Python `string module
516documentation <https://docs.python.org/3/library/string.html#module-string>`_.
517For this reason the documentation is distributed under the Python Software
518Foundation license available in `doc/python-license.txt
519<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
520It only applies if you distribute the documentation of {fmt}.
521
522Maintainers
523-----------
524
525The {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.
528See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
529`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
530Let us know if your contribution is not listed or mentioned incorrectly and
531we'll make it right.
532