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