[format.arg]

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

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

### 28.5.8 Arguments [[format.arguments]](format.arguments#format.arg)

#### 28.5.8.1 Class template basic_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](#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[.](#1.sentence-1)

[2](#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[.](#2.sentence-1)

[ð](#lib:basic_format_arg,constructor)

`basic_format_arg() noexcept;
`

[3](#3)

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

*Postconditions*: !(*this)[.](#3.sentence-1)

[ð](#itemdecl:2)

`template<class T> explicit basic_format_arg(T& v) noexcept;
`

[4](#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>[.](#4.sentence-1)

[5](#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"))[.](#5.sentence-1)

[6](#6)

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

*Effects*: Let TD be remove_const_t<T>[.](#6.sentence-1)

- [(6.1)](#6.1)

If TD is bool or char_type,
initializes value with v;

- [(6.2)](#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)](#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)](#6.4)

otherwise, if TD is an unsigned integer type andsizeof(TD) <= sizeof(unsigned int), initializesvalue with static_cast<unsigned int>(v);

- [(6.5)](#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)](#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)](#6.7)

otherwise, if TD is a standard floating-point type,
initializes value with v;

- [(6.8)](#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)](#6.9)

otherwise, if decay_t<TD> ischar_type* or const char_type*,
initializes value with static_cast<const char_type*>(v);

- [(6.10)](#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)](#6.11)

otherwise, initializes value with handle(v).

[*Note [1](#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[.](#6.sentence-2)

â *end note*]

[ð](#lib:operator_bool,basic_format_arg)

`explicit operator bool() const noexcept;
`

[7](#7)

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

*Returns*: !holds_alternative<monostate>(value)[.](#7.sentence-1)

[ð](#lib:visit,basic_format_arg)

`template<class Visitor>
  decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
`

[8](#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](#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](#10)

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

The class handle allows formatting an object of a user-defined type[.](#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](#11)

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

Let

- [(11.1)](#11.1)

TD be remove_const_t<T>,

- [(11.2)](#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[.](#11.sentence-1)

[12](#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>[.](#12.sentence-1)

[13](#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](#14)

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

*Effects*: Equivalent to: format_(parse_ctx, format_ctx, ptr_);
