]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/fmt/README.rst
update sources to ceph Nautilus 14.2.1
[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-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
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.begin(), "{}-{}-{}", 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 version.
157
158 Projects using this library
159 ---------------------------
160
161 * `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time strategy game
162
163 * `AMPL/MP <https://github.com/ampl/mp>`_:
164 An open-source library for mathematical programming
165
166 * `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft operations suite
167
168 * `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater vehicle
169
170 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
171 Player vs Player Gaming Network with tweaks
172
173 * `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
174
175 * `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
176
177 * `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
178
179 * `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
180
181 * `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox
182 for nonlinear dynamical systems (MIT)
183
184 * `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
185 (Lyft)
186
187 * `FiveM <https://fivem.net/>`_: a modification framework for GTA V
188
189 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
190 generate randomized datasets
191
192 * `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization
193 framework
194
195 * `PenUltima Online (POL) <http://www.polserver.com/>`_:
196 An MMO server, compatible with most Ultima Online clients
197
198 * `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
199 associative database
200
201 * `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
202
203 * `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
204
205 * `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
206 Small crossplatform 2D graphic engine
207
208 * `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
209 Business intelligence software
210
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
213
214 * `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++ framework for
215 high-performance server applications on modern hardware
216
217 * `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
218
219 * `Stellar <https://www.stellar.org/>`_: Financial platform
220
221 * `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
222
223 * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source MMORPG framework
224
225 `More... <https://github.com/search?q=cppformat&type=Code>`_
226
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>`_.
230
231 Motivation
232 ----------
233
234 So why yet another formatting library?
235
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.
241
242 Printf
243 ~~~~~~
244
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
253 platforms.
254
255 IOStreams
256 ~~~~~~~~~
257
258 The main issue with IOStreams is best illustrated with an example:
259
260 .. code:: c++
261
262 std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
263
264 which is a lot of typing compared to printf:
265
266 .. code:: c++
267
268 printf("%.2f\n", 1.23456);
269
270 Matthew Wilson, the author of FastFormat, referred to this situation with
271 IOStreams as "chevron hell". IOStreams doesn't support positional arguments
272 by design.
273
274 The good part is that IOStreams supports user-defined types and is safe
275 although error reporting is awkward.
276
277 Boost Format library
278 ~~~~~~~~~~~~~~~~~~~~
279
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`_).
285
286 FastFormat
287 ~~~~~~~~~~
288
289 This is an interesting library which is fast, safe and has positional
290 arguments. However it has significant limitations, citing its author:
291
292 Three features that have no hope of being accommodated within the
293 current design are:
294
295 * Leading zeros (or any other non-space padding)
296 * Octal/hexadecimal encoding
297 * Runtime width/alignment specification
298
299 It is also quite big and has a heavy dependency, STLSoft, which might be
300 too restrictive for using it in some projects.
301
302 Loki SafeFormat
303 ~~~~~~~~~~~~~~~
304
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
308 format arguments.
309
310 Tinyformat
311 ~~~~~~~~~~
312
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.
317
318 Boost Spirit.Karma
319 ~~~~~~~~~~~~~~~~~~
320
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>`_.
327
328 Benchmarks
329 ----------
330
331 Speed tests
332 ~~~~~~~~~~~
333
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>`_.
341
342 ================= ============= ===========
343 Library Method Run Time, s
344 ================= ============= ===========
345 libc printf 1.35
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 ================= ============= ===========
352
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.
360
361 Compile time and code bloat
362 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
363
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.
372
373 **Optimized build (-O3)**
374
375 ============= =============== ==================== ==================
376 Method Compile Time, s Executable size, KiB Stripped size, KiB
377 ============= =============== ==================== ==================
378 printf 2.6 29 26
379 printf+string 16.4 29 26
380 IOStreams 31.1 59 55
381 fmt 19.0 37 34
382 tinyformat 44.0 103 97
383 Boost Format 91.9 226 203
384 Folly Format 115.7 101 88
385 ============= =============== ==================== ==================
386
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.
390
391 ``printf+string`` is the same as ``printf`` but with extra ``<string>``
392 include to measure the overhead of the latter.
393
394 **Non-optimized build**
395
396 ============= =============== ==================== ==================
397 Method Compile Time, s Executable size, KiB Stripped size, KiB
398 ============= =============== ==================== ==================
399 printf 2.2 33 30
400 printf+string 16.0 33 30
401 IOStreams 28.3 56 52
402 fmt 18.2 59 50
403 tinyformat 32.6 88 82
404 Boost Format 54.1 365 303
405 Folly Format 79.9 445 430
406 ============= =============== ==================== ==================
407
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
411 linkage options.
412
413 Running the tests
414 ~~~~~~~~~~~~~~~~~
415
416 Please refer to `Building the library`__ for the instructions on how to build
417 the library and run the unit tests.
418
419 __ http://fmtlib.net/latest/usage.html#building-the-library
420
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::
425
426 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
427 $ cd format-benchmark
428 $ cmake .
429
430 Then you can run the speed test::
431
432 $ make speed-test
433
434 or the bloat test::
435
436 $ make bloat-test
437
438 FAQ
439 ---
440
441 Q: how can I capture formatting arguments and format them later?
442
443 A: use ``std::tuple``:
444
445 .. code:: c++
446
447 template <typename... Args>
448 auto capture(const Args&... args) {
449 return std::make_tuple(args...);
450 }
451
452 auto print_message = [](const auto&... args) {
453 fmt::print(args...);
454 };
455
456 // Capture and store arguments:
457 auto args = capture("{} {}", 42, "foo");
458 // Do formatting:
459 std::apply(print_message, args);
460
461 License
462 -------
463
464 fmt is distributed under the BSD `license
465 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
466
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.
476
477 Acknowledgments
478 ---------------
479
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
486 we'll make it right.
487
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.