[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_]