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 DToday201.3 KiB

CMakeLists.txtH A D21-May-202214.1 KiB

CONTRIBUTING.mdH A D18-Oct.-2021710

doc/HToday4 KiB

include/fmt/H18-Oct.-20214 KiB

LICENSE.rstH A D18-Oct.-20211.4 KiB

README.rstH A D29-May-202219.2 KiB

src/H01-Jun.-20224 KiB

support/H30-Jan.-20224 KiB

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