| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1 |
Overview |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2 |
======== |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4 |
**{fmt}** is an open-source formatting library providing a fast and safe |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5 |
alternative to C stdio and C++ iostreams. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7 |
.. raw:: html |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9 |
<div class="panel panel-default"> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10 |
<div class="panel-heading">What users say:</div> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11 |
<div class="panel-body"> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12 |
Thanks for creating this library. It’s been a hole in C++ for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13 |
a long time. I’ve used both <code>boost::format</code> and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14 |
<code>loki::SPrintf</code>, and neither felt like the right answer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
15 |
This does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
16 |
</div> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
17 |
</div> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
18 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
19 |
.. _format-api-intro: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
20 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
21 |
Format API |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
22 |
---------- |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
23 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
24 |
The format API is similar in spirit to the C ``printf`` family of function but |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
25 |
is safer, simpler and several times `faster |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
26 |
<https://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
27 |
than common standard library implementations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
28 |
The `format string syntax <syntax.html>`_ is similar to the one used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
29 |
`str.format <https://docs.python.org/3/library/stdtypes.html#str.format>`_ in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
30 |
Python: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
31 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
32 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
33 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
34 |
std::string s = fmt::format("The answer is {}.", 42); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
35 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
36 |
The ``fmt::format`` function returns a string "The answer is 42.". You can use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
37 |
``fmt::memory_buffer`` to avoid constructing ``std::string``: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
38 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
39 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
40 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
41 |
auto out = fmt::memory_buffer(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
42 |
format_to(std::back_inserter(out), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
43 |
"For a moment, {} happened.", "nothing"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
44 |
auto data = out.data(); // pointer to the formatted data |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
45 |
auto size = out.size(); // size of the formatted data |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
46 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
47 |
The ``fmt::print`` function performs formatting and writes the result to a stream: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
48 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
49 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
50 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
51 |
fmt::print(stderr, "System error code = {}\n", errno); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
52 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
53 |
If you omit the file argument the function will print to ``stdout``: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
54 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
55 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
56 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
57 |
fmt::print("Don't {}\n", "panic"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
58 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
59 |
The format API also supports positional arguments useful for localization: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
60 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
61 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
62 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
63 |
fmt::print("I'd rather be {1} than {0}.", "right", "happy"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
64 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
65 |
You can pass named arguments with ``fmt::arg``: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
66 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
67 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
68 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
69 |
fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
70 |
fmt::arg("name", "World"), fmt::arg("number", 42)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
71 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
72 |
If your compiler supports C++11 user-defined literals, the suffix ``_a`` offers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
73 |
an alternative, slightly terser syntax for named arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
74 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
75 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
76 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
77 |
using namespace fmt::literals; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
78 |
fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
79 |
"name"_a="World", "number"_a=42); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
80 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
81 |
.. _safety: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
82 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
83 |
Safety |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
84 |
------ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
85 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
86 |
The library is fully type safe, automatic memory management prevents buffer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
87 |
overflow, errors in format strings are reported using exceptions or at compile |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
88 |
time. For example, the code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
89 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
90 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
91 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
92 |
fmt::format("The answer is {:d}", "forty-two"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
93 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
94 |
throws the ``format_error`` exception because the argument ``"forty-two"`` is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
95 |
string while the format code ``d`` only applies to integers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
96 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
97 |
The code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
98 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
99 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
100 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
101 |
format(FMT_STRING("The answer is {:d}"), "forty-two"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
102 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
103 |
reports a compile-time error on compilers that support relaxed ``constexpr``. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
104 |
See `here <api.html#c.fmt>`_ for details. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
105 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
106 |
The following code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
108 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
109 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
110 |
fmt::format("Cyrillic letter {}", L'\x42e'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
111 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
112 |
produces a compile-time error because wide character ``L'\x42e'`` cannot be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
113 |
formatted into a narrow string. For comparison, writing a wide character to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
114 |
``std::ostream`` results in its numeric value being written to the stream |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
115 |
(i.e. 1070 instead of letter 'ю' which is represented by ``L'\x42e'`` if we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
116 |
use Unicode) which is rarely desirable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
117 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
118 |
Compact Binary Code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
119 |
------------------- |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
120 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
121 |
The library produces compact per-call compiled code. For example |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
122 |
(`godbolt <https://godbolt.org/g/TZU4KF>`_), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
123 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
124 |
.. code:: c++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
125 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
126 |
#include <fmt/core.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
127 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
128 |
int main() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
129 |
fmt::print("The answer is {}.", 42); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
130 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
131 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
132 |
compiles to just |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
134 |
.. code:: asm |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
135 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
136 |
main: # @main |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
137 |
sub rsp, 24 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
138 |
mov qword ptr [rsp], 42 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
139 |
mov rcx, rsp |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
140 |
mov edi, offset .L.str |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
141 |
mov esi, 17 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
142 |
mov edx, 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
143 |
call fmt::v7::vprint(fmt::v7::basic_string_view<char>, fmt::v7::format_args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
144 |
xor eax, eax |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
145 |
add rsp, 24 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
146 |
ret |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
147 |
.L.str: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
148 |
.asciz "The answer is {}." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
150 |
.. _portability: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
151 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
152 |
Portability |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
153 |
----------- |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
154 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
155 |
The library is highly portable and relies only on a small set of C++11 features: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
157 |
* variadic templates |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
158 |
* type traits |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
159 |
* rvalue references |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
160 |
* decltype |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
161 |
* trailing return types |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
162 |
* deleted functions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
163 |
* alias templates |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
164 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
165 |
These are available in GCC 4.8, Clang 3.4, MSVC 19.0 (2015) and more recent |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
166 |
compiler version. For older compilers use {fmt} `version 4.x |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
167 |
<https://github.com/fmtlib/fmt/releases/tag/4.1.0>`_ which is maintained and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
168 |
only requires C++98. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
169 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
170 |
The output of all formatting functions is consistent across platforms. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
171 |
For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
172 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
173 |
.. code:: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
175 |
fmt::print("{}", std::numeric_limits<double>::infinity()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
177 |
always prints ``inf`` while the output of ``printf`` is platform-dependent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
178 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
179 |
.. _ease-of-use: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
180 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
181 |
Ease of Use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
182 |
----------- |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
183 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
184 |
{fmt} has a small self-contained code base with the core library consisting of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
185 |
just three header files and no external dependencies. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
186 |
A permissive MIT `license <https://github.com/fmtlib/fmt#license>`_ allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
187 |
using the library both in open-source and commercial projects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
188 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
189 |
`Learn more... <contents.html>`_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
190 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
191 |
.. raw:: html |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
192 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
193 |
<a class="btn btn-success" href="https://github.com/fmtlib/fmt">GitHub Repository</a> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
194 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
195 |
<div class="section footer"> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
196 |
<iframe src="https://ghbtns.com/github-btn.html?user=fmtlib&repo=fmt&type=watch&count=true" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
197 |
class="github-btn" width="100" height="20"></iframe> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
198 |
</div> |
|
|
1970-01-01 00:00 |
199 |
|