22 General utilities library [utilities]

22.14 Formatting [format]

22.14.8 Arguments [format.arguments]

22.14.8.1 Class template basic_format_arg [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); }; }
An instance of basic_format_arg provides access to a formatting argument for user-defined formatters.
The behavior of a program that adds specializations of basic_format_arg is undefined.
basic_format_arg() noexcept;
Postconditions: !(*this).
template<class T> explicit basic_format_arg(T& v) noexcept;
Constraints: T satisfies formattable-with<Context>.
Preconditions: If decay_t<T> is char_type* or const char_type*, static_cast<const char_
type*>(v)
points to a NTCTS ([defns.ntcts]).
Effects: Let TD be remove_const_t<T>.
  • If TD is bool or char_type, initializes value with v;
  • otherwise, if TD is char and char_type is wchar_t, initializes value with static_cast<wchar_t>(static_cast<unsigned char>(v));
  • otherwise, if TD is a signed integer type ([basic.fundamental]) and sizeof(TD) <= sizeof(int), initializes value with static_cast<int>(v);
  • otherwise, if TD is an unsigned integer type and sizeof(TD) <= sizeof(unsigned int), initializes value with static_cast<unsigned int>(v);
  • otherwise, if TD is a signed integer type and sizeof(TD) <= sizeof(long long int), initializes value with static_cast<long long int>(v);
  • otherwise, if TD is an unsigned integer type and sizeof(TD) <= sizeof(unsigned long long int), initializes value with static_cast<unsigned long long int>(v);
  • otherwise, if TD is a standard floating-point type, initializes value with v;
  • otherwise, if TD is a specialization of basic_string_view or basic_string and TD​::​value_type is char_type, initializes value with basic_string_view<char_type>(v.data(), v.size());
  • otherwise, if decay_t<TD> is char_type* or const char_type*, initializes value with static_cast<const char_type*>(v);
  • otherwise, if is_void_v<remove_pointer_t<TD>> is true or is_null_pointer_v<TD> is true, initializes value with static_cast<const void*>(v);
  • otherwise, initializes value with handle(v).
[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.
— end note]
explicit operator bool() const noexcept;
Returns: !holds_alternative<monostate>(value).
template<class Visitor> decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
Effects: Equivalent to: return arg.value.visit(std​::​forward<Visitor>(vis));
template<class R, class Visitor> R visit(this basic_format_arg arg, Visitor&& vis);
Effects: Equivalent to: return arg.value.visit<R>(std​::​forward<Visitor>(vis));
The class handle allows formatting an object of a user-defined type.
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 friend class basic_format_arg<Context>; // exposition only public: void format(basic_format_parse_context<char_type>&, Context& ctx) const; }; }
template<class T> explicit handle(T& val) noexcept;
Let
Mandates: TQ satisfies formattable-with<Context>.
Effects: Initializes ptr_ with addressof(val) and format_ 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)); }
void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
Effects: Equivalent to: format_(parse_ctx, format_ctx, ptr_);