Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
.github/ | 22-Nov-2023 | - | 4 | 0 | ||
doc/ | 22-Nov-2023 | - | 10,670 | 8,833 | ||
fmt/ | 22-Nov-2023 | - | 6,189 | 4,134 | ||
support/ | 22-Nov-2023 | - | 1,298 | 991 | ||
test/ | 22-Nov-2023 | - | 52,182 | 34,153 | ||
.git | D | 01-Jan-1970 | 0 | |||
.gitignore | D | 22-Nov-2023 | 222 | 20 | 19 | |
.travis.yml | D | 22-Nov-2023 | 645 | 34 | 28 | |
Android.bp | D | 22-Nov-2023 | 257 | 14 | 13 | |
Android.mk | D | 22-Nov-2023 | 242 | 5 | 0 | |
CMakeLists.txt | D | 22-Nov-2023 | 4 KiB | 120 | 99 | |
CONTRIBUTING.rst | D | 22-Nov-2023 | 305 | 12 | 8 | |
ChangeLog.rst | D | 22-Nov-2023 | 34.9 KiB | 915 | 649 | |
LICENSE.rst | D | 22-Nov-2023 | 1.3 KiB | 24 | 19 | |
README.rst | D | 22-Nov-2023 | 16.7 KiB | 429 | 321 |
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