• Home
Name Date Size #Lines LOC

..--

.github/03-May-2024-40

doc/03-May-2024-10,6708,833

fmt/03-May-2024-6,1894,134

support/03-May-2024-1,298991

test/03-May-2024-52,18234,153

.gitignoreD03-May-2024222 2019

.travis.ymlD03-May-2024645 3428

Android.bpD03-May-2024257 1413

Android.mkD03-May-2024242 50

CMakeLists.txtD03-May-20244 KiB12099

CONTRIBUTING.rstD03-May-2024305 128

ChangeLog.rstD03-May-202434.9 KiB915649

LICENSE.rstD03-May-20241.3 KiB2419

README.rstD03-May-202416.7 KiB429321

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 alternative to printf or as a fast
16alternative to IOStreams.
17
18`Documentation <http://fmtlib.net/latest/>`_
19
20Features
21--------
22
23* Two APIs: faster concatenation-based `write API
24  <http://fmtlib.net/latest/api.html#write-api>`_ and slower,
25  but still very fast, replacement-based `format API
26  <http://fmtlib.net/latest/api.html#format-api>`_ with positional arguments
27  for localization.
28* Write API similar to the one used by IOStreams but stateless allowing
29  faster implementation.
30* Format API with `format string syntax
31  <http://fmtlib.net/latest/syntax.html>`_
32  similar to the one used by `str.format
33  <https://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
34* Safe `printf implementation
35  <http://fmtlib.net/latest/api.html#printf-formatting-functions>`_
36  including the POSIX extension for positional arguments.
37* Support for user-defined types.
38* High speed: performance of the format API is close to that of
39  glibc's `printf <http://en.cppreference.com/w/cpp/io/c/fprintf>`_
40  and better than the performance of IOStreams. See `Speed tests`_ and
41  `Fast integer to string conversion in C++
42  <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
43* Small code size both in terms of source code (the core library consists of a single
44  header file and a single source file) and compiled code.
45  See `Compile time and code bloat`_.
46* Reliability: the library has an extensive set of `unit tests
47  <https://github.com/fmtlib/fmt/tree/master/test>`_.
48* Safety: the library is fully type safe, errors in format strings are
49  reported using exceptions, automatic memory management prevents buffer
50  overflow errors.
51* Ease of use: small self-contained code base, no external dependencies,
52  permissive BSD `license
53  <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
54* `Portability <http://fmtlib.net/latest/index.html#portability>`_ with consistent output
55  across platforms and support for older compilers.
56* Clean warning-free codebase even on high warning levels
57  (-Wall -Wextra -pedantic).
58* Support for wide strings.
59* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro.
60
61See the `documentation <http://fmtlib.net/latest/>`_ for more details.
62
63Examples
64--------
65
66This prints ``Hello, world!`` to stdout:
67
68.. code:: c++
69
70    fmt::print("Hello, {}!", "world");  // uses Python-like format string syntax
71    fmt::printf("Hello, %s!", "world"); // uses printf format string syntax
72
73Arguments can be accessed by position and arguments' indices can be repeated:
74
75.. code:: c++
76
77    std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
78    // s == "abracadabra"
79
80fmt can be used as a safe portable replacement for ``itoa``:
81
82.. code:: c++
83
84    fmt::MemoryWriter w;
85    w << 42;           // replaces itoa(42, buffer, 10)
86    w << fmt::hex(42); // replaces itoa(42, buffer, 16)
87    // access the string using w.str() or w.c_str()
88
89An object of any user-defined type for which there is an overloaded
90:code:`std::ostream` insertion operator (``operator<<``) can be formatted:
91
92.. code:: c++
93
94    #include "fmt/ostream.h"
95
96    class Date {
97      int year_, month_, day_;
98     public:
99      Date(int year, int month, int day) : year_(year), month_(month), day_(day) {}
100
101      friend std::ostream &operator<<(std::ostream &os, const Date &d) {
102        return os << d.year_ << '-' << d.month_ << '-' << d.day_;
103      }
104    };
105
106    std::string s = fmt::format("The date is {}", Date(2012, 12, 9));
107    // s == "The date is 2012-12-9"
108
109You can use the `FMT_VARIADIC
110<http://fmtlib.net/latest/api.html#utilities>`_
111macro to create your own functions similar to `format
112<http://fmtlib.net/latest/api.html#format>`_ and
113`print <http://fmtlib.net/latest/api.html#print>`_
114which take arbitrary arguments:
115
116.. code:: c++
117
118    // Prints formatted error message.
119    void report_error(const char *format, fmt::ArgList args) {
120      fmt::print("Error: ");
121      fmt::print(format, args);
122    }
123    FMT_VARIADIC(void, report_error, const char *)
124
125    report_error("file not found: {}", path);
126
127Note that you only need to define one function that takes ``fmt::ArgList``
128argument. ``FMT_VARIADIC`` automatically defines necessary wrappers that
129accept variable number of arguments.
130
131Projects using this library
132---------------------------
133
134* `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time strategy game
135
136* `AMPL/MP <https://github.com/ampl/mp>`_:
137  An open-source library for mathematical programming
138
139* `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater vehicle
140
141* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
142  Player vs Player Gaming Network with tweaks
143
144* `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
145
146* `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
147
148* `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
149
150* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to generate randomized datasets
151
152* `PenUltima Online (POL) <http://www.polserver.com/>`_:
153  An MMO server, compatible with most Ultima Online clients
154
155* `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance, associative database
156
157* `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
158
159* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
160
161* `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
162  Small crossplatform 2D graphic engine
163
164* `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
165  Business intelligence software
166
167* `Scylla <http://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store that can handle
168  1 million transactions per second on a single server
169
170* `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++ framework for
171  high-performance server applications on modern hardware
172
173* `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
174
175* `Stellar <https://www.stellar.org/>`_: Financial platform
176
177* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
178
179* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source MMORPG framework
180
181`More... <https://github.com/search?q=cppformat&type=Code>`_
182
183If you are aware of other projects using this library, please let me know
184by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
185`issue <https://github.com/fmtlib/fmt/issues>`_.
186
187Motivation
188----------
189
190So why yet another formatting library?
191
192There are plenty of methods for doing this task, from standard ones like
193the printf family of function and IOStreams to Boost Format library and
194FastFormat. The reason for creating a new library is that every existing
195solution that I found either had serious issues or didn't provide
196all the features I needed.
197
198Printf
199~~~~~~
200
201The good thing about printf is that it is pretty fast and readily available
202being a part of the C standard library. The main drawback is that it
203doesn't support user-defined types. Printf also has safety issues although
204they are mostly solved with `__attribute__ ((format (printf, ...))
205<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
206There is a POSIX extension that adds positional arguments required for
207`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
208to printf but it is not a part of C99 and may not be available on some
209platforms.
210
211IOStreams
212~~~~~~~~~
213
214The main issue with IOStreams is best illustrated with an example:
215
216.. code:: c++
217
218    std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
219
220which is a lot of typing compared to printf:
221
222.. code:: c++
223
224    printf("%.2f\n", 1.23456);
225
226Matthew Wilson, the author of FastFormat, referred to this situation with
227IOStreams as "chevron hell". IOStreams doesn't support positional arguments
228by design.
229
230The good part is that IOStreams supports user-defined types and is safe
231although error reporting is awkward.
232
233Boost Format library
234~~~~~~~~~~~~~~~~~~~~
235
236This is a very powerful library which supports both printf-like format
237strings and positional arguments. The main its drawback is performance.
238According to various benchmarks it is much slower than other methods
239considered here. Boost Format also has excessive build times and severe
240code bloat issues (see `Benchmarks`_).
241
242FastFormat
243~~~~~~~~~~
244
245This is an interesting library which is fast, safe and has positional
246arguments. However it has significant limitations, citing its author:
247
248    Three features that have no hope of being accommodated within the
249    current design are:
250
251    * Leading zeros (or any other non-space padding)
252    * Octal/hexadecimal encoding
253    * Runtime width/alignment specification
254
255It is also quite big and has a heavy dependency, STLSoft, which might be
256too restrictive for using it in some projects.
257
258Loki SafeFormat
259~~~~~~~~~~~~~~~
260
261SafeFormat is a formatting library which uses printf-like format strings
262and is type safe. It doesn't support user-defined types or positional
263arguments. It makes unconventional use of ``operator()`` for passing
264format arguments.
265
266Tinyformat
267~~~~~~~~~~
268
269This library supports printf-like format strings and is very small and
270fast. Unfortunately it doesn't support positional arguments and wrapping
271it in C++98 is somewhat difficult. Also its performance and code compactness
272are limited by IOStreams.
273
274Boost Spirit.Karma
275~~~~~~~~~~~~~~~~~~
276
277This is not really a formatting library but I decided to include it here
278for completeness. As IOStreams it suffers from the problem of mixing
279verbatim text with arguments. The library is pretty fast, but slower
280on integer formatting than ``fmt::Writer`` on Karma's own benchmark,
281see `Fast integer to string conversion in C++
282<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
283
284Benchmarks
285----------
286
287Speed tests
288~~~~~~~~~~~
289
290The following speed tests results were generated by building
291``tinyformat_test.cpp`` on Ubuntu GNU/Linux 14.04.1 with
292``g++-4.8.2 -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of three
293runs.  In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or
294equivalent is filled 2000000 times with output sent to ``/dev/null``; for
295further details see the `source
296<https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
297
298================= ============= ===========
299Library           Method        Run Time, s
300================= ============= ===========
301EGLIBC 2.19       printf          1.30
302libstdc++ 4.8.2   std::ostream    1.85
303fmt 1.0           fmt::print      1.42
304tinyformat 2.0.1  tfm::printf     2.25
305Boost Format 1.54 boost::format   9.94
306================= ============= ===========
307
308As you can see ``boost::format`` is much slower than the alternative methods; this
309is confirmed by `other tests <http://accu.org/index.php/journals/1539>`_.
310Tinyformat is quite good coming close to IOStreams.  Unfortunately tinyformat
311cannot be faster than the IOStreams because it uses them internally.
312Performance of fmt is close to that of printf, being `faster than printf on integer
313formatting <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_,
314but slower on floating-point formatting which dominates this benchmark.
315
316Compile time and code bloat
317~~~~~~~~~~~~~~~~~~~~~~~~~~~
318
319The script `bloat-test.py
320<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
321from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
322tests compile time and code bloat for nontrivial projects.
323It generates 100 translation units and uses ``printf()`` or its alternative
324five times in each to simulate a medium sized project.  The resulting
325executable size and compile time (g++-4.8.1, Ubuntu GNU/Linux 13.10,
326best of three) is shown in the following tables.
327
328**Optimized build (-O3)**
329
330============ =============== ==================== ==================
331Method       Compile Time, s Executable size, KiB Stripped size, KiB
332============ =============== ==================== ==================
333printf                   2.6                   41                 30
334IOStreams               19.4                   92                 70
335fmt                     46.8                   46                 34
336tinyformat              64.6                  418                386
337Boost Format           222.8                  990                923
338============ =============== ==================== ==================
339
340As you can see, fmt has two times less overhead in terms of resulting
341code size compared to IOStreams and comes pretty close to ``printf``.
342Boost Format has by far the largest overheads.
343
344**Non-optimized build**
345
346============ =============== ==================== ==================
347Method       Compile Time, s Executable size, KiB Stripped size, KiB
348============ =============== ==================== ==================
349printf                   2.1                   41                 30
350IOStreams               19.7                   86                 62
351fmt                     47.9                  108                 86
352tinyformat              27.7                  234                190
353Boost Format           122.6                  884                763
354============ =============== ==================== ==================
355
356``libc``, ``libstdc++`` and ``libfmt`` are all linked as shared
357libraries to compare formatting function overhead only. Boost Format
358and tinyformat are header-only libraries so they don't provide any
359linkage options.
360
361Running the tests
362~~~~~~~~~~~~~~~~~
363
364Please refer to `Building the library`__ for the instructions on how to build
365the library and run the unit tests.
366
367__ http://fmtlib.net/latest/usage.html#building-the-library
368
369Benchmarks reside in a separate repository,
370`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
371so to run the benchmarks you first need to clone this repository and
372generate Makefiles with CMake::
373
374    $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
375    $ cd format-benchmark
376    $ cmake .
377
378Then you can run the speed test::
379
380    $ make speed-test
381
382or the bloat test::
383
384    $ make bloat-test
385
386License
387-------
388
389fmt is distributed under the BSD `license
390<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
391
392The `Format String Syntax
393<http://fmtlib.net/latest/syntax.html>`_
394section in the documentation is based on the one from Python `string module
395documentation <https://docs.python.org/3/library/string.html#module-string>`_
396adapted for the current library. For this reason the documentation is
397distributed under the Python Software Foundation license available in
398`doc/python-license.txt
399<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
400It only applies if you distribute the documentation of fmt.
401
402Acknowledgments
403---------------
404
405The fmt library is maintained by Victor Zverovich (`vitaut <https://github.com/vitaut>`_)
406and Jonathan Müller (`foonathan <https://github.com/foonathan>`_) with contributions from many
407other people. See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names. Let us know if your contribution
408is not listed or mentioned incorrectly and we'll make it right.
409
410The benchmark section of this readme file and the performance tests are taken
411from the excellent `tinyformat <https://github.com/c42f/tinyformat>`_ library
412written by Chris Foster.  Boost Format library is acknowledged transitively
413since it had some influence on tinyformat.
414Some ideas used in the implementation are borrowed from `Loki
415<http://loki-lib.sourceforge.net/>`_ SafeFormat and `Diagnostic API
416<http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html>`_ in
417`Clang <http://clang.llvm.org/>`_.
418Format string syntax and the documentation are based on Python's `str.format
419<http://docs.python.org/2/library/stdtypes.html#str.format>`_.
420Thanks `Doug Turnbull <https://github.com/softwaredoug>`_ for his valuable
421comments and contribution to the design of the type-safe API and
422`Gregory Czajkowski <https://github.com/gcflymoto>`_ for implementing binary
423formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensive
424`comparison of integer formatting algorithms <https://github.com/ruslo/int-dec-format-tests>`_
425and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
426`C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
427Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
428improvements to the code.
429