## File: README.md

[](
https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux)
[](
https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos)
[](
https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows)
[](
https://issues.oss-fuzz.com/issues?q=title:fmt%20cc:victor.zverovich@gmail.com)
[](
https://www.bestpractices.dev/projects/8880)
[](
https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt)
[![Ask questions at StackOverflow with the tag fmt](
https://img.shields.io/badge/stackoverflow-fmt-blue.svg)](https://stackoverflow.com/questions/tagged/fmt)
[![Support Ukraine](
https://img.shields.io/badge/Support-Ukraine-005BBB?labelColor=FFD500)](https://novaukraine.org/)

**{fmt}** is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.

[Documentation](https://fmt.dev)

[Cheat Sheets](https://hackingcpp.com/cpp/libs/fmt.html)

Q&A: ask questions on [StackOverflow with the tag
fmt](https://stackoverflow.com/questions/tagged/fmt).

Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v).

# Features

- Simple [format API](https://fmt.dev/latest/api/) with positional
  arguments for localization
- Implementation of [C++20
  std::format](https://en.cppreference.com/w/cpp/utility/format) and
  [C++23 std::print](https://en.cppreference.com/w/cpp/io/print)
- [Format string syntax](https://fmt.dev/latest/syntax/) similar
  to Python\'s
  [format](https://docs.python.org/3/library/stdtypes.html#str.format)
- Fast IEEE 754 floating-point formatter with correct rounding,
  shortness and round-trip guarantees using the
  [Dragonbox](https://github.com/jk-jeon/dragonbox) algorithm
- Portable Unicode support
- Safe [printf
  implementation](https://fmt.dev/latest/api/#printf-api)
  including the POSIX extension for positional arguments
- Extensibility: [support for user-defined
  types](https://fmt.dev/latest/api/#formatting-user-defined-types)
- High performance: faster than common standard library
  implementations of `(s)printf`, iostreams, `to_string` and
  `to_chars`, see [Speed tests](#speed-tests) and [Converting a
  hundred million integers to strings per
  second](https://vitaut.net/posts/2020/fast-int-to-string-revisited/)
- Small code size both in terms of source code with the minimum
  configuration consisting of just three files, `base.h`, `format.h`
  and `format-inl.h`, and compiled code; see [Compile time and code
  bloat](#compile-time-and-code-bloat)
- Reliability: the library has an extensive set of
  [tests](https://github.com/fmtlib/fmt/tree/master/test) and is
  [continuously fuzzed](https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1)
- Safety: the library is fully type-safe, errors in format strings can
  be reported at compile time, automatic memory management prevents
  buffer overflow errors
- Ease of use: small self-contained code base, no external
  dependencies, permissive MIT
  [license](https://github.com/fmtlib/fmt/blob/master/LICENSE)
- [Portability](https://fmt.dev/latest/#portability) with
  consistent output across platforms and support for older compilers
- Clean warning-free codebase even on high warning levels such as
  `-Wall -Wextra -pedantic`
- Locale independence by default
- Optional header-only configuration enabled with the
  `FMT_HEADER_ONLY` macro

See the [documentation](https://fmt.dev) for more details.

# Examples

**Print to stdout** ([run](https://godbolt.org/z/Tevcjh))

``` c++
#include <fmt/base.h>

int main() {
  fmt::print("Hello, world!\n");
}
```

**Format a string** ([run](https://godbolt.org/z/oK8h33))

``` c++
std::string s = fmt::format("The answer is {}.", 42);
// s == "The answer is 42."
```

**Format a string using positional arguments**
([run](https://godbolt.org/z/Yn7Txe))

``` c++
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
// s == "I'd rather be happy than right."
```

**Print dates and times** ([run](https://godbolt.org/z/c31ExdY3W))

``` c++
#include <fmt/chrono.h>

int main() {
  auto now = std::chrono::system_clock::now();
  fmt::print("Date and time: {}\n", now);
  fmt::print("Time: {:%H:%M}\n", now);
}
```

Output:

    Date and time: 2023-12-26 19:10:31.557195597
    Time: 19:10

**Print a container** ([run](https://godbolt.org/z/MxM1YqjE7))

``` c++
#include <vector>
#include <fmt/ranges.h>

int main() {
  std::vector v = {1, 2, 3};
  fmt::print("{}\n", v);
}
```

Output:

    [1, 2, 3]

**Check a format string at compile time**

``` c++
std::string s = fmt::format("{:d}", "I am not a number");
```

This gives a compile-time error in C++20 because `d` is an invalid
format specifier for a string.

**Write a file from a single thread**

``` c++
#include <fmt/os.h>

int main() {
  auto out = fmt::output_file("guide.txt");
  out.print("Don't {}", "Panic");
}
```

This can be [up to 9 times faster than `fprintf`](
https://vitaut.net/posts/2020/optimal-file-buffer-size/).

**Print with colors and text styles**

``` c++
#include <fmt/color.h>

int main() {
  fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
             "Hello, {}!\n", "world");
  fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
             fmt::emphasis::underline, "Olá, {}!\n", "Mundo");
  fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "你好{}！\n", "世界");
}
```

Output on a modern terminal with Unicode support:



# Benchmarks

## Speed tests

| Library           | Method        | Run Time, s |
|-------------------|---------------|-------------|
| libc              | printf        |   0.66      |
| libc++            | std::ostream  |   1.63      |
| {fmt} 12.1        | fmt::print    |   0.44      |
| Boost Format 1.88 | boost::format |   3.89      |
| Folly Format      | folly::format |   1.28      |

{fmt} is the fastest of the benchmarked methods, \~50% faster than
`printf`.

The above results were generated by building `tinyformat_test.cpp` on
macOS 15.6.1 with `clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT`, and
taking the best of three runs. In the test, the format string
`"%0.10f:%04d:%+g:%s:%p:%c:%%\n"` or equivalent is filled 2,000,000
times with output sent to `/dev/null`; for further details refer to the
[source](https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc).

{fmt} is up to 20-30x faster than `std::ostringstream` and `sprintf` on
IEEE754 `float` and `double` formatting
([dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark)) and faster
than [double-conversion](https://github.com/google/double-conversion)
and [ryu](https://github.com/ulfjack/ryu):

[](https://fmt.dev/unknown_mac64_clang12.0.html)

## Compile time and code bloat

The script [bloat-test.py][test] from [format-benchmark][bench] tests compile
time and code bloat for nontrivial projects. It generates 100 translation units
and uses `printf()` or its alternative five times in each to simulate a
medium-sized project. The resulting executable size and compile time (Apple
clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, best of three) is shown
in the following tables.

[test]: https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py
[bench]: https://github.com/fmtlib/format-benchmark

**Optimized build (-O3)**

| Method          | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|-----------------|-----------------|----------------------|--------------------|
| printf          |             1.6 |                   54 |                 50 |
| IOStreams       |            28.4 |                   98 |                 84 |
| {fmt} `1122268` |             5.0 |                   54 |                 50 |
| tinyformat      |            32.6 |                  164 |                136 |
| Boost Format    |            55.0 |                  530 |                317 |

{fmt} is fast to compile and is comparable to `printf` in terms of per-call
binary size (within a rounding error on this system).

**Non-optimized build**

| Method          | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|-----------------|-----------------|----------------------|--------------------|
| printf          |             1.4 |                   54 |                 50 |
| IOStreams       |            27.0 |                   88 |                 68 |
| {fmt} `1122268` |             4.7 |                   87 |                 84 |
| tinyformat      |            28.1 |                  185 |                145 |
| Boost Format    |            38.9 |                  678 |                381 |

`libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
to compare formatting function overhead only. Boost Format is a
header-only library so it doesn\'t provide any linkage options.

## Running the tests

Please refer to [Building the
library](https://fmt.dev/latest/get-started/#building-from-source) for
instructions on how to build the library and run the unit tests.

Benchmarks reside in a separate repository,
[format-benchmarks](https://github.com/fmtlib/format-benchmark), so to
run the benchmarks you first need to clone this repository and generate
Makefiles with CMake:

    $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
    $ cd format-benchmark
    $ cmake .

Then you can run the speed test:

    $ make speed-test

or the bloat test:

    $ make bloat-test

# Migrating code

[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v18 provides the
[modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
check that is capable of converting occurrences of `printf` and
`fprintf` to `fmt::print` if configured to do so. (By default it
converts to `std::print`.)

# Notable projects using this library

- [0 A.D.](https://play0ad.com/): a free, open-source, cross-platform
  real-time strategy game
- [AMPL/MP](https://github.com/ampl/mp): an open-source library for
  mathematical programming
- [Apple's FoundationDB](https://github.com/apple/foundationdb): an open-source,
  distributed, transactional key-value store
- [Aseprite](https://github.com/aseprite/aseprite): animated sprite
  editor & pixel art tool
- [AvioBook](https://www.aviobook.aero/en): a comprehensive aircraft
  operations suite
- [Blizzard Battle.net](https://battle.net/): an online gaming
  platform
- [Celestia](https://celestia.space/): real-time 3D visualization of
  space
- [Ceph](https://ceph.com/): a scalable distributed storage system
- [ccache](https://ccache.dev/): a compiler cache
- [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
  analytical database management system
- [ContextVision](https://www.contextvision.com/): medical imaging software
- [Contour](https://github.com/contour-terminal/contour/): a modern
  terminal emulator
- [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
  underwater vehicle
- [Drake](https://drake.mit.edu/): a planning, control, and analysis
  toolbox for nonlinear dynamical systems (MIT)
- [Envoy](https://github.com/envoyproxy/envoy): C++ L7 proxy and
  communication bus (Lyft)
- [FiveM](https://fivem.net/): a modification framework for GTA V
- [fmtlog](https://github.com/MengRao/fmtlog): a performant
  fmtlib-style logging library with latency in nanoseconds
- [Folly](https://github.com/facebook/folly): Facebook open-source
  library
- [GemRB](https://gemrb.org/): a portable open-source implementation
  of Bioware's Infinity Engine
- [Grand Mountain
  Adventure](https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/):
  a beautiful open-world ski & snowboarding game
- [HarpyWar/pvpgn](https://github.com/pvpgn/pvpgn-server): Player vs
  Player Gaming Network with tweaks
- [KBEngine](https://github.com/kbengine/kbengine): an open-source
  MMOG server engine
- [Keypirinha](https://keypirinha.com/): a semantic launcher for
  Windows
- [Kodi](https://kodi.tv/) (formerly xbmc): home theater software
- [Knuth](https://kth.cash/): high-performance Bitcoin full-node
- [libunicode](https://github.com/contour-terminal/libunicode/): a
  modern C++17 Unicode library
- [MariaDB](https://mariadb.org/): relational database management
  system
- [Microsoft Verona](https://github.com/microsoft/verona): research
  programming language for concurrent ownership
- [MongoDB](https://mongodb.com/): distributed document database
- [MongoDB Smasher](https://github.com/duckie/mongo_smasher): a small
  tool to generate randomized datasets
- [OpenSpace](https://openspaceproject.com/): an open-source
  astrovisualization framework
- [PenUltima Online (POL)](https://www.polserver.com/): an MMO server,
  compatible with most Ultima Online clients
- [PyTorch](https://github.com/pytorch/pytorch): an open-source
  machine learning library
- [quasardb](https://www.quasardb.net/): a distributed,
  high-performance, associative database
- [Quill](https://github.com/odygrd/quill): asynchronous low-latency
  logging library
- [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
  simplify navigation, and execute complex multi-line terminal
  command sequences
- [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
  cluster proxy
- [redpanda](https://vectorized.io/redpanda): a 10x faster Kafka®
  replacement for mission-critical systems written in C++
- [rpclib](https://github.com/rpclib/rpclib): a modern C++ msgpack-RPC server and
  client library
- [Salesforce Analytics
  Cloud](https://www.salesforce.com/analytics-cloud/overview/):
  business intelligence software
- [Scylla](https://www.scylladb.com/): a Cassandra-compatible NoSQL
  data store that can handle 1 million transactions per second on a
  single server
- [Seastar](https://seastar.io/): an advanced, open-source
  C++ framework for high-performance server applications on modern
  hardware
- [spdlog](https://github.com/gabime/spdlog): super fast C++ logging
  library
- [Stellar](https://www.stellar.org/): financial platform
- [Touch Surgery](https://www.touchsurgery.com/): surgery simulator
- [TrinityCore](https://github.com/TrinityCore/TrinityCore):
  open-source MMORPG framework
- [🐙 userver framework](https://userver.tech/): open-source
  asynchronous framework with a rich set of abstractions and database
  drivers
- [Windows Terminal](https://github.com/microsoft/terminal): the new
  Windows terminal

[More\...](https://github.com/search?q=fmtlib&type=Code)

If you are aware of other projects using this library, please let me
know by [email](mailto:victor.zverovich@gmail.com) or by submitting an
[issue](https://github.com/fmtlib/fmt/issues).

# Maintainers

The {fmt} library is maintained by Victor Zverovich
([vitaut](https://github.com/vitaut)) with contributions from many other
people. See
[Contributors](https://github.com/fmtlib/fmt/graphs/contributors) and
[Releases](https://github.com/fmtlib/fmt/releases) for some of the
names. Let us know if your contribution is not listed or mentioned
incorrectly and we\'ll make it right.

---

## File: doc/api.md

# 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): 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.

## 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...>, 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/base.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"`.



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{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-specifications).

**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="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 {
      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 {
      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` - disables locale support and applies some optimizations
    - `2` - disables some Unicode features, 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`

---

## File: doc/get-started.md

# Get Started

Compile and run {fmt} examples online with [Compiler Explorer](
https://godbolt.org/z/P7h6cd6o3).

{fmt} is compatible with any build system. The next section describes its usage
with CMake, while the [Build Systems](#build-systems) section covers the rest.

## CMake

{fmt} provides three CMake targets: `fmt::fmt` for the standard compiled library,
`fmt::fmt-module` for the C++ module library and `fmt::fmt-header-only` for the
header-only library. It is recommended to use the compiled library or the module 
library for improved build times. 

There are three primary ways to use {fmt} with CMake:

* **FetchContent**: Starting from CMake 3.11, you can use [`FetchContent`](
  https://cmake.org/cmake/help/v3.30/module/FetchContent.html) to automatically
  download {fmt} as a dependency at configure time:

        include(FetchContent)

        FetchContent_Declare(
          fmt
          GIT_REPOSITORY https://github.com/fmtlib/fmt
          GIT_TAG        e69e5f977d458f2650bb346dadf2ad30c5320281) # 10.2.1
        FetchContent_MakeAvailable(fmt)

        target_link_libraries(<your-target> fmt::fmt)

* **Installed**: You can find and use an [installed](#installation) version of
  {fmt} in your `CMakeLists.txt` file as follows:

        find_package(fmt)
        target_link_libraries(<your-target> fmt::fmt)

* **Embedded**: You can add the {fmt} source tree to your project and include it
  in your `CMakeLists.txt` file:

        add_subdirectory(fmt)
        target_link_libraries(<your-target> fmt::fmt)

### Alternative Targets

In order to use the header-only target or the module target, simply substitute the
`fmt::fmt` in the above steps with `fmt::fmt-header-only` or `fmt::fmt-module` 
accordingly.

## Installation

### Debian/Ubuntu

To install {fmt} on Debian, Ubuntu, or any other Debian-based Linux
distribution, use the following command:

    apt install libfmt-dev

### Homebrew

Install {fmt} on macOS using [Homebrew](https://brew.sh/):

    brew install fmt

### Conda

Install {fmt} on Linux, macOS, and Windows with [Conda](
https://docs.conda.io/en/latest/), using its [conda-forge package](
https://github.com/conda-forge/fmt-feedstock):

    conda install -c conda-forge fmt

### vcpkg

Download and install {fmt} using the vcpkg package manager:

    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    ./bootstrap-vcpkg.sh
    ./vcpkg integrate install
    ./vcpkg install fmt



### Conan

You can download and install {fmt} using the [Conan](https://conan.io/) package manager:

    conan install -r conancenter --requires="fmt/[*]" --build=missing



## Building from Source

CMake works by generating native makefiles or project files that can be
used in the compiler environment of your choice. The typical workflow
starts with:

    mkdir build  # Create a directory to hold the build output.
    cd build
    cmake ..     # Generate native build scripts.

run in the `fmt` repository.

If you are on a Unix-like system, you should now see a Makefile in the
current directory. Now you can build the library by running `make`.

Once the library has been built you can invoke `make test` to run the tests.

You can control generation of the make `test` target with the `FMT_TEST`
CMake option. This can be useful if you include fmt as a subdirectory in
your project but don't want to add fmt's tests to your `test` target.

To build a shared library set the `BUILD_SHARED_LIBS` CMake variable to `TRUE`:

    cmake -DBUILD_SHARED_LIBS=TRUE ..

To build a static library with position-independent code (e.g. for
linking it into another shared library such as a Python extension), set the
`CMAKE_POSITION_INDEPENDENT_CODE` CMake variable to `TRUE`:

    cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ..

After building the library you can install it on a Unix-like system by
running `sudo make install`.

### Building the Docs

To build the documentation you need the following software installed on
your system:

- [Python](https://www.python.org/)
- [Doxygen](http://www.stack.nl/~dimitri/doxygen/)
- [MkDocs](https://www.mkdocs.org/) with `mkdocs-material`, `mkdocstrings`,
  `pymdown-extensions` and `mike`

First generate makefiles or project files using CMake as described in
the previous section. Then compile the `doc` target/project, for example:

    make doc

This will generate the HTML documentation in `doc/html`.

## Build Systems

### build2

You can use [build2](https://build2.org), a dependency manager and a build
system, to use {fmt}.

Currently this package is available in these package repositories:

- <https://cppget.org/fmt/> for released and published versions.
- <https://github.com/build2-packaging/fmt> for unreleased or custom versions.

**Usage:**

- `build2` package name: `fmt`
- Library target name: `lib{fmt}`

To make your `build2` project depend on `fmt`:

- Add one of the repositories to your configurations, or in your
  `repositories.manifest`, if not already there:

        :
        role: prerequisite
        location: https://pkg.cppget.org/1/stable

- Add this package as a dependency to your `manifest` file (example
  for version 10):

        depends: fmt ~10.0.0

- Import the target and use it as a prerequisite to your own target
  using `fmt` in the appropriate `buildfile`:

        import fmt = fmt%lib{fmt}
        lib{mylib} : cxx{**} ... $fmt

Then build your project as usual with `b` or `bdep update`.

### Meson

[Meson WrapDB](https://mesonbuild.com/Wrapdb-projects.html) includes an `fmt`
package.

**Usage:**

- Install the `fmt` subproject from the WrapDB by running:

        meson wrap install fmt

  from the root of your project.

- In your project's `meson.build` file, add an entry for the new subproject:

        fmt = subproject('fmt')
        fmt_dep = fmt.get_variable('fmt_dep')

- Include the new dependency object to link with fmt:

        my_build_target = executable(
          'name', 'src/main.cc', dependencies: [fmt_dep])

**Options:**

If desired, {fmt} can be built as a static library, or as a header-only library.

For a static build, use the following subproject definition:

    fmt = subproject('fmt', default_options: 'default_library=static')
    fmt_dep = fmt.get_variable('fmt_dep')

For the header-only version, use:

    fmt = subproject('fmt', default_options: ['header-only=true'])
    fmt_dep = fmt.get_variable('fmt_header_only_dep')

### Android NDK

{fmt} provides [Android.mk file](
https://github.com/fmtlib/fmt/blob/master/support/Android.mk) that can be used
to build the library with [Android NDK](
https://developer.android.com/tools/sdk/ndk/index.html).

### Other

To use the {fmt} library with any other build system, add
`include/fmt/base.h`, `include/fmt/format.h`, `include/fmt/format-inl.h`,
`src/format.cc` and optionally other headers from a [release archive](
https://github.com/fmtlib/fmt/releases) or the [git repository](
https://github.com/fmtlib/fmt) to your project, add `include` to include
directories and make sure `src/format.cc` is compiled and linked with your code.

---

## File: doc/index.md

---
hide:
  - navigation
  - toc
---

# A modern formatting library




<h2>Safety</h2>

  Inspired by Python's formatting facility, {fmt} provides a safe replacement
  for the `printf` family of functions. Errors in format strings,
  which are a common source of vulnerabilities in C, are reported at
  compile time. For example:

  <code class="language-cpp"
  >fmt::format("{:d}", "I am not a number");</code>

  will give a compile-time error because `d` is not a valid
  format specifier for strings. APIs like <a href="api/#format">
  `fmt::format`</a> **prevent buffer overflow errors** via
  automatic memory management.

[→ Learn more](api#compile-time-checks)



<h2>Extensibility</h2>

  Formatting of most **standard types**, including all containers, dates,
  and times is **supported out-of-the-box**. For example:
  
  <code class="language-cpp"
  >fmt::print("{}", std::vector{1, 2, 3});</code>

  prints the vector in a JSON-like format:

  `[1, 2, 3]`

  You can **make your own types formattable** and even make compile-time
  checks work for them.

[→ Learn more](api#udt)



<h2>Performance</h2>

  {fmt} can be anywhere from **tens of percent to 20-30 times faster** than
  iostreams and `sprintf`, especially for numeric formatting.

<a href="https://github.com/fmtlib/fmt?tab=readme-ov-file#benchmarks">

</a>

  The library **minimizes dynamic memory allocations** and can optionally
  [compile format strings](api#compile-api) to optimal code.




<h2>Unicode support</h2>

  {fmt} provides **portable Unicode support** on major operating systems
  with UTF-8 and `char` strings. For example:

  <code class="language-cpp"
  >fmt::print("Слава Україні!");</code>

  will be printed correctly on Linux, macOS, and even Windows console,
  irrespective of the codepages.


  The default is **locale-independent**, but you can opt into localized
  formatting and {fmt} makes it work with Unicode, addressing issues in the
  standard library.




<h2>Fast compilation</h2>

  The library makes extensive use of **type erasure** to achieve fast
  compilation. `fmt/base.h` provides a subset of the API with
  **minimal include dependencies** and enough functionality to replace
  all uses of `*printf`.


  Code using {fmt} is usually several times faster to compile than the
  equivalent iostreams code, and while `printf` compiles faster
  still, the gap is narrowing.

<a href=
"https://github.com/fmtlib/fmt?tab=readme-ov-file#compile-time-and-code-bloat">
→ Learn more</a>



<h2>Small binary footprint</h2>

  Type erasure is also used to prevent template bloat, resulting in compact
  per-call binary code. For example, a call to `fmt::print` with
  a single argument is just <a href="https://godbolt.org/g/TZU4KF">a few
  instructions</a>, comparable to `printf` despite adding
  runtime safety, and much smaller than the equivalent iostreams code.


  The library itself has small binary footprint and some components such as
  floating-point formatting can be disabled to make it even smaller for
  resource-constrained devices.




<h2>Portability</h2>

  {fmt} has a **small self-contained codebase** with the core consisting of
  just three headers and no external dependencies.


  The library is highly portable and requires only a minimal subset of
  C++11 features which are available in GCC 4.9, Clang 3.6, MSVC 19.10
  (2017) and later. Newer compiler and standard library features are used
  if available, and enable additional functionality.


  Where possible, the output of formatting functions is consistent across
  platforms.




<h2>Open source</h2>

  {fmt} is in the top hundred open-source C++ libraries on GitHub and has
  <a href="https://github.com/fmtlib/fmt/graphs/contributors">hundreds of
  all-time contributors</a>.


  The library is distributed under a permissive MIT
  [license](https://github.com/fmtlib/fmt#license) and is
  **relied upon by many open-source projects**, including Blender, PyTorch,
  Apple's FoundationDB, Windows Terminal, MongoDB, and others.

---

## File: doc/syntax.md

# Format String Syntax

The formatting functions in this library — most notably
[`fmt::format`](api.md#format) and [`fmt::print`](api.md#print) — accept
format strings written in the syntax described here.

A format string is plain text with embedded *replacement fields* delimited by
the braces `{` and `}`. Characters outside of any replacement field are
copied to the output unchanged. To emit a literal brace, double it: `{{`
yields a single `{` in the output, and `}}` yields a single `}`.

A replacement field is described by the grammar below.

<a id="replacement-field"></a>
<code class="language-json"
>replacement_field ::= "{" [arg_id] [":" ([format_spec](#format-spec) | [chrono_format_spec](#chrono-format-spec))] "}"
arg_id            ::= integer | identifier
integer           ::= digit+
digit             ::= "0"..."9"
identifier        ::= id_start id_continue*
id_start          ::= "a"..."z" | "A"..."Z" | "_"
id_continue       ::= id_start | digit</code>


An *arg_id* selects which argument to format. It may be a non-negative
integer (positional reference) or an identifier matching the name of an
argument passed via [`fmt::arg`](api.md#arg) (named reference). When *arg_id*
is omitted, arguments are consumed in left-to-right order; this *automatic*
indexing must be used uniformly throughout the format string — mixing
automatic and explicit numeric ids is a compile-time error (or a
`format_error` at runtime).

A *format_spec*, introduced by `:`, describes how the value should be
rendered. Its grammar is type-dependent; the form used by the standard
built-in types is documented in the next section.

For example:

```c++
fmt::format("hello, {}", "world");
// Result: "hello, world"

fmt::format("{1}, {0}!", "world", "hello");
// Result: "hello, world!"

fmt::format("{greeting}, {name}!",
            fmt::arg("greeting", "hi"), fmt::arg("name", "fmt"));
// Result: "hi, fmt!"
```

A *width* or *precision* inside a *format_spec* may itself be written as a
nested replacement field — `{}` or `{arg_id}` — in which case it takes its
value from an integer argument at runtime. Nested fields accept only an
*arg_id*; they cannot themselves contain a *format_spec*.

## Format Specification

The grammar below describes the *format_spec* shared by the built-in
types — integers, floating-point values, characters, strings, booleans, and
pointers — as well as by any user-defined type whose `formatter` reuses
fmt's parser.

<a id="format-spec"></a>
<code class="language-json"
>format_spec ::= [[fill]align][sign]["#"]["0"][width]["." precision]["L"][type]
fill        ::= &lt;a character other than '{' or '}'>
align       ::= "<" | ">" | "^"
sign        ::= "+" | "-" | " "
width       ::= [integer](#replacement-field) | "{" [[arg_id](#replacement-field)] "}"
precision   ::= [integer](#replacement-field) | "{" [[arg_id](#replacement-field)] "}"
type        ::= "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" |
                "g" | "G" | "o" | "p" | "s" | "x" | "X" | "?"</code>


Whether a particular option is meaningful depends on the value being
formatted; options that do not apply to a value's type are diagnosed at
compile time when possible and otherwise raise a `format_error`.

### Fill and alignment

The *align* field selects where padding is placed when *width* makes the
field wider than the value's natural rendering.

| Option | Effect                                                            |
|--------|-------------------------------------------------------------------|
| `<`    | Left-align; pad on the right. Default for non-numeric types.      |
| `>`    | Right-align; pad on the left. Default for numeric types.          |
| `^`    | Center the value; if the padding cannot be split evenly, the extra padding character goes on the right. |

The *fill* character is any single Unicode code point other than `{` or `}`,
encoded the same way as the format string. It supplies the padding character
in place of the default space. A fill character is recognized only when it is
immediately followed by an *align* character — otherwise it would be
indistinguishable from an option in another position — so to use a custom
fill you must also specify an alignment.

Alignment has no observable effect when the value's natural rendering is
already at least as wide as *width*; the value is never truncated to fit.

```c++
fmt::format("[{:<10}]", "42");   // Result: "[42        ]"
fmt::format("[{:>10}]", "42");   // Result: "[        42]"
fmt::format("[{:^10}]", "42");   // Result: "[    42    ]"
fmt::format("[{:*^10}]", "42");  // Result: "[****42****]"  - '*' as fill
```

### Sign

The *sign* field controls how the sign of a numeric value is emitted. It
applies to signed integer and floating-point types only.

| Option | Effect                                                            |
|--------|-------------------------------------------------------------------|
| `+`    | Always emit a sign (`+` for nonnegative values, `-` for negative).|
| `-`    | Emit `-` only for negative values. This is the default.           |
| space  | Emit a leading space for nonnegative values and `-` for negative ones; useful for aligning columns of signed numbers. |

The sign of `-0.0` is preserved in floating-point output.

```c++
fmt::format("{:+d} {:+d}", 7, -7);  // Result: "+7 -7"
fmt::format("{: d} {: d}", 7, -7);  // Result: " 7 -7"
```

### Alternate form (`#`)

The `#` flag selects an *alternate form* whose exact meaning depends on the
presentation type:

- For integers rendered in binary, octal, or hexadecimal, it prepends the
  appropriate base prefix (`0b`/`0B`, `0`, or `0x`/`0X`). The case of the
  prefix follows the case of the type specifier — `0x` for `x`, `0X` for
  `X`, and so on.
- For floating-point values, it forces the decimal point to appear in the
  output even if no fractional digits would otherwise be emitted, and
  prevents the `g`/`G` presentation types from removing trailing zeros from
  the significand.

The `#` flag is not accepted by non-numeric types.

### Zero padding (`0`)

A `0` placed immediately before *width* enables sign-aware zero padding for
numeric types. Zeros are inserted between the sign (or base prefix, if any)
and the most significant digit, so that a sign or `0x` prefix stays adjacent
to the digits rather than being separated by spaces. For example, `{:+08d}`
applied to `120` produces `+0000120`.

Zero padding:

- applies only to numeric types;
- has no effect on `inf` or `nan`;
- is ignored when an explicit *align* is also present.

### Width

*width* is a non-negative decimal integer giving the minimum number of
characters that the field should occupy. If the formatted value is shorter
than *width*, it is padded according to *align* and *fill*; if it is longer,
the value is written in full. *width* never causes the value to be
truncated.

To supply *width* at runtime, write the field as `{}` to consume the next
argument, or as `{arg_id}` to reference an integer argument by position or
by name.

When formatting strings, "width" is measured in display columns using a
Unicode-aware estimate (East Asian wide and fullwidth characters, plus
common emoji ranges, count as two columns; everything else counts as one).
This keeps fixed *width* values visually consistent in monospace renderings
that combine Latin and CJK text.

```c++
fmt::format("[{:6}]", 42);
// Result: "[    42]"  - right-aligned by default
fmt::format("[{:6}]", "hi");
// Result: "[hi    ]"  - left-aligned by default
fmt::format("[{:{}}]", 42, 6);
// Result: "[    42]"  - width from an argument
```

### Precision

*precision* is a non-negative decimal integer (introduced by `.`) whose
meaning depends on the value being formatted. As with *width*, it may be
supplied as a nested replacement field for runtime evaluation.

| Type                          | Meaning of `.precision`                       |
|-------------------------------|-----------------------------------------------|
| `e`, `E`, `f`, `F`            | Digits emitted after the decimal point.       |
| `g`, `G`                      | Total number of significant digits.           |
| `a`, `A`                      | Digits after the decimal point in the hexadecimal significand. If omitted, just enough digits are emitted to round-trip the value exactly. |
| Strings (`s`, `?`, or default) | Upper bound on the number of code points copied from the value. |

A *precision* is not accepted for integer, character, boolean, or pointer
types. When a *precision* limits the number of characters taken from a C
string, the string must still be null-terminated.

```c++
fmt::format("{:.2f}", 3.14159);        // Result: "3.14"
fmt::format("{:.3g}", 3.14159);        // Result: "3.14"
fmt::format("{:.4}", "hello, world");  // Result: "hell"
fmt::format("{:.{}f}", 3.14159, 4);
// Result: "3.1416"  - precision from an argument
```

### Locale (`L`)

The `L` flag selects locale-sensitive formatting for numeric types. The
formatter inspects the C++ locale supplied to the formatting function (or
the global locale, if none was passed) and inserts the locale's digit
grouping characters and — for floating-point values — its decimal point.
The flag has no effect on non-numeric types.

```c++
auto loc = std::locale("en_US.UTF-8");
fmt::format(loc, "{:L}", 1234567890);     // Result: "1,234,567,890"
fmt::format(loc, "{:.2Lf}", 1234567.89);  // Result: "1,234,567.89"
```

### Presentation type

The *type* field chooses the representation for the value. Specifiers are
grouped below by the value categories they apply to.

**Integers, booleans, and characters:**

| Type | Effect                                                              |
|------|---------------------------------------------------------------------|
| `b`  | Base 2. The `#` flag adds a `0b` prefix.                            |
| `B`  | Base 2. The `#` flag adds a `0B` prefix.                            |
| `c`  | Render the integer as the character with that code point. Not allowed for `bool`. |
| `d`  | Base 10. The default for integer types.                             |
| `o`  | Base 8.                                                             |
| `x`  | Base 16, lower-case digits. The `#` flag adds a `0x` prefix.        |
| `X`  | Base 16, upper-case digits. The `#` flag adds a `0X` prefix.        |
| none | Same as `d` for integers, `c` for characters, and the textual form (`true`/`false`) for `bool`. |

```c++
fmt::format("{:d} {:#x} {:#o} {:#b}", 42, 42, 42, 42);
// Result: "42 0x2a 052 0b101010"

fmt::format("{:#06x}", 0xfe);  // # adds the prefix, 06 zero-pads to width 6
// Result: "0x00fe"
```

**Floating-point values:**

| Type | Effect                                                              |
|------|---------------------------------------------------------------------|
| `a`  | Hexadecimal-significand form (e.g. `0x1.8p+1`). Lower-case digits and a lower-case `p` for the binary exponent. The `0x` prefix is always emitted, matching printf's `%a`. The `#` flag forces a decimal point (e.g. `0x1.p+1`).
| `A`  | Same as `a`, but upper-case throughout.                             |
| `e`  | Scientific notation with a lower-case `e` for the decimal exponent. |
| `E`  | Scientific notation with an upper-case `E`.                         |
| `f`  | Fixed-point notation.                                               |
| `F`  | Same as `f`, but renders `nan` as `NAN` and `inf` as `INF`.         |
| `g`  | General form: scientific notation when the exponent would be less than &minus;4 or not less than the precision, otherwise fixed-point; trailing zeros are removed from the fractional part unless `#` is set. A precision of `0` is interpreted as `1`. |
| `G`  | Same as `g`, but uses `E` for the exponent and upper-case `INF`/`NAN`. |
| none | Shortest round-trip representation: the formatted value, when parsed back into the same floating-point type, reproduces the input bit for bit. |

**Strings and characters:**

| Type | Effect                                                              |
|------|---------------------------------------------------------------------|
| `s`  | Plain string output. Default for string types and for `bool` (which is rendered as `true` or `false`). |
| `c`  | Character output. Default for character types. Not allowed for `bool`. |
| `?`  | Debug output: the value is wrapped in single quotes (characters) or double quotes (strings), and non-printable, non-ASCII, and special characters are escaped using C-style escape sequences such as `\n`, `\t`, `\"`, and `\u{...}`. |
| none | Same as `s` for strings and `bool`, and as `c` for characters.      |

```c++
fmt::format("{}",   "tab\there");  // Result contains a literal tab character.
fmt::format("{:?}", "tab\there");  // Result: "\"tab\\there\""
```

**Pointers:**

| Type | Effect                                                              |
|------|---------------------------------------------------------------------|
| `p`  | Hexadecimal address prefixed by `0x`. Default for pointer types.    |
| none | Same as `p`.                                                        |

A C string (`char*` or `const char*`) accepts both the string presentation
types and `p`, so the same value can be formatted as either text or an
address.

## Chrono Format Specification

The format specification for chrono duration and time point types as well
as `std::tm` has the following syntax:

<a id="chrono-format-spec"></a>
<code class="language-json"
>chrono_format_spec ::= [[[fill](#format-spec)][align](#format-spec)][[width](#format-spec)]["." [precision](#format-spec)][chrono_specs]
chrono_specs       ::= conversion_spec |
                       chrono_specs (conversion_spec | literal_char)
conversion_spec    ::= "%" [padding_modifier] [locale_modifier] chrono_type
literal_char       ::= &lt;a character other than '{', '}' or '%'>
padding_modifier   ::= "-" | "_"  | "0"
locale_modifier    ::= "E" | "O"
chrono_type        ::= "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" |
                       "F" | "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" |
                       "n" | "p" | "q" | "Q" | "r" | "R" | "S" | "t" | "T" |
                       "u" | "U" | "V" | "w" | "W" | "x" | "X" | "y" | "Y" |
                       "z" | "Z" | "%"</code>


Literal chars are copied unchanged to the output. Precision is valid only
for `std::chrono::duration` types with a floating-point representation type.

The available presentation types (*chrono_type*) are:



| Type | Meaning |
| --- | --- |
| `'a'` | The abbreviated weekday name, e.g. "Sat". If the value does not contain a
    valid weekday, an exception of type `format_error` is thrown. |
| `'A'` | The full weekday name, e.g. "Saturday". If the value does not contain a
    valid weekday, an exception of type `format_error` is thrown. |
| `'b'` | The abbreviated month name, e.g. "Nov". If the value does not contain a
    valid month, an exception of type `format_error` is thrown. |
| `'B'` | The full month name, e.g. "November". If the value does not contain a valid
    month, an exception of type `format_error` is thrown. |
| `'c'` | The date and time representation, e.g. "Sat Nov 12 22:04:00 1955". The
    modified command `%Ec` produces the locale's alternate date and
    time representation. |
| `'C'` | The year divided by 100 using floored division, e.g. "19". If the result
    is a single decimal digit, it is prefixed with 0. The modified command
    `%EC` produces the locale's alternative representation of the
    century. |
| `'d'` | The day of month as a decimal number. If the result is a single decimal
    digit, it is prefixed with 0. The modified command `%Od`
    produces the locale's alternative representation. |
| `'D'` | Equivalent to `%m/%d/%y`, e.g. "11/12/55". |
| `'e'` | The day of month as a decimal number. If the result is a single decimal
    digit, it is prefixed with a space. The modified command `%Oe`
    produces the locale's alternative representation. |
| `'F'` | Equivalent to `%Y-%m-%d`, e.g. "1955-11-12". |
| `'g'` | The last two decimal digits of the ISO week-based year. If the result is a
    single digit it is prefixed by 0. |
| `'G'` | The ISO week-based year as a decimal number. If the result is less than
    four digits it is left-padded with 0 to four digits. |
| `'h'` | Equivalent to `%b`, e.g. "Nov". |
| `'H'` | The hour (24-hour clock) as a decimal number. If the result is a single
    digit, it is prefixed with 0. The modified command `%OH`
    produces the locale's alternative representation. |
| `'I'` | The hour (12-hour clock) as a decimal number. If the result is a single
    digit, it is prefixed with 0. The modified command `%OI`
    produces the locale's alternative representation. |
| `'j'` | If the type being formatted is a specialization of duration, the decimal
    number of days without padding. Otherwise, the day of the year as a decimal
    number. Jan 1 is 001. If the result is less than three digits, it is
    left-padded with 0 to three digits. |
| `'m'` | The month as a decimal number. Jan is 01. If the result is a single digit,
    it is prefixed with 0. The modified command `%Om` produces the
    locale's alternative representation. |
| `'M'` | The minute as a decimal number. If the result is a single digit, it
    is prefixed with 0. The modified command `%OM` produces the
    locale's alternative representation. |
| `'n'` | A new-line character. |
| `'p'` | The AM/PM designations associated with a 12-hour clock. |
| `'q'` | The duration's unit suffix. |
| `'Q'` | The duration's numeric value (as if extracted via `.count()`). |
| `'r'` | The 12-hour clock time, e.g. "10:04:00 PM". |
| `'R'` | Equivalent to `%H:%M`, e.g. "22:04". |
| `'S'` | Seconds as a decimal number. If the number of seconds is less than 10, the
    result is prefixed with 0. If the precision of the input cannot be exactly
    represented with seconds, then the format is a decimal floating-point number
    with a fixed format and a precision matching that of the precision of the
    input (or to a microseconds precision if the conversion to floating-point
    decimal seconds cannot be made within 18 fractional digits). The modified
    command `%OS` produces the locale's alternative representation. |
| `'t'` | A horizontal-tab character. |
| `'T'` | Equivalent to `%H:%M:%S`. |
| `'u'` | The ISO weekday as a decimal number (1-7), where Monday is 1. The modified
    command `%Ou` produces the locale's alternative representation. |
| `'U'` | The week number of the year as a decimal number. The first Sunday of the
    year is the first day of week 01. Days of the same year prior to that are
    in week 00. If the result is a single digit, it is prefixed with 0.
    The modified command `%OU` produces the locale's alternative
    representation. |
| `'V'` | The ISO week-based week number as a decimal number. If the result is a
    single digit, it is prefixed with 0. The modified command `%OV`
    produces the locale's alternative representation. |
| `'w'` | The weekday as a decimal number (0-6), where Sunday is 0. The modified
    command `%Ow` produces the locale's alternative representation. |
| `'W'` | The week number of the year as a decimal number. The first Monday of the
    year is the first day of week 01. Days of the same year prior to that are
    in week 00. If the result is a single digit, it is prefixed with 0.
    The modified command `%OW` produces the locale's alternative
    representation. |
| `'x'` | The date representation, e.g. "11/12/55". The modified command
    `%Ex` produces the locale's alternate date representation. |
| `'X'` | The time representation, e.g. "10:04:00". The modified command
    `%EX` produces the locale's alternate time representation. |
| `'y'` | The last two decimal digits of the year. If the result is a single digit
    it is prefixed by 0. The modified command `%Oy` produces the
    locale's alternative representation. The modified command `%Ey`
    produces the locale's alternative representation of offset from
    `%EC` (year only). |
| `'Y'` | The year as a decimal number. If the result is less than four digits it is
    left-padded with 0 to four digits. The modified command `%EY`
    produces the locale's alternative full year representation. |
| `'z'` | The offset from UTC in the ISO 8601:2004 format. For example -0430 refers
    to 4 hours 30 minutes behind UTC. If the offset is zero, +0000 is used.
    The modified commands `%Ez` and `%Oz` insert a
    `:` between the hours and minutes: -04:30. If the offset
    information is not available, an exception of type
    `format_error` is thrown. |
| `'Z'` | The time zone abbreviation. If the time zone abbreviation is not available,
    an exception of type `format_error` is thrown. |
| `'%'` | A % character. |



Specifiers that have a calendaric component such as `'d'` (the day of month)
are valid only for `std::tm` and time points but not durations.

The available padding modifiers (*padding_modifier*) are:

| Type  | Meaning                                 |
|-------|-----------------------------------------|
| `'_'` | Pad a numeric result with spaces.       |
| `'-'` | Do not pad a numeric result string.     |
| `'0'` | Pad a numeric result string with zeros. |

These modifiers are only supported for the `'H'`, `'I'`, `'M'`, `'S'`, `'U'`,
`'V'`, `'W'`, `'Y'`, `'d'`, `'j'` and `'m'` presentation types.

Example:

```c++
#include <fmt/chrono.h>

auto t = std::tm();
t.tm_year = 2010 - 1900;
t.tm_mon = 7;
t.tm_mday = 4;
t.tm_hour = 12;
t.tm_min = 15;
t.tm_sec = 58;
fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
// Prints: 2010-08-04 12:15:58
```

## Range Format Specification

The format specification for range types has the following syntax:

<code class="language-json"
>range_format_spec ::= ["n"][range_type][":" range_underlying_spec]</code>


The `'n'` option formats the range without the opening and closing brackets.

The available presentation types for `range_type` are:

| Type   | Meaning                                                    |
|--------|------------------------------------------------------------|
| none   | Default format.                                            |
| `'s'`  | String format. The range is formatted as a string.         |
| `'?⁠s'` | Debug format. The range is formatted as an escaped string. |

If `range_type` is `'s'` or `'?s'`, the range element type must be a character
type. The `'n'` option and `range_underlying_spec` are mutually exclusive with
`'s'` and `'?s'`.

The `range_underlying_spec` is parsed based on the formatter of the range's
element type.

By default, a range of characters or strings is printed escaped and quoted.
But if any `range_underlying_spec` is provided (even if it is empty), then the
characters or strings are printed according to the provided specification.

Examples:

```c++
fmt::print("{}", std::vector{10, 20, 30});
// Output: [10, 20, 30]
fmt::print("{::#x}", std::vector{10, 20, 30});
// Output: [0xa, 0x14, 0x1e]
fmt::print("{}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: ['h', 'e', 'l', 'l', 'o']
fmt::print("{:n}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: 'h', 'e', 'l', 'l', 'o'
fmt::print("{:s}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: "hello"
fmt::print("{:?s}", std::vector{'h', 'e', 'l', 'l', 'o', '\n'});
// Output: "hello\n"
fmt::print("{::}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: [h, e, l, l, o]
fmt::print("{::d}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: [104, 101, 108, 108, 111]
fmt::print("{:n:f}", std::array{std::numbers::pi, std::numbers::e});
// Output: 3.141593, 2.718282
```

## A Combined Example

The example below ties together several elements introduced above — nested
replacement fields, fill characters, and centering — to draw a fixed-width
box around a message:

```c++
fmt::print(
    "┌{0:─^{2}}┐\n"
    "│{1: ^{2}}│\n"
    "└{0:─^{2}}┘\n", "", "Hello, world!", 20);
```

Output:

```
┌────────────────────┐
│   Hello, world!    │
└────────────────────┘
```