You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

485 lines
19 KiB

  1. <img src="https://user-images.githubusercontent.com/576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png" alt="{fmt}" width="25%"/>
  2. [![image](https://github.com/fmtlib/fmt/workflows/linux/badge.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux)
  3. [![image](https://github.com/fmtlib/fmt/workflows/macos/badge.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos)
  4. [![image](https://github.com/fmtlib/fmt/workflows/windows/badge.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows)
  5. [![fmt is continuously fuzzed at oss-fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?\%0Acolspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\%0ASummary&q=proj%3Dfmt&can=1)
  6. [![Ask questions at StackOverflow with the tag fmt](https://img.shields.io/badge/stackoverflow-fmt-blue.svg)](https://stackoverflow.com/questions/tagged/fmt)
  7. [![image](https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge)](https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt)
  8. **{fmt}** is an open-source formatting library providing a fast and safe
  9. alternative to C stdio and C++ iostreams.
  10. If you like this project, please consider donating to one of the funds
  11. that help victims of the war in Ukraine: <https://www.stopputin.net/>.
  12. [Documentation](https://fmt.dev)
  13. [Cheat Sheets](https://hackingcpp.com/cpp/libs/fmt.html)
  14. Q&A: ask questions on [StackOverflow with the tag
  15. fmt](https://stackoverflow.com/questions/tagged/fmt).
  16. Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v).
  17. # Features
  18. - Simple [format API](https://fmt.dev/latest/api/) with positional
  19. arguments for localization
  20. - Implementation of [C++20
  21. std::format](https://en.cppreference.com/w/cpp/utility/format) and
  22. [C++23 std::print](https://en.cppreference.com/w/cpp/io/print)
  23. - [Format string syntax](https://fmt.dev/latest/syntax/) similar
  24. to Python\'s
  25. [format](https://docs.python.org/3/library/stdtypes.html#str.format)
  26. - Fast IEEE 754 floating-point formatter with correct rounding,
  27. shortness and round-trip guarantees using the
  28. [Dragonbox](https://github.com/jk-jeon/dragonbox) algorithm
  29. - Portable Unicode support
  30. - Safe [printf
  31. implementation](https://fmt.dev/latest/api/#printf-formatting)
  32. including the POSIX extension for positional arguments
  33. - Extensibility: [support for user-defined
  34. types](https://fmt.dev/latest/api/#formatting-user-defined-types)
  35. - High performance: faster than common standard library
  36. implementations of `(s)printf`, iostreams, `to_string` and
  37. `to_chars`, see [Speed tests](#speed-tests) and [Converting a
  38. hundred million integers to strings per
  39. second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html)
  40. - Small code size both in terms of source code with the minimum
  41. configuration consisting of just three files, `core.h`, `format.h`
  42. and `format-inl.h`, and compiled code; see [Compile time and code
  43. bloat](#compile-time-and-code-bloat)
  44. - Reliability: the library has an extensive set of
  45. [tests](https://github.com/fmtlib/fmt/tree/master/test) and is
  46. [continuously fuzzed](https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1)
  47. - Safety: the library is fully type-safe, errors in format strings can
  48. be reported at compile time, automatic memory management prevents
  49. buffer overflow errors
  50. - Ease of use: small self-contained code base, no external
  51. dependencies, permissive MIT
  52. [license](https://github.com/fmtlib/fmt/blob/master/LICENSE)
  53. - [Portability](https://fmt.dev/latest/#portability) with
  54. consistent output across platforms and support for older compilers
  55. - Clean warning-free codebase even on high warning levels such as
  56. `-Wall -Wextra -pedantic`
  57. - Locale independence by default
  58. - Optional header-only configuration enabled with the
  59. `FMT_HEADER_ONLY` macro
  60. See the [documentation](https://fmt.dev) for more details.
  61. # Examples
  62. **Print to stdout** ([run](https://godbolt.org/z/Tevcjh))
  63. ``` c++
  64. #include <fmt/core.h>
  65. int main() {
  66. fmt::print("Hello, world!\n");
  67. }
  68. ```
  69. **Format a string** ([run](https://godbolt.org/z/oK8h33))
  70. ``` c++
  71. std::string s = fmt::format("The answer is {}.", 42);
  72. // s == "The answer is 42."
  73. ```
  74. **Format a string using positional arguments**
  75. ([run](https://godbolt.org/z/Yn7Txe))
  76. ``` c++
  77. std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
  78. // s == "I'd rather be happy than right."
  79. ```
  80. **Print dates and times** ([run](https://godbolt.org/z/c31ExdY3W))
  81. ``` c++
  82. #include <fmt/chrono.h>
  83. int main() {
  84. auto now = std::chrono::system_clock::now();
  85. fmt::print("Date and time: {}\n", now);
  86. fmt::print("Time: {:%H:%M}\n", now);
  87. }
  88. ```
  89. Output:
  90. Date and time: 2023-12-26 19:10:31.557195597
  91. Time: 19:10
  92. **Print a container** ([run](https://godbolt.org/z/MxM1YqjE7))
  93. ``` c++
  94. #include <vector>
  95. #include <fmt/ranges.h>
  96. int main() {
  97. std::vector<int> v = {1, 2, 3};
  98. fmt::print("{}\n", v);
  99. }
  100. ```
  101. Output:
  102. [1, 2, 3]
  103. **Check a format string at compile time**
  104. ``` c++
  105. std::string s = fmt::format("{:d}", "I am not a number");
  106. ```
  107. This gives a compile-time error in C++20 because `d` is an invalid
  108. format specifier for a string.
  109. **Write a file from a single thread**
  110. ``` c++
  111. #include <fmt/os.h>
  112. int main() {
  113. auto out = fmt::output_file("guide.txt");
  114. out.print("Don't {}", "Panic");
  115. }
  116. ```
  117. This can be [5 to 9 times faster than
  118. fprintf](http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html).
  119. **Print with colors and text styles**
  120. ``` c++
  121. #include <fmt/color.h>
  122. int main() {
  123. fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
  124. "Hello, {}!\n", "world");
  125. fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
  126. fmt::emphasis::underline, "Olá, {}!\n", "Mundo");
  127. fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
  128. "你好{}!\n", "世界");
  129. }
  130. ```
  131. Output on a modern terminal with Unicode support:
  132. ![image](https://github.com/fmtlib/fmt/assets/%0A576385/2a93c904-d6fa-4aa6-b453-2618e1c327d7)
  133. # Benchmarks
  134. ## Speed tests
  135. | Library | Method | Run Time, s |
  136. |-------------------|---------------|-------------|
  137. | libc | printf | 0.91 |
  138. | libc++ | std::ostream | 2.49 |
  139. | {fmt} 9.1 | fmt::print | 0.74 |
  140. | Boost Format 1.80 | boost::format | 6.26 |
  141. | Folly Format | folly::format | 1.87 |
  142. {fmt} is the fastest of the benchmarked methods, \~20% faster than
  143. `printf`.
  144. The above results were generated by building `tinyformat_test.cpp` on
  145. macOS 12.6.1 with `clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT`, and
  146. taking the best of three runs. In the test, the format string
  147. `"%0.10f:%04d:%+g:%s:%p:%c:%%\n"` or equivalent is filled 2,000,000
  148. times with output sent to `/dev/null`; for further details refer to the
  149. [source](https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc).
  150. {fmt} is up to 20-30x faster than `std::ostringstream` and `sprintf` on
  151. IEEE754 `float` and `double` formatting
  152. ([dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark)) and faster
  153. than [double-conversion](https://github.com/google/double-conversion)
  154. and [ryu](https://github.com/ulfjack/ryu):
  155. [![image](https://user-images.githubusercontent.com/576385/95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png)](https://fmt.dev/unknown_mac64_clang12.0.html)
  156. ## Compile time and code bloat
  157. The script [bloat-test.py][test] from [format-benchmark][bench] tests compile
  158. time and code bloat for nontrivial projects. It generates 100 translation units
  159. and uses `printf()` or its alternative five times in each to simulate a
  160. medium-sized project. The resulting executable size and compile time (Apple
  161. clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, best of three) is shown
  162. in the following tables.
  163. [test]: https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py
  164. [bench]: https://github.com/fmtlib/format-benchmark
  165. **Optimized build (-O3)**
  166. | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
  167. |---------------|-----------------|----------------------|--------------------|
  168. | printf | 1.6 | 54 | 50 |
  169. | IOStreams | 25.9 | 98 | 84 |
  170. | fmt 83652df | 4.8 | 54 | 50 |
  171. | tinyformat | 29.1 | 161 | 136 |
  172. | Boost Format | 55.0 | 530 | 317 |
  173. {fmt} is fast to compile and is comparable to `printf` in terms of per-call
  174. binary size (within a rounding error on this system).
  175. **Non-optimized build**
  176. | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
  177. |---------------|-----------------|----------------------|--------------------|
  178. | printf | 1.4 | 54 | 50 |
  179. | IOStreams | 23.4 | 92 | 68 |
  180. | {fmt} 83652df | 4.4 | 89 | 85 |
  181. | tinyformat | 24.5 | 204 | 161 |
  182. | Boost Format | 36.4 | 831 | 462 |
  183. `libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
  184. to compare formatting function overhead only. Boost Format is a
  185. header-only library so it doesn\'t provide any linkage options.
  186. ## Running the tests
  187. Please refer to [Building the
  188. library](https://fmt.dev/latest/get-started/#building-from-source) for
  189. instructions on how to build the library and run the unit tests.
  190. Benchmarks reside in a separate repository,
  191. [format-benchmarks](https://github.com/fmtlib/format-benchmark), so to
  192. run the benchmarks you first need to clone this repository and generate
  193. Makefiles with CMake:
  194. $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
  195. $ cd format-benchmark
  196. $ cmake .
  197. Then you can run the speed test:
  198. $ make speed-test
  199. or the bloat test:
  200. $ make bloat-test
  201. # Migrating code
  202. [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v18 provides the
  203. [modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
  204. check that is capable of converting occurrences of `printf` and
  205. `fprintf` to `fmt::print` if configured to do so. (By default it
  206. converts to `std::print`.)
  207. # Notable projects using this library
  208. - [0 A.D.](https://play0ad.com/): a free, open-source, cross-platform
  209. real-time strategy game
  210. - [AMPL/MP](https://github.com/ampl/mp): an open-source library for
  211. mathematical programming
  212. - [Apple's FoundationDB](https://github.com/apple/foundationdb): an open-source,
  213. distributed, transactional key-value store
  214. - [Aseprite](https://github.com/aseprite/aseprite): animated sprite
  215. editor & pixel art tool
  216. - [AvioBook](https://www.aviobook.aero/en): a comprehensive aircraft
  217. operations suite
  218. - [Blizzard Battle.net](https://battle.net/): an online gaming
  219. platform
  220. - [Celestia](https://celestia.space/): real-time 3D visualization of
  221. space
  222. - [Ceph](https://ceph.com/): a scalable distributed storage system
  223. - [ccache](https://ccache.dev/): a compiler cache
  224. - [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
  225. analytical database management system
  226. - [ContextVision](https://www.contextvision.com/): medical imaging software
  227. - [Contour](https://github.com/contour-terminal/contour/): a modern
  228. terminal emulator
  229. - [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
  230. underwater vehicle
  231. - [Drake](https://drake.mit.edu/): a planning, control, and analysis
  232. toolbox for nonlinear dynamical systems (MIT)
  233. - [Envoy](https://github.com/envoyproxy/envoy): C++ L7 proxy and
  234. communication bus (Lyft)
  235. - [FiveM](https://fivem.net/): a modification framework for GTA V
  236. - [fmtlog](https://github.com/MengRao/fmtlog): a performant
  237. fmtlib-style logging library with latency in nanoseconds
  238. - [Folly](https://github.com/facebook/folly): Facebook open-source
  239. library
  240. - [GemRB](https://gemrb.org/): a portable open-source implementation
  241. of Bioware's Infinity Engine
  242. - [Grand Mountain
  243. Adventure](https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/):
  244. a beautiful open-world ski & snowboarding game
  245. - [HarpyWar/pvpgn](https://github.com/pvpgn/pvpgn-server): Player vs
  246. Player Gaming Network with tweaks
  247. - [KBEngine](https://github.com/kbengine/kbengine): an open-source
  248. MMOG server engine
  249. - [Keypirinha](https://keypirinha.com/): a semantic launcher for
  250. Windows
  251. - [Kodi](https://kodi.tv/) (formerly xbmc): home theater software
  252. - [Knuth](https://kth.cash/): high-performance Bitcoin full-node
  253. - [libunicode](https://github.com/contour-terminal/libunicode/): a
  254. modern C++17 Unicode library
  255. - [MariaDB](https://mariadb.org/): relational database management
  256. system
  257. - [Microsoft Verona](https://github.com/microsoft/verona): research
  258. programming language for concurrent ownership
  259. - [MongoDB](https://mongodb.com/): distributed document database
  260. - [MongoDB Smasher](https://github.com/duckie/mongo_smasher): a small
  261. tool to generate randomized datasets
  262. - [OpenSpace](https://openspaceproject.com/): an open-source
  263. astrovisualization framework
  264. - [PenUltima Online (POL)](https://www.polserver.com/): an MMO server,
  265. compatible with most Ultima Online clients
  266. - [PyTorch](https://github.com/pytorch/pytorch): an open-source
  267. machine learning library
  268. - [quasardb](https://www.quasardb.net/): a distributed,
  269. high-performance, associative database
  270. - [Quill](https://github.com/odygrd/quill): asynchronous low-latency
  271. logging library
  272. - [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
  273. simplify navigation, and execute complex multi-line terminal
  274. command sequences
  275. - [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
  276. cluster proxy
  277. - [redpanda](https://vectorized.io/redpanda): a 10x faster Kafka®
  278. replacement for mission-critical systems written in C++
  279. - [rpclib](http://rpclib.net/): a modern C++ msgpack-RPC server and
  280. client library
  281. - [Salesforce Analytics
  282. Cloud](https://www.salesforce.com/analytics-cloud/overview/):
  283. business intelligence software
  284. - [Scylla](https://www.scylladb.com/): a Cassandra-compatible NoSQL
  285. data store that can handle 1 million transactions per second on a
  286. single server
  287. - [Seastar](http://www.seastar-project.org/): an advanced, open-source
  288. C++ framework for high-performance server applications on modern
  289. hardware
  290. - [spdlog](https://github.com/gabime/spdlog): super fast C++ logging
  291. library
  292. - [Stellar](https://www.stellar.org/): financial platform
  293. - [Touch Surgery](https://www.touchsurgery.com/): surgery simulator
  294. - [TrinityCore](https://github.com/TrinityCore/TrinityCore):
  295. open-source MMORPG framework
  296. - [🐙 userver framework](https://userver.tech/): open-source
  297. asynchronous framework with a rich set of abstractions and database
  298. drivers
  299. - [Windows Terminal](https://github.com/microsoft/terminal): the new
  300. Windows terminal
  301. [More\...](https://github.com/search?q=fmtlib&type=Code)
  302. If you are aware of other projects using this library, please let me
  303. know by [email](mailto:victor.zverovich@gmail.com) or by submitting an
  304. [issue](https://github.com/fmtlib/fmt/issues).
  305. # Motivation
  306. So why yet another formatting library?
  307. There are plenty of methods for doing this task, from standard ones like
  308. the printf family of function and iostreams to Boost Format and
  309. FastFormat libraries. The reason for creating a new library is that
  310. every existing solution that I found either had serious issues or
  311. didn\'t provide all the features I needed.
  312. ## printf
  313. The good thing about `printf` is that it is pretty fast and readily
  314. available being a part of the C standard library. The main drawback is
  315. that it doesn\'t support user-defined types. `printf` also has safety
  316. issues although they are somewhat mitigated with [\_\_attribute\_\_
  317. ((format (printf,
  318. \...))](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) in
  319. GCC. There is a POSIX extension that adds positional arguments required
  320. for
  321. [i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization)
  322. to `printf` but it is not a part of C99 and may not be available on some
  323. platforms.
  324. ## iostreams
  325. The main issue with iostreams is best illustrated with an example:
  326. ``` c++
  327. std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
  328. ```
  329. which is a lot of typing compared to printf:
  330. ``` c++
  331. printf("%.2f\n", 1.23456);
  332. ```
  333. Matthew Wilson, the author of FastFormat, called this \"chevron hell\".
  334. iostreams don\'t support positional arguments by design.
  335. The good part is that iostreams support user-defined types and are safe
  336. although error handling is awkward.
  337. ## Boost Format
  338. This is a very powerful library that supports both `printf`-like format
  339. strings and positional arguments. Its main drawback is performance.
  340. According to various benchmarks, it is much slower than other methods
  341. considered here. Boost Format also has excessive build times and severe
  342. code bloat issues (see [Benchmarks](#benchmarks)).
  343. ## FastFormat
  344. This is an interesting library that is fast, safe and has positional
  345. arguments. However, it has significant limitations, citing its author:
  346. > Three features that have no hope of being accommodated within the
  347. > current design are:
  348. >
  349. > - Leading zeros (or any other non-space padding)
  350. > - Octal/hexadecimal encoding
  351. > - Runtime width/alignment specification
  352. It is also quite big and has a heavy dependency, on STLSoft, which might be
  353. too restrictive for use in some projects.
  354. ## Boost Spirit.Karma
  355. This is not a formatting library but I decided to include it here for
  356. completeness. As iostreams, it suffers from the problem of mixing
  357. verbatim text with arguments. The library is pretty fast, but slower on
  358. integer formatting than `fmt::format_to` with format string compilation
  359. on Karma\'s own benchmark, see [Converting a hundred million integers to
  360. strings per
  361. second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html).
  362. # License
  363. {fmt} is distributed under the MIT
  364. [license](https://github.com/fmtlib/fmt/blob/master/LICENSE).
  365. # Documentation License
  366. The [Format String Syntax](https://fmt.dev/latest/syntax/) section
  367. in the documentation is based on the one from Python [string module
  368. documentation](https://docs.python.org/3/library/string.html#module-string).
  369. For this reason, the documentation is distributed under the Python
  370. Software Foundation license available in
  371. [doc/python-license.txt](https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt).
  372. It only applies if you distribute the documentation of {fmt}.
  373. # Maintainers
  374. The {fmt} library is maintained by Victor Zverovich
  375. ([vitaut](https://github.com/vitaut)) with contributions from many other
  376. people. See
  377. [Contributors](https://github.com/fmtlib/fmt/graphs/contributors) and
  378. [Releases](https://github.com/fmtlib/fmt/releases) for some of the
  379. names. Let us know if your contribution is not listed or mentioned
  380. incorrectly and we\'ll make it right.
  381. # Security Policy
  382. To report a security issue, please disclose it at [security
  383. advisory](https://github.com/fmtlib/fmt/security/advisories/new).
  384. This project is maintained by a team of volunteers on a
  385. reasonable-effort basis. As such, please give us at least *90* days to
  386. work on a fix before public exposure.