• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

doc/H03-May-2022-10,5188,596

include/fmt/H03-May-2022-8,9466,666

src/H03-May-2022-305216

support/H03-May-2022-1,5871,233

test/H03-May-2022-52,44934,731

.travis.ymlH A D03-May-20223.2 KiB129121

CONTRIBUTING.rstH A D03-May-2022316 139

ChangeLog.rstH A D03-May-202274.9 KiB2,0031,466

LICENSE.rstH A D03-May-20221.3 KiB2419

README.rstH A D03-May-202219.4 KiB520388

README.rst

1{fmt}
2=====
3
4.. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master
5   :target: https://travis-ci.org/fmtlib/fmt
6
7.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v
8   :target: https://ci.appveyor.com/project/vitaut/fmt
9
10.. image:: https://badges.gitter.im/Join%20Chat.svg
11   :alt: Join the chat at https://gitter.im/fmtlib/fmt
12   :target: https://gitter.im/fmtlib/fmt
13
14**{fmt}** is an open-source formatting library for C++.
15It can be used as a safe and fast alternative to (s)printf and IOStreams.
16
17`Documentation <http://fmtlib.net/latest/>`__
18
19This is a development branch that implements the C++ standards proposal `P0645
20Text Formatting <http://fmtlib.net/Text%20Formatting.html>`__.
21Released versions are available from the `Releases page
22<https://github.com/fmtlib/fmt/releases>`__.
23
24Features
25--------
26
27* Replacement-based `format API <http://fmtlib.net/dev/api.html>`_ with
28  positional arguments for localization.
29* `Format string syntax <http://fmtlib.net/dev/syntax.html>`_ similar to the one
30  of `str.format <https://docs.python.org/2/library/stdtypes.html#str.format>`_
31  in Python.
32* Safe `printf implementation
33  <http://fmtlib.net/latest/api.html#printf-formatting>`_ including
34  the POSIX extension for positional arguments.
35* Support for user-defined types.
36* High speed: performance of the format API is close to that of glibc's `printf
37  <http://en.cppreference.com/w/cpp/io/c/fprintf>`_ and better than the
38  performance of IOStreams. See `Speed tests`_ and
39  `Fast integer to string conversion in C++
40  <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
41* Small code size both in terms of source code (the minimum configuration
42  consists of just three header files, ``core.h``, ``format.h`` and
43  ``format-inl.h``) and compiled code. See `Compile time and code bloat`_.
44* Reliability: the library has an extensive set of `unit tests
45  <https://github.com/fmtlib/fmt/tree/master/test>`_.
46* Safety: the library is fully type safe, errors in format strings can be
47  reported at compile time, automatic memory management prevents buffer overflow
48  errors.
49* Ease of use: small self-contained code base, no external dependencies,
50  permissive BSD `license
51  <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
52* `Portability <http://fmtlib.net/latest/index.html#portability>`_ with
53  consistent output across platforms and support for older compilers.
54* Clean warning-free codebase even on high warning levels
55  (``-Wall -Wextra -pedantic``).
56* Support for wide strings.
57* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro.
58
59See the `documentation <http://fmtlib.net/latest/>`_ for more details.
60
61Examples
62--------
63
64This prints ``Hello, world!`` to stdout:
65
66.. code:: c++
67
68    fmt::print("Hello, {}!", "world");  // uses Python-like format string syntax
69    fmt::printf("Hello, %s!", "world"); // uses printf format string syntax
70
71Arguments can be accessed by position and arguments' indices can be repeated:
72
73.. code:: c++
74
75    std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
76    // s == "abracadabra"
77
78Format strings can be checked at compile time:
79
80.. code:: c++
81
82    // test.cc
83    #define FMT_STRING_ALIAS 1
84    #include <fmt/format.h>
85    std::string s = format(fmt("{2}"), 42);
86
87.. code::
88
89    $ c++ -Iinclude -std=c++14 test.cc
90    ...
91    test.cc:4:17: note: in instantiation of function template specialization 'fmt::v5::format<S, int>' requested here
92    std::string s = format(fmt("{2}"), 42);
93                    ^
94    include/fmt/core.h:778:19: note: non-constexpr function 'on_error' cannot be used in a constant expression
95        ErrorHandler::on_error(message);
96                      ^
97    include/fmt/format.h:2226:16: note: in call to '&checker.context_->on_error(&"argument index out of range"[0])'
98          context_.on_error("argument index out of range");
99                   ^
100
101{fmt} can be used as a safe portable replacement for ``itoa``
102(`godbolt <https://godbolt.org/g/NXmpU4>`_):
103
104.. code:: c++
105
106    fmt::memory_buffer buf;
107    format_to(buf, "{}", 42);    // replaces itoa(42, buffer, 10)
108    format_to(buf, "{:x}", 42);  // replaces itoa(42, buffer, 16)
109    // access the string using to_string(buf) or buf.data()
110
111Formatting of user-defined types is supported via a simple
112`extension API <http://fmtlib.net/latest/api.html#formatting-user-defined-types>`_:
113
114.. code:: c++
115
116    #include "fmt/format.h"
117
118    struct date {
119      int year, month, day;
120    };
121
122    template <>
123    struct fmt::formatter<date> {
124      template <typename ParseContext>
125      constexpr auto parse(ParseContext &ctx) { return ctx.begin(); }
126
127      template <typename FormatContext>
128      auto format(const date &d, FormatContext &ctx) {
129        return format_to(ctx.out(), "{}-{}-{}", d.year, d.month, d.day);
130      }
131    };
132
133    std::string s = fmt::format("The date is {}", date{2012, 12, 9});
134    // s == "The date is 2012-12-9"
135
136You can create your own functions similar to `format
137<http://fmtlib.net/latest/api.html#format>`_ and
138`print <http://fmtlib.net/latest/api.html#print>`_
139which take arbitrary arguments (`godbolt <https://godbolt.org/g/MHjHVf>`_):
140
141.. code:: c++
142
143    // Prints formatted error message.
144    void vreport_error(const char *format, fmt::format_args args) {
145      fmt::print("Error: ");
146      fmt::vprint(format, args);
147    }
148    template <typename... Args>
149    void report_error(const char *format, const Args & ... args) {
150      vreport_error(format, fmt::make_format_args(args...));
151    }
152
153    report_error("file not found: {}", path);
154
155Note that ``vreport_error`` is not parameterized on argument types which can
156improve compile times and reduce code size compared to fully parameterized
157version.
158
159Projects using this library
160---------------------------
161
162* `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time
163  strategy game
164
165* `AMPL/MP <https://github.com/ampl/mp>`_:
166  An open-source library for mathematical programming
167
168* `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft
169  operations suite
170
171* `Celestia <https://celestia.space/>`_: Real-time 3D visualization of space
172
173* `Ceph <https://ceph.com/>`_: A scalable distributed storage system
174
175* `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater
176  vehicle
177
178* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
179  Player vs Player Gaming Network with tweaks
180
181* `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
182
183* `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
184
185* `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
186
187* `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
188
189* `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox
190  for nonlinear dynamical systems (MIT)
191
192* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
193  (Lyft)
194
195* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
196
197* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
198  generate randomized datasets
199
200* `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization
201  framework
202
203* `PenUltima Online (POL) <http://www.polserver.com/>`_:
204  An MMO server, compatible with most Ultima Online clients
205
206* `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
207  associative database
208
209* `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
210
211* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster
212  proxy
213
214* `rpclib <http://rpclib.net/>`_: A modern C++ msgpack-RPC server and client
215  library
216
217* `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
218  Small crossplatform 2D graphic engine
219
220* `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
221  Business intelligence software
222
223* `Scylla <http://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store
224  that can handle 1 million transactions per second on a single server
225
226* `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++
227  framework for high-performance server applications on modern hardware
228
229* `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
230
231* `Stellar <https://www.stellar.org/>`_: Financial platform
232
233* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
234
235* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source
236  MMORPG framework
237
238`More... <https://github.com/search?q=cppformat&type=Code>`_
239
240If you are aware of other projects using this library, please let me know
241by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
242`issue <https://github.com/fmtlib/fmt/issues>`_.
243
244Motivation
245----------
246
247So why yet another formatting library?
248
249There are plenty of methods for doing this task, from standard ones like
250the printf family of function and IOStreams to Boost Format library and
251FastFormat. The reason for creating a new library is that every existing
252solution that I found either had serious issues or didn't provide
253all the features I needed.
254
255Printf
256~~~~~~
257
258The good thing about printf is that it is pretty fast and readily available
259being a part of the C standard library. The main drawback is that it
260doesn't support user-defined types. Printf also has safety issues although
261they are mostly solved with `__attribute__ ((format (printf, ...))
262<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
263There is a POSIX extension that adds positional arguments required for
264`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
265to printf but it is not a part of C99 and may not be available on some
266platforms.
267
268IOStreams
269~~~~~~~~~
270
271The main issue with IOStreams is best illustrated with an example:
272
273.. code:: c++
274
275    std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
276
277which is a lot of typing compared to printf:
278
279.. code:: c++
280
281    printf("%.2f\n", 1.23456);
282
283Matthew Wilson, the author of FastFormat, referred to this situation with
284IOStreams as "chevron hell". IOStreams doesn't support positional arguments
285by design.
286
287The good part is that IOStreams supports user-defined types and is safe
288although error reporting is awkward.
289
290Boost Format library
291~~~~~~~~~~~~~~~~~~~~
292
293This is a very powerful library which supports both printf-like format
294strings and positional arguments. Its main drawback is performance.
295According to various benchmarks it is much slower than other methods
296considered here. Boost Format also has excessive build times and severe
297code bloat issues (see `Benchmarks`_).
298
299FastFormat
300~~~~~~~~~~
301
302This is an interesting library which is fast, safe and has positional
303arguments. However it has significant limitations, citing its author:
304
305    Three features that have no hope of being accommodated within the
306    current design are:
307
308    * Leading zeros (or any other non-space padding)
309    * Octal/hexadecimal encoding
310    * Runtime width/alignment specification
311
312It is also quite big and has a heavy dependency, STLSoft, which might be
313too restrictive for using it in some projects.
314
315Loki SafeFormat
316~~~~~~~~~~~~~~~
317
318SafeFormat is a formatting library which uses printf-like format strings
319and is type safe. It doesn't support user-defined types or positional
320arguments. It makes unconventional use of ``operator()`` for passing
321format arguments.
322
323Tinyformat
324~~~~~~~~~~
325
326This library supports printf-like format strings and is very small and
327fast. Unfortunately it doesn't support positional arguments and wrapping
328it in C++98 is somewhat difficult. Also its performance and code compactness
329are limited by IOStreams.
330
331Boost Spirit.Karma
332~~~~~~~~~~~~~~~~~~
333
334This is not really a formatting library but I decided to include it here
335for completeness. As IOStreams it suffers from the problem of mixing
336verbatim text with arguments. The library is pretty fast, but slower
337on integer formatting than ``fmt::Writer`` on Karma's own benchmark,
338see `Fast integer to string conversion in C++
339<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
340
341Benchmarks
342----------
343
344Speed tests
345~~~~~~~~~~~
346
347The following speed tests results were generated by building
348``tinyformat_test.cpp`` on Ubuntu GNU/Linux 14.04.1 with
349``g++-4.8.2 -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of three
350runs.  In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or
351equivalent is filled 2000000 times with output sent to ``/dev/null``; for
352further details see the `source
353<https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
354
355================= ============= ===========
356Library           Method        Run Time, s
357================= ============= ===========
358libc              printf          1.35
359libc++            std::ostream    3.42
360fmt 534bff7       fmt::print      1.56
361tinyformat 2.0.1  tfm::printf     3.73
362Boost Format 1.54 boost::format   8.44
363Folly Format      folly::format   2.54
364================= ============= ===========
365
366As you can see ``boost::format`` is much slower than the alternative methods; this
367is confirmed by `other tests <http://accu.org/index.php/journals/1539>`_.
368Tinyformat is quite good coming close to IOStreams.  Unfortunately tinyformat
369cannot be faster than the IOStreams because it uses them internally.
370Performance of fmt is close to that of printf, being `faster than printf on integer
371formatting <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_,
372but slower on floating-point formatting which dominates this benchmark.
373
374Compile time and code bloat
375~~~~~~~~~~~~~~~~~~~~~~~~~~~
376
377The script `bloat-test.py
378<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
379from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
380tests compile time and code bloat for nontrivial projects.
381It generates 100 translation units and uses ``printf()`` or its alternative
382five times in each to simulate a medium sized project.  The resulting
383executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
384macOS Sierra, best of three) is shown in the following tables.
385
386**Optimized build (-O3)**
387
388============= =============== ==================== ==================
389Method        Compile Time, s Executable size, KiB Stripped size, KiB
390============= =============== ==================== ==================
391printf                    2.6                   29                 26
392printf+string            16.4                   29                 26
393IOStreams                31.1                   59                 55
394fmt                      19.0                   37                 34
395tinyformat               44.0                  103                 97
396Boost Format             91.9                  226                203
397Folly Format            115.7                  101                 88
398============= =============== ==================== ==================
399
400As you can see, fmt has 60% less overhead in terms of resulting binary code
401size compared to IOStreams and comes pretty close to ``printf``. Boost Format
402and Folly Format have the largest overheads.
403
404``printf+string`` is the same as ``printf`` but with extra ``<string>``
405include to measure the overhead of the latter.
406
407**Non-optimized build**
408
409============= =============== ==================== ==================
410Method        Compile Time, s Executable size, KiB Stripped size, KiB
411============= =============== ==================== ==================
412printf                    2.2                   33                 30
413printf+string            16.0                   33                 30
414IOStreams                28.3                   56                 52
415fmt                      18.2                   59                 50
416tinyformat               32.6                   88                 82
417Boost Format             54.1                  365                303
418Folly Format             79.9                  445                430
419============= =============== ==================== ==================
420
421``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared
422libraries to compare formatting function overhead only. Boost Format
423and tinyformat are header-only libraries so they don't provide any
424linkage options.
425
426Running the tests
427~~~~~~~~~~~~~~~~~
428
429Please refer to `Building the library`__ for the instructions on how to build
430the library and run the unit tests.
431
432__ http://fmtlib.net/latest/usage.html#building-the-library
433
434Benchmarks reside in a separate repository,
435`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
436so to run the benchmarks you first need to clone this repository and
437generate Makefiles with CMake::
438
439    $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
440    $ cd format-benchmark
441    $ cmake .
442
443Then you can run the speed test::
444
445    $ make speed-test
446
447or the bloat test::
448
449    $ make bloat-test
450
451FAQ
452---
453
454Q: how can I capture formatting arguments and format them later?
455
456A: use ``std::tuple``:
457
458.. code:: c++
459
460   template <typename... Args>
461   auto capture(const Args&... args) {
462     return std::make_tuple(args...);
463   }
464
465   auto print_message = [](const auto&... args) {
466     fmt::print(args...);
467   };
468
469   // Capture and store arguments:
470   auto args = capture("{} {}", 42, "foo");
471   // Do formatting:
472   std::apply(print_message, args);
473
474License
475-------
476
477fmt is distributed under the BSD `license
478<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
479
480The `Format String Syntax
481<http://fmtlib.net/latest/syntax.html>`_
482section in the documentation is based on the one from Python `string module
483documentation <https://docs.python.org/3/library/string.html#module-string>`_
484adapted for the current library. For this reason the documentation is
485distributed under the Python Software Foundation license available in
486`doc/python-license.txt
487<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
488It only applies if you distribute the documentation of fmt.
489
490Acknowledgments
491---------------
492
493The fmt library is maintained by Victor Zverovich (`vitaut
494<https://github.com/vitaut>`_) and Jonathan Müller (`foonathan
495<https://github.com/foonathan>`_) with contributions from many other people.
496See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
497`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
498Let us know if your contribution is not listed or mentioned incorrectly and
499we'll make it right.
500
501The benchmark section of this readme file and the performance tests are taken
502from the excellent `tinyformat <https://github.com/c42f/tinyformat>`_ library
503written by Chris Foster.  Boost Format library is acknowledged transitively
504since it had some influence on tinyformat.
505Some ideas used in the implementation are borrowed from `Loki
506<http://loki-lib.sourceforge.net/>`_ SafeFormat and `Diagnostic API
507<http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html>`_ in
508`Clang <http://clang.llvm.org/>`_.
509Format string syntax and the documentation are based on Python's `str.format
510<http://docs.python.org/2/library/stdtypes.html#str.format>`_.
511Thanks `Doug Turnbull <https://github.com/softwaredoug>`_ for his valuable
512comments and contribution to the design of the type-safe API and
513`Gregory Czajkowski <https://github.com/gcflymoto>`_ for implementing binary
514formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensive
515`comparison of integer formatting algorithms <https://github.com/ruslo/int-dec-format-tests>`_
516and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
517`C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
518Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
519improvements to the code.
520