| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
1 |
# API Reference |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
2 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
3 |
The {fmt} library API consists of the following components: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
4 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
5 |
- [`fmt/base.h`](#base-api): the base API providing main formatting functions |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
6 |
for `char`/UTF-8 with C++20 compile-time checks and minimal dependencies |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
7 |
- [`fmt/format.h`](#format-api): `fmt::format` and other formatting functions |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
8 |
as well as locale support |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
9 |
- [`fmt/ranges.h`](#ranges-api): formatting of ranges and tuples |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
10 |
- [`fmt/chrono.h`](#chrono-api): date and time formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
11 |
- [`fmt/std.h`](#std-api): formatters for standard library types |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
12 |
- [`fmt/compile.h`](#compile-api): format string compilation |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
13 |
- [`fmt/color.h`](#color-api): terminal colors and text styles |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
14 |
- [`fmt/os.h`](#os-api): system APIs |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
15 |
- [`fmt/ostream.h`](#ostream-api): `std::ostream` support |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
16 |
- [`fmt/args.h`](#args-api): dynamic argument lists |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
17 |
- [`fmt/printf.h`](#printf-api): safe `printf` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
18 |
- [`fmt/xchar.h`](#xchar-api): optional `wchar_t` support |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
19 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
20 |
All functions and types provided by the library reside in namespace `fmt` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
21 |
and macros have prefix `FMT_`. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
22 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
23 |
## Base API |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
24 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
25 |
`fmt/base.h` defines the base API which provides main formatting functions |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
26 |
for `char`/UTF-8 with C++20 compile-time checks. It has minimal include |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
27 |
dependencies for better compile times. This header is only beneficial when |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
28 |
using {fmt} as a library (the default) and not in the header-only mode. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
29 |
It also provides `formatter` specializations for the following types: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
30 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
31 |
- `int`, `long long`, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
32 |
- `unsigned`, `unsigned long long` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
33 |
- `float`, `double`, `long double` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
34 |
- `bool` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
35 |
- `char` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
36 |
- `const char*`, [`fmt::string_view`](#basic_string_view) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
37 |
- `const void*` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
38 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
39 |
The following functions use [format string syntax](syntax.md) similar to that |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
40 |
of [str.format](https://docs.python.org/3/library/stdtypes.html#str.format) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
41 |
in Python. They take *fmt* and *args* as arguments. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
42 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
43 |
*fmt* is a format string that contains literal text and replacement fields |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
44 |
surrounded by braces `{}`. The fields are replaced with formatted arguments |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
45 |
in the resulting string. [`fmt::format_string`](#format_string) is a format |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
46 |
string which can be implicitly constructed from a string literal or a |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
47 |
`constexpr` string and is checked at compile time in C++20. To pass a runtime |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
48 |
format string wrap it in [`fmt::runtime`](#runtime). |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
49 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
50 |
*args* is an argument list representing objects to be formatted. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
51 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
52 |
I/O errors are reported as [`std::system_error`]( |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
53 |
https://en.cppreference.com/w/cpp/error/system_error) exceptions unless |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
54 |
specified otherwise. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
55 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
56 |
::: print(format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
57 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
58 |
::: print(FILE*, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
59 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
60 |
::: println(format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
61 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
62 |
::: println(FILE*, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
63 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
64 |
::: format_to(OutputIt&&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
65 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
66 |
::: format_to_n(OutputIt, size_t, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
67 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
68 |
::: format_to_n_result |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
69 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
70 |
::: formatted_size(format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
71 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
72 |
<a id="udt"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
73 |
### Formatting User-Defined Types |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
74 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
75 |
The {fmt} library provides formatters for many standard C++ types. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
76 |
See [`fmt/ranges.h`](#ranges-api) for ranges and tuples including standard |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
77 |
containers such as `std::vector`, [`fmt/chrono.h`](#chrono-api) for date and |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
78 |
time formatting and [`fmt/std.h`](#std-api) for other standard library types. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
79 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
80 |
There are two ways to make a user-defined type formattable: providing a |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
81 |
`format_as` function or specializing the `formatter` struct template. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
82 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
83 |
Use `format_as` if you want to make your type formattable as some other |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
84 |
type with the same format specifiers. The `format_as` function should |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
85 |
take an object of your type and return an object of a formattable type. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
86 |
It should be defined in the same namespace as your type. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
87 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
88 |
Example ([run](https://godbolt.org/z/nvME4arz8)): |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
89 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
90 |
#include <fmt/format.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
91 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
92 |
namespace kevin_namespacy { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
93 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
94 |
enum class film { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
95 |
house_of_cards, american_beauty, se7en = 7 |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
96 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
97 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
98 |
auto format_as(film f) { return fmt::underlying(f); } |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
99 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
100 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
101 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
102 |
int main() { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
103 |
fmt::print("{}\n", kevin_namespacy::film::se7en); // Output: 7 |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
104 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
105 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
106 |
Using specialization is more complex but gives you full control over |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
107 |
parsing and formatting. To use this method specialize the `formatter` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
108 |
struct template for your type and implement `parse` and `format` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
109 |
methods. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
110 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
111 |
The recommended way of defining a formatter is by reusing an existing |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
112 |
one via inheritance or composition. This way you can support standard |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
113 |
format specifiers without implementing them yourself. For example: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
114 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
115 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
116 |
// color.h: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
117 |
#include <fmt/base.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
118 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
119 |
enum class color {red, green, blue}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
120 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
121 |
template <> struct fmt::formatter<color>: formatter<string_view> { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
122 |
// parse is inherited from formatter<string_view>. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
123 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
124 |
auto format(color c, format_context& ctx) const |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
125 |
-> format_context::iterator; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
126 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
127 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
128 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
129 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
130 |
// color.cc: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
131 |
#include "color.h" |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
132 |
#include <fmt/format.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
133 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
134 |
auto fmt::formatter<color>::format(color c, format_context& ctx) const |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
135 |
-> format_context::iterator { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
136 |
string_view name = "unknown"; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
137 |
switch (c) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
138 |
case color::red: name = "red"; break; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
139 |
case color::green: name = "green"; break; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
140 |
case color::blue: name = "blue"; break; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
141 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
142 |
return formatter<string_view>::format(name, ctx); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
143 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
144 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
145 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
146 |
Note that `formatter<string_view>::format` is defined in `fmt/format.h` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
147 |
so it has to be included in the source file. Since `parse` is inherited |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
148 |
from `formatter<string_view>` it will recognize all string format |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
149 |
specifications, for example |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
150 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
151 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
152 |
fmt::format("{:>10}", color::blue) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
153 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
154 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
155 |
will return `" blue"`. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
156 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
157 |
<!-- The experimental `nested_formatter` provides an easy way of applying a |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
158 |
formatter to one or more subobjects. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
159 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
160 |
For example: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
161 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
162 |
#include <fmt/format.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
163 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
164 |
struct point { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
165 |
double x, y; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
166 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
167 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
168 |
template <> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
169 |
struct fmt::formatter<point> : nested_formatter<double> { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
170 |
auto format(point p, format_context& ctx) const { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
171 |
return write_padded(ctx, [=](auto out) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
172 |
return format_to(out, "({}, {})", this->nested(p.x), |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
173 |
this->nested(p.y)); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
174 |
}); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
175 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
176 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
177 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
178 |
int main() { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
179 |
fmt::print("[{:>20.2f}]", point{1, 2}); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
180 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
181 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
182 |
prints: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
183 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
184 |
[ (1.00, 2.00)] |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
185 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
186 |
Notice that fill, align and width are applied to the whole object which |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
187 |
is the recommended behavior while the remaining specifiers apply to |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
188 |
elements. --> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
189 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
190 |
In general the formatter has the following form: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
191 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
192 |
template <> struct fmt::formatter<T> { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
193 |
// Parses format specifiers and stores them in the formatter. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
194 |
// |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
195 |
// [ctx.begin(), ctx.end()) is a, possibly empty, character range that |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
196 |
// contains a part of the format string starting from the format |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
197 |
// specifications to be parsed, e.g. in |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
198 |
// |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
199 |
// fmt::format("{:f} continued", ...); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
200 |
// |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
201 |
// the range will contain "f} continued". The formatter should parse |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
202 |
// specifiers until '}' or the end of the range. In this example the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
203 |
// formatter should parse the 'f' specifier and return an iterator |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
204 |
// pointing to '}'. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
205 |
constexpr auto parse(format_parse_context& ctx) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
206 |
-> format_parse_context::iterator; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
207 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
208 |
// Formats value using the parsed format specification stored in this |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
209 |
// formatter and writes the output to ctx.out(). |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
210 |
auto format(const T& value, format_context& ctx) const |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
211 |
-> format_context::iterator; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
212 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
213 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
214 |
It is recommended to at least support fill, align and width that apply |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
215 |
to the whole object and have the same semantics as in standard |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
216 |
formatters. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
217 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
218 |
You can also write a formatter for a hierarchy of classes: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
219 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
220 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
221 |
// demo.h: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
222 |
#include <type_traits> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
223 |
#include <fmt/core.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
224 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
225 |
struct A { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
226 |
virtual ~A() {} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
227 |
virtual std::string name() const { return "A"; } |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
228 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
229 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
230 |
struct B : A { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
231 |
virtual std::string name() const { return "B"; } |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
232 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
233 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
234 |
template <typename T> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
235 |
struct fmt::formatter<T, std::enable_if_t<std::is_base_of_v<A, T>, char>> : |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
236 |
fmt::formatter<std::string> { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
237 |
auto format(const A& a, format_context& ctx) const { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
238 |
return formatter<std::string>::format(a.name(), ctx); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
239 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
240 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
241 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
242 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
243 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
244 |
// demo.cc: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
245 |
#include "demo.h" |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
246 |
#include <fmt/format.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
247 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
248 |
int main() { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
249 |
B b; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
250 |
A& a = b; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
251 |
fmt::print("{}", a); // Output: B |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
252 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
253 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
254 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
255 |
Providing both a `formatter` specialization and a `format_as` overload is |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
256 |
disallowed. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
257 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
258 |
::: basic_format_parse_context |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
259 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
260 |
::: context |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
261 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
262 |
::: format_context |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
263 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
264 |
### Compile-Time Checks |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
265 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
266 |
Compile-time format string checks are enabled by default on compilers |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
267 |
that support C++20 `consteval`. On older compilers you can use the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
268 |
[FMT_STRING](#legacy-checks) macro defined in `fmt/format.h` instead. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
269 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
270 |
Unused arguments are allowed as in Python's `str.format` and ordinary functions. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
271 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
272 |
::: basic_format_string |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
273 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
274 |
::: format_string |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
275 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
276 |
::: runtime(string_view) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
277 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
278 |
### Named Arguments |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
279 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
280 |
::: arg(const Char*, const T&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
281 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
282 |
Named arguments are not supported in compile-time checks at the moment. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
283 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
284 |
### Type Erasure |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
285 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
286 |
You can create your own formatting function with compile-time checks and |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
287 |
small binary footprint, for example ([run](https://godbolt.org/z/b9Pbasvzc)): |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
288 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
289 |
```c++ |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
290 |
#include <fmt/format.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
291 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
292 |
void vlog(const char* file, int line, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
293 |
fmt::string_view fmt, fmt::format_args args) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
294 |
fmt::print("{}: {}: {}", file, line, fmt::vformat(fmt, args)); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
295 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
296 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
297 |
template <typename... T> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
298 |
void log(const char* file, int line, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
299 |
fmt::format_string<T...> fmt, T&&... args) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
300 |
vlog(file, line, fmt, fmt::make_format_args(args...)); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
301 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
302 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
303 |
#define MY_LOG(fmt, ...) log(__FILE__, __LINE__, fmt, __VA_ARGS__) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
304 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
305 |
MY_LOG("invalid squishiness: {}", 42); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
306 |
``` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
307 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
308 |
Note that `vlog` is not parameterized on argument types which improves |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
309 |
compile times and reduces binary code size compared to a fully |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
310 |
parameterized version. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
311 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
312 |
::: make_format_args(T&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
313 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
314 |
::: basic_format_args |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
315 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
316 |
::: format_args |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
317 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
318 |
::: basic_format_arg |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
319 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
320 |
### Compatibility |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
321 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
322 |
::: basic_string_view |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
323 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
324 |
::: string_view |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
325 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
326 |
## Format API |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
327 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
328 |
`fmt/format.h` defines the full format API providing additional |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
329 |
formatting functions and locale support. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
330 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
331 |
<a id="format"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
332 |
::: format(format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
333 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
334 |
::: vformat(string_view, format_args) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
335 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
336 |
::: operator""_a() |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
337 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
338 |
### Utilities |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
339 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
340 |
::: ptr(T) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
341 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
342 |
::: underlying(Enum) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
343 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
344 |
::: to_string(const T&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
345 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
346 |
::: group_digits(T) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
347 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
348 |
::: detail::buffer |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
349 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
350 |
::: basic_memory_buffer |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
351 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
352 |
### System Errors |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
353 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
354 |
{fmt} does not use `errno` to communicate errors to the user, but it may |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
355 |
call system functions which set `errno`. Users should not make any |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
356 |
assumptions about the value of `errno` being preserved by library |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
357 |
functions. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
358 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
359 |
::: system_error |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
360 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
361 |
::: format_system_error |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
362 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
363 |
### Custom Allocators |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
364 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
365 |
The {fmt} library supports custom dynamic memory allocators. A custom |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
366 |
allocator class can be specified as a template argument to |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
367 |
[`fmt::basic_memory_buffer`](#basic_memory_buffer): |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
368 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
369 |
using custom_memory_buffer = |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
370 |
fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
371 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
372 |
It is also possible to write a formatting function that uses a custom |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
373 |
allocator: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
374 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
375 |
using custom_string = |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
376 |
std::basic_string<char, std::char_traits<char>, custom_allocator>; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
377 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
378 |
custom_string vformat(custom_allocator alloc, fmt::string_view format_str, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
379 |
fmt::format_args args) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
380 |
auto buf = custom_memory_buffer(alloc); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
381 |
fmt::vformat_to(std::back_inserter(buf), format_str, args); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
382 |
return custom_string(buf.data(), buf.size(), alloc); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
383 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
384 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
385 |
template <typename ...Args> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
386 |
inline custom_string format(custom_allocator alloc, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
387 |
fmt::string_view format_str, |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
388 |
const Args& ... args) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
389 |
return vformat(alloc, format_str, fmt::make_format_args(args...)); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
390 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
391 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
392 |
The allocator will be used for the output container only. Formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
393 |
functions normally don't do any allocations for built-in and string |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
394 |
types except for non-default floating-point formatting that occasionally |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
395 |
falls back on `sprintf`. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
396 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
397 |
### Locale |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
398 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
399 |
All formatting is locale-independent by default. Use the `'L'` format |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
400 |
specifier to insert the appropriate number separator characters from the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
401 |
locale: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
402 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
403 |
#include <fmt/core.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
404 |
#include <locale> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
405 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
406 |
std::locale::global(std::locale("en_US.UTF-8")); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
407 |
auto s = fmt::format("{:L}", 1000000); // s == "1,000,000" |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
408 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
409 |
`fmt/format.h` provides the following overloads of formatting functions |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
410 |
that take `std::locale` as a parameter. The locale type is a template |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
411 |
parameter to avoid the expensive `<locale>` include. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
412 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
413 |
::: format(const Locale&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
414 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
415 |
::: format_to(OutputIt, const Locale&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
416 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
417 |
::: formatted_size(const Locale&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
418 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
419 |
<a id="legacy-checks"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
420 |
### Legacy Compile-Time Checks |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
421 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
422 |
`FMT_STRING` enables compile-time checks on older compilers. It requires |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
423 |
C++14 or later and is a no-op in C++11. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
424 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
425 |
::: FMT_STRING |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
426 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
427 |
To force the use of legacy compile-time checks, define the preprocessor |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
428 |
variable `FMT_ENFORCE_COMPILE_STRING`. When set, functions accepting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
429 |
`FMT_STRING` will fail to compile with regular strings. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
430 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
431 |
<a id="ranges-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
432 |
## Range and Tuple Formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
433 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
434 |
`fmt/ranges.h` provides formatting support for ranges and tuples: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
435 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
436 |
#include <fmt/ranges.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
437 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
438 |
fmt::print("{}", std::tuple<char, int>{'a', 42}); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
439 |
// Output: ('a', 42) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
440 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
441 |
Using `fmt::join`, you can separate tuple elements with a custom separator: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
442 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
443 |
#include <fmt/ranges.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
444 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
445 |
auto t = std::tuple<int, char>{1, 'a'}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
446 |
fmt::print("{}", fmt::join(t, ", ")); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
447 |
// Output: 1, a |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
448 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
449 |
::: join(Range&&, string_view) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
450 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
451 |
::: join(It, Sentinel, string_view) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
452 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
453 |
::: join(std::initializer_list<T>, string_view) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
454 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
455 |
<a id="chrono-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
456 |
## Date and Time Formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
457 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
458 |
`fmt/chrono.h` provides formatters for |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
459 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
460 |
- [`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
461 |
- [`std::chrono::time_point`]( |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
462 |
https://en.cppreference.com/w/cpp/chrono/time_point) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
463 |
- [`std::tm`](https://en.cppreference.com/w/cpp/chrono/c/tm) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
464 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
465 |
The format syntax is described in [Chrono Format Specifications](syntax.md# |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
466 |
chrono-format-specifications). |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
467 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
468 |
**Example**: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
469 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
470 |
#include <fmt/chrono.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
471 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
472 |
int main() { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
473 |
std::time_t t = std::time(nullptr); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
474 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
475 |
fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t)); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
476 |
// Output: The date is 2020-11-07. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
477 |
// (with 2020-11-07 replaced by the current date) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
478 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
479 |
using namespace std::literals::chrono_literals; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
480 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
481 |
fmt::print("Default format: {} {}\n", 42s, 100ms); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
482 |
// Output: Default format: 42s 100ms |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
483 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
484 |
fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
485 |
// Output: strftime-like format: 03:15:30 |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
486 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
487 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
488 |
::: localtime(std::time_t) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
489 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
490 |
::: gmtime(std::time_t) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
491 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
492 |
<a id="std-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
493 |
## Standard Library Types Formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
494 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
495 |
`fmt/std.h` provides formatters for: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
496 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
497 |
- [`std::atomic`](https://en.cppreference.com/w/cpp/atomic/atomic) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
498 |
- [`std::atomic_flag`](https://en.cppreference.com/w/cpp/atomic/atomic_flag) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
499 |
- [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
500 |
- [`std::error_code`](https://en.cppreference.com/w/cpp/error/error_code) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
501 |
- [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
502 |
- [`std::monostate`](https://en.cppreference.com/w/cpp/utility/variant/monostate) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
503 |
- [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
504 |
- [`std::source_location`](https://en.cppreference.com/w/cpp/utility/source_location) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
505 |
- [`std::thread::id`](https://en.cppreference.com/w/cpp/thread/thread/id) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
506 |
- [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant/variant) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
507 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
508 |
::: ptr(const std::unique_ptr<T, Deleter>&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
509 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
510 |
::: ptr(const std::shared_ptr<T>&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
511 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
512 |
### Formatting Variants |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
513 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
514 |
A `std::variant` is only formattable if every variant alternative is |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
515 |
formattable, and requires the `__cpp_lib_variant` [library |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
516 |
feature](https://en.cppreference.com/w/cpp/feature_test). |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
517 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
518 |
**Example**: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
519 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
520 |
#include <fmt/std.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
521 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
522 |
fmt::print("{}", std::variant<char, float>('x')); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
523 |
// Output: variant('x') |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
524 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
525 |
fmt::print("{}", std::variant<std::monostate, char>()); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
526 |
// Output: variant(monostate) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
527 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
528 |
<a id="compile-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
529 |
## Format String Compilation |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
530 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
531 |
`fmt/compile.h` provides format string compilation enabled via the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
532 |
`FMT_COMPILE` macro or the `_cf` user-defined literal defined in |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
533 |
namespace `fmt::literals`. Format strings marked with `FMT_COMPILE` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
534 |
or `_cf` are parsed, checked and converted into efficient formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
535 |
code at compile-time. This supports arguments of built-in and string |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
536 |
types as well as user-defined types with `format` functions taking |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
537 |
the format context type as a template parameter in their `formatter` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
538 |
specializations. For example: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
539 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
540 |
template <> struct fmt::formatter<point> { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
541 |
constexpr auto parse(format_parse_context& ctx); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
542 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
543 |
template <typename FormatContext> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
544 |
auto format(const point& p, FormatContext& ctx) const; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
545 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
546 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
547 |
Format string compilation can generate more binary code compared to the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
548 |
default API and is only recommended in places where formatting is a |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
549 |
performance bottleneck. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
550 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
551 |
::: FMT_COMPILE |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
552 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
553 |
::: operator""_cf |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
554 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
555 |
<a id="color-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
556 |
## Terminal Colors and Text Styles |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
557 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
558 |
`fmt/color.h` provides support for terminal color and text style output. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
559 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
560 |
::: print(const text_style&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
561 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
562 |
::: fg(detail::color_type) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
563 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
564 |
::: bg(detail::color_type) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
565 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
566 |
::: styled(const T&, text_style) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
567 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
568 |
<a id="os-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
569 |
## System APIs |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
570 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
571 |
::: ostream |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
572 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
573 |
::: windows_error |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
574 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
575 |
<a id="ostream-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
576 |
## `std::ostream` Support |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
577 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
578 |
`fmt/ostream.h` provides `std::ostream` support including formatting of |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
579 |
user-defined types that have an overloaded insertion operator |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
580 |
(`operator<<`). In order to make a type formattable via `std::ostream` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
581 |
you should provide a `formatter` specialization inherited from |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
582 |
`ostream_formatter`: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
583 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
584 |
#include <fmt/ostream.h> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
585 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
586 |
struct date { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
587 |
int year, month, day; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
588 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
589 |
friend std::ostream& operator<<(std::ostream& os, const date& d) { |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
590 |
return os << d.year << '-' << d.month << '-' << d.day; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
591 |
} |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
592 |
}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
593 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
594 |
template <> struct fmt::formatter<date> : ostream_formatter {}; |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
595 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
596 |
std::string s = fmt::format("The date is {}", date{2012, 12, 9}); |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
597 |
// s == "The date is 2012-12-9" |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
598 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
599 |
::: streamed(const T&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
600 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
601 |
::: print(std::ostream&, format_string<T...>, T&&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
602 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
603 |
<a id="args-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
604 |
## Dynamic Argument Lists |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
605 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
606 |
The header `fmt/args.h` provides `dynamic_format_arg_store`, a builder-like API |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
607 |
that can be used to construct format argument lists dynamically. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
608 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
609 |
::: dynamic_format_arg_store |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
610 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
611 |
<a id="printf-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
612 |
## Safe `printf` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
613 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
614 |
The header `fmt/printf.h` provides `printf`-like formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
615 |
functionality. The following functions use [printf format string |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
616 |
syntax](https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
617 |
with the POSIX extension for positional arguments. Unlike their standard |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
618 |
counterparts, the `fmt` functions are type-safe and throw an exception |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
619 |
if an argument type doesn't match its format specification. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
620 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
621 |
::: printf(string_view, const T&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
622 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
623 |
::: fprintf(std::FILE*, const S&, const T&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
624 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
625 |
::: sprintf(const S&, const T&...) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
626 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
627 |
<a id="xchar-api"></a> |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
628 |
## Wide Strings |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
629 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
630 |
The optional header `fmt/xchar.h` provides support for `wchar_t` and |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
631 |
exotic character types. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
632 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
633 |
::: is_char |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
634 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
635 |
::: wstring_view |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
636 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
637 |
::: wformat_context |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
638 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
639 |
::: to_wstring(const T&) |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
640 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
641 |
## Compatibility with C++20 `std::format` |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
642 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
643 |
{fmt} implements nearly all of the [C++20 formatting |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
644 |
library](https://en.cppreference.com/w/cpp/utility/format) with the |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
645 |
following differences: |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
646 |
|
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
647 |
- Names are defined in the `fmt` namespace instead of `std` to avoid |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
648 |
collisions with standard library implementations. |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
649 |
- Width calculation doesn't use grapheme clusterization. The latter has |
| 47fd5c32 |
Poul Sander |
2024-10-05 08:44 |
650 |
been implemented in a separate branch but hasn't been integrated yet. |
|
|
1970-01-01 00:00 |
651 |
|