[format.context]

# 28 Text processing library [[text]](./#text)

## 28.5 Formatting [[format]](format#context)

### 28.5.6 Formatter [[format.formatter]](format.formatter#format.context)

#### 28.5.6.7 Class template basic_format_context [format.context]

[ð](#lib:basic_format_context)

namespace std {template<class Out, class charT>class basic_format_context { basic_format_args<basic_format_context> args_; // *exposition only* Out out_; // *exposition only* basic_format_context(const basic_format_context&) = delete;
 basic_format_context& operator=(const basic_format_context&) = delete; public:using iterator = Out; using char_type = charT; template<class T> using formatter_type = formatter<T, charT>;

 basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
 std::locale locale();

 iterator out(); void advance_to(iterator it); };}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7704)

An instance of basic_format_context holds formatting state
consisting of the formatting arguments and the output iterator[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7708)

If a program declares an explicit or partial specialization ofbasic_format_context,
the program is ill-formed, no diagnostic required[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7713)

Out shall model [output_iterator](iterator.concept.output#concept:output_iterator "24.3.4.10 Concept output_­iterator [iterator.concept.output]")<const charT&>[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7716)

format_context is an alias for
a specialization of basic_format_context with an output iterator
that appends to string,
such as back_insert_iterator<string>[.](#4.sentence-1)

Similarly, wformat_context is an alias for
a specialization of basic_format_context with an output iterator
that appends to wstring[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7729)

*Recommended practice*: For a given type charT,
implementations should provide
a single instantiation of basic_format_context for appending tobasic_string<charT>,vector<charT>,
or any other container with contiguous storage
by wrapping those in temporary objects with a uniform interface
(such as a span<charT>) and polymorphic reallocation[.](#5.sentence-1)

[ð](#lib:arg,basic_format_context)

`basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7747)

*Returns*: args_.get(id)[.](#6.sentence-1)

[ð](#lib:locale,basic_format_context)

`std::locale locale();
`

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7758)

*Returns*: The locale passed to the formatting function
if the latter takes one,
and std​::​locale() otherwise[.](#7.sentence-1)

[ð](#lib:out,basic_format_context)

`iterator out();
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7771)

*Effects*: Equivalent to: return std​::​move(out_);

[ð](#lib:advance_to,basic_format_context)

`void advance_to(iterator it);
`

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7782)

*Effects*: Equivalent to: out_ = std​::​move(it);

[*Example [1](#example-1)*: struct S { int value; };

template<> struct std::formatter<S> { size_t width_arg_id = 0; // Parses a width argument id in the format { *digit* }.constexpr auto parse(format_parse_context& ctx) {auto iter = ctx.begin(); auto is_digit = [](auto c) { return c >= '0' && c <= '9'; }; auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; }; if (get_char() != '{')return iter; ++iter; char c = get_char(); if (!is_digit(c) || (++iter, get_char()) != '}')throw format_error("invalid format");
 width_arg_id = c - '0';
 ctx.check_arg_id(width_arg_id); return ++iter; }// Formats an S with width given by the argument width_arg_id.auto format(S s, format_context& ctx) const {int width = ctx.arg(width_arg_id).visit([](auto value) -> int {if constexpr (!is_integral_v<decltype(value)>)throw format_error("width is not integral"); else if (value < 0 || value > numeric_limits<int>::max())throw format_error("invalid width"); elsereturn value; }); return format_to(ctx.out(), "{0:x>{1}}", s.value, width); }};

std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42" â *end example*]
