[format.context] (original) (raw)
28 Text processing library [text]
28.5 Formatting [format]
28.5.6 Formatter [format.formatter]
28.5.6.7 Class template basic_format_context [format.context]
namespace std { template<class Out, class charT> class basic_format_context { basic_format_args<basic_format_context> args_; Out out_; 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);};}
An instance of basic_format_context holds formatting state consisting of the formatting arguments and the output iterator.
If a program declares an explicit or partial specialization ofbasic_format_context, the program is ill-formed, no diagnostic required.
format_context is an alias for a specialization of basic_format_contextwith an output iterator that appends to string, such as back_insert_iterator<string>.
Similarly, wformat_context is an alias for a specialization of basic_format_contextwith an output iterator that appends to wstring.
Recommended practice: For a given type charT, implementations should provide a single instantiation of basic_format_contextfor 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.
basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
Returns: The locale passed to the formatting function if the latter takes one, and std::locale() otherwise.
Effects: Equivalent to: return std::move(out_);
void advance_to(iterator it);
Effects: Equivalent to: out_ = std::move(it);
[Example 1: struct S { int value; };template<> struct std::formatter<S> { size_t width_arg_id = 0;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;} 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");else return value;});return format_to(ctx.out(), "{0:x>{1}}", s.value, width);} }; std::string s = std::format("{0:{1}}", S{42}, 10); — _end example_]