118 lines
4.7 KiB
Markdown
118 lines
4.7 KiB
Markdown
[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*]
|