4 .. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master
5 :target: https://travis-ci.org/fmtlib/fmt
7 .. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v
8 :target: https://ci.appveyor.com/project/vitaut/fmt
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
14 **{fmt}** is an open-source formatting library for C++.
15 It can be used as a safe and fast alternative to (s)printf and IOStreams.
17 `Documentation <http://fmtlib.net/latest/>`__
19 This is a development branch that implements the C++ standards proposal `P0645
20 Text Formatting <http://fmtlib.net/Text%20Formatting.html>`__.
21 Released versions are available from the `Releases page
22 <https://github.com/fmtlib/fmt/releases>`__.
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>`_
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
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.
59 See the `documentation <http://fmtlib.net/latest/>`_ for more details.
64 This prints ``Hello, world!`` to stdout:
68 fmt::print("Hello, {}!", "world"); // uses Python-like format string syntax
69 fmt::printf("Hello, %s!", "world"); // uses printf format string syntax
71 Arguments can be accessed by position and arguments' indices can be repeated:
75 std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
78 Format strings can be checked at compile time:
83 #define FMT_STRING_ALIAS 1
84 #include <fmt/format.h>
85 std::string s = format(fmt("{2}"), 42);
89 $ c++ -Iinclude -std=c++14 test.cc
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);
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);
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");
101 {fmt} can be used as a safe portable replacement for ``itoa``
102 (`godbolt <https://godbolt.org/g/NXmpU4>`_):
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()
111 Formatting of user-defined types is supported via a simple
112 `extension API <http://fmtlib.net/latest/api.html#formatting-user-defined-types>`_:
116 #include "fmt/format.h"
119 int year, month, day;
123 struct fmt::formatter<date> {
124 template <typename ParseContext>
125 constexpr auto parse(ParseContext &ctx) { return ctx.begin(); }
127 template <typename FormatContext>
128 auto format(const date &d, FormatContext &ctx) {
129 return format_to(ctx.out(), "{}-{}-{}", d.year, d.month, d.day);
133 std::string s = fmt::format("The date is {}", date{2012, 12, 9});
134 // s == "The date is 2012-12-9"
136 You 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>`_
139 which take arbitrary arguments (`godbolt <https://godbolt.org/g/MHjHVf>`_):
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);
148 template <typename... Args>
149 void report_error(const char *format, const Args & ... args) {
150 vreport_error(format, fmt::make_format_args(args...));
153 report_error("file not found: {}", path);
155 Note that ``vreport_error`` is not parameterized on argument types which can
156 improve compile times and reduce code size compared to fully parameterized
159 Projects using this library
160 ---------------------------
162 * `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time
165 * `AMPL/MP <https://github.com/ampl/mp>`_:
166 An open-source library for mathematical programming
168 * `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft
171 * `Celestia <https://celestia.space/>`_: Real-time 3D visualization of space
173 * `Ceph <https://ceph.com/>`_: A scalable distributed storage system
175 * `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater
178 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
179 Player vs Player Gaming Network with tweaks
181 * `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
183 * `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
185 * `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
187 * `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
189 * `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox
190 for nonlinear dynamical systems (MIT)
192 * `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
195 * `FiveM <https://fivem.net/>`_: a modification framework for GTA V
197 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
198 generate randomized datasets
200 * `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization
203 * `PenUltima Online (POL) <http://www.polserver.com/>`_:
204 An MMO server, compatible with most Ultima Online clients
206 * `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
209 * `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
211 * `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster
214 * `rpclib <http://rpclib.net/>`_: A modern C++ msgpack-RPC server and client
217 * `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
218 Small crossplatform 2D graphic engine
220 * `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
221 Business intelligence software
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
226 * `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++
227 framework for high-performance server applications on modern hardware
229 * `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
231 * `Stellar <https://www.stellar.org/>`_: Financial platform
233 * `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
235 * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source
238 `More... <https://github.com/search?q=cppformat&type=Code>`_
240 If you are aware of other projects using this library, please let me know
241 by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
242 `issue <https://github.com/fmtlib/fmt/issues>`_.
247 So why yet another formatting library?
249 There are plenty of methods for doing this task, from standard ones like
250 the printf family of function and IOStreams to Boost Format library and
251 FastFormat. The reason for creating a new library is that every existing
252 solution that I found either had serious issues or didn't provide
253 all the features I needed.
258 The good thing about printf is that it is pretty fast and readily available
259 being a part of the C standard library. The main drawback is that it
260 doesn't support user-defined types. Printf also has safety issues although
261 they are mostly solved with `__attribute__ ((format (printf, ...))
262 <http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
263 There is a POSIX extension that adds positional arguments required for
264 `i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
265 to printf but it is not a part of C99 and may not be available on some
271 The main issue with IOStreams is best illustrated with an example:
275 std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
277 which is a lot of typing compared to printf:
281 printf("%.2f\n", 1.23456);
283 Matthew Wilson, the author of FastFormat, referred to this situation with
284 IOStreams as "chevron hell". IOStreams doesn't support positional arguments
287 The good part is that IOStreams supports user-defined types and is safe
288 although error reporting is awkward.
293 This is a very powerful library which supports both printf-like format
294 strings and positional arguments. Its main drawback is performance.
295 According to various benchmarks it is much slower than other methods
296 considered here. Boost Format also has excessive build times and severe
297 code bloat issues (see `Benchmarks`_).
302 This is an interesting library which is fast, safe and has positional
303 arguments. However it has significant limitations, citing its author:
305 Three features that have no hope of being accommodated within the
308 * Leading zeros (or any other non-space padding)
309 * Octal/hexadecimal encoding
310 * Runtime width/alignment specification
312 It is also quite big and has a heavy dependency, STLSoft, which might be
313 too restrictive for using it in some projects.
318 SafeFormat is a formatting library which uses printf-like format strings
319 and is type safe. It doesn't support user-defined types or positional
320 arguments. It makes unconventional use of ``operator()`` for passing
326 This library supports printf-like format strings and is very small and
327 fast. Unfortunately it doesn't support positional arguments and wrapping
328 it in C++98 is somewhat difficult. Also its performance and code compactness
329 are limited by IOStreams.
334 This is not really a formatting library but I decided to include it here
335 for completeness. As IOStreams it suffers from the problem of mixing
336 verbatim text with arguments. The library is pretty fast, but slower
337 on integer formatting than ``fmt::Writer`` on Karma's own benchmark,
338 see `Fast integer to string conversion in C++
339 <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
347 The 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
350 runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or
351 equivalent is filled 2000000 times with output sent to ``/dev/null``; for
352 further details see the `source
353 <https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
355 ================= ============= ===========
356 Library Method Run Time, s
357 ================= ============= ===========
359 libc++ std::ostream 3.42
360 fmt 534bff7 fmt::print 1.56
361 tinyformat 2.0.1 tfm::printf 3.73
362 Boost Format 1.54 boost::format 8.44
363 Folly Format folly::format 2.54
364 ================= ============= ===========
366 As you can see ``boost::format`` is much slower than the alternative methods; this
367 is confirmed by `other tests <http://accu.org/index.php/journals/1539>`_.
368 Tinyformat is quite good coming close to IOStreams. Unfortunately tinyformat
369 cannot be faster than the IOStreams because it uses them internally.
370 Performance of fmt is close to that of printf, being `faster than printf on integer
371 formatting <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_,
372 but slower on floating-point formatting which dominates this benchmark.
374 Compile time and code bloat
375 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
377 The script `bloat-test.py
378 <https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
379 from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
380 tests compile time and code bloat for nontrivial projects.
381 It generates 100 translation units and uses ``printf()`` or its alternative
382 five times in each to simulate a medium sized project. The resulting
383 executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
384 macOS Sierra, best of three) is shown in the following tables.
386 **Optimized build (-O3)**
388 ============= =============== ==================== ==================
389 Method Compile Time, s Executable size, KiB Stripped size, KiB
390 ============= =============== ==================== ==================
392 printf+string 16.4 29 26
395 tinyformat 44.0 103 97
396 Boost Format 91.9 226 203
397 Folly Format 115.7 101 88
398 ============= =============== ==================== ==================
400 As you can see, fmt has 60% less overhead in terms of resulting binary code
401 size compared to IOStreams and comes pretty close to ``printf``. Boost Format
402 and Folly Format have the largest overheads.
404 ``printf+string`` is the same as ``printf`` but with extra ``<string>``
405 include to measure the overhead of the latter.
407 **Non-optimized build**
409 ============= =============== ==================== ==================
410 Method Compile Time, s Executable size, KiB Stripped size, KiB
411 ============= =============== ==================== ==================
413 printf+string 16.0 33 30
416 tinyformat 32.6 88 82
417 Boost Format 54.1 365 303
418 Folly Format 79.9 445 430
419 ============= =============== ==================== ==================
421 ``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared
422 libraries to compare formatting function overhead only. Boost Format
423 and tinyformat are header-only libraries so they don't provide any
429 Please refer to `Building the library`__ for the instructions on how to build
430 the library and run the unit tests.
432 __ http://fmtlib.net/latest/usage.html#building-the-library
434 Benchmarks reside in a separate repository,
435 `format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
436 so to run the benchmarks you first need to clone this repository and
437 generate Makefiles with CMake::
439 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
440 $ cd format-benchmark
443 Then you can run the speed test::
454 Q: how can I capture formatting arguments and format them later?
456 A: use ``std::tuple``:
460 template <typename... Args>
461 auto capture(const Args&... args) {
462 return std::make_tuple(args...);
465 auto print_message = [](const auto&... args) {
469 // Capture and store arguments:
470 auto args = capture("{} {}", 42, "foo");
472 std::apply(print_message, args);
477 fmt is distributed under the BSD `license
478 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
480 The `Format String Syntax
481 <http://fmtlib.net/latest/syntax.html>`_
482 section in the documentation is based on the one from Python `string module
483 documentation <https://docs.python.org/3/library/string.html#module-string>`_
484 adapted for the current library. For this reason the documentation is
485 distributed 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>`_.
488 It only applies if you distribute the documentation of fmt.
493 The 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.
496 See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
497 `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
498 Let us know if your contribution is not listed or mentioned incorrectly and
501 The benchmark section of this readme file and the performance tests are taken
502 from the excellent `tinyformat <https://github.com/c42f/tinyformat>`_ library
503 written by Chris Foster. Boost Format library is acknowledged transitively
504 since it had some influence on tinyformat.
505 Some 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/>`_.
509 Format string syntax and the documentation are based on Python's `str.format
510 <http://docs.python.org/2/library/stdtypes.html#str.format>`_.
511 Thanks `Doug Turnbull <https://github.com/softwaredoug>`_ for his valuable
512 comments and contribution to the design of the type-safe API and
513 `Gregory Czajkowski <https://github.com/gcflymoto>`_ for implementing binary
514 formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensive
515 `comparison of integer formatting algorithms <https://github.com/ruslo/int-dec-format-tests>`_
516 and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
517 `C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
518 Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
519 improvements to the code.