What Is fmt::format_context? A Deep Dive into the {fmt} Library's Formatting Engine

fmt::format_context is the central formatting context in the {fmt} library that bundles the output iterator, type-erased arguments, locale reference, and formatting specifications to drive the string formatting pipeline.

The {fmt} library (fmtlib/fmt) provides fast, type-safe formatting for modern C++. At the heart of this system lies fmt::format_context, a lightweight carrier object defined in include/fmt/core.h that connects format strings to their arguments and output destinations during the formatting process.

What Is fmt::format_context?

fmt::format_context is a type alias for the internal context class, specifically declared at lines 620–624 in include/fmt/core.h. It represents a concrete instantiation of the generic fmt::basic_format_context template, using the default output iterator (fmt::output_iterator<char>) and character type char.

This context object serves as the default carrier for the most common formatting operations in the library, including fmt::format, fmt::print, and fmt::format_to. Because it is designed as a lightweight value type, formatting functions create fmt::format_context instances on the fly, pass them by reference to user-defined formatters, and return the resulting output iterator to callers.

Core Components of the Formatting Context

The context object bundles together four critical pieces of formatting state:

Output Iterator (Out)

The output iterator determines where formatted characters are written. Depending on the specific formatting function called, this may be a std::back_inserter for strings, a FILE* buffer for fmt::print, or any custom output iterator that satisfies the library's requirements.

Argument Store (format_args)

The context holds a type-erased view of the arguments supplied to a format string via fmt::make_format_args. The member type format_context::args_type stores a basic_format_args<context> object that can be queried by index or name during parsing and formatting.

Locale Reference (locale_ref)

fmt::format_context stores a locale_ref member that influences locale-sensitive formatting operations. This reference controls number formatting details such as thousands separators and decimal points when using specifiers like {:n}.

Formatting Specifications

The context maintains per-argument formatting options parsed from the format string, including precision, width, alignment flags, and fill characters. These specifications guide how individual arguments are converted to their string representations.

How fmt::format_context Works in Practice

When you call fmt::format, the library internally constructs a fmt::format_context to bridge the argument pack and the formatting engine:

auto args = fmt::make_format_args<fmt::format_context>(std::forward<Args>(args)...);
return fmt::vformat(fmt::runtime(fmt_str), args);

Here is how fmt::format_context functions in typical usage patterns:

#include <fmt/core.h>
#include <fmt/format.h>
#include <string>
#include <vector>

int main() {
    // 1. Default use – fmt::format_context is implicit
    std::string s = fmt::format("Hello, {}!", "world");
    
    // 2. Custom formatter accessing the context
    struct Point { int x, y; };
    
    template <>
    struct fmt::formatter<Point> {
        constexpr auto parse(fmt::format_parse_context& ctx) -> decltype(ctx.begin()) {
            return ctx.begin();
        }
        
        auto format(const Point& p, fmt::format_context& ctx) const -> decltype(ctx.out()) {
            // ctx.out() provides the output iterator
            return fmt::format_to(ctx.out(), "({},{})", p.x, p.y);
        }
    };
    
    Point pt{3, 4};
    std::string pt_str = fmt::format("Point: {}", pt);
    
    // 3. Explicit buffer formatting with context
    std::vector<char> buffer(64);
    auto out_it = fmt::format_to(buffer.begin(),
                                "ID={:04d}, value={:.2f}", 7, 3.14159);
    std::string result(buffer.begin(), out_it);
}

In the custom formatter example, the format() method receives a reference to fmt::format_context, enabling it to write directly to the output iterator while respecting the current locale and formatting state.

Source Code Architecture and Key Files

The implementation of fmt::format_context spans several files in the fmtlib/fmt repository:

  • include/fmt/core.h – Defines basic_format_context, the format_context alias, and low-level formatting primitives at lines 620–624.

  • include/fmt/format.h – Contains high-level formatting functions such as format, print, and format_to that instantiate fmt::format_context objects (around line 3870 in the implementation).

  • include/fmt/args.h – Implements dynamic_format_arg_store and the make_format_args machinery that builds the type-erased argument packs stored within the context.

  • include/fmt/xchar.h – Provides wide-character variants including wformat_context, which uses basic_format_context<wchar_t> for Unicode formatting operations.

  • src/format.cc – Houses the runtime parser that consumes fmt::format_context to produce the final formatted output.

Summary

  • fmt::format_context is a type alias for basic_format_context using char and the default output iterator, defined in include/fmt/core.h.

  • It bundles the output iterator, type-erased arguments (format_args), locale reference, and formatting specifications into a single lightweight object.

  • The context serves as the bridge between fmt::make_format_args and the low-level formatting engine, enabling type-safe, locale-aware string construction.

  • User-defined formatters receive fmt::format_context& in their format() method, allowing direct output via ctx.out() and access to formatting arguments.

  • Wide-character and custom output iterator variants are available through the basic_format_context template in include/fmt/xchar.h.

Frequently Asked Questions

What is the difference between fmt::format_context and fmt::basic_format_context?

fmt::basic_format_context is a class template parameterized by an output iterator type and character type, while fmt::format_context is a specific type alias that instantiates this template with char and the default output iterator. According to the source code in include/fmt/core.h, format_context provides the standard context used by fmt::format and fmt::print, whereas basic_format_context enables custom output destinations such as wide-character buffers or specialized iterators.

How do I access fmt::format_context in a custom formatter?

User-defined specializations of fmt::formatter<T> receive a reference to fmt::format_context as the second parameter of the format() method. You can access the output iterator via ctx.out() to write formatted data directly, or query formatting arguments through the context's stored format_args if your formatter needs to handle nested formatting. The parse() method, however, receives a format_parse_context& instead.

Does fmt::format_context support wide characters?

Yes, but through a different type alias. The {fmt} library defines fmt::wformat_context in include/fmt/xchar.h as a specialization of basic_format_context using wchar_t. This wide-character context works with fmt::format_to and other functions when formatting Unicode text, providing the same architecture as the standard fmt::format_context but operating on wide-character output iterators.

Is fmt::format_context thread-safe?

fmt::format_context itself is a lightweight, stateful object created on the stack during formatting operations and is not shared between threads. However, the underlying output iterator or locale reference must be thread-safe if used across multiple threads. The {fmt} library does not provide synchronization for the context object, so each thread should create its own formatting context instances when performing concurrent formatting operations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →