# API Reference The {fmt} library API consists of the following components: - [`fmt/base.h`](#base-api): the base 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/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): `printf` formatting - [`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_`. ## Base API `fmt/base.h` defines the base 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&&...) ::: print(FILE*, format_string, T&&...) ::: println(format_string, T&&...) ::: println(FILE*, format_string, T&&...) ::: format_to(OutputIt&&, format_string, T&&...) ::: format_to_n(OutputIt, size_t, format_string, T&&...) ::: format_to_n_result ::: formatted_size(format_string, T&&...) ### 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. 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. Example ([run](https://godbolt.org/z/nvME4arz8)): #include 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 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 enum class color {red, green, blue}; template <> struct fmt::formatter: formatter { // parse is inherited from formatter. auto format(color c, format_context& ctx) const -> format_context::iterator; }; ``` ```c++ // color.cc: #include "color.h" #include auto fmt::formatter::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::format(name, ctx); } ``` Note that `formatter::format` is defined in `fmt/format.h` so it has to be included in the source file. Since `parse` is inherited from `formatter` it will recognize all string format specifications, for example ```c++ fmt::format("{:>10}", color::blue) ``` will return `" blue"`. In general the formatter has the following form: template <> struct fmt::formatter { // 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 #include struct A { virtual ~A() {} virtual std::string name() const { return "A"; } }; struct B : A { virtual std::string name() const { return "B"; } }; template struct fmt::formatter, char>> : fmt::formatter { auto format(const A& a, format_context& ctx) const { return formatter::format(a.name(), ctx); } }; ``` ```c++ // demo.cc: #include "demo.h" #include 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. ::: basic_format_string ::: format_string ::: runtime(string_view) ### Named Arguments ::: arg(const Char*, const T&) Named arguments are not supported in compile-time checks at the moment. ### 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 void vlog(const char* file, int line, fmt::string_view fmt, fmt::format_args args) { fmt::print("{}: {}: {}", file, line, fmt::vformat(fmt, args)); } template void log(const char* file, int line, fmt::format_string 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 ### Compatibility ::: basic_string_view ::: string_view ## Format API `fmt/format.h` defines the full format API providing additional formatting functions and locale support. ::: format(format_string, 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; It is also possible to write a formatting function that uses a custom allocator: using custom_string = std::basic_string, custom_allocator>; custom_string vformat(custom_allocator alloc, fmt::string_view format_str, fmt::format_args args) { auto buf = custom_memory_buffer(alloc); fmt::vformat_to(std::back_inserter(buf), format_str, args); return custom_string(buf.data(), buf.size(), alloc); } template inline custom_string format(custom_allocator alloc, fmt::string_view format_str, const Args& ... args) { return vformat(alloc, format_str, 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 #include 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 `` include. ::: format(const Locale&, format_string, T&&...) ::: format_to(OutputIt, const Locale&, format_string, T&&...) ::: formatted_size(const Locale&, format_string, T&&...) ### 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. ## Range and Tuple Formatting `fmt/ranges.h` provides formatting support for ranges and tuples: #include fmt::print("{}", std::tuple{'a', 42}); // Output: ('a', 42) Using `fmt::join`, you can separate tuple elements with a custom separator: #include auto t = std::tuple{1, 'a'}; fmt::print("{}", fmt::join(t, ", ")); // Output: 1, a ::: join(Range&&, string_view) ::: join(It, Sentinel, string_view) ::: join(std::initializer_list, string_view) ## 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-specifications). **Example**: #include int main() { std::time_t t = std::time(nullptr); fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t)); // 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 } ::: localtime(std::time_t) ::: gmtime(std::time_t) ## 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::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&) ::: ptr(const std::shared_ptr&) ### Formatting Variants A `std::variant` is only formattable if every variant alternative is formattable, and requires the `__cpp_lib_variant` [library feature](https://en.cppreference.com/w/cpp/feature_test). **Example**: #include fmt::print("{}", std::variant('x')); // Output: variant('x') fmt::print("{}", std::variant()); // Output: variant(monostate) ## Format String Compilation `fmt/compile.h` provides format string compilation 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` functions taking the format context type as a template parameter in their `formatter` specializations. For example: template <> struct fmt::formatter { constexpr auto parse(format_parse_context& ctx); template auto format(const point& p, FormatContext& ctx) const; }; 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. ::: FMT_COMPILE ::: operator""_cf ## Terminal Colors and Text Styles `fmt/color.h` provides support for terminal color and text style output. ::: print(const text_style&, format_string, T&&...) ::: fg(detail::color_type) ::: bg(detail::color_type) ::: styled(const T&, text_style) ## System APIs ::: ostream ::: windows_error ## `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 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 : 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&&...) ## 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 ## `printf` Formatting 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*, const S&, const T&...) ::: sprintf(const S&, const T&...) ## Wide Strings The optional header `fmt/xchar.h` provides support for `wchar_t` and exotic character types. ::: is_char ::: 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.