]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/fmt/README.rst
update download target update for octopus release
[ceph.git] / ceph / src / seastar / fmt / 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++.
15 It can be used as a safe and fast alternative to (s)printf and IOStreams.
16
17 `Documentation <http://fmtlib.net/latest/>`__
18
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>`__.
23
24 Features
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
59 See the `documentation <http://fmtlib.net/latest/>`_ for more details.
60
61 Examples
62 --------
63
64 This 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
71 Arguments 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
78 Format 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
111 Formatting 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
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>`_):
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
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
157 version.
158
159 Projects 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
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>`_.
243
244 Motivation
245 ----------
246
247 So why yet another formatting library?
248
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.
254
255 Printf
256 ~~~~~~
257
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
266 platforms.
267
268 IOStreams
269 ~~~~~~~~~
270
271 The 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
277 which is a lot of typing compared to printf:
278
279 .. code:: c++
280
281 printf("%.2f\n", 1.23456);
282
283 Matthew Wilson, the author of FastFormat, referred to this situation with
284 IOStreams as "chevron hell". IOStreams doesn't support positional arguments
285 by design.
286
287 The good part is that IOStreams supports user-defined types and is safe
288 although error reporting is awkward.
289
290 Boost Format library
291 ~~~~~~~~~~~~~~~~~~~~
292
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`_).
298
299 FastFormat
300 ~~~~~~~~~~
301
302 This is an interesting library which is fast, safe and has positional
303 arguments. 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
312 It is also quite big and has a heavy dependency, STLSoft, which might be
313 too restrictive for using it in some projects.
314
315 Loki SafeFormat
316 ~~~~~~~~~~~~~~~
317
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
321 format arguments.
322
323 Tinyformat
324 ~~~~~~~~~~
325
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.
330
331 Boost Spirit.Karma
332 ~~~~~~~~~~~~~~~~~~
333
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>`_.
340
341 Benchmarks
342 ----------
343
344 Speed tests
345 ~~~~~~~~~~~
346
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>`_.
354
355 ================= ============= ===========
356 Library Method Run Time, s
357 ================= ============= ===========
358 libc printf 1.35
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 ================= ============= ===========
365
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.
373
374 Compile time and code bloat
375 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
376
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.
385
386 **Optimized build (-O3)**
387
388 ============= =============== ==================== ==================
389 Method Compile Time, s Executable size, KiB Stripped size, KiB
390 ============= =============== ==================== ==================
391 printf 2.6 29 26
392 printf+string 16.4 29 26
393 IOStreams 31.1 59 55
394 fmt 19.0 37 34
395 tinyformat 44.0 103 97
396 Boost Format 91.9 226 203
397 Folly Format 115.7 101 88
398 ============= =============== ==================== ==================
399
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.
403
404 ``printf+string`` is the same as ``printf`` but with extra ``<string>``
405 include to measure the overhead of the latter.
406
407 **Non-optimized build**
408
409 ============= =============== ==================== ==================
410 Method Compile Time, s Executable size, KiB Stripped size, KiB
411 ============= =============== ==================== ==================
412 printf 2.2 33 30
413 printf+string 16.0 33 30
414 IOStreams 28.3 56 52
415 fmt 18.2 59 50
416 tinyformat 32.6 88 82
417 Boost Format 54.1 365 303
418 Folly Format 79.9 445 430
419 ============= =============== ==================== ==================
420
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
424 linkage options.
425
426 Running the tests
427 ~~~~~~~~~~~~~~~~~
428
429 Please refer to `Building the library`__ for the instructions on how to build
430 the library and run the unit tests.
431
432 __ http://fmtlib.net/latest/usage.html#building-the-library
433
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::
438
439 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
440 $ cd format-benchmark
441 $ cmake .
442
443 Then you can run the speed test::
444
445 $ make speed-test
446
447 or the bloat test::
448
449 $ make bloat-test
450
451 FAQ
452 ---
453
454 Q: how can I capture formatting arguments and format them later?
455
456 A: 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
474 License
475 -------
476
477 fmt is distributed under the BSD `license
478 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
479
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.
489
490 Acknowledgments
491 ---------------
492
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
499 we'll make it right.
500
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.