| # API Reference |
| |
| The {fmt} library API consists of the following components: |
| |
| - [`fmt/core.h`](#core-api): the core API providing main formatting functions |
| for `char`/UTF-8 with C++20 compile-time checks and minimal dependencies |
| - [`fmt/format.h`](#format-api): `fmt::format` and other formatting functions |
| as well as locale support |
| - [`fmt/ranges.h`](#ranges-api): formatting of ranges and tuples |
| - [`fmt/chrono.h`](#chrono-api): date and time formatting |
| - [`fmt/std.h`](#std-api): formatters for standard library types |
| - [`fmt/enum.h`](#enum-api): formatting of annotated enums |
| - [`fmt/compile.h`](#compile-api): format string compilation |
| - [`fmt/color.h`](#color-api): terminal colors and text styles |
| - [`fmt/os.h`](#os-api): system APIs |
| - [`fmt/ostream.h`](#ostream-api): `std::ostream` support |
| - [`fmt/args.h`](#args-api): dynamic argument lists |
| - [`fmt/printf.h`](#printf-api): safe `printf` |
| - [`fmt/xchar.h`](#xchar-api): optional `wchar_t` support |
| |
| All functions and types provided by the library reside in namespace `fmt` |
| and macros have prefix `FMT_`. |
| |
| ## C++ Module API |
| |
| With the C++ module API, the headers listed above don't need to be included. |
| You can use the `import fmt;` statement instead. All other functionality, |
| listed below, remains the same. |
| |
| ## Core API |
| |
| `fmt/core.h` defines the core API which provides main formatting functions |
| for `char`/UTF-8 with C++20 compile-time checks. It has minimal include |
| dependencies for better compile times. This header is only beneficial when |
| using {fmt} as a library (the default) and not in the header-only mode. |
| It also provides `formatter` specializations for the following types: |
| |
| - `int`, `long long` |
| - `unsigned`, `unsigned long long` |
| - `float`, `double`, `long double` |
| - `bool` |
| - `char` |
| - `const char*`, [`fmt::string_view`](#basic_string_view) |
| - `const void*` |
| |
| The following functions use [format string syntax](syntax.md) similar to that |
| of [str.format](https://docs.python.org/3/library/stdtypes.html#str.format) |
| in Python. They take *fmt* and *args* as arguments. |
| |
| *fmt* is a format string that contains literal text and replacement fields |
| surrounded by braces `{}`. The fields are replaced with formatted arguments |
| in the resulting string. [`fmt::format_string`](#format_string) is a format |
| string which can be implicitly constructed from a string literal or a |
| `constexpr` string and is checked at compile time in C++20. To pass a runtime |
| format string wrap it in [`fmt::runtime`](#runtime). |
| |
| *args* is an argument list representing objects to be formatted. |
| |
| I/O errors are reported as [`std::system_error`]( |
| https://en.cppreference.com/w/cpp/error/system_error) exceptions unless |
| specified otherwise. |
| |
| ::: print(format_string<T...>, T&&...) |
| |
| ::: print(FILE*, format_string<T...>, T&&...) |
| |
| ::: println(format_string<T...>, T&&...) |
| |
| ::: println(FILE*, format_string<T...>, T&&...) |
| |
| ::: format_to(OutputIt&&, format_string<T...>, T&&...) |
| |
| ::: format_to_n(OutputIt, size_t, format_string<T...>, T&&...) |
| |
| ::: format_to_n_result |
| |
| ::: formatted_size(format_string<T...>, T&&...) |
| |
| <a id="udt"></a> |
| ### Formatting User-Defined Types |
| |
| The {fmt} library provides formatters for many standard C++ types. |
| See [`fmt/ranges.h`](#ranges-api) for ranges and tuples including standard |
| containers such as `std::vector`, [`fmt/chrono.h`](#chrono-api) for date and |
| time formatting and [`fmt/std.h`](#std-api) for other standard library types. |
| |
| There are two ways to make a user-defined type formattable: providing a |
| `format_as` function or specializing the `formatter` struct template. |
| Formatting of non-void pointer types is intentionally disallowed and they |
| cannot be made formattable via either extension API. |
| |
| Use `format_as` if you want to make your type formattable as some other |
| type with the same format specifiers. The `format_as` function should |
| take an object of your type and return an object of a formattable type. |
| It should be defined in the same namespace as your type. |
| `format_as` cannot be used when a type also matches another `formatter` |
| specialization, such as the range `formatter`, because the specializations |
| would be ambiguous. Disable the conflicting specialization, if possible, |
| or provide an explicit `formatter` specialization instead. |
| |
| Example ([run](https://godbolt.org/z/nvME4arz8)): |
| |
| #include <fmt/format.h> |
| |
| namespace kevin_namespacy { |
| |
| enum class film { |
| house_of_cards, american_beauty, se7en = 7 |
| }; |
| |
| auto format_as(film f) { return fmt::underlying(f); } |
| |
| } |
| |
| int main() { |
| fmt::print("{}\n", kevin_namespacy::film::se7en); // Output: 7 |
| } |
| |
| Using a specialization is more complex, but gives you full control over |
| parsing and formatting. To use this method, specialize the `formatter` |
| struct template for your type and implement `parse` and `format` |
| methods. |
| |
| The recommended way of defining a formatter is by reusing an existing |
| one via inheritance or composition. This way you can support standard |
| format specifiers without implementing them yourself. For example: |
| |
| ```c++ |
| // color.h: |
| #include <fmt/core.h> |
| |
| enum class color {red, green, blue}; |
| |
| template <> struct fmt::formatter<color>: formatter<string_view> { |
| // parse is inherited from formatter<string_view>. |
| |
| auto format(color c, format_context& ctx) const |
| -> format_context::iterator; |
| }; |
| ``` |
| |
| ```c++ |
| // color.cc: |
| #include "color.h" |
| #include <fmt/format.h> |
| |
| auto fmt::formatter<color>::format(color c, format_context& ctx) const |
| -> format_context::iterator { |
| string_view name = "unknown"; |
| switch (c) { |
| case color::red: name = "red"; break; |
| case color::green: name = "green"; break; |
| case color::blue: name = "blue"; break; |
| } |
| return formatter<string_view>::format(name, ctx); |
| } |
| ``` |
| |
| Note that `formatter<string_view>::format` is defined in `fmt/format.h` |
| so it has to be included in the source file. Since `parse` is inherited |
| from `formatter<string_view>` it will recognize all string format |
| specifications, for example |
| |
| ```c++ |
| fmt::format("{:>10}", color::blue) |
| ``` |
| |
| will return `" blue"`. |
| |
| <!-- The experimental `nested_formatter` provides an easy way of applying a |
| formatter to one or more subobjects. |
| |
| For example: |
| |
| #include <fmt/format.h> |
| |
| struct point { |
| double x, y; |
| }; |
| |
| template <> |
| struct fmt::formatter<point> : nested_formatter<double> { |
| auto format(point p, format_context& ctx) const { |
| return write(ctx, "(", nested(p.x), ", ", nested(p.y), ")"); |
| } |
| }; |
| |
| int main() { |
| fmt::print("[{:>20.2f}]", point{1, 2}); |
| } |
| |
| prints: |
| |
| [ (1.00, 2.00)] |
| |
| Notice that fill, align and width are applied to the whole object which |
| is the recommended behavior while the remaining specifiers apply to |
| elements. --> |
| |
| In general the formatter has the following form: |
| |
| template <> struct fmt::formatter<T> { |
| // Parses format specifiers and stores them in the formatter. |
| // |
| // [ctx.begin(), ctx.end()) is a, possibly empty, character range that |
| // contains a part of the format string starting from the format |
| // specifications to be parsed, e.g. in |
| // |
| // fmt::format("{:f} continued", ...); |
| // |
| // the range will contain "f} continued". The formatter should parse |
| // specifiers until '}' or the end of the range. In this example the |
| // formatter should parse the 'f' specifier and return an iterator |
| // pointing to '}'. |
| constexpr auto parse(format_parse_context& ctx) |
| -> format_parse_context::iterator; |
| |
| // Formats value using the parsed format specification stored in this |
| // formatter and writes the output to ctx.out(). |
| auto format(const T& value, format_context& ctx) const |
| -> format_context::iterator; |
| }; |
| |
| It is recommended to at least support fill, align and width that apply |
| to the whole object and have the same semantics as in standard |
| formatters. |
| |
| You can also write a formatter for a hierarchy of classes: |
| |
| ```c++ |
| // demo.h: |
| #include <type_traits> |
| #include <fmt/format.h> |
| |
| struct A { |
| virtual ~A() {} |
| virtual std::string name() const { return "A"; } |
| }; |
| |
| struct B : A { |
| virtual std::string name() const { return "B"; } |
| }; |
| |
| template <typename T> |
| struct fmt::formatter<T, std::enable_if_t<std::is_base_of_v<A, T>, char>> : |
| fmt::formatter<std::string> { |
| auto format(const A& a, format_context& ctx) const { |
| return formatter<std::string>::format(a.name(), ctx); |
| } |
| }; |
| ``` |
| |
| ```c++ |
| // demo.cc: |
| #include "demo.h" |
| #include <fmt/format.h> |
| |
| int main() { |
| B b; |
| A& a = b; |
| fmt::print("{}", a); // Output: B |
| } |
| ``` |
| |
| Providing both a `formatter` specialization and a `format_as` overload is |
| disallowed. |
| |
| ::: basic_format_parse_context |
| |
| ::: context |
| |
| ::: format_context |
| |
| ### Compile-Time Checks |
| |
| Compile-time format string checks are enabled by default on compilers |
| that support C++20 `consteval`. On older compilers you can use the |
| [FMT_STRING](#legacy-checks) macro defined in `fmt/format.h` instead. |
| |
| Unused arguments are allowed as in Python's `str.format` and ordinary functions. |
| |
| See [Type Erasure](#type-erasure) for an example of how to enable compile-time |
| checks in your own functions with `fmt::format_string` while avoiding template |
| bloat. |
| |
| ::: fstring |
| |
| ::: format_string |
| |
| ::: runtime(string_view) |
| |
| ### Type Erasure |
| |
| You can create your own formatting function with compile-time checks and |
| small binary footprint, for example ([run](https://godbolt.org/z/b9Pbasvzc)): |
| |
| ```c++ |
| #include <fmt/format.h> |
| |
| void vlog(const char* file, int line, |
| fmt::string_view fmt, fmt::format_args args) { |
| fmt::print("{}: {}: {}", file, line, fmt::vformat(fmt, args)); |
| } |
| |
| template <typename... T> |
| void log(const char* file, int line, |
| fmt::format_string<T...> fmt, T&&... args) { |
| vlog(file, line, fmt, fmt::make_format_args(args...)); |
| } |
| |
| #define MY_LOG(fmt, ...) log(__FILE__, __LINE__, fmt, __VA_ARGS__) |
| |
| MY_LOG("invalid squishiness: {}", 42); |
| ``` |
| |
| Note that `vlog` is not parameterized on argument types which improves |
| compile times and reduces binary code size compared to a fully |
| parameterized version. |
| |
| ::: make_format_args(T&...) |
| |
| ::: basic_format_args |
| |
| ::: format_args |
| |
| ::: basic_format_arg |
| |
| ### Named Arguments |
| |
| ::: arg(const char*, const T&) |
| |
| ### Compatibility |
| |
| ::: basic_string_view |
| |
| ::: string_view |
| |
| ## Format API |
| |
| `fmt/format.h` defines the full format API providing additional |
| formatting functions and locale support. |
| |
| <a id="format"></a> |
| ::: format(format_string<T...>, T&&...) |
| |
| ::: vformat(string_view, format_args) |
| |
| ::: operator""_a() |
| |
| ### Utilities |
| |
| ::: ptr(T) |
| |
| ::: underlying(Enum) |
| |
| ::: to_string(const T&) |
| |
| ::: group_digits(T) |
| |
| ::: detail::buffer |
| |
| ::: basic_memory_buffer |
| |
| ### System Errors |
| |
| {fmt} does not use `errno` to communicate errors to the user, but it may |
| call system functions which set `errno`. Users should not make any |
| assumptions about the value of `errno` being preserved by library |
| functions. |
| |
| ::: system_error |
| |
| ::: format_system_error |
| |
| ### Custom Allocators |
| |
| The {fmt} library supports custom dynamic memory allocators. A custom |
| allocator class can be specified as a template argument to |
| [`fmt::basic_memory_buffer`](#basic_memory_buffer): |
| |
| using custom_memory_buffer = |
| fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>; |
| |
| It is also possible to write a formatting function that uses a custom |
| allocator: |
| |
| using custom_string = |
| std::basic_string<char, std::char_traits<char>, custom_allocator>; |
| |
| auto vformat(custom_allocator alloc, fmt::string_view fmt, |
| fmt::format_args args) -> custom_string { |
| auto buf = custom_memory_buffer(alloc); |
| fmt::vformat_to(std::back_inserter(buf), fmt, args); |
| return custom_string(buf.data(), buf.size(), alloc); |
| } |
| |
| template <typename ...Args> |
| auto format(custom_allocator alloc, fmt::string_view fmt, |
| const Args& ... args) -> custom_string { |
| return vformat(alloc, fmt, fmt::make_format_args(args...)); |
| } |
| |
| The allocator will be used for the output container only. Formatting |
| functions normally don't do any allocations for built-in and string |
| types except for non-default floating-point formatting that occasionally |
| falls back on `sprintf`. |
| |
| ### Locale |
| |
| All formatting is locale-independent by default. Use the `'L'` format |
| specifier to insert the appropriate number separator characters from the |
| locale: |
| |
| #include <fmt/format.h> |
| #include <locale> |
| |
| std::locale::global(std::locale("en_US.UTF-8")); |
| auto s = fmt::format("{:L}", 1000000); // s == "1,000,000" |
| |
| `fmt/format.h` provides the following overloads of formatting functions |
| that take `std::locale` as a parameter. The locale type is a template |
| parameter to avoid the expensive `<locale>` include. |
| |
| ::: format(locale_ref, format_string<T...>, T&&...) |
| |
| ::: format_to(OutputIt, locale_ref, format_string<T...>, T&&...) |
| |
| ::: formatted_size(locale_ref, format_string<T...>, T&&...) |
| |
| <a id="legacy-checks"></a> |
| ### Legacy Compile-Time Checks |
| |
| `FMT_STRING` enables compile-time checks on older compilers. It requires |
| C++14 or later and is a no-op in C++11. |
| |
| ::: FMT_STRING |
| |
| To force the use of legacy compile-time checks, define the preprocessor |
| variable `FMT_ENFORCE_COMPILE_STRING`. When set, functions accepting |
| `FMT_STRING` will fail to compile with regular strings. |
| |
| <a id="ranges-api"></a> |
| ## Range and Tuple Formatting |
| |
| `fmt/ranges.h` provides formatting support for ranges and tuples: |
| |
| #include <fmt/ranges.h> |
| |
| fmt::print("{}", std::tuple<char, int>{'a', 42}); |
| // Output: ('a', 42) |
| |
| Using `fmt::join`, you can separate tuple elements with a custom separator: |
| |
| #include <fmt/ranges.h> |
| |
| auto t = std::tuple<int, char>{1, 'a'}; |
| fmt::print("{}", fmt::join(t, ", ")); |
| // Output: 1, a |
| |
| ::: join(Range&&, string_view) |
| |
| ::: join(It, Sentinel, string_view) |
| |
| ::: join(std::initializer_list<T>, string_view) |
| |
| <a id="chrono-api"></a> |
| ## Date and Time Formatting |
| |
| `fmt/chrono.h` provides formatters for |
| |
| - [`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration) |
| - [`std::chrono::time_point`]( |
| https://en.cppreference.com/w/cpp/chrono/time_point) |
| - [`std::tm`](https://en.cppreference.com/w/cpp/chrono/c/tm) |
| |
| The format syntax is described in [Chrono Format Specifications](syntax.md# |
| chrono-format-spec). |
| |
| **Example**: |
| |
| #include <fmt/chrono.h> |
| |
| int main() { |
| auto now = std::chrono::system_clock::now(); |
| |
| fmt::print("The date is {:%Y-%m-%d}.\n", now); |
| // Output: The date is 2020-11-07. |
| // (with 2020-11-07 replaced by the current date) |
| |
| using namespace std::literals::chrono_literals; |
| |
| fmt::print("Default format: {} {}\n", 42s, 100ms); |
| // Output: Default format: 42s 100ms |
| |
| fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s); |
| // Output: strftime-like format: 03:15:30 |
| } |
| |
| ::: gmtime(std::time_t) |
| |
| <a id="std-api"></a> |
| ## Standard Library Types Formatting |
| |
| `fmt/std.h` provides formatters for: |
| |
| - [`std::atomic`](https://en.cppreference.com/w/cpp/atomic/atomic) |
| - [`std::atomic_flag`](https://en.cppreference.com/w/cpp/atomic/atomic_flag) |
| - [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset) |
| - [`std::error_code`](https://en.cppreference.com/w/cpp/error/error_code) |
| - [`std::exception`](https://en.cppreference.com/w/cpp/error/exception) |
| - [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path) |
| - [`std::monostate`]( |
| https://en.cppreference.com/w/cpp/utility/variant/monostate) |
| - [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional) |
| - [`std::source_location`]( |
| https://en.cppreference.com/w/cpp/utility/source_location) |
| - [`std::thread::id`](https://en.cppreference.com/w/cpp/thread/thread/id) |
| - [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant/variant) |
| |
| ::: ptr(const std::unique_ptr<T, Deleter>&) |
| |
| ::: ptr(const std::shared_ptr<T>&) |
| |
| ### Variants |
| |
| A `std::variant` can be formatted only if every alternative is |
| formattable, and requires the `__cpp_lib_variant` [library |
| feature](https://en.cppreference.com/w/cpp/feature_test). |
| |
| **Example**: |
| |
| #include <fmt/std.h> |
| |
| fmt::print("{}", std::variant<char, float>('x')); |
| // Output: variant('x') |
| |
| fmt::print("{}", std::variant<std::monostate, char>()); |
| // Output: variant(monostate) |
| |
| ## Bit-Fields and Packed Structs |
| |
| To format a bit-field or a field of a struct with `__attribute__((packed))` |
| applied to it, you need to convert it to the underlying or compatible type via |
| a cast or a unary `+` ([godbolt](https://www.godbolt.org/z/3qKKs6T5Y)): |
| |
| ```c++ |
| struct smol { |
| int bit : 1; |
| }; |
| |
| auto s = smol(); |
| fmt::print("{}", +s.bit); |
| ``` |
| |
| This is a known limitation of "perfect" forwarding in C++. |
| |
| <a id="enum-api"></a> |
| ## Enum Formatting |
| |
| `fmt/enum.h` provides formatting of enums annotated with |
| `fmt::as_identifiers`. Such an enum is formatted as the identifier of the |
| enumerator matching the formatted value: |
| |
| #include <fmt/enum.h> |
| |
| enum class [[=fmt::as_identifiers]] color { red, green, blue }; |
| |
| fmt::print("{}", color::green); |
| // Output: green |
| |
| Such enums are formatted using the string [Format Specification]( |
| syntax.md#format-specification), for example: |
| |
| fmt::print("[{:>7}]", color::red); |
| // Output: [ red] |
| |
| Identifiers are only available as `char` strings so annotated enums are not |
| formattable with other character types. |
| |
| If several enumerators have the same value, the first one in the order of |
| declaration is used. A value that doesn't match any enumerator is represented |
| as its underlying value in decimal before applying string formatting: |
| |
| fmt::print("{}", static_cast<color>(42)); |
| // Output: 42 |
| |
| An enum annotated with `fmt::as_underlying` is instead formatted as its |
| underlying value using the integer [Format Specification]( |
| syntax.md#format-specification): |
| |
| enum class [[=fmt::as_underlying]] color { red = 1, green = 2, blue = 4 }; |
| |
| fmt::print("{:04x}", color::blue); |
| // Output: 0004 |
| |
| Such an enum is mapped to its underlying type before type erasure, so it can |
| also be used as dynamic width or precision. Unlike `fmt::as_identifiers`, it |
| works with all character types. The two annotations specify different |
| representations and cannot be combined. |
| |
| Enums without an annotation are not affected and are formatted as before, i.e. |
| scoped enums require `format_as` or a `formatter` specialization, see |
| [Formatting User-Defined Types](#udt). |
| |
| This uses two C++26 features: |
| [reflection](https://en.cppreference.com/w/cpp/language/operator_reflection) to |
| retrieve the enumerator identifiers and |
| [annotations](https://en.cppreference.com/w/cpp/language/annotations) to opt an |
| enum in via `fmt::as_identifiers`. It therefore requires a compiler with |
| reflection support, |
| which may need an extra flag such as `-freflection` in GCC. The macro |
| `FMT_USE_REFLECTION` is set to 1 if reflection is available and to 0 otherwise. |
| It can also be defined by the user to disable the use of reflection. |
| |
| When {fmt} is built as a module, reflection support is detected when the module |
| itself is compiled, so this API is only available to importers if the module was |
| built with reflection enabled. |
| |
| <a id="compile-api"></a> |
| ## Compile-Time Support |
| |
| `fmt/compile.h` provides format string compilation and compile-time |
| (`constexpr`) formatting enabled via the `FMT_COMPILE` macro or the `_cf` |
| user-defined literal defined in namespace `fmt::literals`. Format strings |
| marked with `FMT_COMPILE` or `_cf` are parsed, checked and converted into |
| efficient formatting code at compile-time. This supports arguments of built-in |
| and string types as well as user-defined types with `format` methods taking |
| the format context type as a template parameter in their `formatter` |
| specializations. For example ([run](https://www.godbolt.org/z/3c13erEoq)): |
| |
| struct point { |
| double x; |
| double y; |
| }; |
| |
| template <> struct fmt::formatter<point> { |
| constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } |
| |
| template <typename FormatContext> |
| auto format(const point& p, FormatContext& ctx) const { |
| return format_to(ctx.out(), "({}, {})"_cf, p.x, p.y); |
| } |
| }; |
| |
| using namespace fmt::literals; |
| std::string s = fmt::format("{}"_cf, point(4, 2)); |
| |
| Format string compilation can generate more binary code compared to the |
| default API and is only recommended in places where formatting is a |
| performance bottleneck. |
| |
| The same APIs support formatting at compile time e.g. in `constexpr` |
| and `consteval` functions. Additionally there is an experimental |
| `FMT_STATIC_FORMAT` that allows formatting into a string of the exact |
| required size at compile time. Compile-time formatting works with built-in |
| and user-defined formatters that have `constexpr` `format` methods. |
| Example: |
| |
| template <> struct fmt::formatter<point> { |
| constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } |
| |
| template <typename FormatContext> |
| constexpr auto format(const point& p, FormatContext& ctx) const { |
| return format_to(ctx.out(), "({}, {})"_cf, p.x, p.y); |
| } |
| }; |
| |
| constexpr auto s = FMT_STATIC_FORMAT("{}", point(4, 2)); |
| const char* cstr = s.c_str(); // Points the static string "(4, 2)". |
| |
| ::: operator""_cf |
| |
| ::: FMT_COMPILE |
| |
| ::: FMT_STATIC_FORMAT |
| |
| <a id="color-api"></a> |
| ## Terminal Colors and Text Styles |
| |
| `fmt/color.h` provides support for terminal color and text style output. |
| |
| ::: print(text_style, format_string<T...>, T&&...) |
| |
| ::: fg(detail::color_type) |
| |
| ::: bg(detail::color_type) |
| |
| ::: styled(const T&, text_style) |
| |
| <a id="os-api"></a> |
| ## System APIs |
| |
| ::: ostream |
| |
| ::: output_file(cstring_view, T...) |
| |
| ::: windows_error |
| |
| <a id="ostream-api"></a> |
| ## `std::ostream` Support |
| |
| `fmt/ostream.h` provides `std::ostream` support including formatting of |
| user-defined types that have an overloaded insertion operator |
| (`operator<<`). In order to make a type formattable via `std::ostream` |
| you should provide a `formatter` specialization inherited from |
| `ostream_formatter`: |
| |
| #include <fmt/ostream.h> |
| |
| struct date { |
| int year, month, day; |
| |
| friend std::ostream& operator<<(std::ostream& os, const date& d) { |
| return os << d.year << '-' << d.month << '-' << d.day; |
| } |
| }; |
| |
| template <> struct fmt::formatter<date> : ostream_formatter {}; |
| |
| std::string s = fmt::format("The date is {}", date{2012, 12, 9}); |
| // s == "The date is 2012-12-9" |
| |
| ::: streamed(const T&) |
| |
| ::: print(std::ostream&, format_string<T...>, T&&...) |
| |
| <a id="args-api"></a> |
| ## Dynamic Argument Lists |
| |
| The header `fmt/args.h` provides `dynamic_format_arg_store`, a builder-like API |
| that can be used to construct format argument lists dynamically. |
| |
| ::: dynamic_format_arg_store |
| |
| <a id="printf-api"></a> |
| ## Safe `printf` |
| |
| The header `fmt/printf.h` provides `printf`-like formatting |
| functionality. The following functions use [printf format string |
| syntax](https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html) |
| with the POSIX extension for positional arguments. Unlike their standard |
| counterparts, the `fmt` functions are type-safe and throw an exception |
| if an argument type doesn't match its format specification. |
| |
| ::: printf(string_view, const T&...) |
| |
| ::: fprintf(std::FILE*, string_view, const T&...) |
| |
| ::: sprintf(string_view, const T&...) |
| |
| <a id="xchar-api"></a> |
| ## Wide Strings |
| |
| The optional header `fmt/xchar.h` provides support for `wchar_t` and |
| exotic character types. |
| |
| ::: wstring_view |
| |
| ::: wformat_context |
| |
| ::: to_wstring(const T&) |
| |
| ## Compatibility with C++20 `std::format` |
| |
| {fmt} implements nearly all of the [C++20 formatting |
| library](https://en.cppreference.com/w/cpp/utility/format) with the |
| following differences: |
| |
| - Names are defined in the `fmt` namespace instead of `std` to avoid |
| collisions with standard library implementations. |
| |
| - Width calculation doesn't use grapheme clusterization. The latter has |
| been implemented in a separate branch but hasn't been integrated yet. |
| |
| - The default floating-point representation in {fmt} uses the smallest |
| precision that provides round-trip guarantees similarly to other languages |
| like Java and Python. `std::format` is currently specified in terms of |
| `std::to_chars` which tries to generate the smallest number of characters |
| (ignoring redundant digits and sign in exponent) and may produce more |
| decimal digits than necessary. |
| |
| ## Configuration Options |
| |
| {fmt} provides configuration via CMake options and preprocessor macros to |
| enable or disable features and to optimize for binary size. For example, you |
| can disable OS-specific APIs defined in `fmt/os.h` with `-DFMT_OS=OFF` when |
| configuring CMake. |
| |
| ### CMake Options |
| |
| - **`FMT_OS`**: When set to `OFF`, disables OS-specific APIs (`fmt/os.h`). |
| - **`FMT_UNICODE`**: When set to `OFF`, disables Unicode support on |
| Windows/MSVC. Unicode support is always enabled on other platforms. |
| |
| ### Macros |
| |
| - **`FMT_HEADER_ONLY`**: Enables the header-only mode when defined. It is an |
| alternative to using the `fmt::fmt-header-only` CMake target. |
| Default: not defined. |
| |
| - **`FMT_USE_EXCEPTIONS`**: Disables the use of exceptions when set to `0`. |
| Default: `1` (`0` if compiled with `-fno-exceptions`). |
| |
| - **`FMT_USE_LOCALE`**: When set to `0`, disables locale support. |
| Default: `1` (`0` when `FMT_OPTIMIZE_SIZE > 1`). |
| |
| - **`FMT_CUSTOM_ASSERT_FAIL`**: When set to `1`, allows users to provide a |
| custom `fmt::assert_fail` function which is called on assertion failures and, |
| if exceptions are disabled, on runtime errors. Default: `0`. |
| |
| - **`FMT_BUILTIN_TYPES`**: When set to `0`, disables built-in handling of |
| arithmetic and string types other than `int`. This reduces library size at |
| the cost of per-call overhead. Default: `1`. |
| |
| - **`FMT_OPTIMIZE_SIZE`**: Controls binary size optimizations: |
| - `0` - off (default) |
| - `1` - applies some optimizations |
| - `2` - disables locale support by default, some Unicode features, and |
| named arguments, and applies more aggressive optimizations |
| |
| ### Binary Size Optimization |
| |
| To minimize the binary footprint of {fmt} as much as possible at the cost of |
| some features, you can use the following configuration: |
| |
| - CMake options: |
| - `FMT_OS=OFF` |
| - Macros: |
| - `FMT_BUILTIN_TYPES=0` |
| - `FMT_OPTIMIZE_SIZE=2` |