GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing timsong-cpp.github.io — [format] 28 Text processing library [text]28.5 Formatting [format]28.5.1 Header <format> synopsis [format.syn]28.5.2 Format string [format.string]28.5.2.1 General [format.string.general]28.5.2.2 Standard format specifiers [format.string.std]28.5.3 Error reporting [format.err.report]28.5.4 Class template basic_format_string [format.fmt.string]28.5.5 Formatting functions [format.functions]28.5.6 Formatter [format.formatter]28.5.6.1 Formatter requirements [formatter.requirements]28.5.6.2 Formatter locking [format.formatter.locking]28.5.6.3 Concept formattable [format.formattable]28.5.6.4 Formatter specializations [format.formatter.spec]28.5.6.5 Formatting escaped characters and strings [format.string.escaped]28.5.6.6 Class template basic_format_parse_context [format.parse.ctx]28.5.6.7 Class template basic_format_context [format.context]28.5.7 Formatting of ranges [format.range]28.5.7.1 Variable template format_kind [format.range.fmtkind]28.5.7.2 Class template range_formatter [format.range.formatter]28.5.7.3 Class template range-default-formatter [format.range.fmtdef]28.5.7.4 Specialization of range-default-formatter for maps [format.range.fmtmap]28.5.7.5 Specialization of range-default-formatter for sets [format.range.fmtset]28.5.7.6 Specialization of range-default-formatter for strings [format.range.fmtstr]28.5.8 Arguments [format.arguments]28.5.8.1 Class template basic_format_arg [format.arg]28.5.8.2 Class template format-arg-store [format.arg.store]28.5.8.3 Class template basic_format_args [format.args]28.5.9 Tuple formatter [format.tuple]28.5.10 Class format_error [format.error]28.5.1 Header <format> synopsis [format.syn]namespace std {
// [format.context], class template basic_format_context
template<class Out, class charT> class basic_format_context;
using format_context = basic_format_context<unspecified, char>;
using wformat_context = basic_format_context<unspecified, wchar_t>;
// [format.args], class template basic_format_args
template<class Context> class basic_format_args;
using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
// [format.fmt.string], class template basic_format_string
template<class charT, class... Args>
struct basic_format_string;
template<class charT> struct dynamic-format-string { // exposition only
private:
basic_string_view<charT> str; // exposition only
public:
constexpr dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {}
dynamic-format-string(const dynamic-format-string&) = delete;
dynamic-format-string& operator=(const dynamic-format-string&) = delete;
};
constexpr dynamic-format-string<char>
dynamic_format(string_view fmt) noexcept { return fmt; }
constexpr dynamic-format-string<wchar_t>
dynamic_format(wstring_view fmt) noexcept { return fmt; }
template<class... Args>
using format_string = basic_format_string<char, type_identity_t<Args>...>;
template<class... Args>
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
// [format.functions], formatting functions
template<class... Args>
constexpr string format(format_string<Args...> fmt, Args&&... args);
template<class... Args>
constexpr wstring format(wformat_string<Args...> fmt, Args&&... args);
template<class... Args>
string format(const locale& loc, format_string<Args...> fmt, Args&&... args);
template<class... Args>
wstring format(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
constexpr string vformat(string_view fmt, format_args args);
constexpr wstring vformat(wstring_view fmt, wformat_args args);
string vformat(const locale& loc, string_view fmt, format_args args);
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
template<class Out, class... Args>
constexpr Out format_to(Out out, format_string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
constexpr Out format_to(Out out, wformat_string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, format_string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, wformat_string<Args...> fmt, Args&&... args);
template<class Out>
constexpr Out vformat_to(Out out, string_view fmt, format_args args);
template<class Out>
constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args);
template<class Out> struct format_to_n_result {
Out out;
iter_difference_t<Out> size;
};
template<class Out, class... Args>
constexpr format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
format_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
constexpr format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
wformat_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, format_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wformat_string<Args...> fmt,
Args&&... args);
template<class... Args>
constexpr size_t formatted_size(format_string<Args...> fmt, Args&&... args);
template<class... Args>
constexpr size_t formatted_size(wformat_string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, format_string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
// [format.formatter], formatter
template<class T, class charT = char> struct formatter;
// [format.formatter.locking], formatter locking
template<class T>
constexpr bool enable_nonlocking_formatter_optimization = false;
// [format.formattable], concept formattable
template<class T, class charT>
concept formattable = see below;
template<class R, class charT>
concept const-formattable-range = // exposition only
ranges::input_range<const R> &&
formattable<ranges::range_reference_t<const R>, charT>;
template<class R, class charT>
using fmt-maybe-const = // exposition only
conditional_t<const-formattable-range<R, charT>, const R, R>;
// [format.parse.ctx], class template basic_format_parse_context
template<class charT> class basic_format_parse_context;
using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
// [format.range], formatting of ranges
// [format.range.fmtkind], variable template format_kind
enum class range_format {
disabled,
map,
set,
sequence,
string,
debug_string
};
template<class R>
constexpr unspecified format_kind = unspecified;
template<ranges::input_range R>
requires same_as<R, remove_cvref_t<R>>
constexpr range_format format_kind<R> = see below;
// [format.range.formatter], class template range_formatter
template<class T, class charT = char>
requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
class range_formatter;
// [format.range.fmtdef], class template range-default-formatter
template<range_format K, ranges::input_range R, class charT>
struct range-default-formatter; // exposition only
// [format.range.fmtmap], [format.range.fmtset], [format.range.fmtstr], specializations for maps, sets, and strings
template<ranges::input_range R, class charT>
requires (format_kind<R> != range_format::disabled) &&
formattable<ranges::range_reference_t<R>, charT>
struct formatter<R, charT> : range-default-formatter<format_kind<R>, R, charT> { };
template<ranges::input_range R>
requires (format_kind<R> != range_format::disabled)
constexpr bool enable_nonlocking_formatter_optimization<R> = false;
// [format.arguments], arguments
// [format.arg], class template basic_format_arg
template<class Context> class basic_format_arg;
// [format.arg.store], class template format-arg-store
template<class Context, class... Args> class format-arg-store; // exposition only
template<class Context = format_context, class... Args>
constexpr format-arg-store<Context, Args...>
make_format_args(Args&... fmt_args);
template<class... Args>
constexpr format-arg-store<wformat_context, Args...>
make_wformat_args(Args&... args);
// [format.error], class format_error
class format_error;
}
28.5.2 Format string [format.string]28.5.2.1 General [format.string.general]A format string for arguments args is
a (possibly empty) sequence of
replacement fields,
escape sequences,
and characters other than { and }. Let charT be the character type of the format string. Each character that is not part of
a replacement field or an escape sequence
is copied unchanged to the output. The syntax of replacement fields is as follows:
replacement-field : { arg-idopt format-specifieropt }
arg-id : 0 positive-integer
format-specifier : : format-spec
format-spec : as specified by the formatter specialization for the argument type; cannot start with } If all arg-ids in a format string are omitted
(including those in the format-spec,
as interpreted by the corresponding formatter specialization),
argument indices 0, 1, 2, … will automatically be used in that order. If some arg-ids are omitted and some are present,
the string is not a format string. [Example 2: string s0 = format("{} to {}", "a", "b"); // OK, automatic indexing
string s1 = format("{1} to {0}", "a", "b"); // OK, manual indexing
string s2 = format("{0} to {}", "a", "b"); // not a format string (mixing automatic and manual indexing),
// ill-formed
string s3 = format("{} to {1}", "a", "b"); // not a format string (mixing automatic and manual indexing),
// ill-formed
— end example] Each type can define its own
interpretation of the format-spec field. If format-spec does not conform
to the format specifications for
the argument type referred to by arg-id,
the string is not a format string for args. [Example 3:
28.5.2.2 Standard format specifiers [format.string.std]Each formatter specialization
described in [format.formatter.spec]
for fundamental and string types
interprets format-spec as a
std-format-spec.
The syntax of format specifications is as follows:
fill-and-align : fillopt align
fill : any character other than { or }
align : one of < > ^
width : positive-integer { arg-idopt }
precision : . nonnegative-integer . { arg-idopt }
type : one of a A b B c d e E f F g G o p P s x X ? Field widths are specified in field width units;
the number of column positions required to display a sequence of
characters in a terminal. The minimum field width
is the number of field width units a replacement field minimally requires of
the formatted sequence of characters produced for a format argument. The estimated field width is the number of field width units
that are required for the formatted sequence of characters
produced for a format argument independent of
the effects of the width option. The padding width is the greater of 0 and
the difference of the minimum field width and the estimated field width. The fill character is the character denoted by
the fill option or,
if the fill option is absent, the space character. For a format specification in UTF-8, UTF-16, or UTF-32,
the fill character corresponds to a single Unicode scalar value. The align option applies to all argument types. [Example 1: char c = 120;
string s0 = format("{:6}", 42); // value of s0 is " 42"
string s1 = format("{:6}", 'x'); // value of s1 is "x "
string s2 = format("{:*<6}", 'x'); // value of s2 is "x*****"
string s3 = format("{:*>6}", 'x'); // value of s3 is "*****x"
string s4 = format("{:*^6}", 'x'); // value of s4 is "**x***"
string s5 = format("{:6d}", c); // value of s5 is " 120"
string s6 = format("{:6}", true); // value of s6 is "true "
string s7 = format("{:*<6.3}", "123456"); // value of s7 is "123***"
string s8 = format("{:02}", 1234); // value of s8 is "1234"
string s9 = format("{:*<}", "12"); // value of s9 is "12"
string sA = format("{:*<6}", "12345678"); // value of sA is "12345678"
string sB = format("{:🤡^6}", "x"); // value of sB is "🤡🤡x🤡🤡🤡"
string sC = format("{:*^6}", "🤡🤡🤡"); // value of sC is "🤡🤡🤡"
— end example] [Note 4: The fill, align, and 0 options
have no effect when the minimum field width
is not greater than the estimated field width
because padding width is 0 in that case. Since fill characters are assumed to have a field width of 1,
use of a character with a different field width can produce misaligned output. The examples above that include that character
illustrate the effect of the field width
when that character is used as a fill character
as opposed to when it is used as a formatting argument. — end note]Table 104 — Meaning of align options [tab:format.align]
The sign option is only valid
for arithmetic types other than charT and bool
or when an integer presentation type is specified. Table 105 — Meaning of sign options [tab:format.sign]
The sign option applies to floating-point infinity and NaN.
[Example 2: double inf = numeric_limits<double>::infinity();
double nan = numeric_limits<double>::quiet_NaN();
string s0 = format("{0:},{0:+},{0:-},{0: }", 1); // value of s0 is "1,+1,1, 1"
string s1 = format("{0:},{0:+},{0:-},{0: }", -1); // value of s1 is "-1,-1,-1,-1"
string s2 = format("{0:},{0:+},{0:-},{0: }", inf); // value of s2 is "inf,+inf,inf, inf"
string s3 = format("{0:},{0:+},{0:-},{0: }", nan); // value of s3 is "nan,+nan,nan, nan"
— end example] This option is valid for arithmetic types other than
charT and bool
or when an integer presentation type is specified, and not otherwise. For integral types,
the alternate form inserts the
base prefix (if any) specified in Table 107
into the output after the sign character (possibly space) if there is one, or
before the output of to_chars otherwise. For floating-point types,
the alternate form causes the result of the conversion of finite values
to always contain a decimal-point character,
even if no digits follow it. Normally, a decimal-point character appears in the result of these
conversions only if a digit follows it. The 0 option is valid for arithmetic types
other than charT and bool, pointer types, or
when an integer presentation type is specified. For formatting arguments that have a value
other than an infinity or a NaN,
this option pads the formatted argument by
inserting the 0 character n times
following the sign or base prefix indicators (if any)
where n is 0 if the align option is present and
is the padding width otherwise. [Example 3: char c = 120;
string s1 = format("{:+06d}", c); // value of s1 is "+00120"
string s2 = format("{:#06x}", 0xa); // value of s2 is "0x000a"
string s3 = format("{:<06}", -42); // value of s3 is "-42 " (0 has no effect)
string s4 = format("{:06}", inf); // value of s4 is " inf" (0 has no effect)
— end example] If { arg-idopt } is used in
a width or precision option,
the value of the corresponding formatting argument is used as the value of the option. The option is valid only if the corresponding formatting argument is
of standard signed or unsigned integer type. If its value is negative,
an exception of type format_error is thrown. If positive-integer is used in a
width option, the value of the positive-integer
is interpreted as a decimal integer and used as the value of the option. For a sequence of characters in UTF-8, UTF-16, or UTF-32,
an implementation should use as its field width
the sum of the field widths of the first code point
of each extended grapheme cluster. Extended grapheme clusters are defined by UAX #29 of the Unicode Standard. The following code points have a field width of 2:
For a sequence of characters in neither UTF-8, UTF-16, nor UTF-32,
the field width is unspecified. The precision option is valid
for floating-point and string types. For floating-point types,
the value of this option specifies the precision
to be used for the floating-point presentation type. For string types,
this option specifies the longest prefix of the formatted argument
to be included in the replacement field such that
the field width of the prefix is no greater than the value of this option. If nonnegative-integer is used in
a precision option,
the value of the decimal integer is used as the value of the option. The L option is only valid for arithmetic types, and
its effect depends upon the type. A call to format on a given formatter specialization
is not a constant subexpression if the locale-specific form is specified.
If the string literal encoding is a Unicode encoding form and
the locale is among an implementation-defined set of locales,
each replacement that depends on the locale is performed as if
the replacement character sequence is converted to
the string literal encoding. Table 106 — Meaning of type options for strings [tab:format.type.string]
The meaning of some non-string presentation types
is defined in terms of a call to to_chars. In such cases,
let [first, last) be a range
large enough to hold the to_chars output
and value be the formatting argument value. Formatting is done as if by calling to_chars as specified,
transcoding the to_chars output to the wide literal encoding if
charT is wchar_t,
and copying the output through the output iterator of the format context. The available integer presentation types
for integral types other than bool and charT
are specified in Table 107. [Example 4: string s0 = format("{}", 42); // value of s0 is "42"
string s1 = format("{0:b} {0:d} {0:o} {0:x}", 42); // value of s1 is "101010 42 52 2a"
string s2 = format("{0:#x} {0:#X}", 42); // value of s2 is "0x2a 0X2A"
string s3 = format("{:L}", 1234); // value of s3 can be "1,234"
// (depending on the locale)
— end example] Table 107 — Meaning of type options for integer types [tab:format.type.int]
Table 108 — Meaning of type options for charT [tab:format.type.char]
Table 110 — Meaning of type options for floating-point types [tab:format.type.float]
Table 111 — Meaning of type options for pointer types [tab:format.type.ptr]
28.5.3 Error reporting [format.err.report]Formatting functions throw format_error if
an argument fmt is passed that
is not a format string for args. They propagate exceptions thrown by operations of
formatter specializations and iterators. Failure to allocate storage is reported by
throwing an exception as described in [res.on.exception.handling]. 28.5.4 Class template basic_format_string [format.fmt.string]namespace std {
template<class charT, class... Args>
struct basic_format_string {
private:
basic_string_view<charT> str; // exposition only
public:
template<class T> consteval basic_format_string(const T& s);
constexpr basic_format_string(dynamic-format-string<charT> s) noexcept : str(s.str) {}
constexpr basic_string_view<charT> get() const noexcept { return str; }
};
}
template<class T> consteval basic_format_string(const T& s);
Remarks: A call to this function is not a core constant expression ([expr.const.core])
unless there exist args of types Args
such that str is a format string for args. 28.5.5 Formatting functions [format.functions]A call to any of the functions defined in this subclause
is a constant subexpression only if
each of the used formatter specializations
is a constexpr-enabled specialization ([format.formatter.spec]). In the description of the functions, operator + is used
for some of the iterator categories for which it does not have to be defined. template<class... Args>
constexpr string format(format_string<Args...> fmt, Args&&... args);
template<class... Args>
constexpr wstring format(wformat_string<Args...> fmt, Args&&... args);
template<class... Args>
string format(const locale& loc, format_string<Args...> fmt, Args&&... args);
template<class... Args>
wstring format(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
constexpr string vformat(string_view fmt, format_args args);
constexpr wstring vformat(wstring_view fmt, wformat_args args);
string vformat(const locale& loc, string_view fmt, format_args args);
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
Throws: As specified in [format.err.report]. template<class Out, class... Args>
constexpr Out format_to(Out out, format_string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
constexpr Out format_to(Out out, wformat_string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, format_string<Args...> fmt, Args&&... args);
Effects: Equivalent to:
return vformat_to(std::move(out), loc, fmt.str, make_format_args(args...));
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, wformat_string<Args...> fmt, Args&&... args);
Effects: Equivalent to:
return vformat_to(std::move(out), loc, fmt.str, make_wformat_args(args...));
template<class Out>
constexpr Out vformat_to(Out out, string_view fmt, format_args args);
template<class Out>
constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args);
Effects: Places the character representation of formatting
the arguments provided by args,
formatted according to the specifications given in fmt,
into the range [out, out + N),
where N is the number of characters in that character representation. If present, loc is used for locale-specific formatting. Throws: As specified in [format.err.report]. template<class Out, class... Args>
constexpr format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
format_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
constexpr format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
wformat_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, format_string<Args...> fmt,
Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wformat_string<Args...> fmt,
Args&&... args);
Preconditions: Out models output_iterator<const charT&>, and
formatter<remove_cvref_t<Ti>, charT>
meets the BasicFormatter requirements ([formatter.requirements])
for each Ti in Args. Throws: As specified in [format.err.report]. template<class... Args>
constexpr size_t formatted_size(format_string<Args...> fmt, Args&&... args);
template<class... Args>
constexpr size_t formatted_size(wformat_string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, format_string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
Preconditions: formatter<remove_cvref_t<Ti>, charT>
meets the BasicFormatter requirements ([formatter.requirements])
for each Ti in Args. Throws: As specified in [format.err.report]. 28.5.6 Formatter [format.formatter]28.5.6.1 Formatter requirements [formatter.requirements]A type F meets the BasicFormatter requirements if
it meets the
Given character type charT, output iterator type
Out, and formatting argument type T,
in Table 112 and Table 113:
pc.begin() points to the beginning of the
format-spec ([format.string])
of the replacement field being formatted
in the format string. Table 112 — BasicFormatter requirements [tab:formatter.basic]
Table 113 — Formatter requirements [tab:formatter]
28.5.6.2 Formatter locking [format.formatter.locking]template<class T>
constexpr bool enable_nonlocking_formatter_optimization = false;
Remarks: Pursuant to [namespace.std],
users may specialize enable_nonlocking_formatter_optimization for
cv-unqualified program-defined types. Such specializations shall be usable in constant expressions ([expr.const.init])
and have type const bool. 28.5.6.3 Concept formattable [format.formattable]Let fmt-iter-for<charT> be an unspecified type
that models
output_iterator<const charT&> ([iterator.concept.output]). template<class T, class Context,
class Formatter = typename Context::template formatter_type<remove_const_t<T>>>
concept formattable-with = // exposition only
semiregular<Formatter> &&
requires(Formatter& f, const Formatter& cf, T&& t, Context fc,
basic_format_parse_context<typename Context::char_type> pc)
{
{ f.parse(pc) } -> same_as<typename decltype(pc)::iterator>;
{ cf.format(t, fc) } -> same_as<typename Context::iterator>;
};
template<class T, class charT>
concept formattable =
formattable-with<remove_reference_t<T>, basic_format_context<fmt-iter-for<charT>, charT>>;
A type T and a character type charT
model formattable
if formatter<remove_cvref_t<T>, charT> meets
the BasicFormatter requirements ([formatter.requirements])
and, if remove_reference_t<T> is const-qualified,
the Formatter requirements. 28.5.6.4 Formatter specializations [format.formatter.spec]The functions defined in [format.functions] use
specializations of the class template formatter to format
individual arguments. Each specialization of formatter is either enabled or disabled,
as described below. A debug-enabled specialization of formatter
additionally provides
a public, constexpr, non-static member function set_debug_format()
which modifies the state of the formatter to be as if
the type of the std-format-spec
parsed by the last call to parse were ?. Each header that declares the template formatter
provides the following enabled specializations:
Unless specified otherwise, for each type T for which
a formatter specialization is provided by the library,
each of the headers provides the following specialization:
template<> inline constexpr bool enable_nonlocking_formatter_optimization<T> = true;
The header <format> provides
the following disabled specializations:
For any types T and charT for which
neither the library nor the user provides
an explicit or partial specialization of
the class template formatter,
formatter<T, charT> is disabled. If the library provides an explicit or partial specialization of
formatter<T, charT>, that specialization is enabled
and meets the Formatter requirements
except as noted otherwise. An enabled specialization formatter<T, charT> meets the
BasicFormatter requirements ([formatter.requirements]). [Example 1: #include <format>
#include <string>
enum color { red, green, blue };
const char* color_names[] = { "red", "green", "blue" };
template<> struct std::formatter<color> : std::formatter<const char*> {
auto format(color c, format_context& ctx) const {
return formatter<const char*>::format(color_names[c], ctx);
}
};
struct err {};
std::string s0 = std::format("{}", 42); // OK, library-provided formatter
std::string s1 = std::format("{}", L"foo"); // error: disabled formatter
std::string s2 = std::format("{}", red); // OK, user-provided formatter
std::string s3 = std::format("{}", err{}); // error: disabled formatter
— end example] 28.5.6.5 Formatting escaped characters and strings [format.string.escaped]The escaped string E representation of a string S
is constructed by encoding a sequence of characters as follows.
The escaped string representation of a character C
is equivalent to the escaped string representation
of a string of C, except that:
[Example 1: string s0 = format("[{}]", "h\tllo"); // s0 has value: [h llo]
string s1 = format("[{:?}]", "h\tllo"); // s1 has value: ["h\tllo"]
string s2 = format("[{:?}]", "Спасибо, Виктор ♥!"); // s2 has value: ["Спасибо, Виктор ♥!"]
string s3 = format("[{:?}, {:?}]", '\'', '"'); // s3 has value: ['\'', '"']
// The following examples assume use of the UTF-8 encoding
string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9));
// s4 has value: ["\u{0} \n \t \u{2} \u{1b}"]
string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8, s5 has value: ["\x{c3}("]
string s6 = format("[{:?}]", "🤷🏻♂️"); // s6 has value: ["🤷\u{200d}♂"]
string s7 = format("[{:?}]", "\u0301"); // s7 has value: ["\u{301}"]
string s8 = format("[{:?}]", "\\\u0301"); // s8 has value: ["\\\u{301}"]
string s9 = format("[{:?}]", "e\u0301\u0323"); // s9 has value: ["ẹ́"]
— end example] 28.5.6.6 Class template basic_format_parse_context [format.parse.ctx]namespace std {
template<class charT>
class basic_format_parse_context {
public:
using char_type = charT;
using const_iterator = basic_string_view<charT>::const_iterator;
using iterator = const_iterator;
private:
iterator begin_; // exposition only
iterator end_; // exposition only
enum indexing { unknown, manual, automatic }; // exposition only
indexing indexing_; // exposition only
size_t next_arg_id_; // exposition only
size_t num_args_; // exposition only
public:
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
basic_format_parse_context(const basic_format_parse_context&) = delete;
basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr void advance_to(const_iterator it);
constexpr size_t next_arg_id();
constexpr void check_arg_id(size_t id);
template<class... Ts>
constexpr void check_dynamic_spec(size_t id) noexcept;
constexpr void check_dynamic_spec_integral(size_t id) noexcept;
constexpr void check_dynamic_spec_string(size_t id) noexcept;
};
}
An instance of basic_format_parse_context holds
the format string parsing state, consisting of
the format string range being parsed and
the argument counter for automatic indexing. If a program declares an explicit or partial specialization of
basic_format_parse_context,
the program is ill-formed, no diagnostic required. constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
Effects: Initializes
begin_ with fmt.begin(),
end_ with fmt.end(),
indexing_ with unknown,
next_arg_id_ with 0, and
num_args_ with 0. constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr void advance_to(const_iterator it);
constexpr size_t next_arg_id();
Effects: If indexing_ != manual is true, equivalent to:
if (indexing_ == unknown)
indexing_ = automatic;
return next_arg_id_++;
Call expressions where cur-arg-id >= num_args_ is true
are not core constant expressions ([expr.const.core]). constexpr void check_arg_id(size_t id);
Effects: If indexing_ != automatic is true, equivalent to:
if (indexing_ == unknown)
indexing_ = manual;
Remarks: A call to this function is a core constant expression ([expr.const.core]) only if
id < num_args_ is true. template<class... Ts>
constexpr void check_dynamic_spec(size_t id) noexcept;
constexpr void check_dynamic_spec_integral(size_t id) noexcept;
Effects: Equivalent to:
check_dynamic_spec<int, unsigned int, long long int, unsigned long long int>(id);
constexpr void check_dynamic_spec_string(size_t id) noexcept;
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_; // 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>;
constexpr basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
std::locale locale();
constexpr iterator out();
constexpr 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 of
basic_format_context,
the program is ill-formed, no diagnostic required. Recommended practice: For a given type charT,
implementations should provide
a single specialization of basic_format_context
for appending to
basic_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. constexpr basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
std::locale locale();
constexpr iterator out();
constexpr void advance_to(iterator it);
[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");
else
return 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] 28.5.7 Formatting of ranges [format.range]28.5.7.1 Variable template format_kind [format.range.fmtkind]template<ranges::input_range R>
requires same_as<R, remove_cvref_t<R>>
constexpr range_format format_kind<R> = see below;
For a type R, format_kind<R> is defined as follows:
Remarks: Pursuant to [namespace.std], users may specialize format_kind
for cv-unqualified program-defined types
that model ranges::input_range. Such specializations shall be usable in constant expressions ([expr.const.init])
and have type const range_format. 28.5.7.2 Class template range_formatter [format.range.formatter]namespace std {
template<class T, class charT = char>
requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
class range_formatter {
formatter<T, charT> underlying_; // exposition only
basic_string_view<charT> separator_ = STATICALLY-WIDEN<charT>(", "); // exposition only
basic_string_view<charT> opening-bracket_ = STATICALLY-WIDEN<charT>("["); // exposition only
basic_string_view<charT> closing-bracket_ = STATICALLY-WIDEN<charT>("]"); // exposition only
public:
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
constexpr formatter<T, charT>& underlying() noexcept { return underlying_; }
constexpr const formatter<T, charT>& underlying() const noexcept { return underlying_; }
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<ranges::input_range R, class FormatContext>
requires formattable<ranges::range_reference_t<R>, charT> &&
same_as<remove_cvref_t<ranges::range_reference_t<R>>, T>
constexpr typename FormatContext::iterator
format(R&& r, FormatContext& ctx) const;
};
}
The class template range_formatter is a utility
for implementing formatter specializations for range types. The syntax of format specifications is as follows:
range-format-spec : range-fill-and-alignopt widthopt nopt range-typeopt range-underlying-specopt
range-fill-and-align : range-fillopt align
range-fill : any character other than { or } or :
range-type : m s ?s
range-underlying-spec : : format-spec For range_formatter<T, charT>,
the format-spec
in a range-underlying-spec, if any,
is interpreted by formatter<T, charT>. The range-type specifier changes the way a range is formatted,
with certain options only valid with certain argument types. Table 115 — Meaning of range-type options [tab:formatter.range.type]
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
Effects: Parses the format specifiers as a range-format-spec and
stores the parsed specifiers in *this. Calls underlying_.parse(ctx) to parse
format-spec in range-format-spec or,
if the latter is not present, an empty format-spec. The values of
opening-bracket_, closing-bracket_, and separator_
are modified if and only if required by
the range-type or the n option, if present. template<ranges::input_range R, class FormatContext>
requires formattable<ranges::range_reference_t<R>, charT> &&
same_as<remove_cvref_t<ranges::range_reference_t<R>>, T>
constexpr typename FormatContext::iterator
format(R&& r, FormatContext& ctx) const;
Effects: Writes the following into ctx.out(),
adjusted according to the range-format-spec:
28.5.7.3 Class template range-default-formatter [format.range.fmtdef]namespace std {
template<ranges::input_range R, class charT>
struct range-default-formatter<range_format::sequence, R, charT> { // exposition only
private:
using maybe-const-r = fmt-maybe-const<R, charT>; // exposition only
range_formatter<remove_cvref_t<ranges::range_reference_t<maybe-const-r>>,
charT> underlying_; // exposition only
public:
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-r& elems, FormatContext& ctx) const;
};
}
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-r& elems, FormatContext& ctx) const;
28.5.7.4 Specialization of range-default-formatter for maps [format.range.fmtmap]namespace std {
template<ranges::input_range R, class charT>
struct range-default-formatter<range_format::map, R, charT> {
private:
using maybe-const-map = fmt-maybe-const<R, charT>; // exposition only
using element-type = // exposition only
remove_cvref_t<ranges::range_reference_t<maybe-const-map>>;
range_formatter<element-type, charT> underlying_; // exposition only
public:
constexpr range-default-formatter();
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-map& r, FormatContext& ctx) const;
};
}
constexpr range-default-formatter();
Effects: Equivalent to:
underlying_.set_brackets(STATICALLY-WIDEN<charT>("{"), STATICALLY-WIDEN<charT>("}"));
underlying_.underlying().set_brackets({}, {});
underlying_.underlying().set_separator(STATICALLY-WIDEN<charT>(": "));
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-map& r, FormatContext& ctx) const;
28.5.7.5 Specialization of range-default-formatter for sets [format.range.fmtset]namespace std {
template<ranges::input_range R, class charT>
struct range-default-formatter<range_format::set, R, charT> {
private:
using maybe-const-set = fmt-maybe-const<R, charT>; // exposition only
range_formatter<remove_cvref_t<ranges::range_reference_t<maybe-const-set>>,
charT> underlying_; // exposition only
public:
constexpr range-default-formatter();
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-set& r, FormatContext& ctx) const;
};
}
constexpr range-default-formatter();
Effects: Equivalent to:
underlying_.set_brackets(STATICALLY-WIDEN<charT>("{"), STATICALLY-WIDEN<charT>("}"));
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(maybe-const-set& r, FormatContext& ctx) const;
28.5.7.6 Specialization of range-default-formatter for strings [format.range.fmtstr]namespace std {
template<range_format K, ranges::input_range R, class charT>
requires (K == range_format::string || K == range_format::debug_string)
struct range-default-formatter<K, R, charT> {
private:
formatter<basic_string<charT>, charT> underlying_; // exposition only
public:
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(see below& str, FormatContext& ctx) const;
};
}
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
Effects: Equivalent to:
auto i = underlying_.parse(ctx);
if constexpr (K == range_format::debug_string) {
underlying_.set_debug_format();
}
return i;
template<class FormatContext>
typename FormatContext::iterator
format(see below& r, FormatContext& ctx) const;
28.5.8 Arguments [format.arguments]28.5.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 = 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> constexpr explicit basic_format_arg(T& v) noexcept; // exposition only
public:
constexpr basic_format_arg() noexcept;
constexpr explicit operator bool() const noexcept;
template<class Visitor>
constexpr decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
template<class R, class Visitor>
constexpr 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. constexpr basic_format_arg() noexcept;
template<class T> constexpr explicit basic_format_arg(T& v) noexcept;
Preconditions: If decay_t<T> is char-type* or const char-type*,
static_cast<const char- type*>(v) points to an NTCTS ([defns.ntcts]).
constexpr explicit operator bool() const noexcept;
template<class Visitor>
constexpr decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
template<class R, class Visitor>
constexpr R visit(this basic_format_arg arg, 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> constexpr explicit handle(T& val) noexcept; // exposition only
public:
constexpr void format(basic_format_parse_context<char-type>&, Context& ctx) const;
};
}
template<class T> constexpr explicit handle(T& val) noexcept;
Let
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));
}
constexpr void format(basic_format_parse_context<char-type>& parse_ctx, Context& format_ctx) const;
28.5.8.2 Class template 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
};
}
template<class Context = format_context, class... Args>
constexpr format-arg-store<Context, Args...>
make_format_args(Args&... fmt_args);
Preconditions: The type
typename Context::template formatter_type<remove_const_t<Ti>> meets the BasicFormatter requirements ([formatter.requirements]) for each Ti in Args. template<class... Args>
constexpr format-arg-store<wformat_context, Args...>
make_wformat_args(Args&... args);
28.5.8.3 Class template basic_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>
constexpr basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
constexpr 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>;
}
template<class... Args>
constexpr basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
constexpr basic_format_arg<Context> get(size_t i) const noexcept;
28.5.9 Tuple formatter [format.tuple]For each of pair and tuple,
the library provides the following formatter specialization
where pair-or-tuple is the name of the template: namespace std {
template<class charT, formattable<charT>... Ts>
struct formatter<pair-or-tuple<Ts...>, charT> {
private:
tuple<formatter<remove_cvref_t<Ts>, charT>...> underlying_; // exposition only
basic_string_view<charT> separator_ = STATICALLY-WIDEN<charT>(", "); // exposition only
basic_string_view<charT> opening-bracket_ = STATICALLY-WIDEN<charT>("("); // exposition only
basic_string_view<charT> closing-bracket_ = STATICALLY-WIDEN<charT>(")"); // exposition only
public:
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
template<class FormatContext>
constexpr typename FormatContext::iterator
format(see below& elems, FormatContext& ctx) const;
};
template<class... Ts>
constexpr bool enable_nonlocking_formatter_optimization<pair-or-tuple<Ts...>> =
(enable_nonlocking_formatter_optimization<remove_cvref_t<Ts>> && ...);
}
The parse member functions of these formatters
interpret the format specification as
a tuple-format-spec according to the following syntax:
tuple-format-spec : tuple-fill-and-alignopt widthopt tuple-typeopt
tuple-fill-and-align : tuple-fillopt align
tuple-fill : any character other than { or } or :
tuple-type : m n The tuple-type specifier
changes the way a pair or tuple is formatted,
with certain options only valid with certain argument types. constexpr void set_separator(basic_string_view<charT> sep) noexcept;
constexpr void set_brackets(basic_string_view<charT> opening,
basic_string_view<charT> closing) noexcept;
template<class ParseContext>
constexpr typename ParseContext::iterator
parse(ParseContext& ctx);
Effects: Parses the format specifiers as a tuple-format-spec and
stores the parsed specifiers in *this. The values of
opening-bracket_,
closing-bracket_, and
separator_
are modified if and only if
required by the tuple-type, if present. For each element e in underlying_,
calls e.parse(ctx) to parse
an empty format-spec and,
if e.set_debug_format() is a valid expression,
calls e.set_debug_format(). template<class FormatContext>
constexpr typename FormatContext::iterator
format(see below& elems, FormatContext& ctx) const;
28.5.10 Class format_error [format.error]namespace std {
class format_error : public runtime_error {
public:
constexpr explicit format_error(const string& what_arg);
constexpr explicit format_error(const char* what_arg);
};
}
The class format_error defines the type of objects thrown as
exceptions to report errors from the formatting library. constexpr format_error(const string& what_arg);
constexpr format_error(const char* what_arg);
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |