301 lines
11 KiB
Markdown
301 lines
11 KiB
Markdown
[format.arguments]
|
||
|
||
# 28 Text processing library [[text]](./#text)
|
||
|
||
## 28.5 Formatting [[format]](format#arguments)
|
||
|
||
### 28.5.8 Arguments [format.arguments]
|
||
|
||
#### [28.5.8.1](#format.arg) Class template basic_format_arg [[format.arg]](format.arg)
|
||
|
||
[ð](#lib:basic_format_arg)
|
||
|
||
namespace std {template<class Context>class basic_format_arg {public:class handle; private:using char_type = typename Context::char_type; // *exposition only* variant<monostate, bool, char_type, int, unsigned int, long long int, unsigned long long int, float, double, long double, const char_type*, basic_string_view<char_type>, const void*, handle> value; // *exposition only*template<class T> explicit basic_format_arg(T& v) noexcept; // *exposition only*public: basic_format_arg() noexcept; explicit operator bool() const noexcept; template<class Visitor>decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); template<class R, class Visitor> R visit(this basic_format_arg arg, Visitor&& vis); };}
|
||
|
||
[1](#format.arg-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8454)
|
||
|
||
An instance of basic_format_arg provides access to
|
||
a formatting argument for user-defined formatters[.](#format.arg-1.sentence-1)
|
||
|
||
[2](#format.arg-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8458)
|
||
|
||
The behavior of a program that adds specializations ofbasic_format_arg is undefined[.](#format.arg-2.sentence-1)
|
||
|
||
[ð](#lib:basic_format_arg,constructor)
|
||
|
||
`basic_format_arg() noexcept;
|
||
`
|
||
|
||
[3](#format.arg-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8468)
|
||
|
||
*Postconditions*: !(*this)[.](#format.arg-3.sentence-1)
|
||
|
||
[ð](#format.arg-itemdecl:2)
|
||
|
||
`template<class T> explicit basic_format_arg(T& v) noexcept;
|
||
`
|
||
|
||
[4](#format.arg-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8478)
|
||
|
||
*Constraints*: T satisfies [*formattable-with*](format.formattable#concept:formattable-with "28.5.6.3 Concept formattable [format.formattable]")<Context>[.](#format.arg-4.sentence-1)
|
||
|
||
[5](#format.arg-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8482)
|
||
|
||
*Preconditions*: If decay_t<T> is char_type* or const char_type*,static_cast<const char_
|
||
type*>(v) points to an NTCTS ([[defns.ntcts]](defns.ntcts "3.36 NTCTS"))[.](#format.arg-5.sentence-1)
|
||
|
||
[6](#format.arg-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8487)
|
||
|
||
*Effects*: Let TD be remove_const_t<T>[.](#format.arg-6.sentence-1)
|
||
|
||
- [(6.1)](#format.arg-6.1)
|
||
|
||
If TD is bool or char_type,
|
||
initializes value with v;
|
||
|
||
- [(6.2)](#format.arg-6.2)
|
||
|
||
otherwise, if TD is char and char_type iswchar_t, initializes value withstatic_cast<wchar_t>(static_cast<unsigned char>(v));
|
||
|
||
- [(6.3)](#format.arg-6.3)
|
||
|
||
otherwise, if TD is a signed integer type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))
|
||
and sizeof(TD) <= sizeof(int),
|
||
initializes value with static_cast<int>(v);
|
||
|
||
- [(6.4)](#format.arg-6.4)
|
||
|
||
otherwise, if TD is an unsigned integer type andsizeof(TD) <= sizeof(unsigned int), initializesvalue with static_cast<unsigned int>(v);
|
||
|
||
- [(6.5)](#format.arg-6.5)
|
||
|
||
otherwise, if TD is a signed integer type andsizeof(TD) <= sizeof(long long int), initializesvalue with static_cast<long long int>(v);
|
||
|
||
- [(6.6)](#format.arg-6.6)
|
||
|
||
otherwise, if TD is an unsigned integer type andsizeof(TD) <= sizeof(unsigned long long int), initializesvalue withstatic_cast<unsigned long long int>(v);
|
||
|
||
- [(6.7)](#format.arg-6.7)
|
||
|
||
otherwise, if TD is a standard floating-point type,
|
||
initializes value with v;
|
||
|
||
- [(6.8)](#format.arg-6.8)
|
||
|
||
otherwise, if TD is
|
||
a specialization of basic_string_view or basic_string andTD::value_type is char_type,
|
||
initializes value withbasic_string_view<char_type>(v.data(), v.size());
|
||
|
||
- [(6.9)](#format.arg-6.9)
|
||
|
||
otherwise, if decay_t<TD> ischar_type* or const char_type*,
|
||
initializes value with static_cast<const char_type*>(v);
|
||
|
||
- [(6.10)](#format.arg-6.10)
|
||
|
||
otherwise, if is_void_v<remove_pointer_t<TD>> is true oris_null_pointer_v<TD> is true,
|
||
initializes value with static_cast<const void*>(v);
|
||
|
||
- [(6.11)](#format.arg-6.11)
|
||
|
||
otherwise, initializes value with handle(v).
|
||
|
||
[*Note [1](#format.arg-note-1)*:
|
||
|
||
Constructing basic_format_arg from a pointer to a member is ill-formed
|
||
unless the user provides an enabled specialization of formatter for that pointer to member type[.](#format.arg-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator_bool,basic_format_arg)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[7](#format.arg-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8550)
|
||
|
||
*Returns*: !holds_alternative<monostate>(value)[.](#format.arg-7.sentence-1)
|
||
|
||
[ð](#lib:visit,basic_format_arg)
|
||
|
||
`template<class Visitor>
|
||
decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
|
||
`
|
||
|
||
[8](#format.arg-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8562)
|
||
|
||
*Effects*: Equivalent to: return arg.value.visit(std::forward<Visitor>(vis));
|
||
|
||
[ð](#lib:visit,basic_format_arg_)
|
||
|
||
`template<class R, class Visitor>
|
||
R visit(this basic_format_arg arg, Visitor&& vis);
|
||
`
|
||
|
||
[9](#format.arg-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8574)
|
||
|
||
*Effects*: Equivalent to: return arg.value.visit<R>(std::forward<Visitor>(vis));
|
||
|
||
[10](#format.arg-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8579)
|
||
|
||
The class handle allows formatting an object of a user-defined type[.](#format.arg-10.sentence-1)
|
||
|
||
[ð](#lib:basic_format_arg::handle)
|
||
|
||
namespace std {template<class Context>class basic_format_arg<Context>::handle {const void* ptr_; // *exposition only*void (*format_)(basic_format_parse_context<char_type>&,
|
||
Context&, const void*); // *exposition only*template<class T> explicit handle(T& val) noexcept; // *exposition only*public:void format(basic_format_parse_context<char_type>&, Context& ctx) const; };}
|
||
|
||
[ð](#lib:basic_format_arg::handle,constructor)
|
||
|
||
`template<class T> explicit handle(T& val) noexcept;
|
||
`
|
||
|
||
[11](#format.arg-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8606)
|
||
|
||
Let
|
||
|
||
- [(11.1)](#format.arg-11.1)
|
||
|
||
TD be remove_const_t<T>,
|
||
|
||
- [(11.2)](#format.arg-11.2)
|
||
|
||
TQ be const TD ifconst TD satisfies [*formattable-with*](format.formattable#concept:formattable-with "28.5.6.3 Concept formattable [format.formattable]")<Context> and TD otherwise[.](#format.arg-11.sentence-1)
|
||
|
||
[12](#format.arg-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8617)
|
||
|
||
*Mandates*: TQ satisfies [*formattable-with*](format.formattable#concept:formattable-with "28.5.6.3 Concept formattable [format.formattable]")<Context>[.](#format.arg-12.sentence-1)
|
||
|
||
[13](#format.arg-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8621)
|
||
|
||
*Effects*: Initializesptr_ with addressof(val) andformat_ with[](basic_format_parse_context<char_type>& parse_ctx,
|
||
Context& format_ctx, const void* ptr) {typename Context::template formatter_type<TD> f;
|
||
parse_ctx.advance_to(f.parse(parse_ctx));
|
||
format_ctx.advance_to(f.format(*const_cast<TQ*>(static_cast<const TD*>(ptr)),
|
||
format_ctx));}
|
||
|
||
[ð](#lib:format,basic_format_arg::handle)
|
||
|
||
`void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
|
||
`
|
||
|
||
[14](#format.arg-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8643)
|
||
|
||
*Effects*: Equivalent to: format_(parse_ctx, format_ctx, ptr_);
|
||
|
||
#### [28.5.8.2](#format.arg.store) Class template *format-arg-store* [[format.arg.store]](format.arg.store)
|
||
|
||
namespace std {template<class Context, class... Args>class *format-arg-store* { // *exposition only* array<basic_format_arg<Context>, sizeof...(Args)> *args*; // *exposition only*};}
|
||
|
||
[1](#format.arg.store-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8659)
|
||
|
||
An instance of *format-arg-store* stores formatting arguments[.](#format.arg.store-1.sentence-1)
|
||
|
||
[ð](#lib:make_format_args)
|
||
|
||
`template<class Context = format_context, class... Args>
|
||
format-arg-store<Context, Args...> make_format_args(Args&... fmt_args);
|
||
`
|
||
|
||
[2](#format.arg.store-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8669)
|
||
|
||
*Preconditions*: The typetypename Context::template formatter_type<remove_const_t<Ti>>
|
||
meets the *BasicFormatter* requirements ([[formatter.requirements]](formatter.requirements "28.5.6.1 Formatter requirements"))
|
||
for each Ti in Args[.](#format.arg.store-2.sentence-1)
|
||
|
||
[3](#format.arg.store-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8676)
|
||
|
||
*Returns*: An object of type *format-arg-store*<Context, Args...> whose *args* data member is initialized with{basic_format_arg<Context>(fmt_args)...}[.](#format.arg.store-3.sentence-1)
|
||
|
||
[ð](#lib:make_wformat_args)
|
||
|
||
`template<class... Args>
|
||
format-arg-store<wformat_context, Args...> make_wformat_args(Args&... args);
|
||
`
|
||
|
||
[4](#format.arg.store-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8690)
|
||
|
||
*Effects*: Equivalent to:return make_format_args<wformat_context>(args...);
|
||
|
||
#### [28.5.8.3](#format.args) Class template basic_format_args [[format.args]](format.args)
|
||
|
||
namespace std {template<class Context>class basic_format_args { size_t size_; // *exposition only*const basic_format_arg<Context>* data_; // *exposition only*public:template<class... Args> basic_format_args(const *format-arg-store*<Context, Args...>& store) noexcept;
|
||
|
||
basic_format_arg<Context> get(size_t i) const noexcept; }; template<class Context, class... Args> basic_format_args(*format-arg-store*<Context, Args...>) -> basic_format_args<Context>;}
|
||
|
||
[1](#format.args-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8717)
|
||
|
||
An instance of basic_format_args provides access to formatting
|
||
arguments[.](#format.args-1.sentence-1)
|
||
|
||
Implementations should
|
||
optimize the representation of basic_format_args for a small number of formatting arguments[.](#format.args-1.sentence-2)
|
||
|
||
[*Note [1](#format.args-note-1)*:
|
||
|
||
For example, by storing indices of type alternatives separately from values
|
||
and packing the former[.](#format.args-1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:basic_format_args,constructor)
|
||
|
||
`template<class... Args>
|
||
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
|
||
`
|
||
|
||
[2](#format.args-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8735)
|
||
|
||
*Effects*: Initializessize_ with sizeof...(Args) anddata_ with store.args.data()[.](#format.args-2.sentence-1)
|
||
|
||
[ð](#lib:get,basic_format_args)
|
||
|
||
`basic_format_arg<Context> get(size_t i) const noexcept;
|
||
`
|
||
|
||
[3](#format.args-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8748)
|
||
|
||
*Returns*: i < size_ ? data_[i] : basic_format_arg<Context>()[.](#format.args-3.sentence-1)
|