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-functions>`_ 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.begin(), "{}-{}-{}", 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 version.
158 Projects using this library
159 ---------------------------
161 * `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time strategy game
163 * `AMPL/MP <https://github.com/ampl/mp>`_:
164 An open-source library for mathematical programming
166 * `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft operations suite
168 * `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater vehicle
170 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
171 Player vs Player Gaming Network with tweaks
173 * `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
175 * `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
177 * `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
179 * `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
181 * `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox
182 for nonlinear dynamical systems (MIT)
184 * `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
187 * `FiveM <https://fivem.net/>`_: a modification framework for GTA V
189 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
190 generate randomized datasets
192 * `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization
195 * `PenUltima Online (POL) <http://www.polserver.com/>`_:
196 An MMO server, compatible with most Ultima Online clients
198 * `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
201 * `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
203 * `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
205 * `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
206 Small crossplatform 2D graphic engine
208 * `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
209 Business intelligence software
211 * `Scylla <http://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store that can handle
212 1 million transactions per second on a single server
214 * `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++ framework for
215 high-performance server applications on modern hardware
217 * `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
219 * `Stellar <https://www.stellar.org/>`_: Financial platform
221 * `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
223 * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source MMORPG framework
225 `More... <https://github.com/search?q=cppformat&type=Code>`_
227 If you are aware of other projects using this library, please let me know
228 by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
229 `issue <https://github.com/fmtlib/fmt/issues>`_.
234 So why yet another formatting library?
236 There are plenty of methods for doing this task, from standard ones like
237 the printf family of function and IOStreams to Boost Format library and
238 FastFormat. The reason for creating a new library is that every existing
239 solution that I found either had serious issues or didn't provide
240 all the features I needed.
245 The good thing about printf is that it is pretty fast and readily available
246 being a part of the C standard library. The main drawback is that it
247 doesn't support user-defined types. Printf also has safety issues although
248 they are mostly solved with `__attribute__ ((format (printf, ...))
249 <http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
250 There is a POSIX extension that adds positional arguments required for
251 `i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
252 to printf but it is not a part of C99 and may not be available on some
258 The main issue with IOStreams is best illustrated with an example:
262 std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
264 which is a lot of typing compared to printf:
268 printf("%.2f\n", 1.23456);
270 Matthew Wilson, the author of FastFormat, referred to this situation with
271 IOStreams as "chevron hell". IOStreams doesn't support positional arguments
274 The good part is that IOStreams supports user-defined types and is safe
275 although error reporting is awkward.
280 This is a very powerful library which supports both printf-like format
281 strings and positional arguments. Its main drawback is performance.
282 According to various benchmarks it is much slower than other methods
283 considered here. Boost Format also has excessive build times and severe
284 code bloat issues (see `Benchmarks`_).
289 This is an interesting library which is fast, safe and has positional
290 arguments. However it has significant limitations, citing its author:
292 Three features that have no hope of being accommodated within the
295 * Leading zeros (or any other non-space padding)
296 * Octal/hexadecimal encoding
297 * Runtime width/alignment specification
299 It is also quite big and has a heavy dependency, STLSoft, which might be
300 too restrictive for using it in some projects.
305 SafeFormat is a formatting library which uses printf-like format strings
306 and is type safe. It doesn't support user-defined types or positional
307 arguments. It makes unconventional use of ``operator()`` for passing
313 This library supports printf-like format strings and is very small and
314 fast. Unfortunately it doesn't support positional arguments and wrapping
315 it in C++98 is somewhat difficult. Also its performance and code compactness
316 are limited by IOStreams.
321 This is not really a formatting library but I decided to include it here
322 for completeness. As IOStreams it suffers from the problem of mixing
323 verbatim text with arguments. The library is pretty fast, but slower
324 on integer formatting than ``fmt::Writer`` on Karma's own benchmark,
325 see `Fast integer to string conversion in C++
326 <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
334 The following speed tests results were generated by building
335 ``tinyformat_test.cpp`` on Ubuntu GNU/Linux 14.04.1 with
336 ``g++-4.8.2 -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of three
337 runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or
338 equivalent is filled 2000000 times with output sent to ``/dev/null``; for
339 further details see the `source
340 <https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
342 ================= ============= ===========
343 Library Method Run Time, s
344 ================= ============= ===========
346 libc++ std::ostream 3.42
347 fmt 534bff7 fmt::print 1.56
348 tinyformat 2.0.1 tfm::printf 3.73
349 Boost Format 1.54 boost::format 8.44
350 Folly Format folly::format 2.54
351 ================= ============= ===========
353 As you can see ``boost::format`` is much slower than the alternative methods; this
354 is confirmed by `other tests <http://accu.org/index.php/journals/1539>`_.
355 Tinyformat is quite good coming close to IOStreams. Unfortunately tinyformat
356 cannot be faster than the IOStreams because it uses them internally.
357 Performance of fmt is close to that of printf, being `faster than printf on integer
358 formatting <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_,
359 but slower on floating-point formatting which dominates this benchmark.
361 Compile time and code bloat
362 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
364 The script `bloat-test.py
365 <https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
366 from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
367 tests compile time and code bloat for nontrivial projects.
368 It generates 100 translation units and uses ``printf()`` or its alternative
369 five times in each to simulate a medium sized project. The resulting
370 executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
371 macOS Sierra, best of three) is shown in the following tables.
373 **Optimized build (-O3)**
375 ============= =============== ==================== ==================
376 Method Compile Time, s Executable size, KiB Stripped size, KiB
377 ============= =============== ==================== ==================
379 printf+string 16.4 29 26
382 tinyformat 44.0 103 97
383 Boost Format 91.9 226 203
384 Folly Format 115.7 101 88
385 ============= =============== ==================== ==================
387 As you can see, fmt has 60% less overhead in terms of resulting binary code
388 size compared to IOStreams and comes pretty close to ``printf``. Boost Format
389 and Folly Format have the largest overheads.
391 ``printf+string`` is the same as ``printf`` but with extra ``<string>``
392 include to measure the overhead of the latter.
394 **Non-optimized build**
396 ============= =============== ==================== ==================
397 Method Compile Time, s Executable size, KiB Stripped size, KiB
398 ============= =============== ==================== ==================
400 printf+string 16.0 33 30
403 tinyformat 32.6 88 82
404 Boost Format 54.1 365 303
405 Folly Format 79.9 445 430
406 ============= =============== ==================== ==================
408 ``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared
409 libraries to compare formatting function overhead only. Boost Format
410 and tinyformat are header-only libraries so they don't provide any
416 Please refer to `Building the library`__ for the instructions on how to build
417 the library and run the unit tests.
419 __ http://fmtlib.net/latest/usage.html#building-the-library
421 Benchmarks reside in a separate repository,
422 `format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
423 so to run the benchmarks you first need to clone this repository and
424 generate Makefiles with CMake::
426 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
427 $ cd format-benchmark
430 Then you can run the speed test::
441 Q: how can I capture formatting arguments and format them later?
443 A: use ``std::tuple``:
447 template <typename... Args>
448 auto capture(const Args&... args) {
449 return std::make_tuple(args...);
452 auto print_message = [](const auto&... args) {
456 // Capture and store arguments:
457 auto args = capture("{} {}", 42, "foo");
459 std::apply(print_message, args);
464 fmt is distributed under the BSD `license
465 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
467 The `Format String Syntax
468 <http://fmtlib.net/latest/syntax.html>`_
469 section in the documentation is based on the one from Python `string module
470 documentation <https://docs.python.org/3/library/string.html#module-string>`_
471 adapted for the current library. For this reason the documentation is
472 distributed under the Python Software Foundation license available in
473 `doc/python-license.txt
474 <https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
475 It only applies if you distribute the documentation of fmt.
480 The fmt library is maintained by Victor Zverovich (`vitaut
481 <https://github.com/vitaut>`_) and Jonathan Müller (`foonathan
482 <https://github.com/foonathan>`_) with contributions from many other people.
483 See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
484 `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
485 Let us know if your contribution is not listed or mentioned incorrectly and
488 The benchmark section of this readme file and the performance tests are taken
489 from the excellent `tinyformat <https://github.com/c42f/tinyformat>`_ library
490 written by Chris Foster. Boost Format library is acknowledged transitively
491 since it had some influence on tinyformat.
492 Some ideas used in the implementation are borrowed from `Loki
493 <http://loki-lib.sourceforge.net/>`_ SafeFormat and `Diagnostic API
494 <http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html>`_ in
495 `Clang <http://clang.llvm.org/>`_.
496 Format string syntax and the documentation are based on Python's `str.format
497 <http://docs.python.org/2/library/stdtypes.html#str.format>`_.
498 Thanks `Doug Turnbull <https://github.com/softwaredoug>`_ for his valuable
499 comments and contribution to the design of the type-safe API and
500 `Gregory Czajkowski <https://github.com/gcflymoto>`_ for implementing binary
501 formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensive
502 `comparison of integer formatting algorithms <https://github.com/ruslo/int-dec-format-tests>`_
503 and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
504 `C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
505 Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
506 improvements to the code.