%!TEX root = std.tex

\rSec0[text]{Text processing library}

\rSec1[text.general]{General}

This Clause describes components for dealing with text.
These components are summarized in \tref{text.summary}.

\begin{libsumtab}{Text library summary}{text.summary}
\ref{charconv}         & Primitive numeric conversions       & \tcode{<charconv>}        \\ \rowsep
\ref{localization}     & Localization library                & \tcode{<locale>}, \tcode{<clocale>} \\ \rowsep
\ref{text.encoding}    & Text encodings identification       & \tcode{<text_encoding>}   \\ \rowsep
\ref{format}           & Formatting                          & \tcode{<format>}          \\ \rowsep
\ref{re}               & Regular expressions library         & \tcode{<regex>}           \\ \rowsep
\ref{text.c.strings}   & Null-terminated sequence utilities  &
  \tcode{<cctype>}, \tcode{<cstdlib>}, \tcode{<cuchar>}, \tcode{<cwchar>}, \tcode{<cwctype>}  \\
\end{libsumtab}

\rSec1[charconv]{Primitive numeric conversions}

\rSec2[charconv.syn]{Header \tcode{<charconv>} synopsis}

\pnum
When a function is specified
with a type placeholder of \tcode{\placeholder{integer-type}},
the implementation provides overloads
for \tcode{char} and all signed and unsigned integer types
in lieu of \tcode{\placeholder{integer-type}}.
When a function is specified
with a type placeholder of \tcode{\placeholder{floating-point-type}},
the implementation provides overloads
for all cv-unqualified floating-point types\iref{basic.fundamental}
in lieu of \tcode{\placeholder{floating-point-type}}.

\indexheader{charconv}%
\begin{codeblock}
namespace std {
  // floating-point format for primitive numerical conversion
  enum class @\libglobal{chars_format}@ {
    @\libmember{scientific}{chars_format}@ = @\unspec@,
    @\libmember{fixed}{chars_format}@ = @\unspec@,
    @\libmember{hex}{chars_format}@ = @\unspec@,
    @\libmember{general}{chars_format}@ = fixed | scientific
  };

  // \ref{charconv.to.chars}, primitive numerical output conversion
  struct @\libglobal{to_chars_result}@ {                                              // freestanding
    char* @\libmember{ptr}{to_chars_result}@;
    errc @\libmember{ec}{to_chars_result}@;
    friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
    constexpr explicit operator bool() const noexcept { return ec == errc{}; }
  };

  constexpr to_chars_result to_chars(char* first, char* last,           // freestanding
                                     @\placeholder{integer-type}@ value, int base = 10);
  to_chars_result to_chars(char* first, char* last,                     // freestanding
                           bool value, int base = 10) = delete;

  to_chars_result to_chars(char* first, char* last,                     // freestanding-deleted
                           @\placeholder{floating-point-type}@ value);
  to_chars_result to_chars(char* first, char* last,                     // freestanding-deleted
                           @\placeholder{floating-point-type}@ value, chars_format fmt);
  to_chars_result to_chars(char* first, char* last,                     // freestanding-deleted
                           @\placeholder{floating-point-type}@ value, chars_format fmt, int precision);

  // \ref{charconv.from.chars}, primitive numerical input conversion
  struct @\libglobal{from_chars_result}@ {                                            // freestanding
    const char* @\libmember{ptr}{from_chars_result}@;
    errc @\libmember{ec}{from_chars_result}@;
    friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
    constexpr explicit operator bool() const noexcept { return ec == errc{}; }
  };

  constexpr from_chars_result from_chars(const char* first, const char* last,   // freestanding
                                         @\placeholder{integer-type}@& value, int base = 10);

  from_chars_result from_chars(const char* first, const char* last,     // freestanding-deleted
                               @\placeholder{floating-point-type}@& value,
                               chars_format fmt = chars_format::general);
}
\end{codeblock}

\pnum
The type \tcode{chars_format} is a bitmask type\iref{bitmask.types}
with elements \tcode{scientific}, \tcode{fixed}, and \tcode{hex}.

\pnum
The types \tcode{to_chars_result} and \tcode{from_chars_result}
have the data members and special members specified above.
They have no base classes or members other than those specified.

\rSec2[charconv.to.chars]{Primitive numeric output conversion}

\pnum
All functions named \tcode{to_chars}
convert \tcode{value} into a character string
by successively filling the range
\range{first}{last},
where \range{first}{last} is required to be a valid range.
If the member \tcode{ec}
of the return value
is such that the value
is equal to the value of a value-initialized \tcode{errc},
the conversion was successful
and the member \tcode{ptr}
is the one-past-the-end pointer of the characters written.
Otherwise,
the member \tcode{ec} has the value \tcode{errc::value_too_large},
the member \tcode{ptr} has the value \tcode{last},
and the contents of the range \range{first}{last} are unspecified.

\pnum
The functions that take a floating-point \tcode{value}
but not a \tcode{precision} parameter
ensure that the string representation
consists of the smallest number of characters
such that
there is at least one digit before the radix point (if present) and
parsing the representation using the corresponding \tcode{from_chars} function
recovers \tcode{value} exactly.
\begin{note}
This guarantee applies only if
\tcode{to_chars} and \tcode{from_chars}
are executed on the same implementation.
\end{note}
If there are several such representations,
the representation with the smallest difference from
the floating-point argument value is chosen,
resolving any remaining ties using rounding according to
\tcode{round_to_nearest}\iref{round.style}.

\pnum
The functions taking a \tcode{chars_format} parameter
determine the conversion specifier for \tcode{printf} as follows:
The conversion specifier is
\tcode{f} if \tcode{fmt} is \tcode{chars_format::fixed},
\tcode{e} if \tcode{fmt} is \tcode{chars_format::scientific},
\tcode{a} (without leading \tcode{"0x"} in the result)
if \tcode{fmt} is \tcode{chars_format::hex},
and
\tcode{g} if \tcode{fmt} is \tcode{chars_format::general}.

\indexlibraryglobal{to_chars}%
\begin{itemdecl}
constexpr to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{base} has a value between 2 and 36 (inclusive).

\pnum
\effects
The value of \tcode{value} is converted
to a string of digits in the given base
(with no redundant leading zeroes).
Digits in the range 10..35 (inclusive)
are represented as lowercase characters \tcode{a}..\tcode{z}.
If \tcode{value} is less than zero,
the representation starts with \tcode{'-'}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryglobal{to_chars}%
\begin{itemdecl}
to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{value} is converted to a string
in the style of \tcode{printf}
in the \tcode{"C"} locale.
The conversion specifier is \tcode{f} or \tcode{e},
chosen according to the requirement for a shortest representation
(see above);
a tie is resolved in favor of \tcode{f}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryglobal{to_chars}%
\begin{itemdecl}
to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{fmt} has the value of
one of the enumerators of \tcode{chars_format}.

\pnum
\effects
\tcode{value} is converted to a string
in the style of \tcode{printf}
in the \tcode{"C"} locale.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryglobal{to_chars}%
\begin{itemdecl}
to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value,
                         chars_format fmt, int precision);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{fmt} has the value of
one of the enumerators of \tcode{chars_format}.

\pnum
\effects
\tcode{value} is converted to a string
in the style of \tcode{printf}
in the \tcode{"C"} locale
with the given precision.

\pnum
\throws
Nothing.
\end{itemdescr}

\xrefc{7.23.6.2}

\rSec2[charconv.from.chars]{Primitive numeric input conversion}

\pnum
All functions named \tcode{from_chars}
analyze the string \range{first}{last}
for a pattern,
where \range{first}{last} is required to be a valid range.
If no characters match the pattern,
\tcode{value} is unmodified,
the member \tcode{ptr} of the return value is \tcode{first} and
the member \tcode{ec} is equal to \tcode{errc::invalid_argument}.
\begin{note}
If the pattern allows for an optional sign,
but the string has no digit characters following the sign,
no characters match the pattern.
\end{note}
Otherwise,
the characters matching the pattern
are interpreted as a representation
of a value of the type of \tcode{value}.
The member \tcode{ptr}
of the return value
points to the first character
not matching the pattern,
or has the value \tcode{last}
if all characters match.
If the parsed value
is not in the range
representable by the type of \tcode{value},
\tcode{value} is unmodified and
the member \tcode{ec} of the return value
is equal to \tcode{errc::result_out_of_range}.
Otherwise,
\tcode{value} is set to the parsed value,
after rounding according to \tcode{round_to_nearest}\iref{round.style}, and
the member \tcode{ec} is value-initialized.

\indexlibraryglobal{from_chars}%
\begin{itemdecl}
constexpr from_chars_result from_chars(const char* first, const char* last,
                                       @\placeholder{integer-type}@&@\itcorr[-1]@ value, int base = 10);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{base} has a value between 2 and 36 (inclusive).

\pnum
\effects
The pattern is the expected form of the subject sequence
in the \tcode{"C"} locale
for the given nonzero base,
as described for \tcode{strtol},
except that
no \tcode{"0b"} or \tcode{"0B"} prefix shall appear
if the value of \tcode{base} is 2,
no \tcode{"0x"} or \tcode{"0X"} prefix shall appear
if the value of \tcode{base} is 16,
and except that \tcode{'-'}
is the only sign that may appear,
and only if \tcode{value} has a signed type.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryglobal{from_chars}%
\begin{itemdecl}
from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value,
                             chars_format fmt = chars_format::general);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{fmt} has the value of
one of the enumerators of \tcode{chars_format}.

\pnum
\effects
The pattern is the expected form of the subject sequence
in the \tcode{"C"} locale,
as described for \tcode{strtod},
except that
\begin{itemize}
\item
the sign \tcode{'+'} may only appear in the exponent part;
\item
if \tcode{fmt} has \tcode{chars_format::scientific} set
but not \tcode{chars_format::fixed},
the otherwise optional exponent part shall appear;
\item
if \tcode{fmt} has \tcode{chars_format::fixed} set
but not \tcode{chars_format::scientific},
the optional exponent part shall not appear; and
\item
if \tcode{fmt} is \tcode{chars_format::hex},
the prefix \tcode{"0x"} or \tcode{"0X"} is assumed.
\begin{example}
The string \tcode{0x123}
is parsed to have the value
\tcode{0}
with remaining characters \tcode{x123}.
\end{example}
\end{itemize}
In any case, the resulting \tcode{value} is one of
at most two floating-point values
closest to the value of the string matching the pattern.

\pnum
\throws
Nothing.
\end{itemdescr}

\xrefc{7.24.2.6, 7.24.2.8}

\rSec1[localization]{Localization library}

\rSec2[localization.general]{General}

\pnum
Subclause \ref{localization} describes components that \Cpp{} programs may use to
encapsulate (and therefore be more portable when confronting)
cultural differences.
The locale facility includes
internationalization support for character classification and string collation,
numeric, monetary, and date/time formatting and parsing, and
message retrieval.

\pnum
The following subclauses describe components for
locales themselves,
the standard facets, and
facilities from the C library,
as summarized in \tref{localization.summary}.

\begin{libsumtab}{Localization library summary}{localization.summary}
\ref{locales}           & Locales                            &   \tcode{<locale>}    \\
\ref{locale.categories} & Standard \tcode{locale} categories &                       \\ \rowsep
\ref{c.locales}         & C library locales                  &   \tcode{<clocale>}   \\ \rowsep
\end{libsumtab}

\rSec2[locale.syn]{Header \tcode{<locale>} synopsis}

\indexheader{locale}%
\begin{codeblock}
namespace std {
  // \ref{locale}, locale
  class locale;
  template<class Facet> const Facet& use_facet(const locale&);
  template<class Facet> bool         has_facet(const locale&) noexcept;

  // \ref{locale.convenience}, convenience interfaces
  template<class charT> bool isspace (charT c, const locale& loc);
  template<class charT> bool isprint (charT c, const locale& loc);
  template<class charT> bool iscntrl (charT c, const locale& loc);
  template<class charT> bool isupper (charT c, const locale& loc);
  template<class charT> bool islower (charT c, const locale& loc);
  template<class charT> bool isalpha (charT c, const locale& loc);
  template<class charT> bool isdigit (charT c, const locale& loc);
  template<class charT> bool ispunct (charT c, const locale& loc);
  template<class charT> bool isxdigit(charT c, const locale& loc);
  template<class charT> bool isalnum (charT c, const locale& loc);
  template<class charT> bool isgraph (charT c, const locale& loc);
  template<class charT> bool isblank (charT c, const locale& loc);
  template<class charT> charT toupper(charT c, const locale& loc);
  template<class charT> charT tolower(charT c, const locale& loc);

  // \ref{category.ctype}, ctype
  class ctype_base;
  template<class charT> class ctype;
  template<>            class ctype<char>;      // specialization
  template<class charT> class ctype_byname;
  class codecvt_base;
  template<class internT, class externT, class stateT> class codecvt;
  template<class internT, class externT, class stateT> class codecvt_byname;

  // \ref{category.numeric}, numeric
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class num_get;
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class num_put;
  template<class charT>
    class numpunct;
  template<class charT>
    class numpunct_byname;

  // \ref{category.collate}, collation
  template<class charT> class collate;
  template<class charT> class collate_byname;

  // \ref{category.time}, date and time
  class time_base;
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get;
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get_byname;
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put;
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put_byname;

  // \ref{category.monetary}, money
  class money_base;
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class money_get;
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class money_put;
  template<class charT, bool Intl = false>
    class moneypunct;
  template<class charT, bool Intl = false>
    class moneypunct_byname;

  // \ref{category.messages}, message retrieval
  class messages_base;
  template<class charT> class messages;
  template<class charT> class messages_byname;
}
\end{codeblock}

\pnum
The header \libheader{locale}
defines classes and declares functions
that encapsulate and manipulate the information peculiar to a locale.
\begin{footnote}
In this subclause, the type name \tcode{tm}
is an incomplete type that is defined in \libheaderref{ctime}.
\end{footnote}

\rSec2[locales]{Locales}

\rSec3[locale]{Class \tcode{locale}}

\rSec4[locale.general]{General}

\begin{codeblock}
namespace std {
  class locale {
  public:
    // \ref{locale.types}, types
    // \ref{locale.facet}, class \tcode{locale::facet}
    class facet;
    // \ref{locale.id}, class \tcode{locale::id}
    class id;
    // \ref{locale.category}, type \tcode{locale::category}
    using category = int;
    static const category   // values assigned here are for exposition only
      none     = 0,
      collate  = 0x010, ctype    = 0x020,
      monetary = 0x040, numeric  = 0x080,
      time     = 0x100, messages = 0x200,
      all = collate | ctype | monetary | numeric | time | messages;

    // \ref{locale.cons}, construct/copy/destroy
    locale() noexcept;
    locale(const locale& other) noexcept;
    explicit locale(const char* std_name);
    explicit locale(const string& std_name);
    locale(const locale& other, const char* std_name, category);
    locale(const locale& other, const string& std_name, category);
    template<class Facet> locale(const locale& other, Facet* f);
    locale(const locale& other, const locale& one, category);
    ~locale();                  // not virtual
    const locale& operator=(const locale& other) noexcept;

    // \ref{locale.members}, locale operations
    template<class Facet> locale combine(const locale& other) const;
    string name() const;
    text_encoding encoding() const;

    bool operator==(const locale& other) const;

    template<class charT, class traits, class Allocator>
      bool operator()(const basic_string<charT, traits, Allocator>& s1,
                      const basic_string<charT, traits, Allocator>& s2) const;

    // \ref{locale.statics}, global locale objects
    static       locale  global(const locale&);
    static const locale& classic();
  };
}
\end{codeblock}

\pnum
Class \tcode{locale} implements a type-safe polymorphic set of facets,
indexed by facet \textit{type}.
In other words, a facet has a dual role:
in one sense, it's just a class interface;
at the same time, it's an index into a locale's set of facets.

\pnum
Access to the facets of a \tcode{locale} is via two function templates,
\tcode{use_facet<>} and \tcode{has_facet<>}.

\pnum
\begin{example}
An iostream \tcode{operator<<} can be implemented as:
\begin{footnote}
Note that in the call to \tcode{put},
the stream is implicitly converted
to an \tcode{ostreambuf_iterator<charT, traits>}.
\end{footnote}

\begin{codeblock}
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>& s, Date d) {
  typename basic_ostream<charT, traits>::sentry cerberos(s);
  if (cerberos) {
    tm tmbuf; d.extract(tmbuf);
    bool failed =
      use_facet<time_put<charT, ostreambuf_iterator<charT, traits>>>(
        s.getloc()).put(s, s, s.fill(), &tmbuf, 'x').failed();
    if (failed)
      s.setstate(s.badbit);     // can throw
  }
  return s;
}
\end{codeblock}
\end{example}

\pnum
In the call to \tcode{use_facet<Facet>(loc)},
the type argument chooses a facet,
making available all members of the named type.
If \tcode{Facet} is not present in a locale,
it throws the standard exception \tcode{bad_cast}.
A \Cpp{} program can check if a locale implements a particular facet
with the function template \tcode{has_facet<Facet>()}.
User-defined facets may be installed in a locale, and
used identically as may standard facets.

\pnum
\begin{note}
All locale semantics are accessed via
\tcode{use_facet<>} and \tcode{has_facet<>},
except that:

\begin{itemize}
\item
A member operator template
\begin{codeblock}
operator()(const basic_string<C, T, A>&, const basic_string<C, T, A>&)
\end{codeblock}
is provided so that a locale can be used as a predicate argument to
the standard collections, to collate strings.
\item
Convenient global interfaces are provided for
traditional \tcode{ctype} functions such as
\tcode{isdigit()} and \tcode{isspace()},
so that given a locale object \tcode{loc}
a \Cpp{} program can call \tcode{isspace(c, loc)}.
(This eases upgrading existing extractors\iref{istream.formatted}.)
\end{itemize}
\end{note}

\pnum
Once a facet reference is obtained from a locale object
by calling \tcode{use_facet<>},
that reference remains usable,
and the results from member functions of it may be cached and re-used,
as long as some locale object refers to that facet.

\pnum
In successive calls to a locale facet member function
on a facet object installed in the same locale,
the returned result shall be identical.

\pnum
A \tcode{locale} constructed
from a name string (such as \tcode{"POSIX"}), or
from parts of two named locales, has a name;
all others do not.
Named locales may be compared for equality;
an unnamed locale is equal only to (copies of) itself.
For an unnamed locale, \tcode{locale::name()} returns the string \tcode{"*"}.

\pnum
Whether there is
one global locale object for the entire program or
one global locale object per thread
is \impldef{whether locale object is global or per-thread}.
Implementations should provide one global locale object per thread.
If there is a single global locale object for the entire program,
implementations are not required to
avoid data races on it\iref{res.on.data.races}.

\rSec4[locale.types]{Types}

\rSec5[locale.category]{Type \tcode{locale::category}}

\indexlibrarymember{locale}{category}%
\begin{itemdecl}
using category = int;
\end{itemdecl}

\pnum
\textit{Valid} \tcode{category} values
include the \tcode{locale} member bitmask elements
\tcode{collate},
\tcode{ctype},
\tcode{monetary},
\tcode{numeric},
\tcode{time},
and
\tcode{messages},
each of which represents a single locale category.
In addition, \tcode{locale} member bitmask constant \tcode{none}
is defined as zero and represents no category.
And \tcode{locale} member bitmask constant \tcode{all}
is defined such that the expression
\begin{codeblock}
(collate | ctype | monetary | numeric | time | messages | all) == all
\end{codeblock}
is \tcode{true},
and represents the union of all categories.
Further, the expression \tcode{(X | Y)},
where \tcode{X} and \tcode{Y} each represent a single category,
represents the union of the two categories.

\pnum
\tcode{locale} member functions
expecting a \tcode{category} argument
require one of the \tcode{category} values defined above, or
the union of two or more such values.
Such a \tcode{category} value identifies a set of locale categories.
Each locale category, in turn, identifies a set of locale facets,
including at least those shown in \tref{locale.category.facets}.

\begin{floattable}{Locale category facets}{locale.category.facets}
{ll}
\topline
\lhdr{Category} &   \rhdr{Includes facets}                                      \\ \capsep
collate     &   \tcode{collate<char>}, \tcode{collate<wchar_t>}                 \\ \rowsep
ctype       &   \tcode{ctype<char>}, \tcode{ctype<wchar_t>}                     \\
            &   \tcode{codecvt<char, char, mbstate_t>}                            \\
            &   \tcode{codecvt<wchar_t, char, mbstate_t>}                         \\ \rowsep
monetary    &   \tcode{moneypunct<char>}, \tcode{moneypunct<wchar_t>}           \\
            &   \tcode{moneypunct<char, true>}, \tcode{moneypunct<wchar_t, true>} \\
            &   \tcode{money_get<char>}, \tcode{money_get<wchar_t>}             \\
            &   \tcode{money_put<char>}, \tcode{money_put<wchar_t>}             \\ \rowsep
numeric     &   \tcode{numpunct<char>}, \tcode{numpunct<wchar_t>}               \\
            &   \tcode{num_get<char>}, \tcode{num_get<wchar_t>}                 \\
            &   \tcode{num_put<char>}, \tcode{num_put<wchar_t>}                 \\ \rowsep
time        &   \tcode{time_get<char>}, \tcode{time_get<wchar_t>}               \\
            &   \tcode{time_put<char>}, \tcode{time_put<wchar_t>}               \\ \rowsep
messages    &   \tcode{messages<char>}, \tcode{messages<wchar_t>}               \\
\end{floattable}

\pnum
For any locale \tcode{loc}
either constructed, or returned by \tcode{locale::classic()},
and any facet \tcode{Facet} shown in \tref{locale.category.facets},
\tcode{has_facet<Facet>(loc)} is \tcode{true}.
Each \tcode{locale} member function
which takes a \tcode{locale::category} argument
operates on the corresponding set of facets.

\pnum
An implementation is required to provide those specializations
for facet templates identified as members of a category, and
for those shown in \tref{locale.spec}.

\begin{floattable}{Required specializations}{locale.spec}
{ll}
\topline
\lhdr{Category} &   \rhdr{Includes facets}                                          \\ \capsep
collate     &   \tcode{collate_byname<char>}, \tcode{collate_byname<wchar_t>}       \\ \rowsep
ctype       &   \tcode{ctype_byname<char>}, \tcode{ctype_byname<wchar_t>}           \\
            &   \tcode{codecvt_byname<char, char, mbstate_t>}                       \\
            &   \tcode{codecvt_byname<wchar_t, char, mbstate_t>}                    \\ \rowsep
monetary    &   \tcode{moneypunct_byname<char, International>}                      \\
            &   \tcode{moneypunct_byname<wchar_t, International>}                   \\
            &   \tcode{money_get<C, InputIterator>}                                 \\
            &   \tcode{money_put<C, OutputIterator>}                                \\ \rowsep
numeric     &   \tcode{numpunct_byname<char>}, \tcode{numpunct_byname<wchar_t>}     \\
            &   \tcode{num_get<C, InputIterator>}, \tcode{num_put<C, OutputIterator>} \\ \rowsep
time        &   \tcode{time_get<char, InputIterator>}                               \\
            &   \tcode{time_get_byname<char, InputIterator>}                        \\
            &   \tcode{time_get<wchar_t, InputIterator>}                            \\
            &   \tcode{time_get_byname<wchar_t, InputIterator>}                     \\
            &   \tcode{time_put<char, OutputIterator>}                              \\
            &   \tcode{time_put_byname<char, OutputIterator>}                       \\
            &   \tcode{time_put<wchar_t, OutputIterator>}                           \\
            &   \tcode{time_put_byname<wchar_t, OutputIterator>}                    \\ \rowsep
messages    &   \tcode{messages_byname<char>}, \tcode{messages_byname<wchar_t>}     \\
\end{floattable}


\pnum
The provided implementation of members of
facets \tcode{num_get<charT>} and \tcode{num_put<charT>}
calls \tcode{use_fac\-et<F>(l)} only for facet \tcode{F} of
types \tcode{numpunct<charT>} and \tcode{ctype<charT>},
and for locale \tcode{l} the value obtained by calling member \tcode{getloc()}
on the \tcode{ios_base\&} argument to these functions.

\pnum
In declarations of facets,
a template parameter with name \tcode{InputIterator} or \tcode{OutputIterator}
indicates the set of all possible specializations on parameters that meet the
\oldconcept{InputIterator} requirements or
\oldconcept{OutputIterator} requirements,
respectively\iref{iterator.requirements}.
A template parameter with name \tcode{C} represents
the set of types containing \keyword{char}, \keyword{wchar_t}, and any other
\impldef{set of character container types
that iostreams templates can be instantiated for}
character container types\iref{defns.character.container}
that meet the requirements for a character
on which any of the iostream components can be instantiated.
A template parameter with name \tcode{International}
represents the set of all possible specializations on a bool parameter.

\rSec5[locale.facet]{Class \tcode{locale::facet}}

\indexlibrarymember{locale}{facet}%
\begin{codeblock}
namespace std {
  class locale::facet {
  protected:
    explicit facet(size_t refs = 0);
    virtual ~facet();
    facet(const facet&) = delete;
    void operator=(const facet&) = delete;
  };
}
\end{codeblock}

\pnum
Class \tcode{facet} is the base class for locale feature sets.
A class is a \defn{facet}
if it is publicly derived from another facet, or
if it is a class derived from \tcode{locale::facet} and
contains a publicly accessible declaration as follows:
\begin{footnote}
This is a complete list of requirements; there are no other requirements.
Thus, a facet class need not have a public
copy constructor, assignment, default constructor, destructor, etc.
\end{footnote}
\begin{codeblock}
static ::std::locale::id id;
\end{codeblock}

\pnum
Template parameters in this Clause
which are required to be facets
are those named \tcode{Facet} in declarations.
A program that passes
a type that is \textit{not} a facet, or
a type that refers to a volatile-qualified facet,
as an (explicit or deduced) template parameter to
a locale function expecting a facet,
is ill-formed.
A const-qualified facet is a valid template argument to
any locale function that expects a \tcode{Facet} template parameter.

\pnum
The \tcode{refs} argument to the constructor is used for lifetime management.
For \tcode{refs == 0},
the implementation performs \tcode{delete static_cast<locale::facet*>(f)}
(where \tcode{f} is a point\-er to the facet)
when the last \tcode{locale} object containing the facet is destroyed;
for \tcode{refs == 1}, the implementation never destroys the facet.

\pnum
Constructors of all facets defined in this Clause
take such an argument and pass it along to
their \tcode{facet} base class constructor.
All one-argument constructors defined in this Clause are explicit,
preventing their participation in implicit conversions.

\pnum
For some standard facets a standard ``$\ldots$\tcode{_byname}'' class,
derived from it, implements the virtual function semantics
equivalent to that facet of the locale
constructed by \tcode{locale(const char*)} with the same name.
Each such facet provides a constructor that takes
a \tcode{const char*} argument, which names the locale, and
a \tcode{refs} argument, which is passed to the base class constructor.
Each such facet also provides a constructor that takes
a \tcode{string} argument \tcode{str} and
a \tcode{refs} argument,
which has the same effect as calling the first constructor
with the two arguments \tcode{str.c_str()} and \tcode{refs}.
If there is no ``$\ldots$\tcode{_byname}'' version of a facet,
the base class implements named locale semantics itself
by reference to other facets.

\rSec5[locale.id]{Class \tcode{locale::id}}

\indexlibrarymember{locale}{id}%
\begin{codeblock}
namespace std {
  class locale::id {
  public:
    id();
    void operator=(const id&) = delete;
    id(const id&) = delete;
  };
}
\end{codeblock}

\pnum
The class \tcode{locale::id} provides
identification of a locale facet interface,
used as an index for lookup and to encapsulate initialization.

\pnum
\begin{note}
Because facets are used by iostreams,
potentially while static constructors are running,
their initialization cannot depend on programmed static initialization.
One initialization strategy is for \tcode{locale}
to initialize each facet's \tcode{id} member
the first time an instance of the facet is installed into a locale.
This depends only on static storage being zero
before constructors run\iref{basic.start.static}.
\end{note}

\rSec4[locale.cons]{Constructors and destructor}

\indexlibraryctor{locale}%
\begin{itemdecl}
locale() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a copy of the argument last passed to
\tcode{locale::global(locale\&)},
if it has been called;
else, the resulting facets have virtual function semantics identical to
those of \tcode{locale::classic()}.
\begin{note}
This constructor yields a copy of the current global locale.
It is commonly used as a default argument for
function parameters of type \tcode{const locale\&}.
\end{note}
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
explicit locale(const char* std_name);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a locale using standard C locale names, e.g., \tcode{"POSIX"}.
The resulting locale implements semantics defined to be associated
with that name.

\pnum
\throws
\tcode{runtime_error} if the argument is not valid, or is null.

\pnum
\remarks
The set of valid string argument values is
\tcode{"C"}, \tcode{""}, and any \impldef{locale names} values.
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
explicit locale(const string& std_name);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{locale(std_name.c_str())}.
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
locale(const locale& other, const char* std_name, category cats);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{cats} is a valid \tcode{category} value\iref{locale.category}.

\pnum
\effects
Constructs a locale as a copy of \tcode{other}
except for the facets identified by the \tcode{category} argument,
which instead implement the same semantics as \tcode{locale(std_name)}.

\pnum
\throws
\tcode{runtime_error} if the second argument is not valid, or is null.

\pnum
\remarks
The locale has a name if and only if \tcode{other} has a name.
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
locale(const locale& other, const string& std_name, category cats);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{locale(other, std_name.c_str(), cats)}.
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
template<class Facet> locale(const locale& other, Facet* f);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a locale incorporating all facets from the first argument
except that of type \tcode{Facet},
and installs the second argument as the remaining facet.
If \tcode{f} is null, the resulting object is a copy of \tcode{other}.

\pnum
\remarks
If \tcode{f} is null,
the resulting locale has the same name as \tcode{other}.
Otherwise, the resulting locale has no name.
\end{itemdescr}

\indexlibraryctor{locale}%
\begin{itemdecl}
locale(const locale& other, const locale& one, category cats);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{cats} is a valid \tcode{category} value.

\pnum
\effects
Constructs a locale incorporating all facets from the first argument
except those that implement \tcode{cats},
which are instead incorporated from the second argument.

\pnum
\remarks
If \tcode{cats} is equal to \tcode{locale::none},
the resulting locale has a name if and only if the first argument has a name.
Otherwise, the resulting locale has a name if and only if
the first two arguments both have names.
\end{itemdescr}

\indexlibrarymember{operator=}{locale}%
\begin{itemdecl}
const locale& operator=(const locale& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Creates a copy of \tcode{other}, replacing the current value.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec4[locale.members]{Members}

\indexlibrarymember{locale}{combine}%
\begin{itemdecl}
template<class Facet> locale combine(const locale& other) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a locale incorporating all facets from \tcode{*this}
except for that one facet of \tcode{other} that is identified by \tcode{Facet}.

\pnum
\returns
The newly created locale.

\pnum
\throws
\tcode{runtime_error} if \tcode{has_facet<Facet>(other)} is \tcode{false}.

\pnum
\remarks
The resulting locale has no name.
\end{itemdescr}

\indexlibrarymember{locale}{name}%
\begin{itemdecl}
string name() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The name of \tcode{*this}, if it has one;
otherwise, the string \tcode{"*"}.
\end{itemdescr}

\indexlibrarymember{locale}{encoding}%
\begin{itemdecl}
text_encoding encoding() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{CHAR_BIT == 8} is \tcode{true}.

\pnum
\returns
A \tcode{text_encoding} object representing
the implementation-defined encoding scheme
associated with the locale \tcode{*this}.
\end{itemdescr}

\rSec4[locale.operators]{Operators}

\indexlibrarymember{locale}{operator==}%
\begin{itemdecl}
bool operator==(const locale& other) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if
both arguments are the same locale, or
one is a copy of the other, or
each has a name and the names are identical;
\tcode{false} otherwise.
\end{itemdescr}

\indexlibrarymember{locale}{operator()}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  bool operator()(const basic_string<charT, traits, Allocator>& s1,
                  const basic_string<charT, traits, Allocator>& s2) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Compares two strings according to the \tcode{std::collate<charT>} facet.

\pnum
\returns
\begin{codeblock}
use_facet<std::collate<charT>>(*this).compare(s1.data(), s1.data() + s1.size(),
                                              s2.data(), s2.data() + s2.size()) < 0
\end{codeblock}

\pnum
\remarks
This member operator template (and therefore \tcode{locale} itself)
meets the requirements for
a comparator predicate template argument\iref{algorithms} applied to strings.

\pnum
\begin{example}
A vector of strings \tcode{v}
can be collated according to collation rules in locale \tcode{loc}
simply by\iref{alg.sort,vector}:

\begin{codeblock}
std::sort(v.begin(), v.end(), loc);
\end{codeblock}
\end{example}
\end{itemdescr}

\rSec4[locale.statics]{Static members}

\indexlibrarymember{locale}{global}%
\begin{itemdecl}
static locale global(const locale& loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Sets the global locale to its argument.
Causes future calls to the constructor \tcode{locale()}
to return a copy of the argument.
If the argument has a name, does
\begin{codeblock}
setlocale(LC_ALL, loc.name().c_str());
\end{codeblock}
otherwise, the effect on the C locale, if any, is
\impldef{effect on C locale of calling \tcode{locale::global}}.

\pnum
\returns
The previous value of \tcode{locale()}.

\pnum
\remarks
No library function other than \tcode{locale::global()}
affects the value returned by \tcode{locale()}.
\begin{note}
See~\ref{c.locales} for data race considerations
when \tcode{setlocale} is invoked.
\end{note}
\end{itemdescr}

\indexlibrarymember{locale}{classic}%
\begin{itemdecl}
static const locale& classic();
\end{itemdecl}

\begin{itemdescr}
\pnum
The \tcode{"C"} locale.

\pnum
\returns
A locale that implements the classic \tcode{"C"} locale semantics,
equivalent to the value \tcode{locale("C")}.

\pnum
\remarks
This locale, its facets, and their member functions, do not change with time.
\end{itemdescr}

\rSec3[locale.global.templates]{\tcode{locale} globals}

\indexlibrarymember{locale}{use_facet}%
\begin{itemdecl}
template<class Facet> const Facet& use_facet(const locale& loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{Facet} is a facet class
whose definition contains the public static member \tcode{id}
as defined in~\ref{locale.facet}.

\pnum
\returns
A reference to the corresponding facet of \tcode{loc}, if present.

\pnum
\throws
\tcode{bad_cast} if \tcode{has_facet<Facet>(loc)} is \tcode{false}.

\pnum
\remarks
The reference returned remains valid
at least as long as any copy of \tcode{loc} exists.
\end{itemdescr}

\indexlibrarymember{locale}{has_facet}%
\begin{itemdecl}
template<class Facet> bool has_facet(const locale& loc) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if the facet requested is present in \tcode{loc};
otherwise \tcode{false}.
\end{itemdescr}

\rSec3[locale.convenience]{Convenience interfaces}

\rSec4[classification]{Character classification}

\indexlibraryglobal{isspace}%
\indexlibraryglobal{isprint}%
\indexlibraryglobal{iscntrl}%
\indexlibraryglobal{isupper}%
\indexlibraryglobal{islower}%
\indexlibraryglobal{isalpha}%
\indexlibraryglobal{isdigit}%
\indexlibraryglobal{ispunct}%
\indexlibraryglobal{isxdigit}%
\indexlibraryglobal{isalnum}%
\indexlibraryglobal{isgraph}%
\indexlibraryglobal{isblank}%
\begin{itemdecl}
template<class charT> bool isspace (charT c, const locale& loc);
template<class charT> bool isprint (charT c, const locale& loc);
template<class charT> bool iscntrl (charT c, const locale& loc);
template<class charT> bool isupper (charT c, const locale& loc);
template<class charT> bool islower (charT c, const locale& loc);
template<class charT> bool isalpha (charT c, const locale& loc);
template<class charT> bool isdigit (charT c, const locale& loc);
template<class charT> bool ispunct (charT c, const locale& loc);
template<class charT> bool isxdigit(charT c, const locale& loc);
template<class charT> bool isalnum (charT c, const locale& loc);
template<class charT> bool isgraph (charT c, const locale& loc);
template<class charT> bool isblank (charT c, const locale& loc);
\end{itemdecl}

\pnum
Each of these functions \tcode{is\placeholder{F}}
returns the result of the expression:
\begin{codeblock}
use_facet<ctype<charT>>(loc).is(ctype_base::@\placeholder{F}@, c)
\end{codeblock}
where \tcode{\placeholder{F}} is the \tcode{ctype_base::mask} value
corresponding to that function\iref{category.ctype}.
\begin{footnote}
When used in a loop,
it is faster to cache the \tcode{ctype<>} facet and use it directly, or
use the vector form of \tcode{ctype<>::is}.
\end{footnote}

\rSec4[conversions.character]{Character conversions}

\indexlibraryglobal{toupper}%
\begin{itemdecl}
template<class charT> charT toupper(charT c, const locale& loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{use_facet<ctype<charT>>(loc).toupper(c)}.
\end{itemdescr}

\indexlibraryglobal{tolower}%
\begin{itemdecl}
template<class charT> charT tolower(charT c, const locale& loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{use_facet<ctype<charT>>(loc).tolower(c)}.
\end{itemdescr}

\rSec2[locale.categories]{Standard \tcode{locale} categories}

\rSec3[locale.categories.general]{General}

\pnum
Each of the standard categories includes a family of facets.
Some of these implement formatting or parsing of a datum,
for use by standard or users' iostream operators \tcode{<<} and \tcode{>>},
as members \tcode{put()} and \tcode{get()}, respectively.
Each such member function takes an
\indexlibrarymember{flags}{ios_base}%
\tcode{ios_base\&} argument whose members
\indexlibrarymember{flags}{ios_base}%
\tcode{flags()},
\indexlibrarymember{precision}{ios_base}%
\tcode{precision()},
and
\indexlibrarymember{width}{ios_base}%
\tcode{width()},
specify the format of the corresponding datum\iref{ios.base}.
Those functions which need to use other facets call its member \tcode{getloc()}
to retrieve the locale imbued there.
Formatting facets use the character argument \tcode{fill}
to fill out the specified width where necessary.

\pnum
The \tcode{put()} members make no provision for error reporting.
(Any failures of the \tcode{OutputIterator} argument can be extracted from
the returned iterator.)
The \tcode{get()} members take an \tcode{ios_base::iostate\&} argument
whose value they ignore,
but set to \tcode{ios_base::failbit} in case of a parse error.

\pnum
Within \ref{locale.categories} it is unspecified whether
one virtual function calls another virtual function.

\rSec3[category.ctype]{The \tcode{ctype} category}

\rSec4[category.ctype.general]{General}

\indexlibraryglobal{ctype_base}%
\begin{codeblock}
namespace std {
  class ctype_base {
  public:
    using @\libmember{mask}{ctype_base}@ = @\seebelow@;

    // numeric values are for exposition only.
    static constexpr mask @\libmember{space}{ctype_base}@  = 1 << 0;
    static constexpr mask @\libmember{print}{ctype_base}@  = 1 << 1;
    static constexpr mask @\libmember{cntrl}{ctype_base}@  = 1 << 2;
    static constexpr mask @\libmember{upper}{ctype_base}@  = 1 << 3;
    static constexpr mask @\libmember{lower}{ctype_base}@  = 1 << 4;
    static constexpr mask @\libmember{alpha}{ctype_base}@  = 1 << 5;
    static constexpr mask @\libmember{digit}{ctype_base}@  = 1 << 6;
    static constexpr mask @\libmember{punct}{ctype_base}@  = 1 << 7;
    static constexpr mask @\libmember{xdigit}{ctype_base}@ = 1 << 8;
    static constexpr mask @\libmember{blank}{ctype_base}@  = 1 << 9;
    static constexpr mask @\libmember{alnum}{ctype_base}@  = alpha | digit;
    static constexpr mask @\libmember{graph}{ctype_base}@  = alnum | punct;
  };
}
\end{codeblock}

\pnum
The type \tcode{mask} is a bitmask type\iref{bitmask.types}.

\rSec4[locale.ctype]{Class template \tcode{ctype}}

\rSec5[locale.ctype.general]{General}

\indexlibraryglobal{ctype}%
\begin{codeblock}
namespace std {
  template<class charT>
  class ctype : public locale::facet, public ctype_base {
  public:
    using @\libmember{char_type}{ctype}@ = charT;

    explicit ctype(size_t refs = 0);

    bool         is(mask m, charT c) const;
    const charT* is(const charT* low, const charT* high, mask* vec) const;
    const charT* scan_is(mask m, const charT* low, const charT* high) const;
    const charT* scan_not(mask m, const charT* low, const charT* high) const;
    charT        toupper(charT c) const;
    const charT* toupper(charT* low, const charT* high) const;
    charT        tolower(charT c) const;
    const charT* tolower(charT* low, const charT* high) const;

    charT        widen(char c) const;
    const char*  widen(const char* low, const char* high, charT* to) const;
    char         narrow(charT c, char dfault) const;
    const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const;

    static locale::id @\libmember{id}{ctype}@;

  protected:
    ~ctype();
    virtual bool         do_is(mask m, charT c) const;
    virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const;
    virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const;
    virtual const charT* do_scan_not(mask m, const charT* low, const charT* high) const;
    virtual charT        do_toupper(charT) const;
    virtual const charT* do_toupper(charT* low, const charT* high) const;
    virtual charT        do_tolower(charT) const;
    virtual const charT* do_tolower(charT* low, const charT* high) const;
    virtual charT        do_widen(char) const;
    virtual const char*  do_widen(const char* low, const char* high, charT* dest) const;
    virtual char         do_narrow(charT, char dfault) const;
    virtual const charT* do_narrow(const charT* low, const charT* high,
                                   char dfault, char* dest) const;
  };
}
\end{codeblock}

\pnum
Class \tcode{ctype} encapsulates the C library \libheaderref{cctype} features.
\tcode{istream} members are required to use \tcode{ctype<>}
for character classing during input parsing.

\pnum
The specializations
required in \tref{locale.category.facets}\iref{locale.category},
namely \tcode{ctype<char>} and \tcode{ctype<wchar_t>},
implement character classing appropriate
to the implementation's native character set.

\rSec5[locale.ctype.members]{\tcode{ctype} members}

\indexlibrarymember{ctype}{is}%
\begin{itemdecl}
bool         is(mask m, charT c) const;
const charT* is(const charT* low, const charT* high, mask* vec) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_is(m, c)} or \tcode{do_is(low, high, vec)}.
\end{itemdescr}

\indexlibrarymember{ctype}{scan_is}%
\begin{itemdecl}
const charT* scan_is(mask m, const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_scan_is(m, low, high)}.
\end{itemdescr}

\indexlibrarymember{ctype}{scan_not}%
\begin{itemdecl}
const charT* scan_not(mask m, const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_scan_not(m, low, high)}.
\end{itemdescr}

\indexlibrarymember{ctype}{toupper}%
\begin{itemdecl}
charT        toupper(charT c) const;
const charT* toupper(charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_toupper(c)} or \tcode{do_toupper(low, high)}.
\end{itemdescr}

\indexlibrarymember{ctype}{tolower}%
\begin{itemdecl}
charT        tolower(charT c) const;
const charT* tolower(charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_tolower(c)} or \tcode{do_tolower(low, high)}.
\end{itemdescr}

\indexlibrarymember{ctype}{widen}%
\begin{itemdecl}
charT       widen(char c) const;
const char* widen(const char* low, const char* high, charT* to) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_widen(c)} or \tcode{do_widen(low, high, to)}.
\end{itemdescr}

\indexlibrarymember{ctype}{narrow}%
\begin{itemdecl}
char         narrow(charT c, char dfault) const;
const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_narrow(c, dfault)} or \tcode{do_narrow(low, high, dfault, to)}.
\end{itemdescr}

\rSec5[locale.ctype.virtuals]{\tcode{ctype} virtual functions}

\indexlibrarymember{ctype}{do_is}%
\begin{itemdecl}
bool         do_is(mask m, charT c) const;
const charT* do_is(const charT* low, const charT* high, mask* vec) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Classifies a character or sequence of characters.
For each argument character,
identifies a value \tcode{M} of type \tcode{ctype_base::mask}.
The second form identifies a value \tcode{M} of type \tcode{ctype_base::mask}
for each \tcode{*p} where \tcode{(low <= p \&\& p < high)},
and places it into \tcode{vec[p - low]}.

\pnum
\returns
The first form returns the result of the expression \tcode{(M \& m) != 0};
i.e., \tcode{true} if the character has the characteristics specified.
The second form returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype_base}{do_scan_is}%
\begin{itemdecl}
const charT* do_scan_is(mask m, const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Locates a character in a buffer that conforms to a classification \tcode{m}.

\pnum
\returns
The smallest pointer \tcode{p} in the range \range{low}{high}
such that \tcode{is(m, *p)} would return \tcode{true};
otherwise, returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype}{do_scan_not}%
\begin{itemdecl}
const charT* do_scan_not(mask m, const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Locates a character in a buffer that fails to conform to a classification
\tcode{m}.

\pnum
\returns
The smallest pointer \tcode{p}, if any, in the range \range{low}{high}
such that \tcode{is(m, *p)} would return \tcode{false};
otherwise, returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype}{do_toupper}%
\begin{itemdecl}
charT        do_toupper(charT c) const;
const charT* do_toupper(charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Converts a character or characters to upper case.
The second form replaces
each character \tcode{*p} in the range \range{low}{high}
for which a corresponding upper-case character exists,
with that character.

\pnum
\returns
The first form returns
the corresponding upper-case character if it is known to exist, or
its argument if not.
The second form returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype}{do_tolower}%
\begin{itemdecl}
charT        do_tolower(charT c) const;
const charT* do_tolower(charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Converts a character or characters to lower case.
The second form replaces
each character \tcode{*p} in the range \range{low}{high}
and for which a corresponding lower-case character exists,
with that character.

\pnum
\returns
The first form returns
the corresponding lower-case character if it is known to exist, or
its argument if not.
The second form returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype}{do_widen}%
\begin{itemdecl}
charT        do_widen(char c) const;
const char*  do_widen(const char* low, const char* high, charT* dest) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Applies the simplest reasonable transformation
from a \tcode{char} value or sequence of \tcode{char} values
to the corresponding \tcode{charT} value or values.
\begin{footnote}
The parameter \tcode{c} of \tcode{do_widen} is intended to
accept values derived from \grammarterm{character-literal}s
for conversion to the locale's encoding.
\end{footnote}
The only characters for which unique transformations are required
are those in the basic character set\iref{lex.charset}.

For any named \tcode{ctype} category with
a \tcode{ctype<char>} facet \tcode{ctc} and
valid \tcode{ctype_base::mask} value \tcode{M},
\tcode{(ctc.\brk{}is(M, c) || !is(M, do_widen(c)) )} is \tcode{true}.
\begin{footnote}
In other words, the transformed character is not
a member of any character classification
that \tcode{c} is not also a member of.
\end{footnote}

The second form transforms
each character \tcode{*p} in the range \range{low}{high},
placing the result in \tcode{dest[p - low]}.

\pnum
\returns
The first form returns the transformed value.
The second form returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype}{do_narrow}%
\begin{itemdecl}
char         do_narrow(charT c, char dfault) const;
const charT* do_narrow(const charT* low, const charT* high, char dfault, char* dest) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Applies the simplest reasonable transformation
from a \tcode{charT} value or sequence of \tcode{charT} values
to the corresponding \tcode{char} value or values.

For any character \tcode{c} in the basic character set\iref{lex.charset}
the transformation is such that
\begin{codeblock}
do_widen(do_narrow(c, 0)) == c
\end{codeblock}

For any named \tcode{ctype} category with
a \tcode{ctype<char>} facet \tcode{ctc} however, and
\tcode{ctype_base::mask} value \tcode{M},
\begin{codeblock}
(is(M, c) || !ctc.is(M, do_narrow(c, dfault)) )
\end{codeblock}
is \tcode{true} (unless \tcode{do_narrow} returns \tcode{dfault}).
In addition, for any digit character \tcode{c},
the expression \tcode{(do_narrow(c, dfault) - '0')}
evaluates to the digit value of the character.
The second form transforms
each character \tcode{*p} in the range \range{low}{high},
placing the result
(or \tcode{dfault} if no simple transformation is readily available)
in \tcode{dest[p - low]}.

\pnum
\returns
The first form returns the transformed value;
or \tcode{dfault} if no mapping is readily available.
The second form returns \tcode{high}.
\end{itemdescr}

\rSec4[locale.ctype.byname]{Class template \tcode{ctype_byname}}

\indexlibraryglobal{ctype_byname}%
\begin{codeblock}
namespace std {
  template<class charT>
  class ctype_byname : public ctype<charT> {
  public:
    using @\libmember{mask}{ctype_byname}@ = ctype<charT>::mask;
    explicit ctype_byname(const char*, size_t refs = 0);
    explicit ctype_byname(const string&, size_t refs = 0);

  protected:
    ~ctype_byname();
  };
}
\end{codeblock}

\rSec4[facet.ctype.special]{\tcode{ctype<char>} specialization}

\rSec5[facet.ctype.special.general]{General}

\indexlibraryglobal{ctype<char>}%
\begin{codeblock}
namespace std {
  template<>
  class ctype<char> : public locale::facet, public ctype_base {
  public:
    using @\libmember{char_type}{ctype<char>}@ = char;

    explicit ctype(const mask* tab = nullptr, bool del = false, size_t refs = 0);

    bool is(mask m, char c) const;
    const char* is(const char* low, const char* high, mask* vec) const;
    const char* scan_is (mask m, const char* low, const char* high) const;
    const char* scan_not(mask m, const char* low, const char* high) const;

    char        toupper(char c) const;
    const char* toupper(char* low, const char* high) const;
    char        tolower(char c) const;
    const char* tolower(char* low, const char* high) const;

    char  widen(char c) const;
    const char* widen(const char* low, const char* high, char* to) const;
    char  narrow(char c, char dfault) const;
    const char* narrow(const char* low, const char* high, char dfault, char* to) const;

    static locale::id @\libmember{id}{ctype<char>}@;
    static const size_t @\libmember{table_size}{ctype<char>}@ = @\impdef@;

    const mask* table() const noexcept;
    static const mask* classic_table() noexcept;

  protected:
    ~ctype();
    virtual char        do_toupper(char c) const;
    virtual const char* do_toupper(char* low, const char* high) const;
    virtual char        do_tolower(char c) const;
    virtual const char* do_tolower(char* low, const char* high) const;

    virtual char        do_widen(char c) const;
    virtual const char* do_widen(const char* low, const char* high, char* to) const;
    virtual char        do_narrow(char c, char dfault) const;
    virtual const char* do_narrow(const char* low, const char* high,
                                  char dfault, char* to) const;
  };
}
\end{codeblock}

\pnum
A specialization \tcode{ctype<char>} is provided
so that the member functions on type \tcode{char} can be implemented inline.
\begin{footnote}
Only the \tcode{char} (not \tcode{unsigned char} and \tcode{signed char})
form is provided.
The specialization is specified in the standard,
and not left as an implementation detail,
because it affects the derivation interface for \tcode{ctype<char>}.
\end{footnote}
The \impldef{value of \tcode{ctype<char>::table_size}} value of
member \tcode{table_size} is at least 256.

\rSec5[facet.ctype.char.dtor]{Destructor}

\indexlibrarydtor{ctype<char>}%
\begin{itemdecl}
~ctype();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If the constructor's first argument was nonzero, and
its second argument was \tcode{true},
does \tcode{delete [] table()}.
\end{itemdescr}

\rSec5[facet.ctype.char.members]{Members}

\pnum
\indexlibrarymember{ctype<char>}{ctype<char>}%
In the following member descriptions,
for \tcode{unsigned char} values \tcode{v} where \tcode{v >= table_size},
\tcode{table()[v]} is assumed to have an implementation-specific value
(possibly different for each such value \tcode{v})
without performing the array lookup.

\indexlibraryctor{ctype<char>}%
\begin{itemdecl}
explicit ctype(const mask* tbl = nullptr, bool del = false, size_t refs = 0);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
Either \tcode{tbl == nullptr} is \tcode{true} or
\range{tbl}{tbl + table_size} is a valid range.

\pnum
\effects
Passes its \tcode{refs} argument to its base class constructor.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{is}%
\begin{itemdecl}
bool        is(mask m, char c) const;
const char* is(const char* low, const char* high, mask* vec) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The second form, for all \tcode{*p} in the range \range{low}{high},
assigns into \tcode{vec[p - low]} the value \tcode{table()[(unsigned char)*p]}.

\pnum
\returns
The first form returns \tcode{table()[(unsigned char)c] \& m};
the second form returns \tcode{high}.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{scan_is}%
\begin{itemdecl}
const char* scan_is(mask m, const char* low, const char* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The smallest \tcode{p} in the range \range{low}{high} such that
\begin{codeblock}
table()[(unsigned char) *p] & m
\end{codeblock}
is \tcode{true}.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{scan_not}%
\begin{itemdecl}
const char* scan_not(mask m, const char* low, const char* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The smallest \tcode{p} in the range \range{low}{high} such that
\begin{codeblock}
table()[(unsigned char) *p] & m
\end{codeblock}
is \tcode{false}.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{toupper}%
\begin{itemdecl}
char        toupper(char c) const;
const char* toupper(char* low, const char* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_toupper(c)} or \tcode{do_toupper(low, high)}, respectively.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{tolower}%
\begin{itemdecl}
char        tolower(char c) const;
const char* tolower(char* low, const char* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_tolower(c)} or \tcode{do_tolower(low, high)}, respectively.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{widen}%
\begin{itemdecl}
char  widen(char c) const;
const char* widen(const char* low, const char* high, char* to) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_widen(c)} or
\indexlibraryglobal{do_widen}%
\tcode{do_widen(low, high, to)}, respectively.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{narrow}%
\begin{itemdecl}
char        narrow(char c, char dfault) const;
const char* narrow(const char* low, const char* high, char dfault, char* to) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\indexlibraryglobal{do_narrow}%
\tcode{do_narrow(c, dfault)} or
\indexlibraryglobal{do_narrow}%
\tcode{do_narrow(low, high, dfault, to)},
respectively.
\end{itemdescr}

\indexlibrarymember{ctype<char>}{table}%
\begin{itemdecl}
const mask* table() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The first constructor argument, if it was nonzero,
otherwise \tcode{classic_table()}.
\end{itemdescr}

\rSec5[facet.ctype.char.statics]{Static members}

\indexlibrarymember{ctype<char>}{classic_table}%
\begin{itemdecl}
static const mask* classic_table() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A pointer to the initial element of an array of size \tcode{table_size}
which represents the classifications of characters in the \tcode{"C"} locale.
\end{itemdescr}

\rSec5[facet.ctype.char.virtuals]{Virtual functions}

\indexlibrarymember{ctype<char>}{do_toupper}%
\indexlibrarymember{ctype<char>}{do_tolower}%
\indexlibrarymember{ctype<char>}{do_widen}%
\indexlibrarymember{ctype<char>}{do_narrow}%
\begin{codeblock}
char        do_toupper(char) const;
const char* do_toupper(char* low, const char* high) const;
char        do_tolower(char) const;
const char* do_tolower(char* low, const char* high) const;

virtual char        do_widen(char c) const;
virtual const char* do_widen(const char* low, const char* high, char* to) const;
virtual char        do_narrow(char c, char dfault) const;
virtual const char* do_narrow(const char* low, const char* high,
                              char dfault, char* to) const;
\end{codeblock}

\pnum
These functions are described identically as those members of the same name
in the \tcode{ctype} class template\iref{locale.ctype.members}.

\rSec4[locale.codecvt]{Class template \tcode{codecvt}}

\rSec5[locale.codecvt.general]{General}

\indexlibraryglobal{codecvt_base}%
\indexlibraryglobal{codecvt}%
\begin{codeblock}
namespace std {
  class codecvt_base {
  public:
    enum @\libmember{result}{codecvt_base}@ { @\libmember{ok}{codecvt_base}@, @\libmember{partial}{codecvt_base}@, @\libmember{error}{codecvt_base}@, @\libmember{noconv}{codecvt_base}@ };
  };

  template<class internT, class externT, class stateT>
  class codecvt : public locale::facet, public codecvt_base {
  public:
    using @\libmember{intern_type}{codecvt}@ = internT;
    using @\libmember{extern_type}{codecvt}@ = externT;
    using @\libmember{state_type}{codecvt}@  = stateT;

    explicit codecvt(size_t refs = 0);

    result out(
      stateT& state,
      const internT* from, const internT* from_end, const internT*& from_next,
            externT*   to,       externT*   to_end,       externT*&   to_next) const;

    result unshift(
      stateT& state,
            externT*    to,      externT*   to_end,       externT*&   to_next) const;

    result in(
      stateT& state,
      const externT* from, const externT* from_end, const externT*& from_next,
            internT*   to,       internT*   to_end,       internT*&   to_next) const;

    int encoding() const noexcept;
    bool always_noconv() const noexcept;
    int length(stateT&, const externT* from, const externT* end, size_t max) const;
    int max_length() const noexcept;

    static locale::id @\libmember{id}{codecvt}@;

  protected:
    ~codecvt();
    virtual result do_out(
      stateT& state,
      const internT* from, const internT* from_end, const internT*& from_next,
            externT* to,         externT*   to_end,       externT*&   to_next) const;
    virtual result do_in(
      stateT& state,
      const externT* from, const externT* from_end, const externT*& from_next,
            internT* to,         internT*   to_end,       internT*&   to_next) const;
    virtual result do_unshift(
      stateT& state,
            externT* to,         externT*   to_end,       externT*&   to_next) const;

    virtual int do_encoding() const noexcept;
    virtual bool do_always_noconv() const noexcept;
    virtual int do_length(stateT&, const externT* from, const externT* end, size_t max) const;
    virtual int do_max_length() const noexcept;
  };
}
\end{codeblock}

\pnum
The class \tcode{codecvt<internT, externT, stateT>} is for use
when converting from one character encoding to another,
such as from wide characters to multibyte characters or
between wide character encodings such as UTF-32 and EUC.

\pnum
The \tcode{stateT} argument selects
the pair of character encodings being mapped between.

\pnum
The specializations required
in \tref{locale.category.facets}\iref{locale.category}
convert the implementation-defined native character set.
\tcode{codecvt<char, char, mbstate_t>} implements a degenerate conversion;
it does not convert at all.
\tcode{codecvt<wchar_t, char, mbstate_t>}
converts between the native character sets for ordinary and wide characters.
Specializations on \tcode{mbstate_t}
perform conversion between encodings known to the library implementer.
Other encodings can be converted by specializing on
a program-defined \tcode{stateT} type.
Objects of type \tcode{stateT} can contain any state
that is useful to communicate to or from
the specialized \tcode{do_in} or \tcode{do_out} members.

\rSec5[locale.codecvt.members]{Members}

\indexlibrarymember{codecvt}{out}%
\begin{itemdecl}
result out(
  stateT& state,
  const internT* from, const internT* from_end, const internT*& from_next,
  externT* to, externT* to_end, externT*& to_next) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_out(state, from, from_end, from_next, to, to_end, to_next)}.
\end{itemdescr}

\indexlibrarymember{codecvt}{unshift}%
\begin{itemdecl}
result unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_unshift(state, to, to_end, to_next)}.
\end{itemdescr}

\indexlibrarymember{codecvt}{in}%
\begin{itemdecl}
result in(
  stateT& state,
  const externT* from, const externT* from_end, const externT*& from_next,
  internT* to, internT* to_end, internT*& to_next) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_in(state, from, from_end, from_next, to, to_end, to_next)}.
\end{itemdescr}

\indexlibrarymember{codecvt}{encoding}%
\begin{itemdecl}
int encoding() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_encoding()}.
\end{itemdescr}

\indexlibrarymember{codecvt}{always_noconv}%
\begin{itemdecl}
bool always_noconv() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_always_noconv()}.
\end{itemdescr}

\indexlibrarymember{codecvt}{length}%
\begin{itemdecl}
int length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_length(state, from, from_end, max)}.
\end{itemdescr}

\indexlibrarymember{codecvt}{max_length}%
\begin{itemdecl}
int max_length() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_max_length()}.
\end{itemdescr}

\rSec5[locale.codecvt.virtuals]{Virtual functions}

\indexlibrarymember{codecvt}{do_out}%
\indexlibrarymember{codecvt}{do_in}%
\begin{itemdecl}
result do_out(
  stateT& state,
  const internT* from, const internT* from_end, const internT*& from_next,
  externT* to, externT* to_end, externT*& to_next) const;

result do_in(
  stateT& state,
  const externT* from, const externT* from_end, const externT*& from_next,
  internT* to, internT* to_end, internT*& to_next) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{(from <= from_end \&\& to <= to_end)} is well-defined and \tcode{true};
\tcode{state} is initialized, if at the beginning of a sequence,
or else is equal to the result of converting
the preceding characters in the sequence.

\pnum
\effects
Translates characters in the source range \range{from}{from_end},
placing the results in sequential positions starting at destination \tcode{to}.
Converts no more than \tcode{(from_end - from)} source elements, and
stores no more than \tcode{(to_end - to)} destination elements.

\pnum
Stops if it encounters a character it cannot convert.
It always leaves the \tcode{from_next} and \tcode{to_next} pointers
pointing one beyond the last element successfully converted.
If it returns \tcode{noconv},
\tcode{internT} and \tcode{externT} are the same type, and
the converted sequence is identical to
the input sequence \range{from}{from\textunderscore\nobreak next},
\tcode{to_next} is set equal to \tcode{to},
the value of \tcode{state} is unchanged, and
there are no changes to the values in \range{to}{to_end}.

\pnum
A \tcode{codecvt} facet
that is used by \tcode{basic_filebuf}\iref{file.streams}
shall have the property that if
\begin{codeblock}
do_out(state, from, from_end, from_next, to, to_end, to_next)
\end{codeblock}
would return \tcode{ok},
where \tcode{from != from_end},
then
\begin{codeblock}
do_out(state, from, from + 1, from_next, to, to_end, to_next)
\end{codeblock}
shall also return \tcode{ok},
and that if
\begin{codeblock}
do_in(state, from, from_end, from_next, to, to_end, to_next)
\end{codeblock}
would return \tcode{ok},
where \tcode{to != to_end},
then
\begin{codeblock}
do_in(state, from, from_end, from_next, to, to + 1, to_next)
\end{codeblock}
shall also return \tcode{ok}.
\begin{footnote}
Informally, this means that \tcode{basic_filebuf}
assumes that the mappings from internal to external characters is 1 to N:
that a \tcode{codecvt} facet that is used by \tcode{basic_filebuf}
can translate characters one internal character at a time.
\end{footnote}
\begin{note}
As a result of operations on \tcode{state},
it can return \tcode{ok} or \tcode{partial} and
set \tcode{from_next == from} and \tcode{to_next != to}.
\end{note}

\pnum
\returns
An enumeration value, as summarized in \tref{locale.codecvt.inout}.

\begin{floattable}{\tcode{do_in/do_out} result values}{locale.codecvt.inout}
{lp{3in}}
\topline
\lhdr{Value}    &   \rhdr{Meaning}                                  \\ \capsep
\tcode{ok}                  &   completed the conversion            \\
\tcode{partial}             &   not all source characters converted \\
\tcode{error}               &
encountered a character in \range{from}{from_end}
that cannot be converted                                           \\
\tcode{noconv}              &
\tcode{internT} and \tcode{externT} are the same type, and input
sequence is identical to converted sequence                         \\
\end{floattable}

A return value of \tcode{partial},
if \tcode{(from_next == from_end)},
indicates
that either the destination sequence has not absorbed
all the available destination elements, or
that additional source elements are needed
before another destination element can be produced.

\pnum
\remarks
Its operations on \tcode{state} are unspecified.
\begin{note}
This argument can be used, for example,
to maintain shift state,
to specify conversion options (such as count only), or
to identify a cache of seek offsets.
\end{note}
\end{itemdescr}

\indexlibrarymember{codecvt}{do_unshift}%
\begin{itemdecl}
result do_unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{(to <= to_end)} is well-defined and \tcode{true};
\tcode{state} is initialized, if at the beginning of a sequence,
or else is equal to the result of converting
the preceding characters in the sequence.

\pnum
\effects
Places characters starting at \tcode{to}
that should be appended to terminate a sequence
when the current \tcode{stateT} is given by \tcode{state}.
\begin{footnote}
Typically these will be characters to return the state to \tcode{stateT()}.
\end{footnote}
Stores no more than \tcode{(to_end - to)} destination elements, and
leaves the \tcode{to_next} pointer
pointing one beyond the last element successfully stored.

\pnum
\returns
An enumeration value, as summarized in \tref{locale.codecvt.unshift}.

\begin{floattable}{\tcode{do_unshift} result values}{locale.codecvt.unshift}
{lp{.50\hsize}}
\topline
\lhdr{Value}                &   \rhdr{Meaning}                                          \\ \capsep
\tcode{ok}                  &   completed the sequence                                  \\
\tcode{partial}             &
space for more than \tcode{to_end - to} destination elements was needed
to terminate a sequence given the value of \tcode{state}\\
\tcode{error}               &   an unspecified error has occurred \\
\tcode{noconv}              &   no termination is needed for this \tcode{state_type}    \\
\end{floattable}
\end{itemdescr}

\indexlibrarymember{codecvt}{do_encoding}%
\begin{itemdecl}
int do_encoding() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{-1} if the encoding of the \tcode{externT} sequence is state-dependent;
else the constant number of \tcode{externT} characters
needed to produce an internal character;
or \tcode{0} if this number is not a constant.
\begin{footnote}
If \tcode{encoding()} yields \tcode{-1},
then more than \tcode{max_length()} \tcode{externT} elements
can be consumed when producing a single \tcode{internT} character, and
additional \tcode{externT} elements can appear at the end of a sequence
after those that yield the final \tcode{internT} character.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{codecvt}{do_always_noconv}%
\begin{itemdecl}
bool do_always_noconv() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \tcode{do_in()} and \tcode{do_out()} return \tcode{noconv}
for all valid argument values.
\tcode{codecvt<char, char, mbstate_t>} returns \tcode{true}.
\end{itemdescr}

\indexlibrarymember{codecvt}{do_length}%
\begin{itemdecl}
int do_length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{(from <= from_end)} is well-defined and \tcode{true};
\tcode{state} is initialized, if at the beginning of a sequence,
or else is equal to the result of converting
the preceding characters in the sequence.

\pnum
\effects
The effect on the \tcode{state} argument is as if
it called \tcode{do_in(state, from, from_end, from, to, to + max, to)}
for \tcode{to} pointing to a buffer of at least \tcode{max} elements.

\pnum
\returns
\tcode{(from_next - from)} where
\tcode{from_next} is the largest value in the range \crange{from}{from_end}
such that the sequence of values in the range \range{from}{from_next}
represents
\tcode{max} or fewer valid complete characters of type \tcode{internT}.
The specialization \tcode{codecvt<char, char, mbstate_t>},
returns the lesser of \tcode{max} and \tcode{(from_end - from)}.
\end{itemdescr}

\indexlibrarymember{codecvt}{do_max_length}%
\begin{itemdecl}
int do_max_length() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The maximum value that \tcode{do_length(state, from, from_end, 1)} can return
for any valid range \range{from}{from_end}
and \tcode{stateT} value \tcode{state}.
The specialization \tcode{codecvt<char, char, mbstate_t>::do_max_length()}
returns 1.
\end{itemdescr}

\rSec4[locale.codecvt.byname]{Class template \tcode{codecvt_byname}}

\indexlibraryglobal{codecvt_byname}%
\begin{codeblock}
namespace std {
  template<class internT, class externT, class stateT>
  class codecvt_byname : public codecvt<internT, externT, stateT> {
  public:
    explicit codecvt_byname(const char*, size_t refs = 0);
    explicit codecvt_byname(const string&, size_t refs = 0);

  protected:
    ~codecvt_byname();
  };
}
\end{codeblock}

\rSec3[category.numeric]{The numeric category}

\rSec4[category.numeric.general]{General}

\pnum
The classes \tcode{num_get<>} and \tcode{num_put<>}
handle numeric formatting and parsing.
Virtual functions are provided for several numeric types.
Implementations may (but are not required to) delegate
extraction of smaller types to extractors for larger types.
\begin{footnote}
Parsing \tcode{"-1"} correctly into, e.g., an \tcode{unsigned short}
requires that the corresponding member \tcode{get()}
at least extract the sign before delegating.
\end{footnote}

\pnum
All specifications of member functions for \tcode{num_put} and \tcode{num_get}
in the subclauses of~\ref{category.numeric} only apply to
the specializations required in Tables~\ref{tab:locale.category.facets}
and~\ref{tab:locale.spec}\iref{locale.category}, namely
\tcode{num_get<char>},
\tcode{num_get<wchar_t>},
\tcode{num_get<C, InputIterator>},
\tcode{num_put<char>},
\tcode{num_put<wchar_t>}, and
\tcode{num_put<C, OutputIterator>}.
These specializations refer to the \tcode{ios_base\&} argument for
formatting specifications\iref{locale.categories},
and to its imbued locale for the \tcode{numpunct<>} facet to
identify all numeric punctuation preferences,
and also for the \tcode{ctype<>} facet to perform character classification.

\pnum
Extractor and inserter members of the standard iostreams use
\tcode{num_get<>} and \tcode{num_put<>} member functions for
formatting and parsing
numeric values\iref{istream.formatted.reqmts,ostream.formatted.reqmts}.

\rSec4[locale.num.get]{Class template \tcode{num_get}}

\rSec5[locale.num.get.general]{General}

\indexlibraryglobal{num_get}%
\begin{codeblock}
namespace std {
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
  class num_get : public locale::facet {
  public:
    using @\libmember{char_type}{num_get}@ = charT;
    using @\libmember{iter_type}{num_get}@ = InputIterator;

    explicit num_get(size_t refs = 0);

    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, bool& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, long& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, long long& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, unsigned short& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, unsigned int& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, unsigned long& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, unsigned long long& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, float& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, double& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, long double& v) const;
    iter_type get(iter_type in, iter_type end, ios_base&,
                  ios_base::iostate& err, void*& v) const;

    static locale::id @\libmember{id}{num_get}@;

  protected:
    ~num_get();
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, bool& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, long& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, long long& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, unsigned short& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, unsigned int& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, unsigned long& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, unsigned long long& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, float& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, double& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, long double& v) const;
    virtual iter_type do_get(iter_type, iter_type, ios_base&,
                             ios_base::iostate& err, void*& v) const;
  };
}
\end{codeblock}

\pnum
The facet \tcode{num_get} is used to parse numeric values
from an input sequence such as an istream.

\rSec5[facet.num.get.members]{Members}

\indexlibrarymember{num_get}{get}%
\begin{itemdecl}
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, bool& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, long long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, unsigned short& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, unsigned int& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, unsigned long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, unsigned long long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, float& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, double& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, long double& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
              ios_base::iostate& err, void*& val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get(in, end, str, err, val)}.
\end{itemdescr}

\rSec5[facet.num.get.virtuals]{Virtual functions}

\indexlibrarymember{num_get}{do_get}%
\begin{itemdecl}
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, long long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, unsigned short& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, unsigned int& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, unsigned long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, unsigned long long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, float& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, double& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, long double& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, void*& val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters from \tcode{in},
interpreting them according to
\tcode{str.flags()},
\tcode{use_facet<ctype<\brk{}charT>>(loc)}, and
\tcode{use_facet<numpunct<charT>>(loc)},
where \tcode{loc} is \tcode{str.getloc()}.

\pnum
The details of this operation occur in three stages:

\begin{itemize}
\item
Stage 1:
Determine a conversion specifier.
\item
Stage 2:
Extract characters from \tcode{in} and
determine a corresponding \tcode{char} value for
the format expected by the conversion specification determined in stage 1.
\item
Stage 3:
Store results.
\end{itemize}

\pnum
The details of the stages are presented below.

\begin{description}
\stage{1}
The function initializes local variables via
\begin{codeblock}
fmtflags flags = str.flags();
fmtflags basefield = (flags & ios_base::basefield);
fmtflags uppercase = (flags & ios_base::uppercase);
fmtflags boolalpha = (flags & ios_base::boolalpha);
\end{codeblock}

For conversion to an integral type,
the function determines the integral conversion specifier
as indicated in \tref{facet.num.get.int}.
The table is ordered.
That is, the first line whose condition is true applies.

\begin{floattable}{Integer conversions}{facet.num.get.int}
{lc}
\topline
\lhdr{State}                    &   \rhdr{\tcode{stdio} equivalent} \\ \capsep
\tcode{basefield == oct}        &   \tcode{\%o}                 \\ \rowsep
\tcode{basefield == hex}        &   \tcode{\%X}                 \\ \rowsep
\tcode{basefield == 0}          &   \tcode{\%i}                 \\ \capsep
\tcode{signed} integral type    &   \tcode{\%d}                 \\ \rowsep
\tcode{unsigned} integral type  &   \tcode{\%u}                 \\
\end{floattable}

For conversions to a floating-point type the specifier is \tcode{\%g}.

For conversions to \tcode{void*} the specifier is \tcode{\%p}.

A length modifier is added to the conversion specification, if needed,
as indicated in \tref{facet.num.get.length}.

\begin{floattable}{Length modifier}{facet.num.get.length}
{lc}
\topline
\lhdr{Type}                 &   \rhdr{Length modifier} \\ \capsep
\tcode{short}               &   \tcode{h}       \\ \rowsep
\tcode{unsigned short}      &   \tcode{h}       \\ \rowsep
\tcode{long}                &   \tcode{l}       \\ \rowsep
\tcode{unsigned long}       &   \tcode{l}       \\ \rowsep
\tcode{long long}           &   \tcode{ll}      \\ \rowsep
\tcode{unsigned long long}  &   \tcode{ll}      \\ \rowsep
\tcode{double}              &   \tcode{l}       \\ \rowsep
\tcode{long double}         &   \tcode{L}       \\
\end{floattable}

\stage{2}
If \tcode{in == end} then stage 2 terminates.
Otherwise a \tcode{charT} is taken from \tcode{in} and
local variables are initialized as if by
\begin{codeblock}
char_type ct = *in;
char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
if (ct == use_facet<numpunct<charT>>(loc).decimal_point())
  c = '.';
bool discard =
  ct == use_facet<numpunct<charT>>(loc).thousands_sep()
  && use_facet<numpunct<charT>>(loc).grouping().length() != 0;
\end{codeblock}
where the values \tcode{src} and \tcode{atoms} are defined as if by:
\begin{codeblock}
static const char src[] = "0123456789abcdefpxABCDEFPX+-";
char_type atoms[sizeof(src)];
use_facet<ctype<charT>>(loc).widen(src, src + sizeof(src), atoms);
\end{codeblock}
for this value of \tcode{loc}.

If \tcode{discard} is \tcode{true},
then if \tcode{'.'} has not yet been accumulated,
then the position of the character is remembered,
but the character is otherwise ignored.
Otherwise, if \tcode{'.'} has already been accumulated,
the character is discarded and Stage 2 terminates.
If it is not discarded,
then a check is made to determine
if \tcode{c} is allowed as the next character of
an input field of the conversion specifier returned by Stage 1.
If so, it is accumulated.

If the character is either discarded or accumulated
then \tcode{in} is advanced by \tcode{++in}
and processing returns to the beginning of stage 2.

\begin{example}
Given an input sequence of \tcode{"0x1a.bp+07p"},
\begin{itemize}
\item
if the conversion specifier returned by Stage 1 is \tcode{\%d},
\tcode{"0"} is accumulated;
\item
if the conversion specifier returned by Stage 1 is \tcode{\%i},
\tcode{"0x1a"} are accumulated;
\item
if the conversion specifier returned by Stage 1 is \tcode{\%g},
\tcode{"0x1a.bp+07"} are accumulated.
\end{itemize}
In all cases, the remainder is left in the input.
\end{example}

\stage{3}
The sequence of \tcode{char}{s} accumulated in stage 2 (the field)
is converted to a numeric value by the rules of one of the functions
declared in the header \libheaderref{cstdlib}:

\begin{itemize}
\item
For a signed integer value, the function \tcode{strtoll}.
\item
For an unsigned integer value, the function \tcode{strtoull}.
\item
For a \tcode{float} value, the function \tcode{strtof}.
\item
For a \tcode{double} value, the function \tcode{strtod}.
\item
For a \tcode{long double} value, the function \tcode{strtold}.
\end{itemize}

The numeric value to be stored can be one of:
\begin{itemize}
\item
zero, if the conversion function does not convert the entire field.
\item
the most positive (or negative) representable value,
if the field to be converted to a signed integer type represents a value
too large positive (or negative) to be represented in \tcode{val}.
\item
the most positive representable value,
if the field to be converted to an unsigned integer type represents a value
that cannot be represented in \tcode{val}.
\item
the converted value, otherwise.
\end{itemize}

The resultant numeric value is stored in \tcode{val}.
If the conversion function does not convert the entire field, or
if the field represents a value outside the range of representable values,
\tcode{ios_base::failbit} is assigned to \tcode{err}.

\end{description}

\pnum
Digit grouping is checked.
That is, the positions of discarded
separators are examined for consistency with
\tcode{use_facet<numpunct<charT>>(loc).grouping()}.
If they are not consistent
then \tcode{ios_base::failbit} is assigned to \tcode{err}.

\pnum
In any case,
if stage 2 processing was terminated by the test for \tcode{in == end}
then \tcode{err |= ios_base::eofbit} is performed.
\end{itemdescr}

\indexlibrarymember{do_get}{num_get}%
\begin{itemdecl}
iter_type do_get(iter_type in, iter_type end, ios_base& str,
                 ios_base::iostate& err, bool& val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{(str.flags() \& ios_base::boolalpha) == 0}
then input proceeds as it would for a \tcode{long}
except that if a value is being stored into \tcode{val},
the value is determined according to the following:
If the value to be stored is 0 then \tcode{false} is stored.
If the value is \tcode{1} then \tcode{true} is stored.
Otherwise \tcode{true} is stored and
\tcode{ios_base::failbit} is assigned to \tcode{err}.

\pnum
Otherwise target sequences are determined ``as if'' by
calling the members \tcode{falsename()} and \tcode{truename()} of
the facet obtained by \tcode{use_facet<numpunct<charT>>(str.getloc())}.
Successive characters in the range \range{in}{end} (see~\ref{sequence.reqmts})
are obtained and matched against
corresponding positions in the target sequences
only as necessary to identify a unique match.
The input iterator \tcode{in} is compared to \tcode{end}
only when necessary to obtain a character.
If a target sequence is uniquely matched,
\tcode{val} is set to the corresponding value.
Otherwise \tcode{false} is stored and
\tcode{ios_base::failbit} is assigned to \tcode{err}.

\pnum
The \tcode{in} iterator is always left pointing one position beyond
the last character successfully matched.
If \tcode{val} is set, then \tcode{err} is set to \tcode{str.goodbit};
or to \tcode{str.eofbit} if,
when seeking another character to match,
it is found that \tcode{(in == end)}.
If \tcode{val} is not set, then \tcode{err} is set to \tcode{str.failbit};
or to \tcode{(str.failbit | str.eofbit)}
if the reason for the failure was that \tcode{(in == end)}.
\begin{example}
For targets \tcode{true}: \tcode{"a"} and \tcode{false}: \tcode{"abb"},
the input sequence \tcode{"a"} yields
\tcode{val == true} and \tcode{err == str.eofbit};
the input sequence \tcode{"abc"} yields
\tcode{err = str.failbit}, with \tcode{in} ending at the \tcode{'c'} element.
For targets \tcode{true}: \tcode{"1"} and \tcode{false}: \tcode{"0"},
the input sequence \tcode{"1"} yields
\tcode{val == true} and \tcode{err == str.goodbit}.
For empty targets \tcode{("")},
any input sequence yields \tcode{err == str.failbit}.
\end{example}

\pnum
\returns
\tcode{in}.
\end{itemdescr}

\rSec4[locale.nm.put]{Class template \tcode{num_put}}

\rSec5[locale.nm.put.general]{General}

\indexlibraryglobal{num_put}%
\begin{codeblock}
namespace std {
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
  class num_put : public locale::facet {
  public:
    using @\libmember{char_type}{num_put}@ = charT;
    using @\libmember{iter_type}{num_put}@ = OutputIterator;

    explicit num_put(size_t refs = 0);

    iter_type put(iter_type s, ios_base& f, char_type fill, bool v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, long v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, long long v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long long v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, double v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, long double v) const;
    iter_type put(iter_type s, ios_base& f, char_type fill, const void* v) const;

    static locale::id @\libmember{id}{num_put}@;

  protected:
    ~num_put();
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, bool v) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, long v) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, long long v) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long long) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, double v) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, long double v) const;
    virtual iter_type do_put(iter_type, ios_base&, char_type fill, const void* v) const;
  };
}
\end{codeblock}

\pnum
The facet
\tcode{num_put}
is used to format numeric values to a character sequence such as an ostream.

\rSec5[facet.num.put.members]{Members}

\indexlibrarymember{num_put}{put}%
\begin{itemdecl}
iter_type put(iter_type out, ios_base& str, char_type fill, bool val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, const void* val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_put(out, str, fill, val)}.
\end{itemdescr}

\rSec5[facet.num.put.virtuals]{Virtual functions}

\indexlibrarymember{num_put}{do_put}%
\begin{itemdecl}
iter_type do_put(iter_type out, ios_base& str, char_type fill, long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, long long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, long double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, const void* val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Writes characters to the sequence \tcode{out},
formatting \tcode{val} as desired.
In the following description, \tcode{loc} names a local variable initialized as
\begin{codeblock}
locale loc = str.getloc();
\end{codeblock}

\pnum
The details of this operation occur in several stages:

\begin{itemize}
\item
Stage 1:
Determine a printf conversion specifier \tcode{spec} and
determine the characters
that would be printed by \tcode{printf}\iref{c.files}
given this conversion specifier for
\begin{codeblock}
printf(spec, val)
\end{codeblock}
assuming that the current locale is the \tcode{"C"} locale.
\item
Stage 2:
Adjust the representation by converting
each \tcode{char} determined by stage 1 to a \tcode{charT}
using a conversion and
values returned by members of \tcode{use_facet<numpunct<charT>>(loc)}.
\item
Stage 3:
Determine where padding is required.
\item
Stage 4:
Insert the sequence into the \tcode{out}.
\end{itemize}

\pnum
Detailed descriptions of each stage follow.

\pnum
\returns
\tcode{out}.

\pnum
\begin{description}
\stage{1}
The first action of stage 1 is to determine a conversion specifier.
The tables that describe this determination use the following local variables

\begin{codeblock}
fmtflags flags = str.flags();
fmtflags basefield =  (flags & (ios_base::basefield));
fmtflags uppercase =  (flags & (ios_base::uppercase));
fmtflags floatfield = (flags & (ios_base::floatfield));
fmtflags showpos =    (flags & (ios_base::showpos));
fmtflags showbase =   (flags & (ios_base::showbase));
fmtflags showpoint =  (flags & (ios_base::showpoint));
\end{codeblock}

All tables used in describing stage 1 are ordered.
That is, the first line whose condition is true applies.
A line without a condition is the default behavior
when none of the earlier lines apply.

For conversion from an integral type other than a character type,
the function determines the integral conversion specifier
as indicated in \tref{facet.num.put.int}.

\begin{floattable}{Integer conversions}{facet.num.put.int}
{lc}
\topline
\lhdr{State}                        &  \rhdr{\tcode{stdio} equivalent} \\ \capsep
\tcode{basefield == ios_base::oct}                      &   \tcode{\%o} \\ \rowsep
\tcode{(basefield == ios_base::hex) \&\& !uppercase}    &   \tcode{\%x} \\ \rowsep
\tcode{(basefield == ios_base::hex)}                    &   \tcode{\%X} \\ \rowsep
for a \tcode{signed} integral type                     &   \tcode{\%d} \\ \rowsep
for an \tcode{unsigned} integral type                  &   \tcode{\%u} \\
\end{floattable}

For conversion from a floating-point type,
the function determines the floating-point conversion specifier
as indicated in \tref{facet.num.put.fp}.

\begin{floattable}{Floating-point conversions}{facet.num.put.fp}
{lc}
\topline
\lhdr{State}            & \rhdr{\tcode{stdio} equivalent}  \\ \capsep
\tcode{floatfield == ios_base::fixed \&\& !uppercase}       &   \tcode{\%f} \\ \rowsep
\tcode{floatfield == ios_base::fixed}                       &   \tcode{\%F} \\ \rowsep
\tcode{floatfield == ios_base::scientific \&\& !uppercase}  &   \tcode{\%e} \\ \rowsep
\tcode{floatfield == ios_base::scientific}                  &   \tcode{\%E} \\ \rowsep
\tcode{floatfield == (ios_base::fixed | ios_base::scientific) \&\& !uppercase} & \tcode{\%a} \\ \rowsep
\tcode{floatfield == (ios_base::fixed | ios_base::scientific)} & \tcode{\%A} \\ \rowsep
\tcode{!uppercase}                                          &   \tcode{\%g} \\ \rowsep
\textit{otherwise}                                          &   \tcode{\%G} \\
\end{floattable}

For conversions from an integral or floating-point type
a length modifier is added to the conversion specifier
as indicated in \tref{facet.num.put.length}.

\begin{floattable}{Length modifier}{facet.num.put.length}
{lc}
\topline
\lhdr{Type}                 &   \rhdr{Length modifier} \\ \capsep
\tcode{long}                &   \tcode{l}       \\ \rowsep
\tcode{long long}           &   \tcode{ll}      \\ \rowsep
\tcode{unsigned long}       &   \tcode{l}       \\ \rowsep
\tcode{unsigned long long}  &   \tcode{ll}      \\ \rowsep
\tcode{long double}         &   \tcode{L}       \\ \rowsep
\textit{otherwise}          &   \textit{none}   \\
\end{floattable}

The conversion specifier has the following optional additional qualifiers
prepended as indicated in \tref{facet.num.put.conv}.

\begin{floattable}{Numeric conversions}{facet.num.put.conv}
{llc}
\topline
\lhdr{Type(s)}                  &   \chdr{State}       &   \rhdr{\tcode{stdio} equivalent} \\ \capsep
an integral type                &   \tcode{showpos}    &   \tcode{+}                   \\
                                &   \tcode{showbase}   &   \tcode{\#}                  \\ \rowsep
a floating-point type           &   \tcode{showpos}    &   \tcode{+}                   \\
                                &   \tcode{showpoint}  &   \tcode{\#}                  \\
\end{floattable}

For conversion from a floating-point type,
if \tcode{floatfield != (ios_base::fixed | ios_base::\brk{}scientific)},
\tcode{str.precision()} is specified as precision
in the conversion specification.
Otherwise, no precision is specified.

For conversion from \tcode{void*} the specifier is \tcode{\%p}.

The representations at the end of stage 1 consists of the \tcode{char}'s
that would be printed by a call of \tcode{printf(s, val)}
where \tcode{s} is the conversion specifier determined above.

\stage{2}
Any character \tcode{c} other than a decimal point(.) is converted to
a \tcode{charT} via
\begin{codeblock}
use_facet<ctype<charT>>(loc).widen(c)
\end{codeblock}

A local variable \tcode{punct} is initialized via
\begin{codeblock}
const numpunct<charT>& punct = use_facet<numpunct<charT>>(loc);
\end{codeblock}

For arithmetic types,
\tcode{punct.thousands_sep()} characters are inserted into
the sequence as determined by the value returned by \tcode{punct.do_grouping()}
using the method described in~\ref{facet.numpunct.virtuals}.

Decimal point characters(.) are replaced by \tcode{punct.decimal_point()}.

\stage{3}
A local variable is initialized as
\begin{codeblock}
fmtflags adjustfield = (flags & (ios_base::adjustfield));
\end{codeblock}

The location of any padding
\begin{footnote}
The conversion specification \tcode{\#o} generates a leading \tcode{0}
which is \textit{not} a padding character.
\end{footnote}
is determined according to \tref{facet.num.put.fill}.

\begin{floattable}{Fill padding}{facet.num.put.fill}
{p{3in}l}
\topline
\lhdr{State}                            &   \rhdr{Location}                 \\ \capsep
\tcode{adjustfield == ios_base::left}   &   pad after                       \\ \rowsep
\tcode{adjustfield == ios_base::right}  &   pad before                      \\ \rowsep
\tcode{adjustfield == internal} and a sign occurs in the representation
                                        &   pad after the sign              \\ \rowsep
\tcode{adjustfield == internal} and representation after stage 1
began with 0x or 0X                     &   pad after x or X                \\ \rowsep
\textit{otherwise}                      &   pad before                      \\
\end{floattable}

If \tcode{str.width()} is nonzero and the number of \tcode{charT}'s
in the sequence after stage 2 is less than \tcode{str.\brk{}width()},
then enough \tcode{fill} characters are added to the sequence
at the position indicated for padding
to bring the length of the sequence to \tcode{str.width()}.

\tcode{str.width(0)} is called.

\stage{4}
The sequence of \tcode{charT}'s at the end of stage 3 are output via
\begin{codeblock}
*out++ = c
\end{codeblock}
\end{description}
\end{itemdescr}

\indexlibrarymember{do_put}{num_put}%
\begin{itemdecl}
iter_type do_put(iter_type out, ios_base& str, char_type fill, bool val) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{(str.flags() \& ios_base::boolalpha) == 0}
returns \tcode{do_put(out, str, fill,\\(int)val)},
otherwise obtains a string \tcode{s} as if by
\begin{codeblock}
string_type s =
  val ? use_facet<numpunct<charT>>(loc).truename()
      : use_facet<numpunct<charT>>(loc).falsename();
\end{codeblock}
and then inserts each character \tcode{c} of \tcode{s} into \tcode{out}
via \tcode{*out++ = c}
and returns \tcode{out}.
\end{itemdescr}

\rSec3[facet.numpunct]{The numeric punctuation facet}

\rSec4[locale.numpunct]{Class template \tcode{numpunct}}

\rSec5[locale.numpunct.general]{General}

\indexlibraryglobal{numpunct}%
\begin{codeblock}
namespace std {
  template<class charT>
  class numpunct : public locale::facet {
  public:
    using @\libmember{char_type}{numpunct}@   = charT;
    using @\libmember{string_type}{numpunct}@ = basic_string<charT>;

    explicit numpunct(size_t refs = 0);

    char_type   decimal_point() const;
    char_type   thousands_sep() const;
    string      grouping()      const;
    string_type truename()      const;
    string_type falsename()     const;

    static locale::id @\libmember{id}{numpunct}@;

  protected:
    ~numpunct();                                                // virtual
    virtual char_type   do_decimal_point() const;
    virtual char_type   do_thousands_sep() const;
    virtual string      do_grouping()      const;
    virtual string_type do_truename()      const;               // for \tcode{bool}
    virtual string_type do_falsename()     const;               // for \tcode{bool}
  };
}
\end{codeblock}

\pnum
\tcode{numpunct<>} specifies numeric punctuation.
The specializations
required in \tref{locale.category.facets}\iref{locale.category},
namely \tcode{numpunct<\brk{}wchar_t>} and \tcode{numpunct<char>},
provide classic \tcode{"C"} numeric formats,
i.e., they contain information
equivalent to that contained in the \tcode{"C"} locale or
their wide character counterparts as if obtained by a call to \tcode{widen}.

% FIXME: For now, keep the locale grammar productions out of the index;
% they are conceptually unrelated to the main C++ grammar.
% Consider renaming these en masse (to locale-* ?) to avoid this problem.
\newcommand{\locnontermdef}[1]{{\BnfNontermshape#1\itcorr}\textnormal{:}}
\newcommand{\locgrammarterm}[1]{\gterm{#1}}

\pnum
The syntax for number formats is as follows,
where \locgrammarterm{digit} represents the radix set
specified by the \tcode{fmtflags} argument value, and
\locgrammarterm{thousands-sep} and \locgrammarterm{decimal-point}
are the results of corresponding \tcode{numpunct<charT>} members.
Integer values have the format:
\begin{ncbnf}
\locnontermdef{intval}\br
    \opt{sign} units
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{sign}\br
    \terminal{+}\br
    \terminal{-}
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{units}\br
    digits\br
    digits thousands-sep units
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{digits}\br
    digit \opt{digits}
\end{ncbnf}
and floating-point values have:
\begin{ncbnf}
\locnontermdef{floatval}\br
    \opt{sign} units \opt{fractional} \opt{exponent}\br
    \opt{sign} decimal-point digits \opt{exponent}
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{fractional}\br
    decimal-point \opt{digits}
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{exponent}\br
    e \opt{sign} digits
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{e}\br
    \terminal{e}\br
    \terminal{E}
\end{ncbnf}
where the number of digits between \locgrammarterm{thousands-sep}{s}
is as specified by \tcode{do_grouping()}.
For parsing,
if the \locgrammarterm{digits} portion contains no thousands-separators,
no grouping constraint is applied.

\rSec5[facet.numpunct.members]{Members}

\indexlibrarymember{numpunct}{decimal_point}%
\begin{itemdecl}
char_type decimal_point() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_decimal_point()}.
\end{itemdescr}

\indexlibrarymember{numpunct}{thousands_sep}%
\begin{itemdecl}
char_type thousands_sep() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_thousands_sep()}.
\end{itemdescr}

\indexlibrarymember{numpunct}{grouping}%
\begin{itemdecl}
string grouping() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_grouping()}.
\end{itemdescr}

\indexlibrarymember{numpunct}{truename}%
\indexlibrarymember{numpunct}{falsename}%
\begin{itemdecl}
string_type truename()  const;
string_type falsename() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_truename()}
or
\tcode{do_falsename()},
respectively.
\end{itemdescr}

\rSec5[facet.numpunct.virtuals]{Virtual functions}

\indexlibrarymember{numpunct}{do_decimal_point}%
\begin{itemdecl}
char_type do_decimal_point() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A character for use as the decimal radix separator.
The required specializations return \tcode{'.'} or \tcode{L'.'}.
\end{itemdescr}

\indexlibrarymember{numpunct}{do_thousands_sep}%
\begin{itemdecl}
char_type do_thousands_sep() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A character for use as the digit group separator.
The required specializations return \tcode{','} or \tcode{L','}.
\end{itemdescr}

\indexlibrarymember{numpunct}{do_grouping}%
\begin{itemdecl}
string do_grouping() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{string} \tcode{vec} used as a vector of integer values,
in which each element \tcode{vec[i]} represents the number of digits
\begin{footnote}
Thus,
the string \tcode{"\textbackslash003"} specifies groups of 3 digits each, and
\tcode{"3"} probably indicates groups of 51 (!) digits each,
because 51 is the ASCII value of \tcode{"3"}.
\end{footnote}
in the group at position \tcode{i},
starting with position 0 as the rightmost group.
If \tcode{vec.size() <= i},
the number is the same as group \tcode{(i - 1)};
if \tcode{(i < 0 || vec[i] <= 0 || vec[i] == CHAR_MAX)},
the size of the digit group is unlimited.

\pnum
The required specializations return the empty string, indicating no grouping.
\end{itemdescr}

\indexlibrarymember{numpunct}{do_truename}%
\indexlibrarymember{numpunct}{do_falsename}%
\begin{itemdecl}
string_type do_truename()  const;
string_type do_falsename() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A string representing the name of
the boolean value \tcode{true} or \tcode{false}, respectively.

\pnum
In the base class implementation
these names are \tcode{"true"} and \tcode{"false"},
or \tcode{L"true"} and \tcode{L"false"}.
\end{itemdescr}

\rSec4[locale.numpunct.byname]{Class template \tcode{numpunct_byname}}

\indexlibraryglobal{numpunct_byname}%
\begin{codeblock}
namespace std {
  template<class charT>
  class numpunct_byname : public numpunct<charT> {
  // this class is specialized for \tcode{char} and \keyword{wchar_t}.
  public:
    using @\libmember{char_type}{numpunct_byname}@   = charT;
    using @\libmember{string_type}{numpunct_byname}@ = basic_string<charT>;

    explicit numpunct_byname(const char*, size_t refs = 0);
    explicit numpunct_byname(const string&, size_t refs = 0);

  protected:
    ~numpunct_byname();
  };
}
\end{codeblock}

\rSec3[category.collate]{The collate category}

\rSec4[locale.collate]{Class template \tcode{collate}}

\rSec5[locale.collate.general]{General}

\indexlibraryglobal{collate}%
\begin{codeblock}
namespace std {
  template<class charT>
  class collate : public locale::facet {
  public:
    using @\libmember{char_type}{collate}@   = charT;
    using @\libmember{string_type}{collate}@ = basic_string<charT>;

    explicit collate(size_t refs = 0);

    int compare(const charT* low1, const charT* high1,
                const charT* low2, const charT* high2) const;
    string_type transform(const charT* low, const charT* high) const;
    long hash(const charT* low, const charT* high) const;

    static locale::id @\libmember{id}{collate}@;

  protected:
    ~collate();
    virtual int do_compare(const charT* low1, const charT* high1,
                           const charT* low2, const charT* high2) const;
    virtual string_type do_transform(const charT* low, const charT* high) const;
    virtual long do_hash (const charT* low, const charT* high) const;
  };
}
\end{codeblock}

\pnum
The class \tcode{collate<charT>} provides features
for use in the collation (comparison) and hashing of strings.
A locale member function template, \tcode{operator()},
uses the collate facet to allow a locale to act directly as
the predicate argument for standard algorithms\iref{algorithms} and
containers operating on strings.
The specializations
required in \tref{locale.category.facets}\iref{locale.category},
namely \tcode{collate<char>} and \tcode{collate<wchar_t>},
apply lexicographical ordering\iref{alg.lex.comparison}.

\pnum
Each function compares a string of characters \tcode{*p}
in the range \range{low}{high}.

\rSec5[locale.collate.members]{Members}

\indexlibrarymember{collate}{compare}%
\begin{itemdecl}
int compare(const charT* low1, const charT* high1,
            const charT* low2, const charT* high2) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_compare(low1, high1, low2, high2)}.
\end{itemdescr}

\indexlibrarymember{collate}{transform}%
\begin{itemdecl}
string_type transform(const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_transform(low, high)}.
\end{itemdescr}

\indexlibrarymember{collate}{hash}%
\begin{itemdecl}
long hash(const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_hash(low, high)}.
\end{itemdescr}

\rSec5[locale.collate.virtuals]{Virtual functions}

\indexlibrarymember{collate}{do_compare}%
\begin{itemdecl}
int do_compare(const charT* low1, const charT* high1,
               const charT* low2, const charT* high2) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{1} if the first string is greater than the second,
\tcode{-1} if less,
zero otherwise.
The specializations
required in \tref{locale.category.facets}\iref{locale.category},
namely \tcode{collate<char>} and \tcode{collate<wchar_t>},
implement a lexicographical comparison\iref{alg.lex.comparison}.
\end{itemdescr}

\indexlibrarymember{collate}{do_transform}%
\begin{itemdecl}
string_type do_transform(const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{basic_string<charT>} value that,
compared lexicographically with
the result of calling \tcode{transform()} on another string,
yields the same result as calling \tcode{do_compare()} on the same two strings.
\begin{footnote}
This function is useful when one string is being compared to many other strings.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{collate}{do_hash}%
\begin{itemdecl}
long do_hash(const charT* low, const charT* high) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An integer value equal to the result of calling \tcode{hash()}
on any other string for which \tcode{do_compare()} returns 0 (equal)
when passed the two strings.

\pnum
\recommended
The probability that the result equals that for another string
which does not compare equal should be very small,
approaching \tcode{(1.0/numeric_limits<unsigned long>::max())}.
\end{itemdescr}

\rSec4[locale.collate.byname]{Class template \tcode{collate_byname}}

\indexlibraryglobal{collate_byname}%
\begin{codeblock}
namespace std {
  template<class charT>
    class collate_byname : public collate<charT> {
    public:
      using @\libmember{string_type}{collate_byname}@ = basic_string<charT>;

      explicit collate_byname(const char*, size_t refs = 0);
      explicit collate_byname(const string&, size_t refs = 0);

    protected:
      ~collate_byname();
    };
}
\end{codeblock}

\rSec3[category.time]{The time category}

\rSec4[category.time.general]{General}

\pnum
Templates
\tcode{time_get<charT, InputIterator>} and
\tcode{time_put<charT, OutputIterator>}
provide date and time formatting and parsing.
All specifications of member functions for \tcode{time_put} and \tcode{time_get}
in the subclauses of~\ref{category.time} only apply to the
specializations required in Tables~\ref{tab:locale.category.facets}
and~\ref{tab:locale.spec}\iref{locale.category}.
Their members use their
\tcode{ios_base\&}, \tcode{ios_base::iostate\&}, and \tcode{fill} arguments
as described in~\ref{locale.categories},
and the \tcode{ctype<>} facet,
to determine formatting details.

\rSec4[locale.time.get]{Class template \tcode{time_get}}

\rSec5[locale.time.get.general]{General}

\indexlibraryglobal{time_base}%
\indexlibraryglobal{time_get}%
\begin{codeblock}
namespace std {
  class time_base {
  public:
    enum @\libmember{dateorder}{time_base}@ { @\libmember{no_order}{time_base}@, @\libmember{dmy}{time_base}@, @\libmember{mdy}{time_base}@, @\libmember{ymd}{time_base}@, @\libmember{ydm}{time_base}@ };
  };

  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get : public locale::facet, public time_base {
    public:
      using @\libmember{char_type}{time_get}@ = charT;
      using @\libmember{iter_type}{time_get}@ = InputIterator;

      explicit time_get(size_t refs = 0);

      dateorder date_order() const { return do_date_order(); }
      iter_type get_time(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get_date(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get_weekday(iter_type s, iter_type end, ios_base& f,
                            ios_base::iostate& err, tm* t) const;
      iter_type get_monthname(iter_type s, iter_type end, ios_base& f,
                              ios_base::iostate& err, tm* t) const;
      iter_type get_year(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get(iter_type s, iter_type end, ios_base& f,
                    ios_base::iostate& err, tm* t, char format, char modifier = 0) const;
      iter_type get(iter_type s, iter_type end, ios_base& f,
                    ios_base::iostate& err, tm* t, const char_type* fmt,
                    const char_type* fmtend) const;

      static locale::id @\libmember{id}{time_get}@;

    protected:
      ~time_get();
      virtual dateorder do_date_order() const;
      virtual iter_type do_get_time(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_date(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, iter_type end, ios_base&,
                                       ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&,
                                         ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_year(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get(iter_type s, iter_type end, ios_base& f,
                               ios_base::iostate& err, tm* t, char format, char modifier) const;
    };
}
\end{codeblock}

\pnum
\tcode{time_get} is used to parse a character sequence,
extracting components of a time or date into a \tcode{tm} object.
Each \tcode{get} member parses a format as produced by a corresponding format specifier to
\tcode{time_put<>::put}.
If the sequence being parsed matches the correct format, the corresponding
members of the
\tcode{tm}
argument are set to the values used to produce the sequence; otherwise
either an error is reported or unspecified values are assigned.
\begin{footnote}
In
other words, user confirmation is required for reliable parsing of
user-entered dates and times, but machine-generated formats can be
parsed reliably.
This allows parsers to be aggressive about
interpreting user variations on standard formats.
\end{footnote}

\pnum
If the end iterator is reached during parsing by any of the
\tcode{get()}
member functions, the member sets
\tcode{ios_base::eof\-bit}
in \tcode{err}.

\rSec5[locale.time.get.members]{Members}

\indexlibrarymember{time_get}{date_order}%
\begin{itemdecl}
dateorder date_order() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_date_order()}.
\end{itemdescr}

\indexlibrarymember{time_get}{get_time}%
\begin{itemdecl}
iter_type get_time(iter_type s, iter_type end, ios_base& str,
                   ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get_time(s, end, str, err, t)}.
\end{itemdescr}

\indexlibrarymember{time_get}{get_date}%
\begin{itemdecl}
iter_type get_date(iter_type s, iter_type end, ios_base& str,
                   ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get_date(s, end, str, err, t)}.
\end{itemdescr}

\indexlibrarymember{time_get}{get_weekday}%
\indexlibrarymember{time_get}{get_monthname}%
\begin{itemdecl}
iter_type get_weekday(iter_type s, iter_type end, ios_base& str,
                      ios_base::iostate& err, tm* t) const;
iter_type get_monthname(iter_type s, iter_type end, ios_base& str,
                        ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get_weekday(s, end, str, err, t)}
or
\tcode{do_get_monthname(s, end, str, err, t)}.
\end{itemdescr}

\indexlibrarymember{time_get}{get_year}%
\begin{itemdecl}
iter_type get_year(iter_type s, iter_type end, ios_base& str,
                   ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get_year(s, end, str, err, t)}.
\end{itemdescr}

\indexlibrarymember{get}{time_get}%
\begin{itemdecl}
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err,
              tm* t, char format, char modifier = 0) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get(s, end, f, err, t, format, modifier)}.
\end{itemdescr}

\indexlibrarymember{get}{time_get}%
\begin{itemdecl}
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err,
              tm* t, const char_type* fmt, const char_type* fmtend) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\range{fmt}{fmtend} is a valid range.

\pnum
\effects
The function starts by evaluating \tcode{err = ios_base::goodbit}.
It then enters a loop,
reading zero or more characters from \tcode{s} at each iteration.
Unless otherwise specified below,
the loop terminates when the first of the following conditions holds:

\begin{itemize}
\item
The expression \tcode{fmt == fmtend} evaluates to \tcode{true}.
\item
The expression \tcode{err == ios_base::goodbit} evaluates to \tcode{false}.
\item
The expression \tcode{s == end} evaluates to \tcode{true},
in which case
the function evaluates \tcode{err = ios_base::eofbit | ios_base::failbit}.
\item
The next element of \tcode{fmt} is equal to \tcode{'\%'},
optionally followed by a modifier character,
followed by a conversion specifier character, \tcode{format},
together forming a conversion specification
valid for the POSIX function \tcode{strptime}.
If the number of elements in the range \range{fmt}{fmtend}
is not sufficient to unambiguously determine
whether the conversion specification is complete and valid,
the function evaluates \tcode{err = ios_base::failbit}.
Otherwise,
the function evaluates \tcode{s = do_get(s, end, f, err, t, format, modifier)},
where the value of \tcode{modifier} is \tcode{'\textbackslash0'}
when the optional modifier is absent from the conversion specification.
If \tcode{err == ios_base::goodbit} holds
after the evaluation of the expression,
the function increments \tcode{fmt}
to point just past the end of the conversion specification and
continues looping.

\item
The expression \tcode{isspace(*fmt, f.getloc())} evaluates to \tcode{true},
in which case the function first increments \tcode{fmt} until
\tcode{fmt == fmtend || !isspace(*fmt, f.getloc())} evaluates to \tcode{true},
then advances \tcode{s}
until \tcode{s == end || !isspace(*s, f.getloc())} is \tcode{true}, and
finally resumes looping.

\item
The next character read from \tcode{s}
matches the element pointed to by \tcode{fmt} in a case-insensitive comparison,
in which case the function evaluates \tcode{++fmt, ++s} and continues looping.
Otherwise, the function evaluates \tcode{err = ios_base::failbit}.
\end{itemize}

\pnum
\begin{note}
The function uses the \tcode{ctype<charT>} facet
installed in \tcode{f}'s locale
to determine valid whitespace characters.
It is unspecified
by what means the function performs case-insensitive comparison or
whether multi-character sequences are considered while doing so.
\end{note}

\pnum
\returns
\tcode{s}.
\end{itemdescr}

\rSec5[locale.time.get.virtuals]{Virtual functions}

\indexlibrarymember{time_get}{do_date_order}%
\begin{itemdecl}
dateorder do_date_order() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An enumeration value indicating the preferred order of components
for those date formats that are composed of day, month, and year.
\begin{footnote}
This function is intended as a convenience only, for common formats, and
can return \tcode{no_order} in valid locales.
\end{footnote}
Returns \tcode{no_order} if the date format specified by \tcode{'x'}
contains other variable components (e.g., Julian day, week number, week day).
\end{itemdescr}

\indexlibrarymember{time_get}{do_get_time}%
\begin{itemdecl}
iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
                      ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters starting at \tcode{s}
until it has extracted those \tcode{tm} members, and
remaining format characters,
used by \tcode{time_put<>::put}
to produce the format specified by \tcode{"\%H:\%M:\%S"},
or until it encounters an error or end of sequence.

\pnum
\returns
An iterator pointing immediately beyond
the last character recognized as possibly part of a valid time.
\end{itemdescr}

\indexlibrarymember{time_get}{do_get_date}%
\begin{itemdecl}
iter_type do_get_date(iter_type s, iter_type end, ios_base& str,
                      ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters starting at \tcode{s}
until it has extracted those \tcode{tm} members and
remaining format characters
used by \tcode{time_put<>::put}
to produce one of the following formats,
or until it encounters an error.
The format depends on the value returned by \tcode{date_order()}
as shown in \tref{locale.time.get.dogetdate}.

\begin{libtab2}{\tcode{do_get_date} effects}{locale.time.get.dogetdate}
{ll}{\tcode{date_order()}}{Format}
\tcode{no_order}  & \tcode{"\%m\%d\%y"} \\
\tcode{dmy}       & \tcode{"\%d\%m\%y"} \\
\tcode{mdy}       & \tcode{"\%m\%d\%y"} \\
\tcode{ymd}       & \tcode{"\%y\%m\%d"} \\
\tcode{ydm}       & \tcode{"\%y\%d\%m"} \\
\end{libtab2}

\pnum
An implementation may also accept additional
\impldef{additional formats for \tcode{time_get::do_get_date}} formats.

\pnum
\returns
An iterator pointing immediately beyond
the last character recognized as possibly part of a valid date.
\end{itemdescr}

\indexlibrarymember{time_get}{do_get_weekday}%
\indexlibrarymember{time_get}{do_get_monthname}%
\begin{itemdecl}
iter_type do_get_weekday(iter_type s, iter_type end, ios_base& str,
                         ios_base::iostate& err, tm* t) const;
iter_type do_get_monthname(iter_type s, iter_type end, ios_base& str,
                           ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters starting at \tcode{s}
until it has extracted the (perhaps abbreviated) name of a weekday or month.
If it finds an abbreviation
that is followed by characters that can match a full name,
it continues reading until it matches the full name or fails.
It sets the appropriate \tcode{tm} member accordingly.

\pnum
\returns
An iterator pointing immediately beyond the last character recognized
as part of a valid name.
\end{itemdescr}

\indexlibrarymember{time_get}{do_get_year}%
\begin{itemdecl}
iter_type do_get_year(iter_type s, iter_type end, ios_base& str,
                      ios_base::iostate& err, tm* t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters starting at \tcode{s}
until it has extracted an unambiguous year identifier.
It is
\impldef{whether \tcode{time_get::do_get_year} accepts two-digit year numbers}
whether two-digit year numbers are accepted,
and (if so) what century they are assumed to lie in.
Sets the \tcode{t->tm_year} member accordingly.

\pnum
\returns
An iterator pointing immediately beyond
the last character recognized as part of a valid year identifier.
\end{itemdescr}

\indexlibrarymember{do_get}{time_get}%
\begin{itemdecl}
iter_type do_get(iter_type s, iter_type end, ios_base& f,
                 ios_base::iostate& err, tm* t, char format, char modifier) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{t} points to an object.

\pnum
\effects
The function starts by evaluating \tcode{err = ios_base::goodbit}.
It then reads characters starting at \tcode{s} until it encounters an error, or
until it has extracted and assigned those \tcode{tm} members, and
any remaining format characters,
corresponding to a conversion specification appropriate for
the POSIX function \tcode{strptime},
formed by concatenating \tcode{'\%'},
the \tcode{modifier} character, when non-NUL, and
the \tcode{format} character.
When the concatenation fails to yield a complete valid directive
the function leaves the object pointed to by \tcode{t} unchanged and
evaluates \tcode{err |= ios_base::failbit}.
When \tcode{s == end} evaluates to \tcode{true} after reading a character
the function evaluates \tcode{err |= ios_base::eofbit}.

\pnum
For complex conversion specifications
such as \tcode{\%c}, \tcode{\%x}, or \tcode{\%X}, or
conversion specifications that involve the optional modifiers \tcode{E} or \tcode{O},
when the function is unable to unambiguously determine
some or all \tcode{tm} members from the input sequence \range{s}{end},
it evaluates \tcode{err |= ios_base::eofbit}.
In such cases the values of those \tcode{tm} members are unspecified
and may be outside their valid range.

\pnum
\returns
An iterator pointing immediately beyond
the last character recognized as possibly part of
a valid input sequence for the given \tcode{format} and \tcode{modifier}.

\pnum
\remarks
It is unspecified whether multiple calls to \tcode{do_get()}
with the address of the same \tcode{tm} object
will update the current contents of the object or simply overwrite its members.
Portable programs should zero out the object before invoking the function.
\end{itemdescr}

\rSec4[locale.time.get.byname]{Class template \tcode{time_get_byname}}

\indexlibraryglobal{time_get_byname}%
\begin{codeblock}
namespace std {
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get_byname : public time_get<charT, InputIterator> {
    public:
      using @\libmember{dateorder}{time_get_byname}@ = time_base::dateorder;
      using @\libmember{iter_type}{time_get_byname}@ = InputIterator;

      explicit time_get_byname(const char*, size_t refs = 0);
      explicit time_get_byname(const string&, size_t refs = 0);

    protected:
      ~time_get_byname();
    };
}
\end{codeblock}

\rSec4[locale.time.put]{Class template \tcode{time_put}}

\rSec5[locale.time.put.general]{General}

\indexlibraryglobal{time_put}%
\begin{codeblock}
namespace std {
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put : public locale::facet {
    public:
      using @\libmember{char_type}{time_put}@ = charT;
      using @\libmember{iter_type}{time_put}@ = OutputIterator;

      explicit time_put(size_t refs = 0);

      // the following is implemented in terms of other member functions.
      iter_type put(iter_type s, ios_base& f, char_type fill, const tm* tmb,
                    const charT* pattern, const charT* pat_end) const;
      iter_type put(iter_type s, ios_base& f, char_type fill,
                    const tm* tmb, char format, char modifier = 0) const;

      static locale::id @\libmember{id}{time_put}@;

    protected:
      ~time_put();
      virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t,
                               char format, char modifier) const;
    };
}
\end{codeblock}

\rSec5[locale.time.put.members]{Members}

\indexlibrarymember{time_put}{put}%
\begin{itemdecl}
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
              const charT* pattern, const charT* pat_end) const;
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
              char format, char modifier = 0) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The first form steps through the sequence
from \tcode{pattern} to \tcode{pat_end},
identifying characters that are part of a format sequence.
Each character that is not part of a format sequence
is written to \tcode{s} immediately, and
each format sequence, as it is identified, results in a call to \tcode{do_put};
thus, format elements and other characters are interleaved in the output
in the order in which they appear in the pattern.
Format sequences are identified by converting each character \tcode{c} to
a \tcode{char} value as if by \tcode{ct.narrow(c, 0)},
where \tcode{ct} is a reference to \tcode{ctype<charT>}
obtained from \tcode{str.getloc()}.
The first character of each sequence is equal to \tcode{'\%'},
followed by an optional modifier character \tcode{mod}
and a format specifier character \tcode{spec}
as defined for the function \tcode{strftime}.
If no modifier character is present, \tcode{mod} is zero.
For each valid format sequence identified,
calls \tcode{do_put(s, str, fill, t, spec, mod)}.

\pnum
The second form calls \tcode{do_put(s, str, fill, t, format, modifier)}.

\pnum
\begin{note}
The \tcode{fill} argument can be used
in the implementation-defined formats or by derivations.
A space character is a reasonable default for this argument.
\end{note}

\pnum
\returns
An iterator pointing immediately after the last character produced.
\end{itemdescr}

\rSec5[locale.time.put.virtuals]{Virtual functions}

\indexlibrarymember{time_put}{do_put}%
\begin{itemdecl}
iter_type do_put(iter_type s, ios_base&, char_type fill, const tm* t,
                 char format, char modifier) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Formats the contents of the parameter \tcode{t}
into characters placed on the output sequence \tcode{s}.
Formatting is controlled by the parameters \tcode{format} and \tcode{modifier},
interpreted identically as the format specifiers
in the string argument to the standard library function
\indexlibraryglobal{strftime}%
\tcode{strftime()},
except that the sequence of characters produced for those specifiers
that are described as depending on the C locale
are instead
\impldef{formatted character sequence generated by \tcode{time_put::do_put}
in C locale}.
\begin{note}
Interpretation of the \tcode{modifier} argument is implementation-defined.
\end{note}

\pnum
\returns
An iterator pointing immediately after the last character produced.
\begin{note}
The \tcode{fill} argument can be used
in the implementation-defined formats or by derivations.
A space character is a reasonable default for this argument.
\end{note}

\pnum
\recommended
Interpretation of the \tcode{modifier} should follow POSIX conventions.
Implementations should refer to other standards such as POSIX
for a specification of the character sequences produced for
those specifiers described as depending on the C locale.
\end{itemdescr}

\rSec4[locale.time.put.byname]{Class template \tcode{time_put_byname}}

\indexlibraryglobal{time_put_byname}%
\begin{codeblock}
namespace std {
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put_byname : public time_put<charT, OutputIterator> {
    public:
      using @\libmember{char_type}{time_put_byname}@ = charT;
      using @\libmember{iter_type}{time_put_byname}@ = OutputIterator;

      explicit time_put_byname(const char*, size_t refs = 0);
      explicit time_put_byname(const string&, size_t refs = 0);

    protected:
      ~time_put_byname();
    };
}
\end{codeblock}

\rSec3[category.monetary]{The monetary category}

\rSec4[category.monetary.general]{General}

\pnum
These templates handle monetary formats.
A template parameter indicates
whether local or international monetary formats are to be used.

\pnum
All specifications of member functions
for \tcode{money_put} and \tcode{money_get}
in the subclauses of~\ref{category.monetary} only apply to
the specializations required in Tables~\ref{tab:locale.category.facets}
and~\ref{tab:locale.spec}\iref{locale.category}.
Their members use their \tcode{ios_base\&}, \tcode{ios_base::io\-state\&},
and \tcode{fill} arguments as described in~\ref{locale.categories}, and
the \tcode{moneypunct<>} and \tcode{ctype<>} facets,
to determine formatting details.

\rSec4[locale.money.get]{Class template \tcode{money_get}}

\rSec5[locale.money.get.general]{General}

\indexlibraryglobal{money_get}%
\begin{codeblock}
namespace std {
  template<class charT, class InputIterator = istreambuf_iterator<charT>>
    class money_get : public locale::facet {
    public:
      using @\libmember{char_type}{money_get}@   = charT;
      using @\libmember{iter_type}{money_get}@   = InputIterator;
      using @\libmember{string_type}{money_get}@ = basic_string<charT>;

      explicit money_get(size_t refs = 0);

      iter_type get(iter_type s, iter_type end, bool intl,
                    ios_base& f, ios_base::iostate& err,
                    long double& units) const;
      iter_type get(iter_type s, iter_type end, bool intl,
                    ios_base& f, ios_base::iostate& err,
                    string_type& digits) const;

      static locale::id @\libmember{id}{money_get}@;

    protected:
      ~money_get();
      virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
                               ios_base::iostate& err, long double& units) const;
      virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
                               ios_base::iostate& err, string_type& digits) const;
    };
}
\end{codeblock}

\rSec5[locale.money.get.members]{Members}

\indexlibrarymember{money_get}{get}%
\begin{itemdecl}
iter_type get(iter_type s, iter_type end, bool intl, ios_base& f,
              ios_base::iostate& err, long double& quant) const;
iter_type get(iter_type s, iter_type end, bool intl, ios_base& f,
              ios_base::iostate& err, string_type& quant) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get(s, end, intl, f, err, quant)}.
\end{itemdescr}

\rSec5[locale.money.get.virtuals]{Virtual functions}

\indexlibrarymember{money_get}{do_get}%
\begin{itemdecl}
iter_type do_get(iter_type s, iter_type end, bool intl, ios_base& str,
                 ios_base::iostate& err, long double& units) const;
iter_type do_get(iter_type s, iter_type end, bool intl, ios_base& str,
                 ios_base::iostate& err, string_type& digits) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Reads characters from \tcode{s} to parse and construct a monetary value
according to the format specified by
a \tcode{moneypunct<charT, Intl>} facet reference \tcode{mp}
and the character mapping specified by
a \tcode{ctype<charT>} facet reference \tcode{ct}
obtained from the locale returned by \tcode{str.getloc()}, and
\tcode{str.flags()}.
If a valid sequence is recognized, does not change \tcode{err};
otherwise, sets \tcode{err} to \tcode{(err | str.failbit)}, or
\tcode{(err | str.failbit | str.eof\-bit)} if no more characters are available,
and does not change \tcode{units} or \tcode{digits}.
Uses the pattern returned by \tcode{mp.neg_format()} to parse all values.
The result is returned as an integral value stored in \tcode{units}
or as a sequence of digits possibly preceded by a minus sign
(as produced by \tcode{ct.widen(c)}
where \tcode{c} is \tcode{'-'} or
in the range from \tcode{'0'} through \tcode{'9'} (inclusive))
stored in \tcode{digits}.
\begin{example}
The sequence \tcode{\$1,056.23} in a common United States locale would yield,
for \tcode{units}, \tcode{105623}, or,
for \tcode{digits}, \tcode{"105623"}.
\end{example}
If \tcode{mp.grouping()} indicates that no thousands separators are permitted,
any such characters are not read, and
parsing is terminated at the point where they first appear.
Otherwise, thousands separators are optional;
if present, they are checked for correct placement only after
all format components have been read.

\pnum
Where \tcode{money_base::space} or \tcode{money_base::none}
appears as the last element in the format pattern,
no whitespace is consumed.
Otherwise, where \tcode{money_base::space} appears in any of
the initial elements of the format pattern,
at least one whitespace character is required.
Where \tcode{money_base::none} appears
in any of the initial elements of the format pattern,
whitespace is allowed but not required.
If \tcode{(str.flags() \& str.showbase)} is \tcode{false},
the currency symbol is optional and
is consumed only if other characters are needed to complete the format;
otherwise, the currency symbol is required.

\pnum
If the first character (if any) in
the string \tcode{pos} returned by \tcode{mp.positive_sign()} or
the string \tcode{neg} returned by \tcode{mp.negative_sign()}
is recognized in the position indicated by \tcode{sign} in the format pattern,
it is consumed and
any remaining characters in the string are required
after all the other format components.
\begin{example}
If \tcode{showbase} is off,
then for a \tcode{neg} value of \tcode{"()"} and
a currency symbol of \tcode{"L"},
in \tcode{"(100 L)"} the \tcode{"L"} is consumed;
but if \tcode{neg} is \tcode{"-"},
the \tcode{"L"} in \tcode{"-100 L"} is not consumed.
\end{example}
If \tcode{pos} or \tcode{neg} is empty,
the sign component is optional, and
if no sign is detected,
the result is given the sign that corresponds to the source of the empty string.
Otherwise,
the character in the indicated position must match
the first character of \tcode{pos} or \tcode{neg},
and the result is given the corresponding sign.
If the first character of \tcode{pos} is equal to
the first character of \tcode{neg},
or if both strings are empty,
the result is given a positive sign.

\pnum
Digits in the numeric monetary component are extracted and
placed in \tcode{digits}, or into a character buffer \tcode{buf1}
for conversion to produce a value for \tcode{units},
in the order in which they appear,
preceded by a minus sign if and only if the result is negative.
The value \tcode{units} is produced as if by
\begin{footnote}
The semantics here are different from \tcode{ct.narrow}.
\end{footnote}
\begin{codeblock}
for (int i = 0; i < n; ++i)
  buf2[i] = src[find(atoms, atoms + sizeof(src), buf1[i]) - atoms];
buf2[n] = 0;
sscanf(buf2, "%Lf", &units);
\end{codeblock}
where \tcode{n} is the number of characters placed in \tcode{buf1},
\tcode{buf2} is a character buffer, and
the values \tcode{src} and \tcode{atoms} are defined as if by
\begin{codeblock}
static const char src[] = "0123456789-";
charT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);
\end{codeblock}

\pnum
\returns
An iterator pointing immediately beyond
the last character recognized as part of a valid monetary quantity.
\end{itemdescr}

\rSec4[locale.money.put]{Class template \tcode{money_put}}

\rSec5[locale.money.put.general]{General}

\indexlibraryglobal{money_put}%
\begin{codeblock}
namespace std {
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class money_put : public locale::facet {
    public:
      using @\libmember{char_type}{money_put}@   = charT;
      using @\libmember{iter_type}{money_put}@   = OutputIterator;
      using @\libmember{string_type}{money_put}@ = basic_string<charT>;

      explicit money_put(size_t refs = 0);

      iter_type put(iter_type s, bool intl, ios_base& f,
                    char_type fill, long double units) const;
      iter_type put(iter_type s, bool intl, ios_base& f,
                    char_type fill, const string_type& digits) const;

      static locale::id @\libmember{id}{money_put}@;

    protected:
      ~money_put();
      virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill,
                               long double units) const;
      virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill,
                               const string_type& digits) const;
    };
}
\end{codeblock}

\rSec5[locale.money.put.members]{Members}

\indexlibrarymember{money_put}{put}%
\begin{itemdecl}
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, long double quant) const;
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, const string_type& quant) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_put(s, intl, f, fill, quant)}.
\end{itemdescr}

\rSec5[locale.money.put.virtuals]{Virtual functions}

\indexlibrarymember{money_put}{do_put}%
\begin{itemdecl}
iter_type do_put(iter_type s, bool intl, ios_base& str,
                 char_type fill, long double units) const;
iter_type do_put(iter_type s, bool intl, ios_base& str,
                 char_type fill, const string_type& digits) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Writes characters to \tcode{s} according to
the format specified by
a \tcode{moneypunct<charT, Intl>} facet reference \tcode{mp} and
the character mapping specified by
a \tcode{ctype<charT>} facet reference \tcode{ct}
obtained from the locale returned by \tcode{str.getloc()},
and \tcode{str.flags()}.
The argument \tcode{units} is transformed into
a sequence of wide characters as if by
\begin{codeblock}
ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)
\end{codeblock}
for character buffers \tcode{buf1} and \tcode{buf2}.
If the first character in \tcode{digits} or \tcode{buf2}
is equal to \tcode{ct.widen('-')},
then the pattern used for formatting is the result of \tcode{mp.neg_format()};
otherwise the pattern is the result of \tcode{mp.pos_format()}.
Digit characters are written,
interspersed with any thousands separators and decimal point
specified by the format,
in the order they appear (after the optional leading minus sign) in
\tcode{digits} or \tcode{buf2}.
In \tcode{digits},
only the optional leading minus sign and
the immediately subsequent digit characters
(as classified according to \tcode{ct})
are used;
any trailing characters
(including digits appearing after a non-digit character)
are ignored.
Calls \tcode{str.width(0)}.

\pnum
\returns
An iterator pointing immediately after the last character produced.

\pnum
\remarks
% issues 22-021, 22-030, 22-034 from 97-0058/N1096, 97-0036/N1074
The currency symbol is generated
if and only if \tcode{(str.flags() \& str.showbase)} is nonzero.
If the number of characters generated for the specified format
is less than the value returned by \tcode{str.width()} on entry to the function,
then copies of \tcode{fill} are inserted as necessary
to pad to the specified width.
For the value \tcode{af} equal to \tcode{(str.flags() \& str.adjustfield)},
if \tcode{(af == str.internal)} is \tcode{true},
the fill characters are placed
where \tcode{none} or \tcode{space} appears in the formatting pattern;
otherwise if \tcode{(af == str.left)} is \tcode{true},
they are placed after the other characters;
otherwise, they are placed before the other characters.
\begin{note}
It is possible, with some combinations of format patterns and flag values,
to produce output that cannot be parsed using \tcode{num_get<>::get}.
\end{note}
\end{itemdescr}

\rSec4[locale.moneypunct]{Class template \tcode{moneypunct}}

\rSec5[locale.moneypunct.general]{General}

\indexlibraryglobal{money_base}%
\indexlibraryglobal{moneypunct}%
\begin{codeblock}
namespace std {
  class money_base {
  public:
    enum @\libmember{part}{money_base}@ { @\libmember{none}{money_base}@, @\libmember{space}{money_base}@, @\libmember{symbol}{money_base}@, @\libmember{sign}{money_base}@, @\libmember{value}{money_base}@ };
    struct @\libmember{pattern}{money_base}@ { char @\libmember{field}{money_base::pattern}@[4]; };
  };

  template<class charT, bool International = false>
    class moneypunct : public locale::facet, public money_base {
    public:
      using @\libmember{char_type}{moneypunct}@   = charT;
      using @\libmember{string_type}{moneypunct}@ = basic_string<charT>;

      explicit moneypunct(size_t refs = 0);

      charT       decimal_point() const;
      charT       thousands_sep() const;
      string      grouping()      const;
      string_type curr_symbol()   const;
      string_type positive_sign() const;
      string_type negative_sign() const;
      int         frac_digits()   const;
      pattern     pos_format()    const;
      pattern     neg_format()    const;

      static locale::id @\libmember{id}{moneypunct}@;
      static const bool @\libmember{intl}{moneypunct}@ = International;

    protected:
      ~moneypunct();
      virtual charT       do_decimal_point() const;
      virtual charT       do_thousands_sep() const;
      virtual string      do_grouping()      const;
      virtual string_type do_curr_symbol()   const;
      virtual string_type do_positive_sign() const;
      virtual string_type do_negative_sign() const;
      virtual int         do_frac_digits()   const;
      virtual pattern     do_pos_format()    const;
      virtual pattern     do_neg_format()    const;
    };
}
\end{codeblock}

\pnum
The \tcode{moneypunct<>} facet defines monetary formatting parameters
used by \tcode{money_get<>} and \tcode{money_put<>}.
A monetary format is a sequence of four components,
specified by a \tcode{pattern} value \tcode{p},
such that the \tcode{part} value \tcode{static_cast<part>(p.field[i])}
determines the $\tcode{i}^\text{th}$ component of the format.
\begin{footnote}
An array of \tcode{char},
rather than an array of \tcode{part},
is specified for \tcode{pattern::field} purely for efficiency.
\end{footnote}
In the \tcode{field} member of a \tcode{pattern} object,
each value \tcode{symbol}, \tcode{sign}, \tcode{value}, and
either \tcode{space} or \tcode{none}
appears exactly once.
The value \tcode{none}, if present, is not first;
the value \tcode{space}, if present, is neither first nor last.

\pnum
Where \tcode{none} or \tcode{space} appears,
whitespace is permitted in the format,
except where \tcode{none} appears at the end,
in which case no whitespace is permitted.
The value \tcode{space} indicates that
at least one space is required at that position.
Where \tcode{symbol} appears,
the sequence of characters returned by \tcode{curr_symbol()} is permitted, and
can be required.
Where \tcode{sign} appears,
the first (if any) of the sequence of characters returned by
\tcode{positive_sign()} or \tcode{negative_sign()}
(respectively as the monetary value is non-negative or negative) is required.
Any remaining characters of the sign sequence are required after
all other format components.
Where \tcode{value} appears, the absolute numeric monetary value is required.

\pnum
The format of the numeric monetary value is a decimal number:
\begin{ncbnf}
\locnontermdef{value}\br
    units \opt{fractional}\br
    decimal-point digits
\end{ncbnf}
\begin{ncbnf}
\locnontermdef{fractional}\br
    decimal-point \opt{digits}
\end{ncbnf}
if \tcode{frac_digits()} returns a positive value, or
\begin{ncbnf}
\locnontermdef{value}\br
    units
\end{ncbnf}
otherwise.
The symbol \locgrammarterm{decimal-point}
indicates the character returned by \tcode{decimal_point()}.
The other symbols are defined as follows:

\begin{ncbnf}
\locnontermdef{units}\br
    digits\br
    digits thousands-sep units
\end{ncbnf}

\begin{ncbnf}
\locnontermdef{digits}\br
    adigit \opt{digits}
\end{ncbnf}

In the syntax specification,
the symbol \locgrammarterm{adigit} is any of the values \tcode{ct.widen(c)}
for \tcode{c} in the range \tcode{'0'} through \tcode{'9'} (inclusive) and
\tcode{ct} is a reference of type \tcode{const ctype<charT>\&}
obtained as described in the definitions
of \tcode{money_get<>} and \tcode{money_put<>}.
The symbol \locgrammarterm{thousands-sep}
is the character returned by \tcode{thousands_sep()}.
The space character used is the value \tcode{ct.widen(' ')}.
Whitespace characters are those characters \tcode{c}
for which \tcode{ci.is(space, c)} returns \tcode{true}.
The number of digits required after the decimal point (if any)
is exactly the value returned by \tcode{frac_digits()}.

\pnum
The placement of thousands-separator characters (if any)
is determined by the value returned by \tcode{grouping()},
defined identically as the member \tcode{numpunct<>::do_grouping()}.

\rSec5[locale.moneypunct.members]{Members}

\indexlibrarymember{moneypunct}{decimal_point}%
\indexlibrarymember{moneypunct}{thousands_sep}%
\indexlibrarymember{moneypunct}{grouping}%
\indexlibrarymember{moneypunct}{curr_symbol}%
\indexlibrarymember{moneypunct}{positive_sign}%
\indexlibrarymember{moneypunct}{negative_sign}%
\indexlibrarymember{moneypunct}{frac_digits}%
\indexlibrarymember{moneypunct}{positive_sign}%
\indexlibrarymember{moneypunct}{negative_sign}%
\begin{codeblock}
charT       decimal_point() const;
charT       thousands_sep() const;
string      grouping()      const;
string_type curr_symbol()   const;
string_type positive_sign() const;
string_type negative_sign() const;
int         frac_digits()   const;
pattern     pos_format()    const;
pattern     neg_format()    const;
\end{codeblock}

\pnum
Each of these functions \tcode{\placeholder{F}}
returns the result of calling the corresponding
virtual member function
\tcode{do_\placeholder{F}()}.

\rSec5[locale.moneypunct.virtuals]{Virtual functions}

\indexlibrarymember{moneypunct}{do_decimal_point}%
\begin{itemdecl}
charT do_decimal_point() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The radix separator to use
in case \tcode{do_frac_digits()} is greater than zero.
\begin{footnote}
In common U.S. locales this is \tcode{'.'}.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_thousands_sep}%
\begin{itemdecl}
charT do_thousands_sep() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The digit group separator to use
in case \tcode{do_grouping()} specifies a digit grouping pattern.
\begin{footnote}
In common U.S. locales this is \tcode{','}.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_grouping}%
\begin{itemdecl}
string do_grouping() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A pattern defined identically as, but not necessarily equal to,
the result of \tcode{numpunct<charT>::\brk{}do_grouping()}.
\begin{footnote}
To specify grouping by 3s,
the value is \tcode{"\textbackslash003"} \textit{not} \tcode{"3"}.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_curr_symbol}%
\begin{itemdecl}
string_type do_curr_symbol() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A string to use as the currency identifier symbol.
\begin{note}
For specializations where the second template parameter is \tcode{true},
this is typically four characters long:
a three-letter code as specified by ISO 4217\supercite{iso4217}
followed by a space.
\end{note}
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_positive_sign}%
\indexlibrarymember{moneypunct}{do_negative_sign}%
\begin{itemdecl}
string_type do_positive_sign() const;
string_type do_negative_sign() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_positive_sign()}
returns the string to use to indicate a positive monetary value;
\begin{footnote}
This is usually the empty string.
\end{footnote}
\tcode{do_negative_sign()}
returns the string to use to indicate a negative value.
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_frac_digits}%
\begin{itemdecl}
int do_frac_digits() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The number of digits after the decimal radix separator, if any.
\begin{footnote}
In common U.S. locales, this is 2.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{moneypunct}{do_pos_format}%
\indexlibrarymember{moneypunct}{do_neg_format}%
\begin{itemdecl}
pattern do_pos_format() const;
pattern do_neg_format() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The specializations required in \tref{locale.spec}\iref{locale.category}, namely
\begin{itemize}
\item \tcode{moneypunct<char>},
\item \tcode{moneypunct<wchar_t>},
\item \tcode{moneypunct<char, true>}, and
\item \tcode{moneypunct<wchar_t, true>},
\end{itemize}
return an object of type \tcode{pattern}
initialized to \tcode{\{ symbol, sign, none, value \}}.
\begin{footnote}
Note that the international symbol returned by \tcode{do_curr_symbol()}
usually contains a space, itself;
for example, \tcode{"USD "}.
\end{footnote}
\end{itemdescr}

\rSec4[locale.moneypunct.byname]{Class template \tcode{moneypunct_byname}}

\indexlibraryglobal{moneypunct_byname}%
\begin{codeblock}
namespace std {
  template<class charT, bool Intl = false>
    class moneypunct_byname : public moneypunct<charT, Intl> {
    public:
      using @\libmember{pattern}{moneypunct_byname}@     = money_base::pattern;
      using @\libmember{string_type}{moneypunct_byname}@ = basic_string<charT>;

      explicit moneypunct_byname(const char*, size_t refs = 0);
      explicit moneypunct_byname(const string&, size_t refs = 0);

    protected:
      ~moneypunct_byname();
    };
}
\end{codeblock}

\rSec3[category.messages]{The message retrieval category}

\rSec4[category.messages.general]{General}

\pnum
Class \tcode{messages<charT>}
implements retrieval of strings from message catalogs.

\rSec4[locale.messages]{Class template \tcode{messages}}

\rSec5[locale.messages.general]{General}

\indexlibraryglobal{messages_base}%
\indexlibraryglobal{messages}%
\begin{codeblock}
namespace std {
  class messages_base {
  public:
    using @\libmember{catalog}{messages_base}@ = @\textit{unspecified signed integer type}@;
  };

  template<class charT>
    class messages : public locale::facet, public messages_base {
    public:
      using @\libmember{char_type}{messages}@   = charT;
      using @\libmember{string_type}{messages}@ = basic_string<charT>;

      explicit messages(size_t refs = 0);

      catalog open(const string& fn, const locale&) const;
      string_type get(catalog c, int set, int msgid,
                      const string_type& dfault) const;
      void close(catalog c) const;

      static locale::id @\libmember{id}{messages}@;

    protected:
      ~messages();
      virtual catalog do_open(const string&, const locale&) const;
      virtual string_type do_get(catalog, int set, int msgid,
                                 const string_type& dfault) const;
      virtual void do_close(catalog) const;
    };
}
\end{codeblock}

\pnum
Values of type \tcode{messages_base::catalog}
usable as arguments to members \tcode{get} and \tcode{close}
can be obtained only by calling member \tcode{open}.

\rSec5[locale.messages.members]{Members}

\indexlibrarymember{messages}{open}%
\begin{itemdecl}
catalog open(const string& name, const locale& loc) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_open(name, loc)}.
\end{itemdescr}

\indexlibrarymember{messages}{get}%
\begin{itemdecl}
string_type get(catalog cat, int set, int msgid, const string_type& dfault) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{do_get(cat, set, msgid, dfault)}.
\end{itemdescr}

\indexlibrarymember{messages}{close}%
\begin{itemdecl}
void close(catalog cat) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{do_close(cat)}.
\end{itemdescr}

\rSec5[locale.messages.virtuals]{Virtual functions}

\indexlibrarymember{messages}{do_open}%
\begin{itemdecl}
catalog do_open(const string& name, const locale& loc) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A value that may be passed to \tcode{get()}
to retrieve a message from the message catalog
identified by the string \tcode{name}
according to an \impldef{mapping from name to catalog when calling
\tcode{mes\-sages::do_open}} mapping.
The result can be used until it is passed to \tcode{close()}.

\pnum
Returns a value less than 0 if no such catalog can be opened.

\pnum
\remarks
The locale argument \tcode{loc} is used for
character set code conversion when retrieving messages, if needed.
\end{itemdescr}

\indexlibrarymember{messages}{do_get}%
\begin{itemdecl}
string_type do_get(catalog cat, int set, int msgid, const string_type& dfault) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{cat} is a catalog obtained from \tcode{open()} and not yet closed.

\pnum
\returns
A message identified by
arguments \tcode{set}, \tcode{msgid}, and \tcode{dfault},
according to
an \impldef{mapping to message when calling \tcode{messages::do_get}} mapping.
If no such message can be found, returns \tcode{dfault}.
\end{itemdescr}

\indexlibrarymember{message}{do_close}%
\begin{itemdecl}
void do_close(catalog cat) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{cat} is a catalog obtained from \tcode{open()} and not yet closed.

\pnum
\effects
Releases unspecified resources associated with  \tcode{cat}.

\pnum
\remarks
The limit on such resources, if any, is
\impldef{resource limits on a message catalog}.
\end{itemdescr}

\rSec4[locale.messages.byname]{Class template \tcode{messages_byname}}

\indexlibraryglobal{messages_byname}%
\begin{codeblock}
namespace std {
  template<class charT>
    class messages_byname : public messages<charT> {
    public:
      using @\libmember{catalog}{messages_byname}@     = messages_base::catalog;
      using @\libmember{string_type}{messages_byname}@ = basic_string<charT>;

      explicit messages_byname(const char*, size_t refs = 0);
      explicit messages_byname(const string&, size_t refs = 0);

    protected:
      ~messages_byname();
    };
}
\end{codeblock}

\rSec2[c.locales]{C library locales}

\rSec3[clocale.syn]{Header \tcode{<clocale>} synopsis}

\indexlibraryglobal{lconv}%
\indexlibraryglobal{setlocale}%
\indexlibraryglobal{localeconv}%
\begin{codeblock}
namespace std {
  struct lconv;

  char* setlocale(int category, const char* locale);
  lconv* localeconv();
}

#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@
#define @\libmacro{LC_ALL}@ @\seebelow@
#define @\libmacro{LC_COLLATE}@ @\seebelow@
#define @\libmacro{LC_CTYPE}@ @\seebelow@
#define @\libmacro{LC_MONETARY}@ @\seebelow@
#define @\libmacro{LC_NUMERIC}@ @\seebelow@
#define @\libmacro{LC_TIME}@ @\seebelow@
\end{codeblock}

\pnum
The contents and meaning of the header \libheaderdef{clocale}
are the same as the C standard library header \libheader{locale.h}.

\rSec3[clocale.data.races]{Data races}

\pnum
Calls to the function \tcode{setlocale}
may introduce a data race\iref{res.on.data.races}
with other calls to \tcode{setlocale} or
with calls to the functions listed in \tref{setlocale.data.races}.

\xrefc{7.11}

\begin{floattable}
{Potential \tcode{setlocale} data races}
{setlocale.data.races}
{lllll}
\topline

\tcode{fprintf}     &
\tcode{isprint}     &
\tcode{iswdigit}    &
\tcode{localeconv}  &
\tcode{tolower}     \\

\tcode{fscanf}      &
\tcode{ispunct}     &
\tcode{iswgraph}    &
\tcode{mblen}       &
\tcode{toupper}     \\

\tcode{isalnum}     &
\tcode{isspace}     &
\tcode{iswlower}    &
\tcode{mbstowcs}    &
\tcode{towlower}    \\

\tcode{isalpha}     &
\tcode{isupper}     &
\tcode{iswprint}    &
\tcode{mbtowc}      &
\tcode{towupper}    \\

\tcode{isblank}     &
\tcode{iswalnum}    &
\tcode{iswpunct}    &
\tcode{setlocale}   &
\tcode{wcscoll}     \\

\tcode{iscntrl}     &
\tcode{iswalpha}    &
\tcode{iswspace}    &
\tcode{strcoll}     &
\tcode{wcstod}      \\

\tcode{isdigit}     &
\tcode{iswblank}    &
\tcode{iswupper}    &
\tcode{strerror}    &
\tcode{wcstombs}    \\

\tcode{isgraph}     &
\tcode{iswcntrl}    &
\tcode{iswxdigit}   &
\tcode{strtod}      &
\tcode{wcsxfrm}     \\

\tcode{islower}     &
\tcode{iswctype}    &
\tcode{isxdigit}    &
\tcode{strxfrm}     &
\tcode{wctomb}      \\
\end{floattable}

\rSec1[text.encoding]{Text encodings identification}

\rSec2[text.encoding.syn]{Header \tcode{<text_encoding>} synopsis}

\indexheader{text_encoding}%
\begin{codeblock}
namespace std {
  struct text_encoding;

  // \ref{text.encoding.hash}, hash support
  template<class T> struct hash;
  template<> struct hash<text_encoding>;
}
\end{codeblock}

\rSec2[text.encoding.class]{Class \tcode{text_encoding}}

\rSec3[text.encoding.overview]{Overview}

\pnum
The class \tcode{text_encoding} describes an interface
for accessing the IANA Character Sets registry\supercite{iana-charset}.

\indexlibraryglobal{text_encoding}%
\begin{codeblock}
namespace std {
  struct text_encoding {
    static constexpr size_t @\libmember{max_name_length}{text_encoding}@ = 63;

    // \ref{text.encoding.id}, enumeration \tcode{text_encoding::id}
    enum class id : int_least32_t {
      @\seebelow@
    };
    using enum id;

    constexpr text_encoding() = default;
    constexpr explicit text_encoding(string_view enc) noexcept;
    constexpr text_encoding(id i) noexcept;

    constexpr id mib() const noexcept;
    constexpr const char* name() const noexcept;

    // \ref{text.encoding.aliases}, class \tcode{text_encoding::aliases_view}
    struct aliases_view;
    constexpr aliases_view aliases() const noexcept;

    friend constexpr bool operator==(const text_encoding& a,
                                     const text_encoding& b) noexcept;
    friend constexpr bool operator==(const text_encoding& encoding, id i) noexcept;

    static consteval text_encoding literal() noexcept;
    static text_encoding environment();
    template<id i> static bool environment_is();

  private:
    id @\exposid{mib_}@ = id::unknown;                                              // \expos
    char @\exposid{name_}@[max_name_length + 1] = {0};                              // \expos
    static constexpr bool @\exposidnc{comp-name}@(string_view a, string_view b);      // \expos
  };
}
\end{codeblock}

\pnum
Class \tcode{text_encoding} is
a trivially copyable type\iref{term.trivially.copyable.type}.

\rSec3[text.encoding.general]{General}

\pnum
A \defnadj{registered character}{encoding} is
a character encoding scheme in the IANA Character Sets registry.
\begin{note}
The IANA Character Sets registry uses the term ``character sets''
to refer to character encodings.
\end{note}
The primary name of a registered character encoding is
the name of that encoding specified in the IANA Character Sets registry.

\pnum
The set of known registered character encodings contains
every registered character encoding
specified in the IANA Character Sets registry except for the following:
\begin{itemize}
\item NATS-DANO (33)
\item NATS-DANO-ADD (34)
\end{itemize}

\pnum
Each known registered character encoding
is identified by an enumerator in \tcode{text_encoding::id}, and
has a set of zero or more \defnx{aliases}{encoding!registered character!alias}.

\pnum
The set of aliases of a known registered character encoding is an
\impldef{set of aliases of a known registered character encoding}
superset of the aliases specified in the IANA Character Sets registry.
The set of aliases for US-ASCII includes ``ASCII''.
No two aliases or primary names of distinct registered character encodings
are equivalent when compared by \tcode{text_encoding::\exposid{comp-name}}.

\pnum
How a \tcode{text_encoding} object
is determined to be representative of a character encoding scheme
implemented in the translation or execution environment is
\impldef{how \tcode{text_encoding} objects are
determined to be representative of a character encoding scheme}.

\pnum
An object \tcode{e} of type \tcode{text_encoding} such that
\tcode{e.mib() == text_encoding::id::unknown} is \tcode{false} and
\tcode{e.mib() == text_encoding::id::other} is \tcode{false}
maintains the following invariants:
\begin{itemize}
\item \tcode{*e.name() == '\textbackslash 0'} is \tcode{false}, and
\item \tcode{e.mib() == text_encoding(e.name()).mib()} is \tcode{true}.
\end{itemize}

\pnum
\recommended
\begin{itemize}
\item
Implementations should not consider registered encodings to be interchangeable.
\begin{example}
Shift_JIS and Windows-31J denote different encodings.
\end{example}
\item
Implementations should not use the name of a registered encoding
to describe another similar yet different non-registered encoding
unless there is a precedent on that implementation.
\begin{example}
Big5
\end{example}
\end{itemize}

\rSec3[text.encoding.members]{Members}

\indexlibraryctor{text_encoding}%
\begin{itemdecl}
constexpr explicit text_encoding(string_view enc) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\begin{itemize}
\item
\tcode{enc} represents a string in the ordinary literal encoding
consisting only of elements of the basic character set\iref{lex.charset}.
\item
\tcode{enc.size() <= max_name_length} is \tcode{true}.
\item
\tcode{enc.contains('\textbackslash 0')} is \tcode{false}.
\end{itemize}

\pnum
\ensures
\begin{itemize}
\item
If there exists a primary name or alias \tcode{a}
of a known registered character encoding such that
\tcode{\exposid{comp-name}(a, enc)} is \tcode{true},
\exposid{mib_} has the value of the enumerator of \tcode{id}
associated with that registered character encoding.
Otherwise, \tcode{\exposid{mib_} == id::other} is \tcode{true}.
\item
\tcode{enc.compare(\exposid{name_}) == 0} is \tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibraryctor{text_encoding}%
\begin{itemdecl}
constexpr text_encoding(id i) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{i} has the value of one of the enumerators of \tcode{id}.

\pnum
\ensures
\begin{itemize}
\item
\tcode{\exposid{mib_} == i} is \tcode{true}.
\item
If \tcode{(\exposid{mib_} == id::unknown || \exposid{mib_} == id::other)}
is \tcode{true},
\tcode{strlen(\exposid{name_}) == 0} is \tcode{true}.
Otherwise,
\tcode{ranges::contains(aliases(), string_view(\exposid{name_}))}
is \tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{mib}{text_encoding}%
\begin{itemdecl}
constexpr id mib() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\exposid{mib_}.
\end{itemdescr}

\indexlibrarymember{name}{text_encoding}%
\begin{itemdecl}
constexpr const char* name() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\exposid{name_}.

\pnum
\remarks
\tcode{name()} is an \ntbs{} and
accessing elements of \exposid{name_}
outside of the range \countedrange{name()}{strlen(name()) + 1}
is undefined behavior.
\end{itemdescr}

\indexlibrarymember{aliases}{text_encoding}%
\begin{itemdecl}
constexpr aliases_view aliases() const noexcept;
\end{itemdecl}

\begin{itemdescr}
Let \tcode{r} denote an instance of \tcode{aliases_view}.
If \tcode{*this} represents a known registered character encoding, then:
\begin{itemize}
\item
\tcode{r.front()} is the primary name of the registered character encoding,
\item
\tcode{r} contains the aliases of the registered character encoding, and
\item
\tcode{r} does not contain duplicate values when compared with \tcode{strcmp}.
\end{itemize}
Otherwise, \tcode{r} is an empty range.

\pnum
Each element in \tcode{r}
is a non-null, non-empty \ntbs{} encoded in the literal character encoding and
comprising only characters from the basic character set.

\pnum
\returns
\tcode{r}.

\pnum
\begin{note}
The order of aliases in \tcode{r} is unspecified.
\end{note}
\end{itemdescr}

\indexlibrarymember{literal}{text_encoding}%
\begin{itemdecl}
static consteval text_encoding literal() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{CHAR_BIT == 8} is \tcode{true}.

\pnum
\returns
A \tcode{text_encoding} object representing
the ordinary character literal encoding\iref{lex.charset}.
\end{itemdescr}

\indexlibrarymember{environment}{text_encoding}%
\begin{itemdecl}
static text_encoding environment();
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{CHAR_BIT == 8} is \tcode{true}.

\pnum
\returns
A \tcode{text_encoding} object representing
the \impldef{character encoding scheme of the environment}
character encoding scheme of the environment.
On a POSIX implementation, this is the encoding scheme associated with
the POSIX locale denoted by the empty string \tcode{""}.

\pnum
\begin{note}
This function is not affected by calls to \tcode{setlocale}.
\end{note}

\pnum
\recommended
Implementations should return a value that is not affected by calls to
the POSIX function \tcode{setenv} and
other functions which can modify the environment\iref{support.runtime}.
\end{itemdescr}

\indexlibrarymember{environment_is}{text_encoding}%
\begin{itemdecl}
template<id i>
  static bool environment_is();
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{CHAR_BIT == 8} is \tcode{true}.

\pnum
\returns
\tcode{environment() == i}.
\end{itemdescr}

\indexlibrarymember{\exposid{comp-name}}{text_encoding}%
\begin{itemdecl}
static constexpr bool @\exposid{comp-name}@(string_view a, string_view b);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if the two strings \tcode{a} and \tcode{b}
encoded in the ordinary literal encoding
are equal, ignoring, from left-to-right,
\begin{itemize}
\item
all elements that are not digits or letters\iref{character.seq.general},
\item
character case, and
\item
any sequence of one or more \tcode{0} characters
not immediately preceded by a numeric prefix, where
a numeric prefix is a sequence consisting of
a digit in the range \crange{1}{9}
optionally followed by one or more elements which are not digits or letters,
\end{itemize}
and \tcode{false} otherwise.

\begin{note}
This comparison is identical to
the ``Charset Alias Matching'' algorithm
described in the Unicode Technical Standard 22\supercite{unicode-charmap}.
\end{note}

\begin{example}
\begin{codeblock}
static_assert(@\exposid{comp-name}@("UTF-8", "utf8") == true);
static_assert(@\exposid{comp-name}@("u.t.f-008", "utf8") == true);
static_assert(@\exposid{comp-name}@("ut8", "utf8") == false);
static_assert(@\exposid{comp-name}@("utf-80", "utf8") == false);
\end{codeblock}
\end{example}
\end{itemdescr}

\rSec3[text.encoding.cmp]{Comparison functions}

\indexlibrarymember{operator==}{text_encoding}%
\begin{itemdecl}
friend constexpr bool operator==(const text_encoding& a, const text_encoding& b) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{a.\exposid{mib_} == id::other \&\& b.\exposid{mib_} == id::other}
is \tcode{true},
then \tcode{\exposid{comp-name}(a.\exposid{name_},\linebreak{}b.\exposid{name_})}.
Otherwise, \tcode{a.\exposid{mib_} == b.\exposid{mib_}}.
\end{itemdescr}

\indexlibrarymember{operator==}{text_encoding}%
\begin{itemdecl}
friend constexpr bool operator==(const text_encoding& encoding, id i) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{encoding.\exposid{mib_} == i}.

\pnum
\remarks
This operator induces an equivalence relation on its arguments
if and only if \tcode{i != id::other} is \tcode{true}.
\end{itemdescr}

\rSec3[text.encoding.aliases]{Class \tcode{text_encoding::aliases_view}}

\indexlibrarymember{aliases_view}{text_encoding}%
\indexlibrarymember{begin}{text_encoding::aliases_view}%
\indexlibrarymember{end}{text_encoding::aliases_view}%
\begin{itemdecl}
struct text_encoding::aliases_view : ranges::view_interface<text_encoding::aliases_view> {
  constexpr @\impdefx{type of \tcode{text_encoding::aliases_view::begin()}}@ begin() const;
  constexpr @\impdefx{type of \tcode{text_encoding::aliases_view::end()}}@ end() const;
};
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{text_encoding::aliases_view} models
\libconcept{copyable},
\tcode{ranges::\libconcept{view}},
\tcode{ranges::\libconcept{random_access_range}}, and
\tcode{ranges::\libconcept{borrowed_range}}.
\begin{note}
\tcode{text_encoding::aliases_view} is not required to satisfy
\tcode{ranges::}\libconcept{common_range},
nor \libconcept{default_initializable}.
\end{note}

\pnum
Both
\tcode{ranges::range_value_t<text_encoding::aliases_view>} and
\tcode{ranges::range_reference_t<text_encoding::aliases_view>}
denote \tcode{const char*}.

\pnum
\tcode{ranges::iterator_t<text_encoding::aliases_view>}
is a constexpr iterator\iref{iterator.requirements.general}.
\end{itemdescr}

\rSec3[text.encoding.id]{Enumeration \tcode{text_encoding::id}}

\indexlibrarymember{id}{text_encoding}%
\begin{codeblock}
namespace std {
  enum class text_encoding::id : int_least32_t {
    @\libmember{other}{text_encoding}@ = 1,
    @\libmember{unknown}{text_encoding}@ = 2,
    @\libmember{ASCII}{text_encoding}@ = 3,
    @\libmember{ISOLatin1}{text_encoding}@ = 4,
    @\libmember{ISOLatin2}{text_encoding}@ = 5,
    @\libmember{ISOLatin3}{text_encoding}@ = 6,
    @\libmember{ISOLatin4}{text_encoding}@ = 7,
    @\libmember{ISOLatinCyrillic}{text_encoding}@ = 8,
    @\libmember{ISOLatinArabic}{text_encoding}@ = 9,
    @\libmember{ISOLatinGreek}{text_encoding}@ = 10,
    @\libmember{ISOLatinHebrew}{text_encoding}@ = 11,
    @\libmember{ISOLatin5}{text_encoding}@ = 12,
    @\libmember{ISOLatin6}{text_encoding}@ = 13,
    @\libmember{ISOTextComm}{text_encoding}@ = 14,
    @\libmember{HalfWidthKatakana}{text_encoding}@ = 15,
    @\libmember{JISEncoding}{text_encoding}@ = 16,
    @\libmember{ShiftJIS}{text_encoding}@ = 17,
    @\libmember{EUCPkdFmtJapanese}{text_encoding}@ = 18,
    @\libmember{EUCFixWidJapanese}{text_encoding}@ = 19,
    @\libmember{ISO4UnitedKingdom}{text_encoding}@ = 20,
    @\libmember{ISO11SwedishForNames}{text_encoding}@ = 21,
    @\libmember{ISO15Italian}{text_encoding}@ = 22,
    @\libmember{ISO17Spanish}{text_encoding}@ = 23,
    @\libmember{ISO21German}{text_encoding}@ = 24,
    @\libmember{ISO60DanishNorwegian}{text_encoding}@ = 25,
    @\libmember{ISO69French}{text_encoding}@ = 26,
    @\libmember{ISO10646UTF1}{text_encoding}@ = 27,
    @\libmember{ISO646basic1983}{text_encoding}@ = 28,
    @\libmember{INVARIANT}{text_encoding}@ = 29,
    @\libmember{ISO2IntlRefVersion}{text_encoding}@ = 30,
    @\libmember{NATSSEFI}{text_encoding}@ = 31,
    @\libmember{NATSSEFIADD}{text_encoding}@ = 32,
    @\libmember{ISO10Swedish}{text_encoding}@ = 35,
    @\libmember{KSC56011987}{text_encoding}@ = 36,
    @\libmember{ISO2022KR}{text_encoding}@ = 37,
    @\libmember{EUCKR}{text_encoding}@ = 38,
    @\libmember{ISO2022JP}{text_encoding}@ = 39,
    @\libmember{ISO2022JP2}{text_encoding}@ = 40,
    @\libmember{ISO13JISC6220jp}{text_encoding}@ = 41,
    @\libmember{ISO14JISC6220ro}{text_encoding}@ = 42,
    @\libmember{ISO16Portuguese}{text_encoding}@ = 43,
    @\libmember{ISO18Greek7Old}{text_encoding}@ = 44,
    @\libmember{ISO19LatinGreek}{text_encoding}@ = 45,
    @\libmember{ISO25French}{text_encoding}@ = 46,
    @\libmember{ISO27LatinGreek1}{text_encoding}@ = 47,
    @\libmember{ISO5427Cyrillic}{text_encoding}@ = 48,
    @\libmember{ISO42JISC62261978}{text_encoding}@ = 49,
    @\libmember{ISO47BSViewdata}{text_encoding}@ = 50,
    @\libmember{ISO49INIS}{text_encoding}@ = 51,
    @\libmember{ISO50INIS8}{text_encoding}@ = 52,
    @\libmember{ISO51INISCyrillic}{text_encoding}@ = 53,
    @\libmember{ISO54271981}{text_encoding}@ = 54,
    @\libmember{ISO5428Greek}{text_encoding}@ = 55,
    @\libmember{ISO57GB1988}{text_encoding}@ = 56,
    @\libmember{ISO58GB231280}{text_encoding}@ = 57,
    @\libmember{ISO61Norwegian2}{text_encoding}@ = 58,
    @\libmember{ISO70VideotexSupp1}{text_encoding}@ = 59,
    @\libmember{ISO84Portuguese2}{text_encoding}@ = 60,
    @\libmember{ISO85Spanish2}{text_encoding}@ = 61,
    @\libmember{ISO86Hungarian}{text_encoding}@ = 62,
    @\libmember{ISO87JISX0208}{text_encoding}@ = 63,
    @\libmember{ISO88Greek7}{text_encoding}@ = 64,
    @\libmember{ISO89ASMO449}{text_encoding}@ = 65,
    @\libmember{ISO90}{text_encoding}@ = 66,
    @\libmember{ISO91JISC62291984a}{text_encoding}@ = 67,
    @\libmember{ISO92JISC62991984b}{text_encoding}@ = 68,
    @\libmember{ISO93JIS62291984badd}{text_encoding}@ = 69,
    @\libmember{ISO94JIS62291984hand}{text_encoding}@ = 70,
    @\libmember{ISO95JIS62291984handadd}{text_encoding}@ = 71,
    @\libmember{ISO96JISC62291984kana}{text_encoding}@ = 72,
    @\libmember{ISO2033}{text_encoding}@ = 73,
    @\libmember{ISO99NAPLPS}{text_encoding}@ = 74,
    @\libmember{ISO102T617bit}{text_encoding}@ = 75,
    @\libmember{ISO103T618bit}{text_encoding}@ = 76,
    @\libmember{ISO111ECMACyrillic}{text_encoding}@ = 77,
    @\libmember{ISO121Canadian1}{text_encoding}@ = 78,
    @\libmember{ISO122Canadian2}{text_encoding}@ = 79,
    @\libmember{ISO123CSAZ24341985gr}{text_encoding}@ = 80,
    @\libmember{ISO88596E}{text_encoding}@ = 81,
    @\libmember{ISO88596I}{text_encoding}@ = 82,
    @\libmember{ISO128T101G2}{text_encoding}@ = 83,
    @\libmember{ISO88598E}{text_encoding}@ = 84,
    @\libmember{ISO88598I}{text_encoding}@ = 85,
    @\libmember{ISO139CSN369103}{text_encoding}@ = 86,
    @\libmember{ISO141JUSIB1002}{text_encoding}@ = 87,
    @\libmember{ISO143IECP271}{text_encoding}@ = 88,
    @\libmember{ISO146Serbian}{text_encoding}@ = 89,
    @\libmember{ISO147Macedonian}{text_encoding}@ = 90,
    @\libmember{ISO150}{text_encoding}@ = 91,
    @\libmember{ISO151Cuba}{text_encoding}@ = 92,
    @\libmember{ISO6937Add}{text_encoding}@ = 93,
    @\libmember{ISO153GOST1976874}{text_encoding}@ = 94,
    @\libmember{ISO8859Supp}{text_encoding}@ = 95,
    @\libmember{ISO10367Box}{text_encoding}@ = 96,
    @\libmember{ISO158Lap}{text_encoding}@ = 97,
    @\libmember{ISO159JISX02121990}{text_encoding}@ = 98,
    @\libmember{ISO646Danish}{text_encoding}@ = 99,
    @\libmember{USDK}{text_encoding}@ = 100,
    @\libmember{DKUS}{text_encoding}@ = 101,
    @\libmember{KSC5636}{text_encoding}@ = 102,
    @\libmember{Unicode11UTF7}{text_encoding}@ = 103,
    @\libmember{ISO2022CN}{text_encoding}@ = 104,
    @\libmember{ISO2022CNEXT}{text_encoding}@ = 105,
    @\libmember{UTF8}{text_encoding}@ = 106,
    @\libmember{ISO885913}{text_encoding}@ = 109,
    @\libmember{ISO885914}{text_encoding}@ = 110,
    @\libmember{ISO885915}{text_encoding}@ = 111,
    @\libmember{ISO885916}{text_encoding}@ = 112,
    @\libmember{GBK}{text_encoding}@ = 113,
    @\libmember{GB18030}{text_encoding}@ = 114,
    @\libmember{OSDEBCDICDF0415}{text_encoding}@ = 115,
    @\libmember{OSDEBCDICDF03IRV}{text_encoding}@ = 116,
    @\libmember{OSDEBCDICDF041}{text_encoding}@ = 117,
    @\libmember{ISO115481}{text_encoding}@ = 118,
    @\libmember{KZ1048}{text_encoding}@ = 119,
    @\libmember{UCS2}{text_encoding}@ = 1000,
    @\libmember{UCS4}{text_encoding}@ = 1001,
    @\libmember{UnicodeASCII}{text_encoding}@ = 1002,
    @\libmember{UnicodeLatin1}{text_encoding}@ = 1003,
    @\libmember{UnicodeJapanese}{text_encoding}@ = 1004,
    @\libmember{UnicodeIBM1261}{text_encoding}@ = 1005,
    @\libmember{UnicodeIBM1268}{text_encoding}@ = 1006,
    @\libmember{UnicodeIBM1276}{text_encoding}@ = 1007,
    @\libmember{UnicodeIBM1264}{text_encoding}@ = 1008,
    @\libmember{UnicodeIBM1265}{text_encoding}@ = 1009,
    @\libmember{Unicode11}{text_encoding}@ = 1010,
    @\libmember{SCSU}{text_encoding}@ = 1011,
    @\libmember{UTF7}{text_encoding}@ = 1012,
    @\libmember{UTF16BE}{text_encoding}@ = 1013,
    @\libmember{UTF16LE}{text_encoding}@ = 1014,
    @\libmember{UTF16}{text_encoding}@ = 1015,
    @\libmember{CESU8}{text_encoding}@ = 1016,
    @\libmember{UTF32}{text_encoding}@ = 1017,
    @\libmember{UTF32BE}{text_encoding}@ = 1018,
    @\libmember{UTF32LE}{text_encoding}@ = 1019,
    @\libmember{BOCU1}{text_encoding}@ = 1020,
    @\libmember{UTF7IMAP}{text_encoding}@ = 1021,
    @\libmember{Windows30Latin1}{text_encoding}@ = 2000,
    @\libmember{Windows31Latin1}{text_encoding}@ = 2001,
    @\libmember{Windows31Latin2}{text_encoding}@ = 2002,
    @\libmember{Windows31Latin5}{text_encoding}@ = 2003,
    @\libmember{HPRoman8}{text_encoding}@ = 2004,
    @\libmember{AdobeStandardEncoding}{text_encoding}@ = 2005,
    @\libmember{VenturaUS}{text_encoding}@ = 2006,
    @\libmember{VenturaInternational}{text_encoding}@ = 2007,
    @\libmember{DECMCS}{text_encoding}@ = 2008,
    @\libmember{PC850Multilingual}{text_encoding}@ = 2009,
    @\libmember{PCp852}{text_encoding}@ = 2010,
    @\libmember{PC8CodePage437}{text_encoding}@ = 2011,
    @\libmember{PC8DanishNorwegian}{text_encoding}@ = 2012,
    @\libmember{PC862LatinHebrew}{text_encoding}@ = 2013,
    @\libmember{PC8Turkish}{text_encoding}@ = 2014,
    @\libmember{IBMSymbols}{text_encoding}@ = 2015,
    @\libmember{IBMThai}{text_encoding}@ = 2016,
    @\libmember{HPLegal}{text_encoding}@ = 2017,
    @\libmember{HPPiFont}{text_encoding}@ = 2018,
    @\libmember{HPMath8}{text_encoding}@ = 2019,
    @\libmember{HPPSMath}{text_encoding}@ = 2020,
    @\libmember{HPDesktop}{text_encoding}@ = 2021,
    @\libmember{VenturaMath}{text_encoding}@ = 2022,
    @\libmember{MicrosoftPublishing}{text_encoding}@ = 2023,
    @\libmember{Windows31J}{text_encoding}@ = 2024,
    @\libmember{GB2312}{text_encoding}@ = 2025,
    @\libmember{Big5}{text_encoding}@ = 2026,
    @\libmember{Macintosh}{text_encoding}@ = 2027,
    @\libmember{IBM037}{text_encoding}@ = 2028,
    @\libmember{IBM038}{text_encoding}@ = 2029,
    @\libmember{IBM273}{text_encoding}@ = 2030,
    @\libmember{IBM274}{text_encoding}@ = 2031,
    @\libmember{IBM275}{text_encoding}@ = 2032,
    @\libmember{IBM277}{text_encoding}@ = 2033,
    @\libmember{IBM278}{text_encoding}@ = 2034,
    @\libmember{IBM280}{text_encoding}@ = 2035,
    @\libmember{IBM281}{text_encoding}@ = 2036,
    @\libmember{IBM284}{text_encoding}@ = 2037,
    @\libmember{IBM285}{text_encoding}@ = 2038,
    @\libmember{IBM290}{text_encoding}@ = 2039,
    @\libmember{IBM297}{text_encoding}@ = 2040,
    @\libmember{IBM420}{text_encoding}@ = 2041,
    @\libmember{IBM423}{text_encoding}@ = 2042,
    @\libmember{IBM424}{text_encoding}@ = 2043,
    @\libmember{IBM500}{text_encoding}@ = 2044,
    @\libmember{IBM851}{text_encoding}@ = 2045,
    @\libmember{IBM855}{text_encoding}@ = 2046,
    @\libmember{IBM857}{text_encoding}@ = 2047,
    @\libmember{IBM860}{text_encoding}@ = 2048,
    @\libmember{IBM861}{text_encoding}@ = 2049,
    @\libmember{IBM863}{text_encoding}@ = 2050,
    @\libmember{IBM864}{text_encoding}@ = 2051,
    @\libmember{IBM865}{text_encoding}@ = 2052,
    @\libmember{IBM868}{text_encoding}@ = 2053,
    @\libmember{IBM869}{text_encoding}@ = 2054,
    @\libmember{IBM870}{text_encoding}@ = 2055,
    @\libmember{IBM871}{text_encoding}@ = 2056,
    @\libmember{IBM880}{text_encoding}@ = 2057,
    @\libmember{IBM891}{text_encoding}@ = 2058,
    @\libmember{IBM903}{text_encoding}@ = 2059,
    @\libmember{IBM904}{text_encoding}@ = 2060,
    @\libmember{IBM905}{text_encoding}@ = 2061,
    @\libmember{IBM918}{text_encoding}@ = 2062,
    @\libmember{IBM1026}{text_encoding}@ = 2063,
    @\libmember{IBMEBCDICATDE}{text_encoding}@ = 2064,
    @\libmember{EBCDICATDEA}{text_encoding}@ = 2065,
    @\libmember{EBCDICCAFR}{text_encoding}@ = 2066,
    @\libmember{EBCDICDKNO}{text_encoding}@ = 2067,
    @\libmember{EBCDICDKNOA}{text_encoding}@ = 2068,
    @\libmember{EBCDICFISE}{text_encoding}@ = 2069,
    @\libmember{EBCDICFISEA}{text_encoding}@ = 2070,
    @\libmember{EBCDICFR}{text_encoding}@ = 2071,
    @\libmember{EBCDICIT}{text_encoding}@ = 2072,
    @\libmember{EBCDICPT}{text_encoding}@ = 2073,
    @\libmember{EBCDICES}{text_encoding}@ = 2074,
    @\libmember{EBCDICESA}{text_encoding}@ = 2075,
    @\libmember{EBCDICESS}{text_encoding}@ = 2076,
    @\libmember{EBCDICUK}{text_encoding}@ = 2077,
    @\libmember{EBCDICUS}{text_encoding}@ = 2078,
    @\libmember{Unknown8BiT}{text_encoding}@ = 2079,
    @\libmember{Mnemonic}{text_encoding}@ = 2080,
    @\libmember{Mnem}{text_encoding}@ = 2081,
    @\libmember{VISCII}{text_encoding}@ = 2082,
    @\libmember{VIQR}{text_encoding}@ = 2083,
    @\libmember{KOI8R}{text_encoding}@ = 2084,
    @\libmember{HZGB2312}{text_encoding}@ = 2085,
    @\libmember{IBM866}{text_encoding}@ = 2086,
    @\libmember{PC775Baltic}{text_encoding}@ = 2087,
    @\libmember{KOI8U}{text_encoding}@ = 2088,
    @\libmember{IBM00858}{text_encoding}@ = 2089,
    @\libmember{IBM00924}{text_encoding}@ = 2090,
    @\libmember{IBM01140}{text_encoding}@ = 2091,
    @\libmember{IBM01141}{text_encoding}@ = 2092,
    @\libmember{IBM01142}{text_encoding}@ = 2093,
    @\libmember{IBM01143}{text_encoding}@ = 2094,
    @\libmember{IBM01144}{text_encoding}@ = 2095,
    @\libmember{IBM01145}{text_encoding}@ = 2096,
    @\libmember{IBM01146}{text_encoding}@ = 2097,
    @\libmember{IBM01147}{text_encoding}@ = 2098,
    @\libmember{IBM01148}{text_encoding}@ = 2099,
    @\libmember{IBM01149}{text_encoding}@ = 2100,
    @\libmember{Big5HKSCS}{text_encoding}@ = 2101,
    @\libmember{IBM1047}{text_encoding}@ = 2102,
    @\libmember{PTCP154}{text_encoding}@ = 2103,
    @\libmember{Amiga1251}{text_encoding}@ = 2104,
    @\libmember{KOI7switched}{text_encoding}@ = 2105,
    @\libmember{BRF}{text_encoding}@ = 2106,
    @\libmember{TSCII}{text_encoding}@ = 2107,
    @\libmember{CP51932}{text_encoding}@ = 2108,
    @\libmember{windows874}{text_encoding}@ = 2109,
    @\libmember{windows1250}{text_encoding}@ = 2250,
    @\libmember{windows1251}{text_encoding}@ = 2251,
    @\libmember{windows1252}{text_encoding}@ = 2252,
    @\libmember{windows1253}{text_encoding}@ = 2253,
    @\libmember{windows1254}{text_encoding}@ = 2254,
    @\libmember{windows1255}{text_encoding}@ = 2255,
    @\libmember{windows1256}{text_encoding}@ = 2256,
    @\libmember{windows1257}{text_encoding}@ = 2257,
    @\libmember{windows1258}{text_encoding}@ = 2258,
    @\libmember{TIS620}{text_encoding}@ = 2259,
    @\libmember{CP50220}{text_encoding}@ = 2260
  };
}
\end{codeblock}

\begin{note}
The \tcode{text_encoding::id} enumeration
contains an enumerator for each known registered character encoding.
For each encoding, the corresponding enumerator is derived from
the alias beginning with ``\tcode{cs}'', as follows:
\begin{itemize}
\item
\tcode{csUnicode} is mapped to \tcode{text_encoding::id::UCS2},
\item
\tcode{csIBBM904} is mapped to \tcode{text_encoding::id::IBM904}, and
\item
the ``\tcode{cs}'' prefix is removed from other names.
\end{itemize}
\end{note}

\rSec3[text.encoding.hash]{Hash support}

\indexlibrarymember{hash}{text_encoding}%
\begin{itemdecl}
template<> struct hash<text_encoding>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization is enabled\iref{unord.hash}.
\end{itemdescr}

\rSec1[format]{Formatting}

\rSec2[format.syn]{Header \tcode{<format>} synopsis}

\indexheader{format}%
\indexlibraryglobal{format_parse_context}%
\indexlibraryglobal{wformat_parse_context}%
\indexlibraryglobal{format_context}%
\indexlibraryglobal{wformat_context}%
\indexlibraryglobal{format_args}%
\indexlibraryglobal{wformat_args}%
\indexlibraryglobal{format_to_n_result}%
\indexlibrarymember{out}{format_to_n_result}%
\indexlibrarymember{size}{format_to_n_result}%
\begin{codeblock}
namespace std {
  // \ref{format.context}, class template \tcode{basic_format_context}
  template<class Out, class charT> class basic_format_context;
  using format_context = basic_format_context<@\unspec@, char>;
  using wformat_context = basic_format_context<@\unspec@, wchar_t>;

  // \ref{format.args}, class template \tcode{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>;

  // \ref{format.fmt.string}, class template \tcode{basic_format_string}
  template<class charT, class... Args>
    struct basic_format_string;

  template<class charT> struct @\exposid{dynamic-format-string}@ {                  // \expos
  private:
    basic_string_view<charT> @\exposid{str}@;                                       // \expos
  public:
    constexpr @\exposid{dynamic-format-string}@(basic_string_view<charT> s) noexcept : @\exposid{str}@(s) {}
    @\exposid{dynamic-format-string}@(const @\exposid{dynamic-format-string}@&) = delete;
    @\exposid{dynamic-format-string}@& operator=(const @\exposid{dynamic-format-string}@&) = delete;
  };
  constexpr @\exposid{dynamic-format-string}@<char>
    dynamic_format(string_view fmt) noexcept { return fmt; }
  constexpr @\exposid{dynamic-format-string}@<wchar_t>
    dynamic_format(wstring_view fmt) noexcept { return fmt; }

  template<class... Args>
    using @\libglobal{format_string}@ = basic_format_string<char, type_identity_t<Args>...>;
  template<class... Args>
    using @\libglobal{wformat_string}@ = basic_format_string<wchar_t, type_identity_t<Args>...>;

  // \ref{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);

  // \ref{format.formatter}, formatter
  template<class T, class charT = char> struct formatter;

  // \ref{format.formatter.locking}, formatter locking
  template<class T>
    constexpr bool enable_nonlocking_formatter_optimization = false;

  // \ref{format.formattable}, concept \libconcept{formattable}
  template<class T, class charT>
    concept formattable = @\seebelow@;

  template<class R, class charT>
    concept @\defexposconcept{const-formattable-range}@ =                                   // \expos
      ranges::@\libconcept{input_range}@<const R> &&
      @\libconcept{formattable}@<ranges::range_reference_t<const R>, charT>;

  template<class R, class charT>
    using @\exposid{fmt-maybe-const}@ =                                             // \expos
      conditional_t<@\exposconcept{const-formattable-range}@<R, charT>, const R, R>;

  // \ref{format.parse.ctx}, class template \tcode{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>;

  // \ref{format.range}, formatting of ranges
  // \ref{format.range.fmtkind}, variable template \tcode{format_kind}
  enum class @\libglobal{range_format}@ {
    @\libmember{disabled}{range_format}@,
    @\libmember{map}{range_format}@,
    @\libmember{set}{range_format}@,
    @\libmember{sequence}{range_format}@,
    @\libmember{string}{range_format}@,
    @\libmember{debug_string}{range_format}@
  };

  template<class R>
    constexpr @\unspec@ format_kind = @\unspec@;

  template<ranges::@\libconcept{input_range}@ R>
    requires @\libconcept{same_as}@<R, remove_cvref_t<R>>
    constexpr range_format format_kind<R> = @\seebelow@;

  // \ref{format.range.formatter}, class template \tcode{range_formatter}
  template<class T, class charT = char>
    requires @\libconcept{same_as}@<remove_cvref_t<T>, T> && @\libconcept{formattable}@<T, charT>
  class range_formatter;

  // \ref{format.range.fmtdef}, class template \exposid{range-default-formatter}
  template<range_format K, ranges::@\libconcept{input_range}@ R, class charT>
    struct @\exposid{range-default-formatter}@;                                     // \expos

  // \ref{format.range.fmtmap}, \ref{format.range.fmtset}, \ref{format.range.fmtstr}, specializations for maps, sets, and strings
  template<ranges::@\libconcept{input_range}@ R, class charT>
    requires (format_kind<R> != range_format::disabled) &&
             @\libconcept{formattable}@<ranges::range_reference_t<R>, charT>
  struct formatter<R, charT> : @\exposid{range-default-formatter}@<format_kind<R>, R, charT> { };

  template<ranges::@\libconcept{input_range}@ R>
    requires (format_kind<R> != range_format::disabled)
    constexpr bool enable_nonlocking_formatter_optimization<R> = false;

  // \ref{format.arguments}, arguments
  // \ref{format.arg}, class template \tcode{basic_format_arg}
  template<class Context> class basic_format_arg;

  // \ref{format.arg.store}, class template \exposid{format-arg-store}
  template<class Context, class... Args> class @\exposidnc{format-arg-store}@;        // \expos

  template<class Context = format_context, class... Args>
    constexpr @\exposid{format-arg-store}@<Context, Args...>
      make_format_args(Args&... fmt_args);
  template<class... Args>
    constexpr @\exposid{format-arg-store}@<wformat_context, Args...>
      make_wformat_args(Args&... args);

  // \ref{format.error}, class \tcode{format_error}
  class format_error;
}
\end{codeblock}


\pnum
The class template \tcode{format_to_n_result}
has the template parameters, data members, and special members specified above. It has no base classes or members other than those specified.

\rSec2[format.string]{Format string}

\rSec3[format.string.general]{General}

\pnum
A \defn{format string} for arguments \tcode{args} is
a (possibly empty) sequence of
\defnx{replacement fields}{replacement field!format string},
\defnx{escape sequences}{escape sequence!format string},
and characters other than \tcode{\{} and \tcode{\}}.
Let \tcode{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.
An escape sequence is one of \tcode{\{\{} or \tcode{\}\}}.
It is replaced with \tcode{\{} or \tcode{\}}, respectively, in the output.
The syntax of replacement fields is as follows:

\begin{ncbnf}
\fmtnontermdef{replacement-field}\br
    \terminal{\{} \opt{arg-id} \opt{format-specifier} \terminal{\}}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{arg-id}\br
    \terminal{0}\br
    positive-integer
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{positive-integer}\br
    nonzero-digit\br
    positive-integer digit
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{nonnegative-integer}\br
    digit\br
    nonnegative-integer digit
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{nonzero-digit} \textnormal{one of}\br
    \terminal{1 2 3 4 5 6 7 8 9}
\end{ncbnf}

% FIXME: This exactly duplicates the digit grammar term from [lex]
\begin{ncbnf}
\fmtnontermdef{digit} \textnormal{one of}\br
    \terminal{0 1 2 3 4 5 6 7 8 9}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{format-specifier}\br
    \terminal{:} format-spec
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{format-spec}\br
    \textnormal{as specified by the \tcode{formatter} specialization for the argument type; cannot start with \terminal{\}} }
\end{ncbnf}

\pnum
The \fmtgrammarterm{arg-id} field specifies the index of
the argument in \tcode{args}
whose value is to be formatted and inserted into the output
instead of the replacement field.
If there is no argument with
the index \fmtgrammarterm{arg-id} in \tcode{args},
the string is not a format string for \tcode{args}.
The optional \fmtgrammarterm{format-specifier} field
explicitly specifies a format for the replacement value.

\pnum
\begin{example}
\begin{codeblock}
string s = format("{0}-{{", 8);         // value of \tcode{s} is \tcode{"8-\{"}
\end{codeblock}
\end{example}

\pnum
If all \fmtgrammarterm{arg-id}s in a format string are omitted
(including those in the \fmtgrammarterm{format-spec},
as interpreted by the corresponding \tcode{formatter} specialization),
argument indices 0, 1, 2, \ldots{} will automatically be used in that order.
If some \fmtgrammarterm{arg-id}s are omitted and some are present,
the string is not a format string.
\begin{note}
A format string cannot contain a
mixture of automatic and manual indexing.
\end{note}
\begin{example}
\begin{codeblock}
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{codeblock}
\end{example}

\pnum
The \fmtgrammarterm{format-spec} field contains
\defnx{format specifications}{format specification!format string}
that define how the value should be presented.
Each type can define its own
interpretation of the \fmtgrammarterm{format-spec} field.
If \fmtgrammarterm{format-spec} does not conform
to the format specifications for
the argument type referred to by \fmtgrammarterm{arg-id},
the string is not a format string for \tcode{args}.
\begin{example}
\begin{itemize}
\item
For arithmetic, pointer, and string types
the \fmtgrammarterm{format-spec}
is interpreted as a \fmtgrammarterm{std-format-spec}
as described in~\ref{format.string.std}.
\item
For chrono types
the \fmtgrammarterm{format-spec}
is interpreted as a \fmtgrammarterm{chrono-format-spec}
as described in~\ref{time.format}.
\item
For user-defined \tcode{formatter} specializations,
the behavior of the \tcode{parse} member function
determines how the \fmtgrammarterm{format-spec}
is interpreted.
\end{itemize}
\end{example}

\rSec3[format.string.std]{Standard format specifiers}

\pnum
Each \tcode{formatter} specialization
described in \ref{format.formatter.spec}
for fundamental and string types
interprets \fmtgrammarterm{format-spec} as a
\fmtgrammarterm{std-format-spec}.
\begin{note}
The format specification can be used to specify such details as
minimum field width, alignment, padding, and decimal precision.
Some of the formatting options
are only supported for arithmetic types.
\end{note}
The syntax of format specifications is as follows:

\begin{ncbnf}
\fmtnontermdef{std-format-spec}\br
    \opt{fill-and-align} \opt{sign} \opt{\terminal{\#}} \opt{\terminal{0}} \opt{width} \opt{precision} \opt{\terminal{L}} \opt{type}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{fill-and-align}\br
    \opt{fill} align
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{fill}\br
    \textnormal{any character other than \tcode{\{} or \tcode{\}}}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{align} \textnormal{one of}\br
    \terminal{< > \caret}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{sign} \textnormal{one of}\br
    \terminal{+ -} \textnormal{space}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{width}\br
    positive-integer\br
    \terminal{\{} \opt{arg-id} \terminal{\}}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{precision}\br
    \terminal{.} nonnegative-integer\br
    \terminal{.} \terminal{\{} \opt{arg-id} \terminal{\}}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{type} \textnormal{one of}\br
    \terminal{a A b B c d e E f F g G o p P s x X ?}
\end{ncbnf}

\pnum
Field widths are specified in \defnadj{field width}{units};
the number of column positions required to display a sequence of
characters in a terminal.
The \defnadj{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 \defnadj{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 \fmtgrammarterm{width} option.
The \defnadj{padding}{width} is the greater of \tcode{0} and
the difference of the minimum field width and the estimated field width.

\begin{note}
The POSIX \tcode{wcswidth} function is an example of a function that,
given a string, returns the number of column positions required by
a terminal to display the string.
\end{note}

\pnum
The \defnadj{fill}{character} is the character denoted by
the \fmtgrammarterm{fill} option or,
if the \fmtgrammarterm{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.
\begin{note}
The presence of a \fmtgrammarterm{fill} option
is signaled by the character following it,
which must be one of the alignment options.
If the second character of \fmtgrammarterm{std-format-spec}
is not a valid alignment option,
then it is assumed that
the \fmtgrammarterm{fill} and \fmtgrammarterm{align} options
are both absent.
\end{note}

\pnum
The \fmtgrammarterm{align} option applies to all argument types.
The meaning of the various alignment options is as specified in \tref{format.align}.
\begin{example}
\begin{codeblock}
char c = 120;
string s0 = format("{:6}", 42);             // value of \tcode{s0} is \tcode{"\ \ \ \ 42"}
string s1 = format("{:6}", 'x');            // value of \tcode{s1} is \tcode{"x\ \ \ \ \ "}
string s2 = format("{:*<6}", 'x');          // value of \tcode{s2} is \tcode{"x*****"}
string s3 = format("{:*>6}", 'x');          // value of \tcode{s3} is \tcode{"*****x"}
string s4 = format("{:*@\caret{}@6}", 'x');          // value of \tcode{s4} is \tcode{"**x***"}
string s5 = format("{:6d}", c);             // value of \tcode{s5} is \tcode{"\ \ \ 120"}
string s6 = format("{:6}", true);           // value of \tcode{s6} is \tcode{"true\ \ "}
string s7 = format("{:*<6.3}", "123456");   // value of \tcode{s7} is \tcode{"123***"}
string s8 = format("{:02}", 1234);          // value of \tcode{s8} is \tcode{"1234"}
string s9 = format("{:*<}", "12");          // value of \tcode{s9} is \tcode{"12"}
string sA = format("{:*<6}", "12345678");   // value of \tcode{sA} is \tcode{"12345678"}
string sB = format("{:@\importexample[-2pt]{example_05}\kern0.75pt\caret{}@6}", "x");         // value of \tcode{sB} is \tcode{"\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}x\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"}
string sC = format("{:*@\caret{}@6}", "@\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt@");     // value of \tcode{sC} is \tcode{"\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"}
\end{codeblock}
\end{example}
\begin{note}
The \fmtgrammarterm{fill}, \fmtgrammarterm{align}, and \tcode{0} options
have no effect when the minimum field width
is not greater than the estimated field width
because padding width is \tcode{0} in that case.
Since fill characters are assumed to have a field width of \tcode{1},
use of a character with a different field width can produce misaligned output.
The \importexample[-2pt]{example_05} (\unicode{1f921}{clown face}) character has a field width of \tcode{2}.
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}

\begin{floattable}{Meaning of \fmtgrammarterm{align} options}{format.align}{lp{.8\hsize}}
\topline
\lhdr{Option} & \rhdr{Meaning} \\ \rowsep
\tcode{<} &
Forces the formatted argument to be aligned to the start of the field
by inserting $n$ fill characters after the formatted argument
where $n$ is the padding width.
This is the default for
non-arithmetic non-pointer types, \tcode{charT}, and \tcode{bool},
unless an integer presentation type is specified.
\\ \rowsep
%
\tcode{>} &
Forces the formatted argument to be aligned to the end of the field
by inserting $n$ fill characters before the formatted argument
where $n$ is the padding width.
This is the default for
arithmetic types other than \tcode{charT} and \tcode{bool},
pointer types,
or when an integer presentation type is specified.
\\ \rowsep
%
\tcode{\caret} &
Forces the formatted argument to be centered within the field
by inserting
$\bigl\lfloor \frac{n}{2} \bigr\rfloor$
fill characters before and
$\bigl\lceil \frac{n}{2} \bigr\rceil$
fill characters after the formatted argument, where
$n$ is the padding width.
\\
\end{floattable}

\pnum
The \fmtgrammarterm{sign} option is only valid
for arithmetic types other than \tcode{charT} and \tcode{bool}
or when an integer presentation type is specified.
The meaning of the various options is as specified in \tref{format.sign}.

\begin{floattable}{Meaning of \fmtgrammarterm{sign} options}{format.sign}{lp{.8\hsize}}
\topline
\lhdr{Option} & \rhdr{Meaning} \\ \rowsep
\tcode{+} &
Indicates that a sign should be used for both non-negative and negative
numbers.
The \tcode{+} sign is inserted before the output of \tcode{to_chars} for
non-negative numbers other than negative zero.
\begin{tailnote}
For negative numbers and negative zero
the output of \tcode{to_chars} will already contain the sign
so no additional transformation is performed.
\end{tailnote}
\\ \rowsep
%
\tcode{-} &
Indicates that a sign should be used for
negative numbers and negative zero only (this is the default behavior).
\\ \rowsep
%
space &
Indicates that a leading space should be used for
non-negative numbers other than negative zero, and
a minus sign for negative numbers and negative zero.
\\
\end{floattable}

\pnum
The \fmtgrammarterm{sign} option applies to floating-point infinity and NaN.
\begin{example}
\begin{codeblock}
double inf = numeric_limits<double>::infinity();
double nan = numeric_limits<double>::quiet_NaN();
string s0 = format("{0:},{0:+},{0:-},{0: }", 1);        // value of \tcode{s0} is \tcode{"1,+1,1, 1"}
string s1 = format("{0:},{0:+},{0:-},{0: }", -1);       // value of \tcode{s1} is \tcode{"-1,-1,-1,-1"}
string s2 = format("{0:},{0:+},{0:-},{0: }", inf);      // value of \tcode{s2} is \tcode{"inf,+inf,inf, inf"}
string s3 = format("{0:},{0:+},{0:-},{0: }", nan);      // value of \tcode{s3} is \tcode{"nan,+nan,nan, nan"}
\end{codeblock}
\end{example}

\pnum
The \tcode{\#} option causes the
% FIXME: This is not a definition.
\defnx{alternate form}{alternate form!format string}
to be used for the conversion.
This option is valid for arithmetic types other than
\tcode{charT} and \tcode{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 \tref{format.type.int}
into the output after the sign character (possibly space) if there is one, or
before the output of \tcode{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.
% FIXME: This is a weird place for this part of the spec to appear.
Normally, a decimal-point character appears in the result of these
conversions only if a digit follows it.
In addition, for \tcode{g} and \tcode{G} conversions,
% FIXME: Are they normally? What does this even mean? Reach into to_chars and
% alter its behavior?
trailing zeros are not removed from the result.

\pnum
The \tcode{0} option is valid for arithmetic types
other than \tcode{charT} and \tcode{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 \tcode{0} character $n$ times
following the sign or base prefix indicators (if any)
where $n$ is \tcode{0} if the \fmtgrammarterm{align} option is present and
is the padding width otherwise.
\begin{example}
\begin{codeblock}
char c = 120;
string s1 = format("{:+06d}", c);       // value of \tcode{s1} is \tcode{"+00120"}
string s2 = format("{:#06x}", 0xa);     // value of \tcode{s2} is \tcode{"0x000a"}
string s3 = format("{:<06}", -42);      // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} has no effect)
string s4 = format("{:06}", inf);       // value of \tcode{s4} is \tcode{"\ \ \ inf"} (\tcode{0} has no effect)
\end{codeblock}
\end{example}

\pnum
The \fmtgrammarterm{width} option specifies the minimum field width.
If the \fmtgrammarterm{width} option is absent,
the minimum field width is \tcode{0}.

\pnum
If \tcode{\{ \opt{\fmtgrammarterm{arg-id}} \}} is used in
a \fmtgrammarterm{width} or \fmtgrammarterm{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 \tcode{format_error} is thrown.

\pnum
% FIXME: What if it's an arg-id?
If \fmtgrammarterm{positive-integer} is used in a
\fmtgrammarterm{width} option, the value of the \fmtgrammarterm{positive-integer}
is interpreted as a decimal integer and used as the value of the option.

\pnum
For the purposes of width computation,
a string is assumed to be in
a locale-independent,
\impldef{encoding assumption for \tcode{format} width computation} encoding.
Implementations should use either UTF-8, UTF-16, or UTF-32,
on platforms capable of displaying Unicode text in a terminal.
\begin{note}
This is the case for Windows\textregistered{}-based
\begin{footnote}
Windows\textregistered\ is a registered trademark of Microsoft Corporation.
This information is given for the convenience of users of this document and
does not constitute an endorsement by ISO or IEC of this product.
\end{footnote}
and many POSIX-based operating systems.
\end{note}

\pnum
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:
\begin{itemize}
\item
any code point with the \tcode{East_Asian_Width="W"} or
\tcode{East_Asian_Width="F"} property as described by
\UAX{44} of the Unicode Standard
\item
\ucode{4dc0} -- \ucode{4dff} (Yijing Hexagram Symbols)
\item
\ucode{1f300} -- \ucode{1f5ff} (Miscellaneous Symbols and Pictographs)
\item
\ucode{1f900} -- \ucode{1f9ff} (Supplemental Symbols and Pictographs)
\end{itemize}
The field width of all other code points is 1.

\pnum
For a sequence of characters in neither UTF-8, UTF-16, nor UTF-32,
the field width is unspecified.

\pnum
The \fmtgrammarterm{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.

\pnum
If \fmtgrammarterm{nonnegative-integer} is used in
a \fmtgrammarterm{precision} option,
the value of the decimal integer is used as the value of the option.

\pnum
When the \tcode{L} option is used, the form used for the conversion is called
the \defnx{locale-specific form}{locale-specific form!format string}.
The \tcode{L} option is only valid for arithmetic types, and
its effect depends upon the type.
A call to \tcode{format} on a given formatter specialization
is not a constant subexpression if the locale-specific form is specified.
\begin{itemize}
\item
For integral types, the locale-specific form
causes the context's locale to be used
to insert the appropriate digit group separator characters
as if obtained with
\tcode{numpunct<charT>::grouping} and
\tcode{numpunct<charT>::thousands_sep}.

\item
For floating-point types, the locale-specific form
causes the context's locale to be used
to insert the appropriate digit group and radix separator characters
as if obtained with
\tcode{numpunct<charT>::grouping},
\tcode{numpunct<charT>::thousands_sep}, and
\tcode{numpunct<charT>::decimal_point}.

\item
For the textual representation of \tcode{bool}, the locale-specific form
causes the context's locale to be used
to insert the appropriate string as if obtained
with \tcode{numpunct<charT>::truename} or \tcode{numpunct<charT>::\brk{}falsename}.
\end{itemize}
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.

\pnum
The \fmtgrammarterm{type} determines how the data should be presented.

\pnum
% FIXME: What is a "string" here, exactly?
The available string presentation types are specified in \tref{format.type.string}.
%
\begin{floattable}{Meaning of \fmtgrammarterm{type} options for strings}{format.type.string}{ll}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
none, \tcode{s} &
Copies the string to the output.
\\ \rowsep
%
\tcode{?} &
Copies the escaped string\iref{format.string.escaped} to the output.
\\
\end{floattable}

\pnum
The meaning of some non-string presentation types
is defined in terms of a call to \tcode{to_chars}.
In such cases,
let \range{first}{last} be a range
large enough to hold the \tcode{to_chars} output
and \tcode{value} be the formatting argument value.
Formatting is done as if by calling \tcode{to_chars} as specified,
transcoding the \tcode{to_chars} output to the wide literal encoding if
\tcode{charT} is \tcode{wchar_t},
and copying the output through the output iterator of the format context.
\begin{note}
Additional padding and adjustments are performed
prior to copying the output through the output iterator
as specified by the format specifiers.
\end{note}

\pnum
The available integer presentation types
for integral types other than \tcode{bool} and \tcode{charT}
are specified in \tref{format.type.int}.
\begin{example}
\begin{codeblock}
string s0 = format("{}", 42);                           // value of \tcode{s0} is \tcode{"42"}
string s1 = format("{0:b} {0:d} {0:o} {0:x}", 42);      // value of \tcode{s1} is \tcode{"101010 42 52 2a"}
string s2 = format("{0:#x} {0:#X}", 42);                // value of \tcode{s2} is \tcode{"0x2a 0X2A"}
string s3 = format("{:L}", 1234);                       // value of \tcode{s3} can be \tcode{"1,234"}
                                                        // (depending on the locale)
\end{codeblock}
\end{example}

\begin{floattable}{Meaning of \fmtgrammarterm{type} options for integer types}{format.type.int}{lp{.8\hsize}}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
\tcode{b} &
\tcode{to_chars(first, last, value, 2)};
\indextext{base prefix}%
the base prefix is \tcode{0b}.
\\ \rowsep
%
\tcode{B} &
The same as \tcode{b}, except that
\indextext{base prefix}%
the base prefix is \tcode{0B}.
\\ \rowsep
%
\tcode{c} &
Copies the character \tcode{static_cast<charT>(value)} to the output.
Throws \tcode{format_error} if \tcode{value} is not
in the range of representable values for \tcode{charT}.
\\ \rowsep
%
\tcode{d} &
\tcode{to_chars(first, last, value)}.
\\ \rowsep
%
\tcode{o} &
\tcode{to_chars(first, last, value, 8)};
\indextext{base prefix}%
the base prefix is \tcode{0} if \tcode{value} is nonzero and is empty otherwise.
\\ \rowsep
%
\tcode{x} &
\tcode{to_chars(first, last, value, 16)};
\indextext{base prefix}%
the base prefix is \tcode{0x}.
\\ \rowsep
%
\tcode{X} &
The same as \tcode{x}, except that
it uses uppercase letters for digits above 9 and
\indextext{base prefix}%
the base prefix is \tcode{0X}.
\\ \rowsep
%
none &
The same as \tcode{d}.
\begin{tailnote}
If the formatting argument type is \tcode{charT} or \tcode{bool},
the default is instead \tcode{c} or \tcode{s}, respectively.
\end{tailnote}
\\
\end{floattable}

\pnum
The available \tcode{charT} presentation types are specified in \tref{format.type.char}.
%
\begin{floattable}{Meaning of \fmtgrammarterm{type} options for \tcode{charT}}{format.type.char}{lp{.8\hsize}}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
none, \tcode{c} &
Copies the character to the output.
\\ \rowsep
%
\tcode{b}, \tcode{B}, \tcode{d}, \tcode{o}, \tcode{x}, \tcode{X} &
As specified in \tref{format.type.int}
with \tcode{value} converted to the unsigned version of the underlying type.
\\ \rowsep
%
\tcode{?} &
Copies the escaped character\iref{format.string.escaped} to the output.
\\
\end{floattable}

\pnum
The available \tcode{bool} presentation types are specified in \tref{format.type.bool}.
%
\begin{floattable}{Meaning of \fmtgrammarterm{type} options for \tcode{bool}}{format.type.bool}{ll}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
none,
\tcode{s} &
Copies textual representation, either \tcode{true} or \tcode{false}, to the output.
\\ \rowsep
%
\tcode{b}, \tcode{B}, \tcode{d}, \tcode{o}, \tcode{x}, \tcode{X} &
As specified in \tref{format.type.int}
for the value
\tcode{static_cast<unsigned char>(value)}.
\\
\end{floattable}

\pnum
The available floating-point presentation types and their meanings
for values other than infinity and NaN are
specified in \tref{format.type.float}.
For lower-case presentation types, infinity and NaN are formatted as
\tcode{inf} and \tcode{nan}, respectively.
For upper-case presentation types, infinity and NaN are formatted as
\tcode{INF} and \tcode{NAN}, respectively.
\begin{note}
In either case, a sign is included
if indicated by the \fmtgrammarterm{sign} option.
\end{note}

\begin{floattable}{Meaning of \fmtgrammarterm{type} options for floating-point types}{format.type.float}{lp{.8\hsize}}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
\tcode{a} &
If \fmtgrammarterm{precision} is specified, equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::hex, precision)
\end{codeblock}
where \tcode{precision} is the specified formatting precision; equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::hex)
\end{codeblock}
otherwise.
\\
\rowsep
%
\tcode{A} &
The same as \tcode{a}, except that
it uses uppercase letters for digits above 9 and
\tcode{P} to indicate the exponent.
\\ \rowsep
%
\tcode{e} &
Equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::scientific, precision)
\end{codeblock}
where \tcode{precision} is the specified formatting precision,
or \tcode{6} if \fmtgrammarterm{precision} is not specified.
\\ \rowsep
%
\tcode{E} &
The same as \tcode{e}, except that it uses \tcode{E} to indicate exponent.
\\ \rowsep
%
\tcode{f}, \tcode{F} &
Equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::fixed, precision)
\end{codeblock}
where \tcode{precision} is the specified formatting precision,
or \tcode{6} if \fmtgrammarterm{precision} is not specified.
\\ \rowsep
%
\tcode{g} &
Equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::general, precision)
\end{codeblock}
where \tcode{precision} is the specified formatting precision,
or \tcode{6} if \fmtgrammarterm{precision} is not specified.
\\ \rowsep
%
\tcode{G} &
The same as \tcode{g}, except that
it uses \tcode{E} to indicate exponent.
\\ \rowsep
%
none &
If \fmtgrammarterm{precision} is specified, equivalent to
\begin{codeblock}
to_chars(first, last, value, chars_format::general, precision)
\end{codeblock}
where \tcode{precision} is the specified formatting precision; equivalent to
\begin{codeblock}
to_chars(first, last, value)
\end{codeblock}
otherwise.
\\
\end{floattable}

\pnum
The available pointer presentation types and their mapping to
\tcode{to_chars} are specified in \tref{format.type.ptr}.
\begin{note}
Pointer presentation types also apply to \tcode{nullptr_t}.
\end{note}

\begin{floattable}{Meaning of \fmtgrammarterm{type} options for pointer types}{format.type.ptr}{lp{.8\hsize}}
\topline
\lhdr{Type} & \rhdr{Meaning} \\ \rowsep
none, \tcode{p} &
If \tcode{uintptr_t} is declared,
\begin{codeblock}
to_chars(first, last, reinterpret_cast<uintptr_t>(value), 16)
\end{codeblock}
with the prefix \tcode{0x} inserted immediately before the output of \tcode{to_chars};
otherwise, implementation-defined.
\\ \rowsep
\tcode{P} &
The same as \tcode{p},
except that it uses uppercase letters for digits above \tcode{9} and
the base prefix is \tcode{0X}.
\\
\end{floattable}

\rSec2[format.err.report]{Error reporting}

\pnum
Formatting functions throw \tcode{format_error} if
an argument \tcode{fmt} is passed that
is not a format string for \tcode{args}.
They propagate exceptions thrown by operations of
\tcode{formatter} specializations and iterators.
Failure to allocate storage is reported by
throwing an exception as described in~\ref{res.on.exception.handling}.

\rSec2[format.fmt.string]{Class template \tcode{basic_format_string}}

\begin{codeblock}
namespace std {
  template<class charT, class... Args>
  struct @\libglobal{basic_format_string}@ {
  private:
    basic_string_view<charT> @\exposidnc{str}@;         // \expos

  public:
    template<class T> consteval basic_format_string(const T& s);
    constexpr basic_format_string(@\exposid{dynamic-format-string}@<charT> s) noexcept : str(s.@\exposid{str}@) {}

    constexpr basic_string_view<charT> get() const noexcept { return @\exposid{str}@; }
  };
}
\end{codeblock}

\begin{itemdecl}
template<class T> consteval basic_format_string(const T& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{const T\&} models \tcode{\libconcept{convertible_to}<basic_string_view<charT>>}.

\pnum
\effects
Direct-non-list-initializes \exposid{str} with \tcode{s}.

\pnum
\remarks
A call to this function is not a core constant expression\iref{expr.const.core}
unless there exist \tcode{args} of types \tcode{Args}
such that \exposid{str} is a format string for \tcode{args}.
\end{itemdescr}

\rSec2[format.functions]{Formatting functions}

\pnum
A call to any of the functions defined in this subclause
is a constant subexpression only if
each of the used \tcode{formatter} specializations
is a constexpr-enabled specialization\iref{format.formatter.spec}.

\pnum
In the description of the functions, operator \tcode{+} is used
for some of the iterator categories for which it does not have to be defined.
In these cases the semantics of \tcode{a + n} are
the same as in \ref{algorithms.requirements}.

\indexlibraryglobal{format}%
\begin{itemdecl}
template<class... Args>
  constexpr string format(format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat(fmt.@\exposid{str}@, make_format_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format}%
\begin{itemdecl}
template<class... Args>
  constexpr wstring format(wformat_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat(fmt.@\exposid{str}@, make_wformat_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format}%
\begin{itemdecl}
template<class... Args>
  string format(const locale& loc, format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat(loc, fmt.@\exposid{str}@, make_format_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format}%
\begin{itemdecl}
template<class... Args>
  wstring format(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat(loc, fmt.@\exposid{str}@, make_wformat_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{vformat}%
\begin{itemdecl}
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);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A string object holding the character representation of
formatting arguments provided by \tcode{args} formatted according to
specifications given in \tcode{fmt}.
If present, \tcode{loc} is used for locale-specific formatting.

\pnum
\throws
As specified in~\ref{format.err.report}.
\end{itemdescr}

\indexlibraryglobal{format_to}%
\begin{itemdecl}
template<class Out, class... Args>
  constexpr Out format_to(Out out, format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat_to(std::move(out), fmt.@\exposid{str}@, make_format_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format_to}%
\begin{itemdecl}
template<class Out, class... Args>
  constexpr Out format_to(Out out, wformat_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat_to(std::move(out), fmt.@\exposid{str}@, make_wformat_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format_to}%
\begin{itemdecl}
template<class Out, class... Args>
  Out format_to(Out out, const locale& loc, format_string<Args...>  fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat_to(std::move(out), loc, fmt.@\exposid{str}@, make_format_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{format_to}%
\begin{itemdecl}
template<class Out, class... Args>
  Out format_to(Out out, const locale& loc, wformat_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return vformat_to(std::move(out), loc, fmt.@\exposid{str}@, make_wformat_args(args...));
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{vformat_to}%
\begin{itemdecl}
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);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{charT} be \tcode{decltype(fmt)::value_type}.

\pnum
\constraints
\tcode{Out} satisfies \tcode{\libconcept{output_iterator}<const charT\&>}.

\pnum
\expects
\tcode{Out} models \tcode{\libconcept{output_iterator}<const charT\&>}.

\pnum
\effects
Places the character representation of formatting
the arguments provided by \tcode{args},
formatted according to the specifications given in \tcode{fmt},
into the range \range{out}{out + N},
where \tcode{N} is the number of characters in that character representation.
If present, \tcode{loc} is used for locale-specific formatting.

\pnum
\returns
\tcode{out + N}.

\pnum
\throws
As specified in~\ref{format.err.report}.
\end{itemdescr}

\indexlibraryglobal{format_to_n}%
\begin{itemdecl}
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);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let
\begin{itemize}
\item \tcode{charT} be \tcode{decltype(fmt.\exposid{str})::value_type},
\item \tcode{N} be
\tcode{formatted_size(fmt, args...)} for the functions without a \tcode{loc} parameter and
\tcode{formatted_size(loc, fmt, args...)} for the functions with a \tcode{loc} parameter, and
\item \tcode{M} be \tcode{clamp(n, 0, N)}.
\end{itemize}

\pnum
\constraints
\tcode{Out} satisfies \tcode{\libconcept{output_iterator}<const charT\&>}.

\pnum
\expects
\tcode{Out} models \tcode{\libconcept{output_iterator}<const charT\&>}, and
\tcode{formatter<}$\tcode{remove_cvref_t<T}_i$\tcode{>, charT>}
meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}
for each $\tcode{T}_i$ in \tcode{Args}.

\pnum
\effects
Places the first \tcode{M} characters of the character representation of
formatting the arguments provided by \tcode{args},
formatted according to the specifications given in \tcode{fmt},
into the range \range{out}{out + M}.
If present, \tcode{loc} is used for locale-specific formatting.

\pnum
\returns
\tcode{\{out + M, N\}}.

\pnum
\throws
As specified in~\ref{format.err.report}.
\end{itemdescr}

\indexlibraryglobal{formatted_size}%
\begin{itemdecl}
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);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{charT} be \tcode{decltype(fmt.\exposid{str})::value_type}.

\pnum
\expects
\tcode{formatter<}$\tcode{remove_cvref_t<T}_i$\tcode{>, charT>}
meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}
for each $\tcode{T}_i$ in \tcode{Args}.

\pnum
\returns
The number of characters in the character representation of
formatting arguments \tcode{args}
formatted according to specifications given in \tcode{fmt}.
If present, \tcode{loc} is used for locale-specific formatting.

\pnum
\throws
As specified in~\ref{format.err.report}.
\end{itemdescr}

\rSec2[format.formatter]{Formatter}

\rSec3[formatter.requirements]{Formatter requirements}

\pnum
A type \tcode{F} meets the \defnnewoldconcept{BasicFormatter} requirements if
it meets the
\begin{itemize}
\item \oldconcept{DefaultConstructible} (\tref{cpp17.defaultconstructible}),
\item \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}),
\item \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}),
\item \oldconcept{Swappable}\iref{swappable.requirements}, and
\item \oldconcept{Destructible} (\tref{cpp17.destructible})
\end{itemize}
requirements, and
the expressions shown in \tref{formatter.basic} are valid and
have the indicated semantics.

\pnum
A type \tcode{F} meets the \defnnewoldconcept{Formatter} requirements
if it meets the \newoldconcept{BasicFormatter} requirements and
the expressions shown in \tref{formatter} are valid and
have the indicated semantics.

\pnum
Given character type \tcode{charT}, output iterator type
\tcode{Out}, and formatting argument type \tcode{T},
in \tref{formatter.basic} and \tref{formatter}:
\begin{itemize}
\item \tcode{f} is a value of type (possibly const) \tcode{F},
\item \tcode{g} is an lvalue of type \tcode{F},
\item \tcode{u} is an lvalue of type \tcode{T},
\item \tcode{t} is a value of a type convertible to (possibly const) \tcode{T},
\item \tcode{PC} is \tcode{basic_format_parse_context<charT>},
\item \tcode{FC} is \tcode{basic_format_context<Out, charT>},
\item \tcode{pc} is an lvalue of type \tcode{PC}, and
\item \tcode{fc} is an lvalue of type \tcode{FC}.
\end{itemize}
\tcode{pc.begin()} points to the beginning of the
\fmtgrammarterm{format-spec}\iref{format.string}
of the replacement field being formatted
in the format string.
If \fmtgrammarterm{format-spec} is not present or empty then either
\tcode{pc.begin() == pc.end()} or
\tcode{*pc.begin() == '\}'}.

\begin{concepttable}{\newoldconcept{BasicFormatter} requirements}{formatter.basic}
{p{1.2in}p{1in}p{2.9in}}
\topline
\hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Requirement} \\ \capsep
\tcode{g.parse(pc)} &
\tcode{PC::iterator} &
Parses \fmtgrammarterm{format-spec}\iref{format.string}
for type \tcode{T}
in the range \range{pc.begin()}{pc.end()}
until the first unmatched character.
Throws \tcode{format_error} unless the whole range is parsed
or the unmatched character is \tcode{\}}.
\begin{note}
This allows formatters to emit meaningful error messages.
\end{note}
Stores the parsed format specifiers in \tcode{*this} and
returns an iterator past the end of the parsed range.
\\ \rowsep
\tcode{f.format(u, fc)} &
\tcode{FC::iterator} &
Formats \tcode{u} according to the specifiers stored in \tcode{*this},
writes the output to \tcode{fc.out()}, and
returns an iterator past the end of the output range.
The output shall only depend on
\tcode{u},
\tcode{fc.locale()},
\tcode{fc.arg(n)} for any value \tcode{n} of type \tcode{size_t},
and the range \range{pc.begin()}{pc.end()}
from the last call to \tcode{f.parse(pc)}.
\\
\end{concepttable}

\begin{concepttable}{\newoldconcept{Formatter} requirements}{formatter}
{p{1.2in}p{1in}p{2.9in}}
\topline
\hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Requirement} \\ \capsep
\tcode{f.format(t, fc)} &
\tcode{FC::iterator} &
Formats \tcode{t} according to the specifiers stored in \tcode{*this},
writes the output to \tcode{fc.out()}, and
returns an iterator past the end of the output range.
The output shall only depend on
\tcode{t},
\tcode{fc.locale()},
\tcode{fc.arg(n)} for any value \tcode{n} of type \tcode{size_t},
and the range \range{pc.begin()}{pc.end()}
from the last call to \tcode{f.parse(pc)}.
\\ \rowsep
\tcode{f.format(u, fc)} &
\tcode{FC::iterator} &
As above, but does not modify \tcode{u}.
\\
\end{concepttable}

\rSec3[format.formatter.locking]{Formatter locking}

\indexlibraryglobal{enable_nonlocking_formatter_optimization}%
\begin{itemdecl}
template<class T>
  constexpr bool enable_nonlocking_formatter_optimization = false;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
Pursuant to \ref{namespace.std},
users may specialize \tcode{enable_nonlocking_formatter_optimization} for
cv-unqualified program-defined types.
Such specializations shall be usable in constant expressions\iref{expr.const.init}
and have type \tcode{const bool}.
\end{itemdescr}

\rSec3[format.formattable]{Concept \cname{formattable}}

\pnum
Let \tcode{\placeholder{fmt-iter-for}<charT>} be an unspecified type
that models
\tcode{\libconcept{output_iterator}<const charT\&>}\iref{iterator.concept.output}.

\begin{codeblock}
template<class T, class Context,
         class Formatter = typename Context::template formatter_type<remove_const_t<T>>>
  concept @\defexposconcept{formattable-with}@ =                // \expos
    @\libconcept{semiregular}@<Formatter> &&
    requires(Formatter& f, const Formatter& cf, T&& t, Context fc,
             basic_format_parse_context<typename Context::char_type> pc)
    {
      { f.parse(pc) } -> @\libconcept{same_as}@<typename decltype(pc)::iterator>;
      { cf.format(t, fc) } -> @\libconcept{same_as}@<typename Context::iterator>;
    };

template<class T, class charT>
  concept @\deflibconcept{formattable}@ =
    @\exposconcept{formattable-with}@<remove_reference_t<T>, basic_format_context<@\placeholder{fmt-iter-for}@<charT>, charT>>;
\end{codeblock}

\pnum
A type \tcode{T} and a character type \tcode{charT}
model \libconcept{formattable}
if \tcode{formatter<remove_cvref_t<T>, charT>} meets
the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}
and, if \tcode{remove_reference_t<T>} is const-qualified,
the \newoldconcept{Formatter} requirements.

\rSec3[format.formatter.spec]{Formatter specializations}
\indexlibraryglobal{formatter}%

\pnum
% FIXME: Specify this in [format.functions], not here!
The functions defined in \ref{format.functions} use
specializations of the class template \tcode{formatter} to format
individual arguments.

\pnum
Let \tcode{charT} be either \tcode{char} or \keyword{wchar_t}.
Each specialization of \tcode{formatter} is either enabled or disabled,
as described below.
\indextext{\idxcode{formatter}!debug-enabled specialization of}%
A \defn{debug-enabled} specialization of \tcode{formatter}
additionally provides
a public, constexpr, non-static member function \tcode{set_debug_format()}
which modifies the state of the \tcode{formatter} to be as if
the type of the \fmtgrammarterm{std-format-spec}
parsed by the last call to \tcode{parse} were \tcode{?}.
A \defn{constexpr-enabled} specialization of \tcode{formatter}
has its \tcode{format} member function declared \tcode{constexpr}.
Each header that declares the template \tcode{formatter}
provides the following enabled specializations:
\begin{itemize}
\item
\indexlibrary{\idxcode{formatter}!specializations!character types}%
The debug-enabled and constexpr-enabled specializations
\begin{codeblock}
template<> struct formatter<char, char>;
template<> struct formatter<char, wchar_t>;
template<> struct formatter<wchar_t, wchar_t>;
\end{codeblock}

\item
\indexlibrary{\idxcode{formatter}!specializations!string types}%
For each \tcode{charT},
the debug-enabled and constexpr-enabled string type specializations
\begin{codeblock}
template<> struct formatter<charT*, charT>;
template<> struct formatter<const charT*, charT>;
template<size_t N> struct formatter<charT[N], charT>;
template<class traits, class Allocator>
  struct formatter<basic_string<charT, traits, Allocator>, charT>;
template<class traits>
  struct formatter<basic_string_view<charT, traits>, charT>;
\end{codeblock}

\item
\indexlibrary{\idxcode{formatter}!specializations!integer types}%
For each \tcode{charT},
for each \tcode{IntegerT} that is either
a signed or unsigned integer type or \tcode{bool},
a constexpr-enabled specialization
\begin{codeblock}
template<> struct formatter<IntegerT, charT>;
\end{codeblock}

\item
\indexlibrary{\idxcode{formatter}!specializations!floating-point types}%
For each \tcode{charT},
for each \tcode{FloatingT} that is a cv-unqualified floating-point type,
a specialization
\begin{codeblock}
template<> struct formatter<FloatingT, charT>;
\end{codeblock}

\item
\indexlibrary{\idxcode{formatter}!specializations!pointer types}%
\indexlibrary{\idxcode{formatter}!specializations!\idxcode{nullptr_t}}%
For each \tcode{charT},
the constexpr-enabled pointer type specialization
\begin{codeblock}
template<> struct formatter<nullptr_t, charT>;
\end{codeblock}

\item
For each \tcode{charT},
the pointer type specializations
\begin{codeblock}
template<> struct formatter<void*, charT>;
template<> struct formatter<const void*, charT>;
\end{codeblock}
\end{itemize}
The \tcode{parse} member functions of these formatters
interpret the format specification
as a \fmtgrammarterm{std-format-spec}
as described in~\ref{format.string.std}.

\pnum
Unless specified otherwise, for each type \tcode{T} for which
a \tcode{formatter} specialization is provided by the library,
each of the headers provides the following specialization:
\begin{codeblock}
template<> inline constexpr bool enable_nonlocking_formatter_optimization<T> = true;
\end{codeblock}
\begin{note}
Specializations such as \tcode{formatter<wchar_t, char>}
that would require implicit
multibyte / wide string or character conversion are disabled.
\end{note}

\pnum
The header \libheaderdef{format} provides
the following disabled specializations:
\begin{itemize}
\item
The string type specializations
\begin{codeblock}
template<> struct formatter<char*, wchar_t>;
template<> struct formatter<const char*, wchar_t>;
template<size_t N> struct formatter<char[N], wchar_t>;
template<class traits, class Allocator>
  struct formatter<basic_string<char, traits, Allocator>, wchar_t>;
template<class traits>
  struct formatter<basic_string_view<char, traits>, wchar_t>;
\end{codeblock}
\end{itemize}

\pnum
For any types \tcode{T} and \tcode{charT} for which
neither the library nor the user provides
an explicit or partial specialization of
the class template \tcode{formatter},
\tcode{formatter<T, charT>} is disabled.

\pnum
If the library provides an explicit or partial specialization of
\tcode{formatter<T, charT>}, that specialization is enabled
and meets the \newoldconcept{Formatter} requirements
except as noted otherwise.

\pnum
If \tcode{F} is a disabled specialization of \tcode{formatter}, these
values are \tcode{false}:
\begin{itemize}
\item \tcode{is_default_constructible_v<F>},
\item \tcode{is_copy_constructible_v<F>},
\item \tcode{is_move_constructible_v<F>},
\item \tcode{is_copy_assignable_v<F>}, and
\item \tcode{is_move_assignable_v<F>}.
\end{itemize}

\pnum
An enabled specialization \tcode{formatter<T, charT>} meets the
\newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}.
\begin{example}
\begin{codeblock}
#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{codeblock}
\end{example}

\rSec3[format.string.escaped]{Formatting escaped characters and strings}

\pnum
\indextext{string!formatted as escaped}%
\indextext{character!formatted as escaped}%
A character or string can be formatted as \defn{escaped}
to make it more suitable for debugging or for logging.

\pnum
The escaped string \placeholder{E} representation of a string \placeholder{S}
is constructed by encoding a sequence of characters as follows.
The associated character encoding \placeholder{CE}
for \tcode{charT}~(\tref{lex.string.literal})
is used to both interpret \placeholder{S} and construct \placeholder{E}.

\begin{itemize}
\item
\unicode{0022}{quotation mark} (\tcode{"}) is appended to \placeholder{E}.

\item
For each code unit sequence \placeholder{X} in \placeholder{S} that either
encodes a single character,
is a shift sequence, or
is a sequence of ill-formed code units,
processing is in order as follows:

\begin{itemize}
\item
If \placeholder{X} encodes a single character \placeholder{C}, then:

\begin{itemize}
\item
If \placeholder{C} is one of the characters in \tref{format.escape.sequences},
then the two characters shown as the corresponding escape sequence
are appended to \placeholder{E}.

\item
Otherwise, if \placeholder{C} is not \unicode{0020}{space} and

\begin{itemize}
\item
\placeholder{CE} is UTF-8, UTF-16, or UTF-32 and
\placeholder{C} corresponds to a Unicode scalar value
whose Unicode property \tcode{General_Category} has a value in the groups
\tcode{Separator} (\tcode{Z}) or \tcode{Other} (\tcode{C}),
as described by \UAX{44} of the Unicode Standard, or

\item
\placeholder{CE} is UTF-8, UTF-16, or UTF-32 and
\placeholder{C} corresponds to a Unicode scalar value
with the Unicode property \tcode{Grapheme_Extend=Yes}
as described by \UAX{44} of the Unicode Standard and
\placeholder{C} is not immediately preceded in \placeholder{S} by
a character \placeholder{P} appended to \placeholder{E}
without translation to an escape sequence, or

\item
\placeholder{CE} is neither UTF-8, UTF-16, nor UTF-32 and
\placeholder{C} is one of an implementation-defined set
of separator or non-printable characters
\end{itemize}

then the sequence \tcode{\textbackslash u\{\placeholder{hex-digit-sequence}\}}
is appended to \placeholder{E},
where \tcode{\placeholder{hex-digit-sequence}}
is the shortest hexadecimal representation
of \placeholder{C} using lower-case hexadecimal digits.

\item
Otherwise, \placeholder{C} is appended to \placeholder{E}.
\end{itemize}

\item
Otherwise, if \placeholder{X} is a shift sequence,
the effect on \placeholder{E} and further decoding of \placeholder{S}
is unspecified.

\recommended
A shift sequence should be represented in \placeholder{E}
such that the original code unit sequence of \placeholder{S}
can be reconstructed.

\item
Otherwise (\placeholder{X} is a sequence of ill-formed code units),
each code unit \placeholder{U} is appended to \placeholder{E} in order
as the sequence \tcode{\textbackslash x\{\placeholder{hex-digit-sequence}\}},
where \tcode{\placeholder{hex-digit-sequence}}
is the shortest hexadecimal representation of \placeholder{U}
using lower-case hexadecimal digits.
\end{itemize}

\item
Finally, \unicode{0022}{quotation mark} (\tcode{"})
is appended to \placeholder{E}.
\end{itemize}
%
\begin{floattable}{Mapping of characters to escape sequences}{format.escape.sequences}{ll}
\topline
\lhdr{Character} & \rhdr{Escape sequence} \\ \rowsep
\unicode{0009}{character tabulation} &
\tcode{\textbackslash t}
\\ \rowsep
%
\unicode{000a}{line feed} &
\tcode{\textbackslash n}
\\ \rowsep
%
\unicode{000d}{carriage return} &
\tcode{\textbackslash r}
\\ \rowsep
%
\unicode{0022}{quotation mark} &
\tcode{\textbackslash "}
\\ \rowsep
%
\unicode{005c}{reverse solidus} &
\tcode{\textbackslash\textbackslash}
\\
\end{floattable}

\pnum
The escaped string representation of a character \placeholder{C}
is equivalent to the escaped string representation
of a string of \placeholder{C}, except that:

\begin{itemize}
\item
the result starts and ends with \unicode{0027}{apostrophe} (\tcode{'})
instead of \unicode{0022}{quotation mark} (\tcode{"}), and
\item
if \placeholder{C} is \unicode{0027}{apostrophe},
the two characters \tcode{\textbackslash '} are appended to \placeholder{E}, and
\item
if \placeholder{C} is \unicode{0022}{quotation mark},
then \placeholder{C} is appended unchanged.
\end{itemize}

\begin{example}
\begin{codeblock}
string s0 = format("[{}]", "h\tllo");                   // \tcode{s0} has value: \tcode{[h\ \ \ \ llo]}
string s1 = format("[{:?}]", "h\tllo");                 // \tcode{s1} has value: \tcode{["h\textbackslash tllo"]}
string s2 = format("[{:?}]", "@\importexample[-2.5pt]{example_01}@");  @\kern1.25pt@// \tcode{s2} has value: \tcode{["\importexample[-2.5pt]{example_01}"]}
string s3 = format("[{:?}, {:?}]", '\'', '"');          // \tcode{s3} has value: \tcode{['\textbackslash '', '"']}

// The following examples assume use of the UTF-8 encoding
string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9));
                                                    // \tcode{s4} has value: \tcode{["\textbackslash u\{0\} \textbackslash n \textbackslash t \textbackslash u\{2\} \textbackslash u\{1b\}"]}
string s5 = format("[{:?}]", "\xc3\x28");           // invalid UTF-8, \tcode{s5} has value: \tcode{["\textbackslash x\{c3\}("]}
string s6 = format("[{:?}]", "@\importexample{example_02}@");                 @\kern0.75pt@// \tcode{s6} has value: \tcode{["\importexample{example_03}\textbackslash{u}\{200d\}\importexample{example_04}"]}
string s7 = format("[{:?}]", "\u0301");             // \tcode{s7} has value: \tcode{["\textbackslash u\{301\}"]}
string s8 = format("[{:?}]", "\\\u0301");           // \tcode{s8} has value: \tcode{["\textbackslash \textbackslash \textbackslash u\{301\}"]}
string s9 = format("[{:?}]", "e\u0301\u0323");      // \tcode{s9} has value: \tcode{["\importexample[-2pt]{example_06}"]}
\end{codeblock}
\end{example}

\rSec3[format.parse.ctx]{Class template \tcode{basic_format_parse_context}}

\indexlibraryglobal{basic_format_parse_context}%
\indexlibrarymember{char_type}{basic_format_parse_context}%
\indexlibrarymember{const_iterator}{basic_format_parse_context}%
\indexlibrarymember{iterator}{basic_format_parse_context}%
\begin{codeblock}
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_;                                    // \expos
    iterator end_;                                      // \expos
    enum indexing { unknown, manual, automatic };       // \expos
    indexing indexing_;                                 // \expos
    size_t next_arg_id_;                                // \expos
    size_t num_args_;                                   // \expos

  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;
  };
}
\end{codeblock}

\pnum
An instance of \tcode{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.

\pnum
If a program declares an explicit or partial specialization of
\tcode{basic_format_parse_context},
the program is ill-formed, no diagnostic required.

\indexlibraryctor{basic_format_parse_context}%
\begin{itemdecl}
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes
\tcode{begin_} with \tcode{fmt.begin()},
\tcode{end_} with \tcode{fmt.end()},
\tcode{indexing_} with \tcode{unknown},
\tcode{next_arg_id_} with \tcode{0}, and
\tcode{num_args_} with \tcode{0}.
\begin{note}
Any call to
\tcode{next_arg_id}, \tcode{check_arg_id}, or \tcode{check_dynamic_spec}
on an instance of \tcode{basic_format_parse_context}
initialized using this constructor is not a core constant expression.
\end{note}
\end{itemdescr}

\indexlibrarymember{begin}{basic_format_parse_context}%
\begin{itemdecl}
constexpr const_iterator begin() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{begin_}.
\end{itemdescr}

\indexlibrarymember{end}{basic_format_parse_context}%
\begin{itemdecl}
constexpr const_iterator end() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{end_}.
\end{itemdescr}

\indexlibrarymember{advance_to}{basic_format_parse_context}%
\begin{itemdecl}
constexpr void advance_to(const_iterator it);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{end()} is reachable from \tcode{it}.

\pnum
\effects
Equivalent to: \tcode{begin_ = it;}
\end{itemdescr}

\indexlibrarymember{next_arg_id}{basic_format_parse_context}%
\begin{itemdecl}
constexpr size_t next_arg_id();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{indexing_ != manual} is \tcode{true}, equivalent to:
\begin{codeblock}
if (indexing_ == unknown)
  indexing_ = automatic;
return next_arg_id_++;
\end{codeblock}

\pnum
\throws
\tcode{format_error} if \tcode{indexing_ == manual} is \tcode{true}.
\begin{note}
This indicates mixing of automatic and manual argument indexing.
\end{note}

\pnum
\remarks
Let \tcode{\placeholder{cur-arg-id}} be the value of \tcode{next_arg_id_} prior to this call.
Call expressions where \tcode{\placeholder{cur-arg-id} >= num_args_} is \tcode{true}
are not core constant expressions\iref{expr.const.core}.
\end{itemdescr}

\indexlibrarymember{check_arg_id}{basic_format_parse_context}%
\begin{itemdecl}
constexpr void check_arg_id(size_t id);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{indexing_ != automatic} is \tcode{true}, equivalent to:
\begin{codeblock}
if (indexing_ == unknown)
  indexing_ = manual;
\end{codeblock}

\pnum
\throws
\tcode{format_error} if
\tcode{indexing_ == automatic} is \tcode{true}.
\begin{note}
This indicates mixing of automatic and manual argument indexing.
\end{note}

\pnum
\remarks
A call to this function is a core constant expression\iref{expr.const.core} only if
\tcode{id < num_args_} is \tcode{true}.
\end{itemdescr}

\indexlibrarymember{check_dynamic_spec}{basic_format_parse_context}%
\begin{itemdecl}
template<class... Ts>
  constexpr void check_dynamic_spec(size_t id) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
$\tcode{sizeof...(Ts)} \ge 1$.
The types in \tcode{Ts...} are unique.
Each type in \tcode{Ts...} is one of
\keyword{bool},
\tcode{char_type},
\keyword{int},
\tcode{\keyword{unsigned} \keyword{int}},
\tcode{\keyword{long} \keyword{long} \keyword{int}},
\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}},
\keyword{float},
\keyword{double},
\tcode{\keyword{long} \keyword{double}},
\tcode{\keyword{const} char_type*},
\tcode{basic_string_view<char_type>}, or
\tcode{\keyword{const} \keyword{void}*}.

\pnum
\remarks
A call to this function is a core constant expression only if
\begin{itemize}
\item
\tcode{id < num_args_} is \tcode{true} and
\item
the type of the corresponding format argument
(after conversion to \tcode{basic_format_arg<Context>}) is one of the types in \tcode{Ts...}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{check_dynamic_spec_integral}{basic_format_parse_context}%
\begin{itemdecl}
constexpr void check_dynamic_spec_integral(size_t id) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
check_dynamic_spec<int, unsigned int, long long int, unsigned long long int>(id);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{check_dynamic_spec_string}{basic_format_parse_context}%
\begin{itemdecl}
constexpr void check_dynamic_spec_string(size_t id) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
check_dynamic_spec<const char_type*, basic_string_view<char_type>>(id);
\end{codeblock}
\end{itemdescr}

\rSec3[format.context]{Class template \tcode{basic_format_context}}

\indexlibraryglobal{basic_format_context}%
\indexlibrarymember{iterator}{basic_format_context}%
\indexlibrarymember{char_type}{basic_format_context}%
\indexlibrarymember{formatter_type}{basic_format_context}%
\begin{codeblock}
namespace std {
  template<class Out, class charT>
  class basic_format_context {
    basic_format_args<basic_format_context> args_;      // \expos
    Out out_;                                           // \expos

    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);
  };
}
\end{codeblock}

\pnum
An instance of \tcode{basic_format_context} holds formatting state
consisting of the formatting arguments and the output iterator.

\pnum
If a program declares an explicit or partial specialization of
\tcode{basic_format_context},
the program is ill-formed, no diagnostic required.

\pnum
\tcode{Out} shall model \tcode{\libconcept{output_iterator}<const charT\&>}.

\pnum
\indexlibraryglobal{format_context}%
\tcode{format_context} is an alias for
a specialization of \tcode{basic_format_context}
with an output iterator
that appends to \tcode{string},
such as \tcode{back_insert_iterator<string>}.
\indexlibraryglobal{wformat_context}%
Similarly, \tcode{wformat_context} is an alias for
a specialization of \tcode{basic_format_context}
with an output iterator
that appends to \tcode{wstring}.

\pnum
\recommended
For a given type \tcode{charT},
implementations should provide
a single specialization of \tcode{basic_format_context}
for appending to
\tcode{basic_string<charT>},
\tcode{vector<charT>},
or any other container with contiguous storage
by wrapping those in temporary objects with a uniform interface
(such as a \tcode{span<charT>}) and polymorphic reallocation.

\indexlibrarymember{arg}{basic_format_context}%
\begin{itemdecl}
constexpr basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{args_.get(id)}.
\end{itemdescr}

\indexlibrarymember{locale}{basic_format_context}%
\begin{itemdecl}
std::locale locale();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The locale passed to the formatting function
if the latter takes one,
and \tcode{std::locale()} otherwise.
\end{itemdescr}

\indexlibrarymember{out}{basic_format_context}%
\begin{itemdecl}
constexpr iterator out();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return std::move(out_);}
\end{itemdescr}

\indexlibrarymember{advance_to}{basic_format_context}%
\begin{itemdecl}
constexpr void advance_to(iterator it);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{out_ = std::move(it);}
\end{itemdescr}

\indextext{left-pad}%
\begin{example}
\begin{codeblock}
struct S { int value; };

template<> struct std::formatter<S> {
  size_t width_arg_id = 0;

  // Parses a width argument id in the format \tcode{\{} \fmtgrammarterm{digit} \tcode{\}}.
  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 \tcode{S} with width given by the argument \tcode{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 \tcode{s} is \tcode{"xxxxxxxx42"}
\end{codeblock}
\end{example}

\rSec2[format.range]{Formatting of ranges}

\rSec3[format.range.fmtkind]{Variable template \tcode{format_kind}}

\indexlibraryglobal{format_kind}
\begin{itemdecl}
template<ranges::@\libconcept{input_range}@ R>
  requires @\libconcept{same_as}@<R, remove_cvref_t<R>>
  constexpr range_format format_kind<R> = @\seebelow@;
\end{itemdecl}

\begin{itemdescr}
\pnum
A program that instantiates the primary template of \tcode{format_kind}
is ill-formed.

\pnum
For a type \tcode{R}, \tcode{format_kind<R>} is defined as follows:
\begin{itemize}
\item
If \tcode{\libconcept{same_as}<remove_cvref_t<ranges::range_reference_t<R>>, R>}
is \tcode{true},
\tcode{format_kind<R>} is \tcode{range_format::disabled}.
\begin{note}
This prevents constraint recursion for ranges whose
reference type is the same range type.
For example,
\tcode{std::filesystem::path} is a range of \tcode{std::filesystem::path}.
\end{note}

\item
Otherwise, if the \grammarterm{qualified-id} \tcode{R::key_type}
is valid and denotes a type:
\begin{itemize}
\item
If the \grammarterm{qualified-id} \tcode{R::mapped_type}
is valid and denotes a type,
let \tcode{U} be \tcode{remove_cvref_t<ranges::range_reference_t<R>>}.
If either \tcode{U} is a specialization of \tcode{pair} or
\tcode{U} is a specialization of \tcode{tuple} and
\tcode{tuple_size_v<U> == 2},
\tcode{format_kind<R>} is \tcode{range_format::map}.
\item
Otherwise, \tcode{format_kind<R>} is \tcode{range_format::set}.
\end{itemize}

\item
Otherwise, \tcode{format_kind<R>} is \tcode{range_format::sequence}.
\end{itemize}

\pnum
\remarks
Pursuant to \ref{namespace.std}, users may specialize \tcode{format_kind}
for cv-unqualified program-defined types
that model \tcode{ranges::\libconcept{input_range}}.
Such specializations shall be usable in constant expressions\iref{expr.const.init}
and have type \tcode{const range_format}.
\end{itemdescr}

\rSec3[format.range.formatter]{Class template \tcode{range_formatter}}

\indexlibraryglobal{range_formatter}%
\begin{codeblock}
namespace std {
  template<class T, class charT = char>
    requires @\libconcept{same_as}@<remove_cvref_t<T>, T> && @\libconcept{formattable}@<T, charT>
  class range_formatter {
    formatter<T, charT> @\exposid{underlying_}@;                                          // \expos
    basic_string_view<charT> @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@<charT>(", ");      // \expos
    basic_string_view<charT> @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@<charT>("["); // \expos
    basic_string_view<charT> @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@<charT>("]"); // \expos

  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 @\exposid{underlying_}@; }
    constexpr const formatter<T, charT>& underlying() const noexcept { return @\exposid{underlying_}@; }

    template<class ParseContext>
      constexpr typename ParseContext::iterator
        parse(ParseContext& ctx);

    template<ranges::@\libconcept{input_range}@ R, class FormatContext>
        requires @\libconcept{formattable}@<ranges::range_reference_t<R>, charT> &&
                 @\libconcept{same_as}@<remove_cvref_t<ranges::range_reference_t<R>>, T>
      constexpr typename FormatContext::iterator
        format(R&& r, FormatContext& ctx) const;
  };
}
\end{codeblock}

\pnum
The class template \tcode{range_formatter} is a utility
for implementing \tcode{formatter} specializations for range types.

\pnum
\tcode{range_formatter} interprets \fmtgrammarterm{format-spec}
as a \fmtgrammarterm{range-format-spec}.
The syntax of format specifications is as follows:

\begin{ncbnf}
\fmtnontermdef{range-format-spec}\br
    \opt{range-fill-and-align} \opt{width} \opt{\terminal{n}} \opt{range-type} \opt{range-underlying-spec}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{range-fill-and-align}\br
    \opt{range-fill} align
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{range-fill}\br
    \textnormal{any character other than} \terminal{\{} \textnormal{or} \terminal{\}} \textnormal{or} \terminal{:}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{range-type}\br
    \terminal{m}\br
    \terminal{s}\br
    \terminal{?s}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{range-underlying-spec}\br
    \terminal{:} format-spec
\end{ncbnf}

\pnum
For \tcode{range_formatter<T, charT>},
the \fmtgrammarterm{format-spec}
in a \fmtgrammarterm{range-underlying-spec}, if any,
is interpreted by \tcode{formatter<T, charT>}.

\pnum
The \fmtgrammarterm{range-fill-and-align} is interpreted
the same way as a \fmtgrammarterm{fill-and-align}\iref{format.string.std}.
The productions \fmtgrammarterm{align} and \fmtgrammarterm{width}
are described in \ref{format.string}.

\pnum
The \tcode{n} option causes the range to be formatted
without the opening and closing brackets.
\begin{note}
This is equivalent to invoking \tcode{set_brackets(\{\}, \{\})}.
\end{note}

\pnum
The \fmtgrammarterm{range-type} specifier changes the way a range is formatted,
with certain options only valid with certain argument types.
The meaning of the various type options
is as specified in \tref{formatter.range.type}.

\begin{concepttable}{Meaning of \fmtgrammarterm{range-type} options}{formatter.range.type}
{p{1in}p{1.4in}p{2.7in}}
\topline
\hdstyle{Option} & \hdstyle{Requirements} & \hdstyle{Meaning} \\ \capsep
%
\tcode{m} &
\tcode{T} shall be
either a specialization of \tcode{pair} or a specialization of \tcode{tuple}
such that \tcode{tuple_size_v<T>} is \tcode{2}. &
Indicates that
the opening bracket should be \tcode{"\{"},
the closing bracket should be \tcode{"\}"},
the separator should be \tcode{", "}, and
each range element should be formatted as if
\tcode{m} were specified for its \fmtgrammarterm{tuple-type}.
\begin{tailnote}
If the \tcode{n} option is provided in addition to the \tcode{m} option,
both the opening and closing brackets are still empty.
\end{tailnote}
\\ \rowsep
%
\tcode{s} &
\tcode{T} shall be \tcode{charT}. &
Indicates that the range should be formatted as a \tcode{string}.
\\ \rowsep
%
\tcode{?s} &
\tcode{T} shall be \tcode{charT}. &
Indicates that the range should be formatted as
an escaped string\iref{format.string.escaped}.
\\
\end{concepttable}

If the \fmtgrammarterm{range-type} is \tcode{s} or \tcode{?s},
then there shall be
no \tcode{n} option and no \fmtgrammarterm{range-underlying-spec}.

\indexlibrarymember{set_separator}{range_formatter}%
\begin{itemdecl}
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{\exposid{separator_} = sep;}
\end{itemdescr}

\indexlibrarymember{set_brackets}{range_formatter}%
\begin{itemdecl}
constexpr void set_brackets(basic_string_view<charT> opening,
                            basic_string_view<charT> closing) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{opening-bracket_}@ = opening;
@\exposid{closing-bracket_}@ = closing;
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{parse}{range_formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Parses the format specifiers as a \fmtgrammarterm{range-format-spec} and
stores the parsed specifiers in \tcode{*this}.
Calls \tcode{\exposid{underlying_}.parse(ctx)} to parse
\fmtgrammarterm{format-spec} in \fmtgrammarterm{range-format-spec} or,
if the latter is not present, an empty \fmtgrammarterm{format-spec}.
The values of
\exposid{opening-bracket_}, \exposid{closing-bracket_}, and \exposid{separator_}
are modified if and only if required by
the \fmtgrammarterm{range-type} or the \tcode{n} option, if present.
If:
\begin{itemize}
\item
the \fmtgrammarterm{range-type} is neither \tcode{s} nor \tcode{?s},
\item
\tcode{\exposid{underlying_}.set_debug_format()} is a valid expression, and
\item
there is no \fmtgrammarterm{range-underlying-spec},
\end{itemize}
then calls \tcode{\exposid{underlying_}.set_debug_format()}.

\pnum
\returns
An iterator past the end of the \fmtgrammarterm{range-format-spec}.
\end{itemdescr}

\indexlibrarymember{format}{range_formatter}%
\begin{itemdecl}
template<ranges::@\libconcept{input_range}@ R, class FormatContext>
    requires @\libconcept{formattable}@<ranges::range_reference_t<R>, charT> &&
             @\libconcept{same_as}@<remove_cvref_t<ranges::range_reference_t<R>>, T>
  constexpr typename FormatContext::iterator
    format(R&& r, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Writes the following into \tcode{ctx.out()},
adjusted according to the \fmtgrammarterm{range-format-spec}:

\begin{itemize}
\item
If the \fmtgrammarterm{range-type} was \tcode{s},
then as if by formatting \tcode{basic_string<charT>(from_range, r)}.
\item
Otherwise, if the \fmtgrammarterm{range-type} was \tcode{?s},
then as if by formatting \tcode{basic_string<charT>(from_range, r)}
as an escaped string\iref{format.string.escaped}.
\item
Otherwise,
\begin{itemize}
\item
\exposid{opening-bracket_},
\item
for each element \tcode{e} of the range \tcode{r}:
\begin{itemize}
\item
the result of writing \tcode{e} via \exposid{underlying_} and
\item
\exposid{separator_}, unless \tcode{e} is the last element of \tcode{r}, and
\end{itemize}
\item
\exposid{closing-bracket_}.
\end{itemize}
\end{itemize}

\pnum
\returns
An iterator past the end of the output range.
\end{itemdescr}

\rSec3[format.range.fmtdef]{Class template \exposid{range-default-formatter}}

\indexlibrary{range-default-formatter@\exposid{range-default-formatter}}%
\begin{codeblock}
namespace std {
  template<ranges::@\libconcept{input_range}@ R, class charT>
  struct @\exposidnc{range-default-formatter}@<range_format::sequence, R, charT> {    // \expos
  private:
    using @\exposidnc{maybe-const-r}@ = @\exposidnc{fmt-maybe-const}@<R, charT>;                    // \expos
    range_formatter<remove_cvref_t<ranges::range_reference_t<@\exposid{maybe-const-r}@>>,
                    charT> @\exposid{underlying_}@;                                 // \expos

  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(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const;
  };
}
\end{codeblock}

\indexlibrarymemberexpos{set_separator}{range-default-formatter}%
\begin{itemdecl}
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{\exposid{underlying_}.set_separator(sep);}
\end{itemdescr}

\indexlibrarymemberexpos{set_brackets}{range-default-formatter}%
\begin{itemdecl}
constexpr void set_brackets(basic_string_view<charT> opening,
                            basic_string_view<charT> closing) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{\exposid{underlying_}.set_brackets(opening, closing);}
\end{itemdescr}

\indexlibrarymemberexpos{parse}{range-default-formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);}
\end{itemdescr}

\indexlibrarymemberexpos{format}{range-default-formatter}%
\begin{itemdecl}
template<class FormatContext>
  constexpr typename FormatContext::iterator
    format(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.format(elems, ctx);}
\end{itemdescr}

\rSec3[format.range.fmtmap]{Specialization of \exposid{range-default-formatter} for maps}

\indexlibrary{range-default-formatter@\exposid{range-default-formatter}}%
\begin{codeblock}
namespace std {
  template<ranges::@\libconcept{input_range}@ R, class charT>
  struct @\exposid{range-default-formatter}@<range_format::map, R, charT> {
  private:
    using @\exposidnc{maybe-const-map}@ = @\exposidnc{fmt-maybe-const}@<R, charT>;                  // \expos
    using @\exposidnc{element-type}@ =                                                // \expos
      remove_cvref_t<ranges::range_reference_t<@\exposid{maybe-const-map}@>>;
    range_formatter<@\exposidnc{element-type}@, charT> @\exposid{underlying_}@;                   // \expos

  public:
    constexpr @\exposid{range-default-formatter}@();

    template<class ParseContext>
      constexpr typename ParseContext::iterator
        parse(ParseContext& ctx);

    template<class FormatContext>
      constexpr typename FormatContext::iterator
        format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const;
  };
}
\end{codeblock}

\indexlibrarymisc{range-default-formatter@\exposid{range-default-formatter}}{constructor}%
\begin{itemdecl}
constexpr @\exposid{range-default-formatter}@();
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
Either:
\begin{itemize}
\item
\exposid{element-type} is a specialization of \tcode{pair}, or
\item
\exposid{element-type} is a specialization of \tcode{tuple} and
\tcode{tuple_size_v<\exposid{element-type}> == 2}.
\end{itemize}

\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@<charT>("{"), @\exposid{STATICALLY-WIDEN}@<charT>("}"));
@\exposid{underlying_}@.underlying().set_brackets({}, {});
@\exposid{underlying_}@.underlying().set_separator(@\exposid{STATICALLY-WIDEN}@<charT>(": "));
\end{codeblock}
\end{itemdescr}

\indexlibrarymemberexpos{parse}{range-default-formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);}
\end{itemdescr}

\indexlibrarymemberexpos{format}{range-default-formatter}%
\begin{itemdecl}
template<class FormatContext>
  constexpr typename FormatContext::iterator
    format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);}
\end{itemdescr}

\rSec3[format.range.fmtset]{Specialization of \exposid{range-default-formatter} for sets}

\indexlibrary{range-default-formatter@\exposid{range-default-formatter}}%
\begin{codeblock}
namespace std {
  template<ranges::@\libconcept{input_range}@ R, class charT>
  struct @\exposid{range-default-formatter}@<range_format::set, R, charT> {
  private:
    using @\exposidnc{maybe-const-set}@ = @\exposidnc{fmt-maybe-const}@<R, charT>;                  // \expos
    range_formatter<remove_cvref_t<ranges::range_reference_t<@\exposid{maybe-const-set}@>>,
                    charT> @\exposid{underlying_}@;                                 // \expos

  public:
    constexpr @\exposid{range-default-formatter}@();

    template<class ParseContext>
      constexpr typename ParseContext::iterator
        parse(ParseContext& ctx);

    template<class FormatContext>
      constexpr typename FormatContext::iterator
        format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const;
  };
}
\end{codeblock}

\indexlibrarymisc{range-default-formatter@\exposid{range-default-formatter}}{constructor}%
\begin{itemdecl}
constexpr @\exposid{range-default-formatter}@();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@<charT>("{"), @\exposid{STATICALLY-WIDEN}@<charT>("}"));
\end{codeblock}
\end{itemdescr}

\indexlibrarymemberexpos{parse}{range-default-formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);}
\end{itemdescr}

\indexlibrarymemberexpos{format}{range-default-formatter}%
\begin{itemdecl}
template<class FormatContext>
  constexpr typename FormatContext::iterator
    format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);}
\end{itemdescr}

\rSec3[format.range.fmtstr]{Specialization of \exposid{range-default-formatter} for strings}

\indexlibrary{range-default-formatter@\exposid{range-default-formatter}}%
\begin{codeblock}
namespace std {
  template<range_format K, ranges::@\libconcept{input_range}@ R, class charT>
    requires (K == range_format::string || K == range_format::debug_string)
  struct @\exposid{range-default-formatter}@<K, R, charT> {
  private:
    formatter<basic_string<charT>, charT> @\exposid{underlying_}@;                  // \expos

  public:
    template<class ParseContext>
      constexpr typename ParseContext::iterator
        parse(ParseContext& ctx);

    template<class FormatContext>
      constexpr typename FormatContext::iterator
        format(@\seebelow@& str, FormatContext& ctx) const;
  };
}
\end{codeblock}

\pnum
\mandates
\tcode{\libconcept{same_as}<remove_cvref_t<range_reference_t<R>>, charT>}
is \tcode{true}.

\indexlibrarymemberexpos{parse}{range-default-formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
auto i = @\exposid{underlying_}@.parse(ctx);
if constexpr (K == range_format::debug_string) {
  @\exposid{underlying_}@.set_debug_format();
}
return i;
\end{codeblock}
\end{itemdescr}

\indexlibrarymemberexpos{format}{range-default-formatter}%
\begin{itemdecl}
template<class FormatContext>
  typename FormatContext::iterator
    format(@\seebelow@& r, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
The type of \tcode{r} is \tcode{const R\&}
if \tcode{ranges::\libconcept{input_range}<const R>} is \tcode{true} and
\tcode{R\&} otherwise.

\pnum
\effects
Let \tcode{\placeholder{s}} be a \tcode{basic_string<charT>} such that
\tcode{ranges::equal(\placeholder{s}, r)} is \tcode{true}.
Equivalent to: \tcode{return \exposid{underlying_}.format(\placeholder{s}, ctx);}
\end{itemdescr}

\rSec2[format.arguments]{Arguments}

\rSec3[format.arg]{Class template \tcode{basic_format_arg}}

\indexlibraryglobal{basic_format_arg}%
\begin{codeblock}
namespace std {
  template<class Context>
  class basic_format_arg {
  public:
    class handle;

  private:
    using @\exposid{char-type}@ = Context::char_type;                                       // \expos

    variant<monostate, bool, @\exposid{char-type}@,
            int, unsigned int, long long int, unsigned long long int,
            float, double, long double,
            const @\exposid{char-type}@*, basic_string_view<@\exposid{char-type}@>,
            const void*, handle> @\exposid{value_}@;                                        // \expos

    template<class T> constexpr explicit basic_format_arg(T& v) noexcept;       // \expos

  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);
  };
}
\end{codeblock}

\pnum
An instance of \tcode{basic_format_arg} provides access to
a formatting argument for user-defined formatters.

\pnum
The behavior of a program that adds specializations of
\tcode{basic_format_arg} is undefined.

\indexlibrary{\idxcode{basic_format_arg}!constructor|(}%
\begin{itemdecl}
constexpr basic_format_arg() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{!(*this)}.
\end{itemdescr}

\begin{itemdecl}
template<class T> constexpr explicit basic_format_arg(T& v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{T} satisfies \tcode{\exposconcept{formattable-with}<Context>}.

\pnum
\expects
If \tcode{decay_t<T>} is \tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*},
\tcode{static_cast<const \exposid{char-\linebreak{}type}*>(v)} points to an NTCTS\iref{defns.ntcts}.

\pnum
\effects
Let \tcode{TD} be \tcode{remove_const_t<T>}.
\begin{itemize}
\item
If \tcode{TD} is \tcode{bool} or \exposid{char-type},
initializes \exposid{value_} with \tcode{v};
\item
otherwise, if \tcode{TD} is \tcode{char} and \exposid{char-type} is
\keyword{wchar_t}, initializes \exposid{value_} with
\tcode{static_cast<wchar_t>(static_cast<unsigned char>(v))};
\item
otherwise, if \tcode{TD} is a signed integer type\iref{basic.fundamental}
and \tcode{sizeof(TD) <= sizeof(int)},
initializes \exposid{value_} with \tcode{static_cast<int>(v)};
\item
otherwise, if \tcode{TD} is an unsigned integer type and
\tcode{sizeof(TD) <= sizeof(unsigned int)}, initializes
\exposid{value_} with \tcode{static_cast<unsigned int>(v)};
\item
otherwise, if \tcode{TD} is a signed integer type and
\tcode{sizeof(TD) <= sizeof(long long int)}, initializes
\exposid{value_} with \tcode{static_cast<long long int>(v)};
\item
otherwise, if \tcode{TD} is an unsigned integer type and
\tcode{sizeof(TD) <= sizeof(unsigned long long int)}, initializes
\exposid{value_} with
\tcode{static_cast<unsigned long long int>(v)};
\item
otherwise, if \tcode{TD} is a standard floating-point type,
initializes \exposid{value_} with \tcode{v};
\item
otherwise, if \tcode{TD} is
a specialization of \tcode{basic_string_view} or \tcode{basic_string} and
\tcode{TD::value_type} is \exposid{char-type},
initializes \exposid{value_} with
\tcode{basic_string_view<\exposid{char-type}>(v.data(), v.size())};
\item
otherwise, if \tcode{decay_t<TD>} is
\tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*},
initializes \exposid{value_} with \tcode{static_cast<const \exposid{char-type}*>(v)};
\item
otherwise, if \tcode{is_void_v<remove_pointer_t<TD>>} is \tcode{true} or
\tcode{is_null_pointer_v<TD>} is \tcode{true},
initializes \exposid{value_} with \tcode{static_cast<const void*>(v)};
\item
otherwise, initializes \exposid{value_} with \tcode{handle(v)}.
\end{itemize}
\begin{note}
Constructing \tcode{basic_format_arg} from a pointer to a member is ill-formed
unless the user provides an enabled specialization of \tcode{formatter}
for that pointer to member type.
\end{note}
\end{itemdescr}

\indexlibrary{\idxcode{basic_format_arg}!constructor|)}%

\indexlibrarymember{operator bool}{basic_format_arg}%
\begin{itemdecl}
constexpr explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!holds_alternative<monostate>(\exposid{value_})}.
\end{itemdescr}

\indexlibrarymember{visit}{basic_format_arg}%
\begin{itemdecl}
template<class Visitor>
  constexpr decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return arg.\exposid{value_}.visit(std::forward<Visitor>(vis));}
\end{itemdescr}

\indexlibrarymember{visit}{basic_format_arg}%
\begin{itemdecl}
template<class R, class Visitor>
  constexpr R visit(this basic_format_arg arg, Visitor&& vis);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return arg.\exposid{value_}.visit<R>(std::forward<Visitor>(vis));}
\end{itemdescr}

\pnum
The class \tcode{handle} allows formatting an object of a user-defined type.

\indexlibraryglobal{basic_format_arg::handle}%
\indexlibrarymember{handle}{basic_format_arg}%
\begin{codeblock}
namespace std {
  template<class Context>
  class basic_format_arg<Context>::handle {
    const void* @\exposid{ptr_}@;                                                   // \expos
    void (*@\exposid{format_}@)(basic_format_parse_context<@\exposid{char-type}@>&,
                    Context&, const void*);                             // \expos

    template<class T> constexpr explicit handle(T& val) noexcept;       // \expos

  public:
    constexpr void format(basic_format_parse_context<@\exposid{char-type}@>&, Context& ctx) const;
  };
}
\end{codeblock}

\indexlibraryctor{basic_format_arg::handle}%
\begin{itemdecl}
template<class T> constexpr explicit handle(T& val) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Let
\begin{itemize}
\item
\tcode{TD} be \tcode{remove_const_t<T>},
\item
\tcode{TQ} be \tcode{const TD} if
\tcode{const TD} satisfies \tcode{\exposconcept{formattable-with}<Context>}
and \tcode{TD} otherwise.
\end{itemize}

\pnum
\mandates
\tcode{TQ} satisfies \tcode{\exposconcept{formattable-with}<Context>}.

\pnum
\effects
Initializes
\exposid{ptr_} with \tcode{addressof(val)} and
\exposid{format_} with
\begin{codeblock}
[](basic_format_parse_context<@\exposid{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));
}
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{format}{basic_format_arg::handle}%
\begin{itemdecl}
constexpr void format(basic_format_parse_context<@\exposid{char-type}@>& parse_ctx, Context& format_ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{\exposid{format_}(parse_ctx, format_ctx, \exposid{ptr_});}
\end{itemdescr}

\rSec3[format.arg.store]{Class template \exposid{format-arg-store}}

\begin{codeblock}
namespace std {
  template<class Context, class... Args>
  class @\exposidnc{format-arg-store}@ {                                      // \expos
    array<basic_format_arg<Context>, sizeof...(Args)> @\exposidnc{args}@;     // \expos
  };
}
\end{codeblock}

\pnum
An instance of \exposid{format-arg-store} stores formatting arguments.

\indexlibraryglobal{make_format_args}%
\begin{itemdecl}
template<class Context = format_context, class... Args>
  constexpr @\exposid{format-arg-store}@<Context, Args...>
    make_format_args(Args&... fmt_args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The type
\tcode{typename Context::template formatter_type<remove_const_t<}$\tcode{T}_i$\tcode{>>}\linebreak{}
meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}
for each $\tcode{T}_i$ in \tcode{Args}.

\pnum
\returns
An object of type \tcode{\exposid{format-arg-store}<Context, Args...>}
whose \exposid{args} data member is initialized with
\tcode{\{basic_format_arg<Context>(fmt_args)...\}}.
\end{itemdescr}

\indexlibraryglobal{make_wformat_args}%
\begin{itemdecl}
template<class... Args>
  constexpr @\exposid{format-arg-store}@<wformat_context, Args...>
    make_wformat_args(Args&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\tcode{return make_format_args<wformat_context>(args...);}
\end{itemdescr}

\rSec3[format.args]{Class template \tcode{basic_format_args}}

\begin{codeblock}
namespace std {
  template<class Context>
  class basic_format_args {
    size_t @\exposid{size_}@;                               // \expos
    const basic_format_arg<Context>* @\exposid{data_}@;     // \expos

  public:
    template<class... Args>
      constexpr basic_format_args(const @\exposid{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(@\exposid{format-arg-store}@<Context, Args...>) -> basic_format_args<Context>;
}
\end{codeblock}

\pnum
An instance of \tcode{basic_format_args} provides access to formatting
arguments.

\pnum
\recommended
Implementations should
optimize the representation of \tcode{basic_format_args}
for a small number of formatting arguments.
\begin{note}
For example, by storing indices of type alternatives separately from values
and packing the former.
\end{note}

\indexlibraryctor{basic_format_args}%
\begin{itemdecl}
template<class... Args>
  constexpr basic_format_args(const @\exposid{format-arg-store}@<Context, Args...>& store) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes
\exposid{size_} with \tcode{sizeof...(Args)} and
\exposid{data_} with \tcode{store.\exposid{args}.data()}.
\end{itemdescr}

\indexlibrarymember{get}{basic_format_args}%
\begin{itemdecl}
constexpr basic_format_arg<Context> get(size_t i) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{i < \exposid{size_} ?\ \exposid{data_}[i] :\ basic_format_arg<Context>()}.
\end{itemdescr}

\rSec2[format.tuple]{Tuple formatter}

\pnum
For each of \tcode{pair} and \tcode{tuple},
the library provides the following formatter specialization
where \tcode{\placeholder{pair-or-tuple}} is the name of the template:

\indexlibraryglobal{formatter}%
\begin{codeblock}
namespace std {
  template<class charT, @\libconcept{formattable}@<charT>... Ts>
  struct formatter<@\placeholder{pair-or-tuple}@<Ts...>, charT> {
  private:
    tuple<formatter<remove_cvref_t<Ts>, charT>...> @\exposid{underlying_}@;               // \expos
    basic_string_view<charT> @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@<charT>(", ");      // \expos
    basic_string_view<charT> @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@<charT>("("); // \expos
    basic_string_view<charT> @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@<charT>(")"); // \expos

  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(@\seebelow@& elems, FormatContext& ctx) const;
  };

  template<class... Ts>
    constexpr bool enable_nonlocking_formatter_optimization<@\placeholder{pair-or-tuple}@<Ts...>> =
      (enable_nonlocking_formatter_optimization<remove_cvref_t<Ts>> && ...);
}
\end{codeblock}

\pnum
The \tcode{parse} member functions of these formatters
interpret the format specification as
a \fmtgrammarterm{tuple-format-spec} according to the following syntax:

\begin{ncbnf}
\fmtnontermdef{tuple-format-spec}\br
    \opt{tuple-fill-and-align} \opt{width} \opt{tuple-type}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{tuple-fill-and-align}\br
    \opt{tuple-fill} align
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{tuple-fill}\br
    \textnormal{any character other than} \terminal{\{} \textnormal{or} \terminal{\}} \textnormal{or} \terminal{:}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{tuple-type}\br
    \terminal{m}\br
    \terminal{n}
\end{ncbnf}

\pnum
The \fmtgrammarterm{tuple-fill-and-align} is interpreted the same way as
a \fmtgrammarterm{fill-and-align}\iref{format.string.std}.
The productions \fmtgrammarterm{align} and \fmtgrammarterm{width}
are described in \ref{format.string}.

\pnum
The \fmtgrammarterm{tuple-type} specifier
changes the way a \tcode{pair} or \tcode{tuple} is formatted,
with certain options only valid with certain argument types.
The meaning of the various type options
is as specified in \tref{formatter.tuple.type}.

\begin{concepttable}{Meaning of \fmtgrammarterm{tuple-type} options}{formatter.tuple.type}
{p{0.5in}p{1.4in}p{3.2in}}
\topline
\hdstyle{Option} & \hdstyle{Requirements} & \hdstyle{Meaning} \\ \capsep
%
\tcode{m} &
\tcode{sizeof...(Ts) == 2} &
Equivalent to:
\begin{codeblock}
set_separator(@\exposid{STATICALLY-WIDEN}@<charT>(": "));
set_brackets({}, {});
\end{codeblock}%
\\ \rowsep
%
\tcode{n} &
none &
Equivalent to: \tcode{set_brackets(\{\}, \{\});}
\\ \rowsep
%
none &
none &
No effects
\\
\end{concepttable}

\indexlibrarymember{set_separator}{formatter}%
\begin{itemdecl}
constexpr void set_separator(basic_string_view<charT> sep) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{\exposid{separator_} = sep;}
\end{itemdescr}

\indexlibrarymember{set_brackets}{formatter}%
\begin{itemdecl}
constexpr void set_brackets(basic_string_view<charT> opening,
                            basic_string_view<charT> closing) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{opening-bracket_}@ = opening;
@\exposid{closing-bracket_}@ = closing;
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{parse}{formatter}%
\begin{itemdecl}
template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Parses the format specifiers as a \fmtgrammarterm{tuple-format-spec} and
stores the parsed specifiers in \tcode{*this}.
The values of
\exposid{opening-bracket_},
\exposid{closing-bracket_}, and
\exposid{separator_}
are modified if and only if
required by the \fmtgrammarterm{tuple-type}, if present.
For each element \tcode{\placeholder{e}} in \exposid{underlying_},
calls \tcode{\placeholder{e}.parse(ctx)} to parse
an empty \fmtgrammarterm{format-spec} and,
if \tcode{\placeholder{e}.set_debug_format()} is a valid expression,
calls \tcode{\placeholder{e}.set_debug_format()}.

\pnum
\returns
An iterator past the end of the \fmtgrammarterm{tuple-format-spec}.
\end{itemdescr}

\indexlibrarymember{format}{formatter}%
\begin{itemdecl}
template<class FormatContext>
  constexpr typename FormatContext::iterator
    format(@\seebelow@& elems, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
The type of \tcode{elems} is:
\begin{itemize}
\item
If \tcode{(\libconcept{formattable}<const Ts, charT> \&\& ...)} is \tcode{true},
\tcode{const \placeholder{pair-or-tuple}<Ts...>\&}.
\item
Otherwise \tcode{\placeholder{pair-or-tuple}<Ts...>\&}.
\end{itemize}

\pnum
\effects
Writes the following into \tcode{ctx.out()},
adjusted according to the \fmtgrammarterm{tuple-format-spec}:
\begin{itemize}
\item
\exposid{opening-bracket_},
\item
for each index \tcode{I} in the \range{0}{sizeof...(Ts)}:
\begin{itemize}
\item
if \tcode{I != 0}, \exposid{separator_},
\item
the result of writing \tcode{get<I>(elems)}
via \tcode{get<I>(\exposid{underlying_})}, and
\end{itemize}
\item
\exposid{closing-bracket_}.
\end{itemize}

\pnum
\returns
An iterator past the end of the output range.
\end{itemdescr}

\rSec2[format.error]{Class \tcode{format_error}}

\indexlibraryglobal{format_error}%
\begin{codeblock}
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);
  };
}
\end{codeblock}

\pnum
The class \tcode{format_error} defines the type of objects thrown as
exceptions to report errors from the formatting library.

\indexlibraryctor{format_error}%
\begin{itemdecl}
constexpr format_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{strcmp(what(), what_arg.c_str()) == 0}.

\indexlibraryctor{format_error}%
\end{itemdescr}
\begin{itemdecl}
constexpr format_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec1[re]{Regular expressions library}
\indextext{regular expression|(}

\rSec2[re.general]{General}

\pnum
Subclause \ref{re} describes components that \Cpp{} programs may use to
perform operations involving regular expression matching and
searching.

\pnum
The following subclauses describe a basic regular expression class template and its
traits that can handle char-like\iref{strings.general} template arguments,
two specializations of this class template that handle sequences of \tcode{char} and \keyword{wchar_t},
a class template that holds the
result of a regular expression match, a series of algorithms that allow a character
sequence to be operated upon by a regular expression,
and two iterator types for
enumerating regular expression matches, as summarized in \tref{re.summary}.

\begin{libsumtab}{Regular expressions library summary}{re.summary}
\ref{re.req}        &   Requirements                &                       \\ \rowsep
\ref{re.const}      &   Constants                   & \tcode{<regex>}       \\
\ref{re.badexp}     &   Exception type              &                       \\
\ref{re.traits}     &   Traits                      &                       \\
\ref{re.regex}      &   Regular expression template &                       \\
\ref{re.submatch}   &   Submatches                  &                       \\
\ref{re.results}    &   Match results               &                       \\
\ref{re.alg}        &   Algorithms                  &                       \\
\ref{re.iter}       &   Iterators                   &                       \\ \rowsep
\ref{re.grammar}    &   Grammar                     &                       \\
\end{libsumtab}

\pnum
The ECMAScript Language Specification described in Standard Ecma-262
is called \defn{ECMA-262} in this Clause.

\rSec2[re.req]{Requirements}

\pnum
This subclause defines requirements on classes representing regular
expression traits.
\begin{note}
The class template
\tcode{regex_traits}, defined in \ref{re.traits},
meets these requirements.
\end{note}

\pnum
The class template \tcode{basic_regex}, defined in
\ref{re.regex}, needs a set of related types and
functions to complete the definition of its semantics. These types
and functions are provided as a set of member \grammarterm{typedef-name}{s} and functions
in the template parameter \tcode{traits} used by the \tcode{basic_regex} class
template. This subclause defines the semantics of these
members.

\pnum
To specialize class template \tcode{basic_regex} for a character
container \tcode{CharT} and its related regular
expression traits class \tcode{Traits}, use \tcode{basic_regex<CharT, Traits>}.

\pnum
\indextext{regular expression traits!requirements}%
\indextext{requirements!regular expression traits}%
\indextext{regular expression!requirements}%
\indextext{locale}%
In the following requirements,
\begin{itemize}
\item
\tcode{X} denotes a traits class defining types and functions
for the character container type \tcode{charT};
\item
\tcode{u} is an object of type \tcode{X};
\item
\tcode{v} is an object of type \tcode{const X};
\item
\tcode{p} is a value of type \tcode{const charT*};
\item
\tcode{I1} and \tcode{I2} are input iterators\iref{input.iterators};
\item
\tcode{F1} and \tcode{F2} are forward iterators\iref{forward.iterators};
\item
\tcode{c} is a value of type \tcode{const charT};
\item
\tcode{s} is an object of type \tcode{X::string_type};
\item
\tcode{cs} is an object of type \tcode{const X::string_type};
\item
\tcode{b} is a value of  type \tcode{bool};
\item
\tcode{I} is a value of type \tcode{int};
\item
\tcode{cl} is an object of type \tcode{X::char_class_type}; and
\item
\tcode{loc} is an object of type \tcode{X::locale_type}.
\end{itemize}

\pnum
A traits class \tcode{X} meets the regular expression traits requirements
if the following types and expressions are well-formed and have the specified
semantics.

\begin{itemdecl}
typename X::char_type
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{charT},
the character container type used in the implementation of class
template \tcode{basic_regex}.
\end{itemdescr}

\begin{itemdecl}
typename X::string_type
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{basic_string<charT>}
\end{itemdescr}

\begin{itemdecl}
typename X::locale_type
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
A copy constructible type
that represents the locale used by the traits class.
\end{itemdescr}

\begin{itemdecl}
typename X::char_class_type
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
A bitmask type\iref{bitmask.types}
representing a particular character classification.
\end{itemdescr}

\begin{itemdecl}
X::length(p)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{size_t}

\pnum
\returns
The smallest \tcode{i} such that \tcode{p[i] == 0}.

\pnum
\complexity
Linear in \tcode{i}.
\end{itemdescr}

\begin{itemdecl}
v.translate(c)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::char_type}

\pnum
\returns
A character such that for any character \tcode{d}
that is to be considered equivalent to \tcode{c}
then \tcode{v.translate(c) == v.translate(d)}.
\end{itemdescr}

\begin{itemdecl}
v.translate_nocase(c)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::char_type}

\pnum
\returns
For all characters \tcode{C} that are to be considered equivalent to \tcode{c}
when comparisons are to be performed without regard to case,
then \tcode{v.translate_nocase(c) == v.translate_nocase(C)}.
\end{itemdescr}

\begin{itemdecl}
v.transform(F1, F2)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::string_type}

\pnum
\returns
A sort key for the character sequence designated by
the iterator range \range{F1}{F2} such that
if the character sequence \range{G1}{G2} sorts before
the character sequence \range{H1}{H2}
then \tcode{v.transform(G1, G2) < v.transform(H1, H2)}.
\end{itemdescr}

\begin{itemdecl}
v.transform_primary(F1, F2)
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{regular expression traits!\idxcode{transform_primary}}%
\indextext{transform_primary@\tcode{transform_primary}!regular expression traits}%
\result
\tcode{X::string_type}

\pnum
\returns
A sort key for the character sequence designated by
the iterator range \range{F1}{F2} such that
if the character sequence \range{G1}{G2} sorts before
the character sequence \range{H1}{H2}
when character case is not considered
then \tcode{v.transform_primary(G1, G2) < v.transform_primary(H1, H2)}.
\end{itemdescr}

\begin{itemdecl}
v.lookup_collatename(F1, F2)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::string_type}

\pnum
\returns
A sequence of characters that represents the collating element
consisting of the character sequence designated by
the iterator range \range{F1}{F2}.
Returns an empty string
if the character sequence is not a valid collating element.
\end{itemdescr}

\begin{itemdecl}
v.lookup_classname(F1, F2, b)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::char_class_type}

\pnum
\returns
Converts the character sequence designated by the iterator range
\range{F1}{F2} into a value of a bitmask type that can
subsequently be passed to \tcode{isctype}.
Values returned from \tcode{lookup_classname} can be bitwise \logop{or}'ed together;
the resulting value represents membership
in either of the corresponding character classes.
If \tcode{b} is \tcode{true}, the returned bitmask is suitable for
matching characters without regard to their case.
Returns \tcode{0}
if the character sequence is not the name of
a character class recognized by  \tcode{X}.
The value returned shall be independent of
the case of the characters in the sequence.
\end{itemdescr}

\begin{itemdecl}
v.isctype(c, cl)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{bool}

\pnum
\returns
Returns \tcode{true} if character \tcode{c} is a member of
one of the character classes designated by \tcode{cl},
\tcode{false} otherwise.
\end{itemdescr}

\begin{itemdecl}
v.value(c, I)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{int}

\pnum
\returns
Returns the value represented by the digit \textit{c} in base
\textit{I} if the character \textit{c} is a valid digit in base \textit{I};
otherwise returns \tcode{-1}.
\begin{note}
The value of \textit{I} will only be 8, 10, or 16.
\end{note}
\end{itemdescr}

\begin{itemdecl}
u.imbue(loc)
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::locale_type}

\indextext{locale}%
\pnum
\effects
Imbues \tcode{u} with the locale \tcode{loc} and
returns the previous locale used by \tcode{u} if any.
\end{itemdescr}

\begin{itemdecl}
v.getloc()
\end{itemdecl}

\begin{itemdescr}
\pnum
\result
\tcode{X::locale_type}

\pnum
\returns
Returns the current locale used by \tcode{v}, if any. \indextext{locale}%
\end{itemdescr}

\pnum
\begin{note}
Class template \tcode{regex_traits} meets the requirements for a
regular expression traits class when it is specialized for
\tcode{char} or \keyword{wchar_t}.  This class template is described in
the header \libheader{regex}, and is described in \ref{re.traits}.
\end{note}

\rSec2[re.syn]{Header \tcode{<regex>} synopsis}

\indexheader{regex}%
\indexlibraryglobal{basic_regex}%
\indexlibraryglobal{regex}%
\indexlibraryglobal{wregex}%
\begin{codeblock}
#include <compare>              // see \ref{compare.syn}
#include <initializer_list>     // see \ref{initializer.list.syn}

namespace std {
  // \ref{re.const}, regex constants
  namespace regex_constants {
    using syntax_option_type = @\placeholder{T1}@;
    using match_flag_type = @\placeholder{T2}@;
    using error_type = @\placeholder{T3}@;
  }

  // \ref{re.badexp}, class \tcode{regex_error}
  class regex_error;

  // \ref{re.traits}, class template \tcode{regex_traits}
  template<class charT> struct regex_traits;

  // \ref{re.regex}, class template \tcode{basic_regex}
  template<class charT, class traits = regex_traits<charT>> class basic_regex;

  using regex  = basic_regex<char>;
  using wregex = basic_regex<wchar_t>;

  // \ref{re.regex.swap}, \tcode{basic_regex} swap
  template<class charT, class traits>
    void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);

  // \ref{re.submatch}, class template \tcode{sub_match}
  template<class BidirectionalIterator>
    class sub_match;

  using csub_match  = sub_match<const char*>;
  using wcsub_match = sub_match<const wchar_t*>;
  using ssub_match  = sub_match<string::const_iterator>;
  using wssub_match = sub_match<wstring::const_iterator>;

  // \ref{re.submatch.op}, \tcode{sub_match} non-member operators
  template<class BiIter>
    bool operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template<class BiIter>
    auto operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);

  template<class BiIter, class ST, class SA>
    bool operator==(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template<class BiIter, class ST, class SA>
    auto operator<=>(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);

  template<class BiIter>
    bool operator==(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type* rhs);
  template<class BiIter>
    auto operator<=>(const sub_match<BiIter>& lhs,
                     const typename iterator_traits<BiIter>::value_type* rhs);

  template<class BiIter>
    bool operator==(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type& rhs);
  template<class BiIter>
    auto operator<=>(const sub_match<BiIter>& lhs,
                     const typename iterator_traits<BiIter>::value_type& rhs);

  template<class charT, class ST, class BiIter>
    basic_ostream<charT, ST>&
      operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);

  // \ref{re.results}, class template \tcode{match_results}
  template<class BidirectionalIterator,
           class Allocator = allocator<sub_match<BidirectionalIterator>>>
    class match_results;

  using cmatch  = match_results<const char*>;
  using wcmatch = match_results<const wchar_t*>;
  using smatch  = match_results<string::const_iterator>;
  using wsmatch = match_results<wstring::const_iterator>;

  // \tcode{match_results} comparisons
  template<class BidirectionalIterator, class Allocator>
    bool operator==(const match_results<BidirectionalIterator, Allocator>& m1,
                    const match_results<BidirectionalIterator, Allocator>& m2);

  // \ref{re.results.swap}, \tcode{match_results} swap
  template<class BidirectionalIterator, class Allocator>
    void swap(match_results<BidirectionalIterator, Allocator>& m1,
              match_results<BidirectionalIterator, Allocator>& m2);

  // \ref{re.alg.match}, function template \tcode{regex_match}
  template<class BidirectionalIterator, class Allocator, class charT, class traits>
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     match_results<BidirectionalIterator, Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class BidirectionalIterator, class charT, class traits>
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class charT, class Allocator, class traits>
    bool regex_match(const charT* str, match_results<const charT*, Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class Allocator, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>& s,
                     match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                   Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class Allocator, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>&&,
                     match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                   Allocator>&,
                     const basic_regex<charT, traits>&,
                     regex_constants::match_flag_type = regex_constants::match_default) = delete;
  template<class charT, class traits>
    bool regex_match(const charT* str,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>& s,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);

  // \ref{re.alg.search}, function template \tcode{regex_search}
  template<class BidirectionalIterator, class Allocator, class charT, class traits>
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      match_results<BidirectionalIterator, Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class BidirectionalIterator, class charT, class traits>
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class charT, class Allocator, class traits>
    bool regex_search(const charT* str,
                      match_results<const charT*, Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class charT, class traits>
    bool regex_search(const charT* str,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>& s,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class Allocator, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>& s,
                      match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                    Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class ST, class SA, class Allocator, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>&&,
                      match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                    Allocator>&,
                      const basic_regex<charT, traits>&,
                      regex_constants::match_flag_type
                        = regex_constants::match_default) = delete;

  // \ref{re.alg.replace}, function template \tcode{regex_replace}
  template<class OutputIterator, class BidirectionalIterator,
           class traits, class charT, class ST, class SA>
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, ST, SA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class OutputIterator, class BidirectionalIterator, class traits, class charT>
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class traits, class charT, class ST, class SA, class FST, class FSA>
    basic_string<charT, ST, SA>
      regex_replace(const basic_string<charT, ST, SA>& s,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, FST, FSA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class traits, class charT, class ST, class SA>
    basic_string<charT, ST, SA>
      regex_replace(const basic_string<charT, ST, SA>& s,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class traits, class charT, class ST, class SA>
    basic_string<charT>
      regex_replace(const charT* s,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, ST, SA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template<class traits, class charT>
    basic_string<charT>
      regex_replace(const charT* s,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);

  // \ref{re.regiter}, class template \tcode{regex_iterator}
  template<class BidirectionalIterator,
           class charT = typename iterator_traits<BidirectionalIterator>::value_type,
           class traits = regex_traits<charT>>
    class regex_iterator;

  using cregex_iterator  = regex_iterator<const char*>;
  using wcregex_iterator = regex_iterator<const wchar_t*>;
  using sregex_iterator  = regex_iterator<string::const_iterator>;
  using wsregex_iterator = regex_iterator<wstring::const_iterator>;

  // \ref{re.tokiter}, class template \tcode{regex_token_iterator}
  template<class BidirectionalIterator,
           class charT = typename iterator_traits<BidirectionalIterator>::value_type,
           class traits = regex_traits<charT>>
    class regex_token_iterator;

  using cregex_token_iterator  = regex_token_iterator<const char*>;
  using wcregex_token_iterator = regex_token_iterator<const wchar_t*>;
  using sregex_token_iterator  = regex_token_iterator<string::const_iterator>;
  using wsregex_token_iterator = regex_token_iterator<wstring::const_iterator>;

  namespace pmr {
    template<class BidirectionalIterator>
      using match_results =
        std::match_results<BidirectionalIterator,
                           polymorphic_allocator<sub_match<BidirectionalIterator>>>;

    using cmatch  = match_results<const char*>;
    using wcmatch = match_results<const wchar_t*>;
    using smatch  = match_results<string::const_iterator>;
    using wsmatch = match_results<wstring::const_iterator>;
  }
}
\end{codeblock}

\rSec2[re.const]{Namespace \tcode{std::regex_constants}}

\rSec3[re.const.general]{General}

\pnum
\indexlibraryglobal{regex_constants}%
The namespace \tcode{std::regex_constants} holds
symbolic constants used by the regular expression library.  This
namespace provides three types, \tcode{syntax_option_type},
\tcode{match_flag_type}, and \tcode{error_type}, along with several
constants of these types.

\rSec3[re.synopt]{Bitmask type \tcode{syntax_option_type}}
\indexlibraryglobal{syntax_option_type}%
\indexlibrarymember{regex_constants}{syntax_option_type}%
\begin{codeblock}
namespace std::regex_constants {
  using syntax_option_type = @\textit{T1}@;
  inline constexpr syntax_option_type icase = @\unspec@;
  inline constexpr syntax_option_type nosubs = @\unspec@;
  inline constexpr syntax_option_type optimize = @\unspec@;
  inline constexpr syntax_option_type collate = @\unspec@;
  inline constexpr syntax_option_type ECMAScript = @\unspec@;
  inline constexpr syntax_option_type basic = @\unspec@;
  inline constexpr syntax_option_type extended = @\unspec@;
  inline constexpr syntax_option_type awk = @\unspec@;
  inline constexpr syntax_option_type grep = @\unspec@;
  inline constexpr syntax_option_type egrep = @\unspec@;
  inline constexpr syntax_option_type multiline = @\unspec@;
}
\end{codeblock}

\pnum
\indexlibraryglobal{syntax_option_type}%
\indexlibrarymember{syntax_option_type}{icase}%
\indexlibrarymember{syntax_option_type}{nosubs}%
\indexlibrarymember{syntax_option_type}{optimize}%
\indexlibrarymember{syntax_option_type}{collate}%
\indexlibrarymember{syntax_option_type}{ECMAScript}%
\indexlibrarymember{syntax_option_type}{basic}%
\indexlibrarymember{syntax_option_type}{extended}%
\indexlibrarymember{syntax_option_type}{awk}%
\indexlibrarymember{syntax_option_type}{grep}%
\indexlibrarymember{syntax_option_type}{egrep}%
The type \tcode{syntax_option_type} is an \impldef{type of \tcode{syntax_option_type}} bitmask
type\iref{bitmask.types}. Setting its elements has the effects listed in
\tref{re.synopt}.  A valid value of type
\tcode{syntax_option_type} shall have at most one of the grammar elements
\tcode{ECMAScript}, \tcode{basic}, \tcode{extended}, \tcode{awk}, \tcode{grep}, \tcode{egrep}, set.
If no grammar element is set, the default grammar is \tcode{ECMAScript}.

\begin{libefftab}
  {\tcode{syntax_option_type} effects}
  {re.synopt}
%
\tcode{icase} &
Specifies that matching of regular expressions against a character
container sequence shall be performed without regard to case.
\indexlibrarymember{syntax_option_type}{icase}%
\\ \rowsep
%
\tcode{nosubs} &
Specifies that no sub-expressions shall be considered to be marked, so that
when a regular expression is matched against a
character container sequence, no sub-expression matches shall be
stored in the supplied \tcode{match_results} object.
\indexlibrarymember{syntax_option_type}{nosubs}%
\\ \rowsep
%
\tcode{optimize} &
Specifies that the regular expression engine should pay more attention
to the speed with which regular expressions are matched, and less to
the speed with which regular expression objects are
constructed. Otherwise it has no detectable effect on the program
output.
\indexlibrarymember{syntax_option_type}{optimize}%
\\ \rowsep
%
\tcode{collate} &
Specifies that character ranges of the form \tcode{"[a-b]"} shall be locale
sensitive.%
\indexlibrarymember{syntax_option_type}{collate}%
\indextext{locale}%
\\ \rowsep
%
\tcode{ECMAScript} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by ECMAScript in ECMA-262, as modified in~\ref{re.grammar}.
\newline \xref{ECMA-262 15.10}
\indextext{ECMAScript}%
\indexlibrarymember{syntax_option_type}{ECMAScript}%
\\ \rowsep
%
\tcode{basic} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by basic regular expressions in POSIX.
\newline \xref{POSIX, Base Definitions and Headers, Section 9.3}
\indextext{POSIX!regular expressions}%
\indexlibrarymember{syntax_option_type}{basic}%
\\ \rowsep
%
\tcode{extended} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by extended regular expressions in POSIX.
\newline \xref{POSIX, Base Definitions and Headers, Section 9.4}
\indextext{POSIX!extended regular expressions}%
\indexlibrarymember{syntax_option_type}{extended}%
\\ \rowsep
%
\tcode{awk} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by the utility awk in POSIX.
\indexlibrarymember{syntax_option_type}{awk}%
\\ \rowsep
%
\tcode{grep} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by the utility grep in POSIX.
\indexlibrarymember{syntax_option_type}{grep}%
\\ \rowsep
%
\tcode{egrep} &
Specifies that the grammar recognized by the regular expression engine
shall be that used by the utility grep when given the -E
option in POSIX.
\indexlibrarymember{syntax_option_type}{egrep}%
\\ \rowsep
%
\tcode{multiline} &
Specifies that \tcode{\caret} shall match the beginning of a line and
\tcode{\$} shall match the end of a line,
if the \tcode{ECMAScript} engine is selected.
\indexlibrarymember{syntax_option_type}{multiline}%
\\
%
\end{libefftab}

\rSec3[re.matchflag]{Bitmask type \tcode{match_flag_type}}

\indexlibraryglobal{match_flag_type}%
\indexlibrarymember{regex_constants}{match_flag_type}%
\indexlibraryglobal{match_default}%
\indexlibraryglobal{match_not_bol}%
\indexlibraryglobal{match_not_eol}%
\indexlibraryglobal{match_not_bow}%
\indexlibraryglobal{match_not_eow}%
\indexlibraryglobal{match_any}%
\indexlibraryglobal{match_not_null}%
\indexlibraryglobal{match_continuous}%
\indexlibraryglobal{match_prev_avail}%
\indexlibraryglobal{format_default}%
\indexlibraryglobal{format_sed}%
\indexlibraryglobal{format_no_copy}%
\indexlibraryglobal{format_first_only}%
\begin{codeblock}
namespace std::regex_constants {
  using match_flag_type = @\textit{T2}@;
  inline constexpr match_flag_type match_default = {};
  inline constexpr match_flag_type match_not_bol = @\unspec@;
  inline constexpr match_flag_type match_not_eol = @\unspec@;
  inline constexpr match_flag_type match_not_bow = @\unspec@;
  inline constexpr match_flag_type match_not_eow = @\unspec@;
  inline constexpr match_flag_type match_any = @\unspec@;
  inline constexpr match_flag_type match_not_null = @\unspec@;
  inline constexpr match_flag_type match_continuous = @\unspec@;
  inline constexpr match_flag_type match_prev_avail = @\unspec@;
  inline constexpr match_flag_type format_default = {};
  inline constexpr match_flag_type format_sed = @\unspec@;
  inline constexpr match_flag_type format_no_copy = @\unspec@;
  inline constexpr match_flag_type format_first_only = @\unspec@;
}
\end{codeblock}

\pnum
\indexlibraryglobal{match_flag_type}%
The type \tcode{match_flag_type} is an
\impldef{type of \tcode{regex_constants::match_flag_type}} bitmask type\iref{bitmask.types}.
The constants of that type, except for \tcode{match_default} and
\tcode{format_default}, are bitmask elements. The \tcode{match_default} and
\tcode{format_default} constants are empty bitmasks.
Matching a regular expression against a sequence of characters
\range{first}{last} proceeds according to the rules of the grammar specified for the regular
expression object, modified according to the effects listed in \tref{re.matchflag} for
any bitmask elements set.

\begin{longlibefftab}
  {\tcode{regex_constants::match_flag_type} effects}
  {re.matchflag}
%
\indexlibraryglobal{match_not_bol}%
\tcode{match_not_bol} &
The first character in the sequence \range{first}{last} shall be treated
as though it is not at the beginning of a line, so the character
\verb|^| in the regular expression shall not match \range{first}{first}.
\\ \rowsep
%
\indexlibraryglobal{match_not_eol}%
\tcode{match_not_eol} &
The last character in the sequence \range{first}{last} shall be treated
as though it is not at the end of a line, so the character
\verb|"$"| in the regular expression shall not match \range{last}{last}.
\\ \rowsep
%
\indexlibraryglobal{match_not_bow}%
\tcode{match_not_bow} &
The expression \verb|"\\b"| shall not match the
sub-sequence \range{first}{first}.
\\ \rowsep
%
\indexlibraryglobal{match_not_eow}%
\tcode{match_not_eow} &
The expression \verb|"\\b"| shall not match the
sub-sequence \range{last}{last}.
\\ \rowsep
%
\indexlibraryglobal{match_any}%
\tcode{match_any} &
If more than one match is possible then any match is an
acceptable result.
\\ \rowsep
%
\indexlibraryglobal{match_not_null}%
\tcode{match_not_null} &
The expression shall not match an empty
sequence.
\\ \rowsep
%
\indexlibraryglobal{match_continuous}%
\tcode{match_continuous} &
The expression shall only match a sub-sequence that begins at
\tcode{first}.
\\ \rowsep
%
\indexlibraryglobal{match_prev_avail}%
\tcode{match_prev_avail} &
\verb!--first! is a valid iterator position. When this flag is
set the flags \tcode{match_not_bol} and \tcode{match_not_bow} shall be ignored by the
regular expression algorithms\iref{re.alg} and iterators\iref{re.iter}.
\\ \rowsep
%
\indexlibraryglobal{format_default}%
\tcode{format_default} &
When a regular expression match is to be replaced by a
new string, the new string shall be constructed using the rules used by
the ECMAScript replace function in ECMA-262,
part 15.5.4.11 String.prototype.replace. In
addition, during search and replace operations all non-overlapping
occurrences of the regular expression shall be located and replaced, and
sections of the input that did not match the expression shall be copied
unchanged to the output string.
\\ \rowsep
%
\indexlibraryglobal{format_sed}%
\tcode{format_sed} &
When a regular expression match is to be replaced by a
new string, the new string shall be constructed using the rules used by
the sed utility in POSIX.
\\ \rowsep
%
\indexlibraryglobal{format_no_copy}%
\tcode{format_no_copy} &
During a search and replace operation, sections of
the character container sequence being searched that do not match the
regular expression shall not be copied to the output string. \\ \rowsep
%
\indexlibraryglobal{format_first_only}%
\tcode{format_first_only} &
When specified during a search and replace operation, only the
first occurrence of the regular expression shall be replaced.
\\
\end{longlibefftab}

\rSec3[re.err]{Implementation-defined \tcode{error_type}}
\indexlibraryglobal{error_type}%
\indexlibrarymember{regex_constants}{error_type}%
\begin{codeblock}
namespace std::regex_constants {
  using error_type = @\textit{T3}@;
  inline constexpr error_type error_collate = @\unspec@;
  inline constexpr error_type error_ctype = @\unspec@;
  inline constexpr error_type error_escape = @\unspec@;
  inline constexpr error_type error_backref = @\unspec@;
  inline constexpr error_type error_brack = @\unspec@;
  inline constexpr error_type error_paren = @\unspec@;
  inline constexpr error_type error_brace = @\unspec@;
  inline constexpr error_type error_badbrace = @\unspec@;
  inline constexpr error_type error_range = @\unspec@;
  inline constexpr error_type error_space = @\unspec@;
  inline constexpr error_type error_badrepeat = @\unspec@;
  inline constexpr error_type error_complexity = @\unspec@;
  inline constexpr error_type error_stack = @\unspec@;
}
\end{codeblock}

\pnum
\indexlibraryglobal{error_type}%
\indexlibrarymember{regex_constants}{error_type}%
The type \tcode{error_type} is an \impldef{type of
\tcode{regex_constants::error_type}} enumerated type\iref{enumerated.types}.
Values of type \tcode{error_type} represent the error
conditions described in \tref{re.err}:

\begin{longliberrtab}
  {\tcode{error_type} values in the C locale}
  {re.err}
\tcode{error_collate}
&
The expression contains an invalid collating element name.  \\ \rowsep
%
\tcode{error_ctype}
&
The expression contains an invalid character class name.  \\ \rowsep
%
\tcode{error_escape}
&
The expression contains an invalid escaped character, or a trailing
escape.  \\ \rowsep
%
\tcode{error_backref}
&
The expression contains an invalid back reference.  \\ \rowsep
%
\tcode{error_brack}
&
The expression contains mismatched \verb|[| and \verb|]|.  \\ \rowsep
%
\tcode{error_paren}
&
The expression contains mismatched \verb|(| and \verb|)|.  \\ \rowsep
%
\tcode{error_brace}
&
The expression contains mismatched \verb|{| and \verb|}|.  \\ \rowsep
%
\tcode{error_badbrace}
&
The expression contains an invalid range in a \verb|{}| expression.  \\
\rowsep
%
\tcode{error_range}
&
The expression contains an invalid character range, such as
\verb|[b-a]| in most encodings.  \\ \rowsep
%
\tcode{error_space}
&
There is insufficient memory to convert the expression into a finite
state machine.  \\ \rowsep
%
\tcode{error_badrepeat}
&
One of \verb|*?+{| is not preceded by a valid regular expression.  \\ \rowsep
%
\tcode{error_complexity}
&
The complexity of an attempted match against a regular expression
exceeds a pre-set level.  \\ \rowsep
%
\tcode{error_stack}
&
There is insufficient memory to determine whether the regular
expression matches the specified character sequence.  \\
%
\end{longliberrtab}

\rSec2[re.badexp]{Class \tcode{regex_error}}
\indexlibraryglobal{regex_error}%
\begin{codeblock}
namespace std {
  class regex_error : public runtime_error {
  public:
    explicit regex_error(regex_constants::error_type ecode);
    regex_constants::error_type code() const;
  };
}
\end{codeblock}

\pnum
The class \tcode{regex_error} defines the type of objects thrown as
exceptions to report errors from the regular expression library.

\indexlibraryctor{regex_error}%
\begin{itemdecl}
regex_error(regex_constants::error_type ecode);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{ecode == code()}.
\end{itemdescr}

\indexlibraryglobal{error_type}%
\indexlibrarymember{regex_constants}{error_type}%
\begin{itemdecl}
regex_constants::error_type code() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The error code that was passed to the constructor.
\end{itemdescr}

\rSec2[re.traits]{Class template \tcode{regex_traits}}
\indexlibraryglobal{regex_traits}%
\begin{codeblock}
namespace std {
  template<class charT>
    struct regex_traits {
      using char_type       = charT;
      using string_type     = basic_string<char_type>;
      using locale_type     = locale;
      using char_class_type = @\placeholdernc{bitmask_type}@;

      regex_traits();
      static size_t length(const char_type* p);
      charT translate(charT c) const;
      charT translate_nocase(charT c) const;
      template<class ForwardIterator>
        string_type transform(ForwardIterator first, ForwardIterator last) const;
      template<class ForwardIterator>
        string_type transform_primary(
          ForwardIterator first, ForwardIterator last) const;
      template<class ForwardIterator>
        string_type lookup_collatename(
          ForwardIterator first, ForwardIterator last) const;
      template<class ForwardIterator>
        char_class_type lookup_classname(
          ForwardIterator first, ForwardIterator last, bool icase = false) const;
      bool isctype(charT c, char_class_type f) const;
      int value(charT ch, int radix) const;
      locale_type imbue(locale_type l);
      locale_type getloc() const;
    };
}
\end{codeblock}

\pnum
\indextext{regular expression traits!requirements}%
\indextext{requirements!regular expression traits}%
The specializations \tcode{regex_traits<char>} and
\tcode{regex_traits<wchar_t>} meet the
requirements for a regular expression traits class\iref{re.req}.

\indexlibrarymember{regex_traits}{char_class_type}%
\begin{itemdecl}
using char_class_type = @\textit{bitmask_type}@;
\end{itemdecl}

\begin{itemdescr}
\pnum
The type \tcode{char_class_type} is used to represent a character
classification and is capable of holding an implementation specific
set returned by \tcode{lookup_classname}.
\end{itemdescr}

\indexlibrarymember{length}{regex_traits}%
\begin{itemdecl}
static size_t length(const char_type* p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{char_traits<charT>::length(p)}.
\end{itemdescr}

\indexlibrarymember{regex_traits}{translate}%
\begin{itemdecl}
charT translate(charT c) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{c}.
\end{itemdescr}

\indexlibrarymember{regex_traits}{translate_nocase}%
\begin{itemdecl}
charT translate_nocase(charT c) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{use_facet<ctype<charT>>(getloc()).tolower(c)}.
\end{itemdescr}

\indexlibrarymember{regex_traits}{transform}%
\begin{itemdecl}
template<class ForwardIterator>
  string_type transform(ForwardIterator first, ForwardIterator last) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by:
\begin{codeblock}
string_type str(first, last);
return use_facet<collate<charT>>(
  getloc()).transform(str.data(), str.data() + str.length());
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{regex_traits}{transform_primary}%
\begin{itemdecl}
template<class ForwardIterator>
  string_type transform_primary(ForwardIterator first, ForwardIterator last) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If
\begin{codeblock}
typeid(use_facet<collate<charT>>(getloc())) == typeid(collate_byname<charT>)
\end{codeblock}
and the form of the sort key returned
by \tcode{collate_byname<charT>::transform(first, last)} is known and
can be converted into a primary sort key then returns that key,
otherwise returns an empty string.
\end{itemdescr}

\indexlibrarymember{regex_traits}{lookup_collatename}%
\begin{itemdecl}
template<class ForwardIterator>
  string_type lookup_collatename(ForwardIterator first, ForwardIterator last) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A sequence of one or more characters that
represents the collating element consisting of the character
sequence designated by the iterator range \range{first}{last}.
Returns an empty string if the character sequence is not a
valid collating element.
\end{itemdescr}

\indexlibrarymember{regex_traits}{lookup_classname}%
\begin{itemdecl}
template<class ForwardIterator>
  char_class_type lookup_classname(
    ForwardIterator first, ForwardIterator last, bool icase = false) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An unspecified value that represents
the character classification named by the character sequence
designated by the iterator range \range{first}{last}.
If the parameter \tcode{icase} is \tcode{true} then the returned mask identifies the
character classification without regard to the case of the characters being
matched, otherwise it does honor the case of the characters being
matched.
\begin{footnote}
For example, if the parameter \tcode{icase} is \tcode{true} then
\tcode{[[:lower:]]} is the same as \tcode{[[:alpha:]]}.
\end{footnote}
The value
returned shall be independent of the case of the characters in
the character sequence. If the name
is not recognized then returns \tcode{char_class_type()}.

\pnum
\remarks
For \tcode{regex_traits<char>}, at least the narrow character names
in \tref{re.traits.classnames} shall be recognized.
For \tcode{regex_traits<wchar_t>}, at least the wide character names
in \tref{re.traits.classnames} shall be recognized.
\end{itemdescr}

\indexlibrarymember{regex_traits}{isctype}%
\begin{itemdecl}
bool isctype(charT c, char_class_type f) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Determines if the character \tcode{c} is a member of the character
classification represented by \tcode{f}.

\pnum
\returns
Given the following function declaration:
\begin{codeblock}
// for exposition only
template<class C>
  ctype_base::mask convert(typename regex_traits<C>::char_class_type f);
\end{codeblock}
that returns a value in which each \tcode{ctype_base::mask} value corresponding to
a value in \tcode{f} named in \tref{re.traits.classnames} is set, then the
result is determined as if by:
\begin{codeblock}
ctype_base::mask m = convert<charT>(f);
const ctype<charT>& ct = use_facet<ctype<charT>>(getloc());
if (ct.is(m, c)) {
  return true;
} else if (c == ct.widen('_')) {
  charT w[1] = { ct.widen('w') };
  char_class_type x = lookup_classname(w, w+1);
  return (f&x) == x;
} else {
  return false;
}
\end{codeblock}
\begin{example}
\begin{codeblock}
regex_traits<char> t;
string d("d");
string u("upper");
regex_traits<char>::char_class_type f;
f = t.lookup_classname(d.begin(), d.end());
f |= t.lookup_classname(u.begin(), u.end());
ctype_base::mask m = convert<char>(f);  // \tcode{m == ctype_base::digit | ctype_base::upper}
\end{codeblock}
\end{example}
\begin{example}
\begin{codeblock}
regex_traits<char> t;
string w("w");
regex_traits<char>::char_class_type f;
f = t.lookup_classname(w.begin(), w.end());
t.isctype('A', f);  // returns \tcode{true}
t.isctype('_', f);  // returns \tcode{true}
t.isctype(' ', f);  // returns \tcode{false}
\end{codeblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{value}{regex_traits}%
\begin{itemdecl}
int value(charT ch, int radix) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The value of \tcode{radix} is 8, 10, or 16.

\pnum
\returns
The value represented by the digit \tcode{ch} in base
\tcode{radix} if the character \tcode{ch} is a valid digit in base
\tcode{radix}; otherwise returns \tcode{-1}.
\end{itemdescr}

\indexlibraryglobal{locale}%
\indexlibraryglobal{imbue}%
\begin{itemdecl}
locale_type imbue(locale_type loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Imbues \tcode{*this} with a copy of the
locale \tcode{loc}.
\begin{note}
Calling \tcode{imbue} with a
different locale than the one currently in use invalidates all cached
data held by \tcode{*this}.
\end{note}

\pnum
\ensures
\tcode{getloc() == loc}.

\pnum
\returns
If no locale has been previously imbued then a copy of the
global locale in effect at the time of construction of \tcode{*this},
otherwise a copy of the last argument passed to \tcode{imbue}.
\end{itemdescr}

\indexlibraryglobal{locale}%
\indexlibraryglobal{getloc}%
\begin{itemdecl}
locale_type getloc() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If no locale has been imbued then a copy of the global locale
in effect at the time of construction of \tcode{*this}, otherwise a copy of
the last argument passed to \tcode{imbue}.
\end{itemdescr}

\begin{floattable}{Character class names and corresponding \tcode{ctype} masks}{re.traits.classnames}{lll}
\topline
\lhdr{Narrow character name} & \chdr{Wide character name} & \rhdr{Corresponding \tcode{ctype_base::mask} value} \\\capsep
\tcode{"alnum"}  & \tcode{L"alnum"}  & \tcode{ctype_base::alnum}  \\ \rowsep
\tcode{"alpha"}  & \tcode{L"alpha"}  & \tcode{ctype_base::alpha}  \\ \rowsep
\tcode{"blank"}  & \tcode{L"blank"}  & \tcode{ctype_base::blank}  \\ \rowsep
\tcode{"cntrl"}  & \tcode{L"cntrl"}  & \tcode{ctype_base::cntrl}  \\ \rowsep
\tcode{"digit"}  & \tcode{L"digit"}  & \tcode{ctype_base::digit}  \\ \rowsep
\tcode{"d"}      & \tcode{L"d"}      & \tcode{ctype_base::digit}  \\ \rowsep
\tcode{"graph"}  & \tcode{L"graph"}  & \tcode{ctype_base::graph}  \\ \rowsep
\tcode{"lower"}  & \tcode{L"lower"}  & \tcode{ctype_base::lower}  \\ \rowsep
\tcode{"print"}  & \tcode{L"print"}  & \tcode{ctype_base::print}  \\ \rowsep
\tcode{"punct"}  & \tcode{L"punct"}  & \tcode{ctype_base::punct}  \\ \rowsep
\tcode{"space"}  & \tcode{L"space"}  & \tcode{ctype_base::space}  \\ \rowsep
\tcode{"s"}      & \tcode{L"s"}      & \tcode{ctype_base::space}  \\ \rowsep
\tcode{"upper"}  & \tcode{L"upper"}  & \tcode{ctype_base::upper}  \\ \rowsep
\tcode{"w"}      & \tcode{L"w"}      & \tcode{ctype_base::alnum}  \\ \rowsep
\tcode{"xdigit"} & \tcode{L"xdigit"} & \tcode{ctype_base::xdigit} \\
\end{floattable}

\rSec2[re.regex]{Class template \tcode{basic_regex}}

\rSec3[re.regex.general]{General}
\indexlibraryglobal{basic_regex}%

\pnum
For a char-like type \tcode{charT}, specializations of class
template \tcode{basic_regex} represent regular expressions constructed
from character sequences of \tcode{charT} characters.  In the rest
of~\ref{re.regex}, \tcode{charT} denotes a given char-like
type. Storage for a regular expression is allocated and freed as
necessary by the member functions of class \tcode{basic_regex}.

\pnum
Objects of type specialization of \tcode{basic_regex} are responsible for
converting the sequence of \tcode{charT} objects to an internal
representation. It is not specified what form this representation
takes, nor how it is accessed by algorithms that operate on regular
expressions.
\begin{note}
Implementations will typically declare
some function templates as friends of \tcode{basic_regex} to achieve
this.
\end{note}

\pnum
\indexlibraryglobal{regex_error}%
The functions described in \ref{re.regex} report errors by throwing
exceptions of type \tcode{regex_error}.

\indexlibraryglobal{basic_regex}%
\begin{codeblock}
namespace std {
  template<class charT, class traits = regex_traits<charT>>
    class basic_regex {
    public:
      // types
      using value_type  = charT;
      using traits_type = traits;
      using string_type = traits::string_type;
      using flag_type   = regex_constants::syntax_option_type;
      using locale_type = traits::locale_type;

      // \ref{re.synopt}, constants
      static constexpr flag_type icase = regex_constants::icase;
      static constexpr flag_type nosubs = regex_constants::nosubs;
      static constexpr flag_type optimize = regex_constants::optimize;
      static constexpr flag_type collate = regex_constants::collate;
      static constexpr flag_type ECMAScript = regex_constants::ECMAScript;
      static constexpr flag_type basic = regex_constants::basic;
      static constexpr flag_type extended = regex_constants::extended;
      static constexpr flag_type awk = regex_constants::awk;
      static constexpr flag_type grep = regex_constants::grep;
      static constexpr flag_type egrep = regex_constants::egrep;
      static constexpr flag_type multiline = regex_constants::multiline;

      // \ref{re.regex.construct}, construct/copy/destroy
      basic_regex();
      explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
      basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
      basic_regex(const basic_regex&);
      basic_regex(basic_regex&&) noexcept;
      template<class ST, class SA>
        explicit basic_regex(const basic_string<charT, ST, SA>& s,
                             flag_type f = regex_constants::ECMAScript);
      template<class ForwardIterator>
        basic_regex(ForwardIterator first, ForwardIterator last,
                    flag_type f = regex_constants::ECMAScript);
      basic_regex(initializer_list<charT> il, flag_type f = regex_constants::ECMAScript);

      ~basic_regex();

      // \ref{re.regex.assign}, assign
      basic_regex& operator=(const basic_regex& e);
      basic_regex& operator=(basic_regex&& e) noexcept;
      basic_regex& operator=(const charT* p);
      basic_regex& operator=(initializer_list<charT> il);
      template<class ST, class SA>
        basic_regex& operator=(const basic_string<charT, ST, SA>& s);

      basic_regex& assign(const basic_regex& e);
      basic_regex& assign(basic_regex&& e) noexcept;
      basic_regex& assign(const charT* p, flag_type f = regex_constants::ECMAScript);
      basic_regex& assign(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
      template<class ST, class SA>
        basic_regex& assign(const basic_string<charT, ST, SA>& s,
                            flag_type f = regex_constants::ECMAScript);
      template<class InputIterator>
        basic_regex& assign(InputIterator first, InputIterator last,
                            flag_type f = regex_constants::ECMAScript);
      basic_regex& assign(initializer_list<charT>,
                          flag_type f = regex_constants::ECMAScript);

      // \ref{re.regex.operations}, const operations
      unsigned mark_count() const;
      flag_type flags() const;

      // \ref{re.regex.locale}, locale
      locale_type imbue(locale_type loc);
      locale_type getloc() const;

      // \ref{re.regex.swap}, swap
      void swap(basic_regex&);
    };

  template<class ForwardIterator>
    basic_regex(ForwardIterator, ForwardIterator,
                regex_constants::syntax_option_type = regex_constants::ECMAScript)
      -> basic_regex<typename iterator_traits<ForwardIterator>::value_type>;
}
\end{codeblock}

\rSec3[re.regex.construct]{Constructors}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
basic_regex();
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{*this} does not match any character sequence.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\range{p}{p + char_traits<charT>::length(p)} is a valid range.

\pnum
\effects
The object's internal finite state machine
is constructed from the regular expression contained in
the sequence of characters
\range{p}{p + char_traits<charT>::\brk{}length(p)}, and
interpreted according to the flags \tcode{f}.

\pnum
\ensures
\tcode{flags()} returns \tcode{f}.
\tcode{mark_count()} returns the number of marked sub-expressions
within the expression.

\pnum
\throws
\tcode{regex_error} if
\range{p}{p + char_traits<charT>::length(p)} is not a valid regular expression.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\range{p}{p + len} is a valid range.

\pnum
\effects
The object's internal finite state machine
is constructed from the regular expression contained in
the sequence of characters \range{p}{p + len}, and
interpreted according the flags specified in \tcode{f}.

\pnum
\ensures
\tcode{flags()} returns \tcode{f}.
\tcode{mark_count()} returns the number of marked sub-expressions
within the expression.

\pnum
\throws
\tcode{regex_error} if \range{p}{p + len} is not a valid regular expression.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
basic_regex(const basic_regex& e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{flags()} and \tcode{mark_count()} return
\tcode{e.flags()} and \tcode{e.mark_count()}, respectively.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
basic_regex(basic_regex&& e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{flags()} and \tcode{mark_count()} return the values that
\tcode{e.flags()} and \tcode{e.mark_count()}, respectively, had before construction.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
template<class ST, class SA>
  explicit basic_regex(const basic_string<charT, ST, SA>& s,
                       flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object's internal finite state machine
is constructed from the regular expression contained in
the string \tcode{s}, and
interpreted according to the flags specified in \tcode{f}.

\pnum
\ensures
\tcode{flags()} returns \tcode{f}.
\tcode{mark_count()} returns the number of marked sub-expressions
within the expression.

\pnum
\throws
\tcode{regex_error} if \tcode{s} is not a valid regular expression.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
template<class ForwardIterator>
  basic_regex(ForwardIterator first, ForwardIterator last,
              flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object's internal finite state machine
is constructed from the regular expression contained in
the sequence of characters \range{first}{last}, and
interpreted according to the flags specified in \tcode{f}.

\pnum
\ensures
\tcode{flags()} returns \tcode{f}.
\tcode{mark_count()} returns the number of marked sub-expressions
within the expression.

\pnum
\throws
\tcode{regex_error} if the sequence \range{first}{last} is not a
valid regular expression.
\end{itemdescr}

\indexlibraryctor{basic_regex}%
\begin{itemdecl}
basic_regex(initializer_list<charT> il, flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Same as \tcode{basic_regex(il.begin(), il.end(), f)}.
\end{itemdescr}

\rSec3[re.regex.assign]{Assignment}

\indexlibrarymember{basic_regex}{operator=}%
\begin{itemdecl}
basic_regex& operator=(const basic_regex& e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{flags()} and \tcode{mark_count()} return
\tcode{e.flags()} and \tcode{e.mark_count()}, respectively.
\end{itemdescr}

\indexlibrarymember{basic_regex}{operator=}%
\begin{itemdecl}
basic_regex& operator=(basic_regex&& e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{flags()} and \tcode{mark_count()} return the values that
\tcode{e.flags()} and \tcode{e.mark_count()}, respectively, had before assignment.
\tcode{e} is in a valid state with unspecified value.
\end{itemdescr}

\indexlibrarymember{basic_regex}{operator=}%
\begin{itemdecl}
basic_regex& operator=(const charT* p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(p);}
\end{itemdescr}

\indexlibrarymember{basic_regex}{operator=}%
\begin{itemdecl}
basic_regex& operator=(initializer_list<charT> il);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(il.begin(), il.end());}
\end{itemdescr}

\indexlibrarymember{basic_regex}{operator=}%
\begin{itemdecl}
template<class ST, class SA>
  basic_regex& operator=(const basic_string<charT, ST, SA>& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(s);}
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
basic_regex& assign(const basic_regex& e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return *this = e;}
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
basic_regex& assign(basic_regex&& e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return *this = std::move(e);}
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
basic_regex& assign(const charT* p, flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(string_type(p), f);}
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
basic_regex& assign(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(string_type(p, len), f);}
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
template<class ST, class SA>
  basic_regex& assign(const basic_string<charT, ST, SA>& s,
                      flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Assigns the regular expression contained in the string
\tcode{s}, interpreted according the flags specified in \tcode{f}.
If an exception is thrown, \tcode{*this} is unchanged.

\pnum
\ensures
If no exception is thrown,
\tcode{flags()} returns \tcode{f} and \tcode{mark_count()}
returns the number of marked sub-expressions within the expression.

\pnum
\returns
\tcode{*this}.

\pnum
\throws
\tcode{regex_error} if \tcode{s} is not a valid regular expression.
\end{itemdescr}

\indexlibrarymember{basic_regex}{assign}%
\begin{itemdecl}
template<class InputIterator>
  basic_regex& assign(InputIterator first, InputIterator last,
                      flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(string_type(first, last), f);}
\end{itemdescr}

\indexlibrarymember{assign}{basic_regex}%
\begin{itemdecl}
basic_regex& assign(initializer_list<charT> il,
                    flag_type f = regex_constants::ECMAScript);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return assign(il.begin(), il.end(), f);}
\end{itemdescr}


\rSec3[re.regex.operations]{Constant operations}

\indexlibrarymember{mark_count}{basic_regex}%
\begin{itemdecl}
unsigned mark_count() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Returns the number of marked sub-expressions within the
regular expression.
\end{itemdescr}

\indexlibrarymember{flag_type}{basic_regex}%
\begin{itemdecl}
flag_type flags() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Returns a copy of the regular expression syntax flags that
were passed to the object's constructor or to the last call
to \tcode{assign}.
\end{itemdescr}

\rSec3[re.regex.locale]{Locale}%
\indexlibraryglobal{locale}

\indexlibrarymember{imbue}{basic_regex}%
\begin{itemdecl}
locale_type imbue(locale_type loc);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Returns the result of \tcode{traits_inst.imbue(loc)} where
\tcode{traits_inst} is a (default-initialized) instance of the template
type argument \tcode{traits} stored within the object.  After a call
to \tcode{imbue} the \tcode{basic_regex} object does not match any
character sequence.
\end{itemdescr}

\indexlibrarymember{getloc}{basic_regex}%
\begin{itemdecl}
locale_type getloc() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Returns the result of \tcode{traits_inst.getloc()} where
\tcode{traits_inst} is a (default-initialized) instance of the template
parameter \tcode{traits} stored within the object.
\end{itemdescr}

\rSec3[re.regex.swap]{Swap}
\indexlibrarymember{basic_regex}{swap}%

\indexlibrarymember{swap}{basic_regex}%
\begin{itemdecl}
void swap(basic_regex& e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the contents of the two regular expressions.

\pnum
\ensures
\tcode{*this} contains the regular expression
that was in \tcode{e}, \tcode{e} contains the regular expression that
was in \tcode{*this}.

\pnum
\complexity
Constant time.
\end{itemdescr}

\rSec3[re.regex.nonmemb]{Non-member functions}

\indexlibrarymember{basic_regex}{swap}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_regex<charT, traits>& lhs, basic_regex<charT, traits>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{lhs.swap(rhs)}.
\end{itemdescr}

\rSec2[re.submatch]{Class template \tcode{sub_match}}

\rSec3[re.submatch.general]{General}
\pnum
\indexlibraryglobal{sub_match}%
Class template \tcode{sub_match} denotes the sequence of characters matched
by a particular marked sub-expression.

\begin{codeblock}
namespace std {
  template<class BidirectionalIterator>
    class sub_match : public pair<BidirectionalIterator, BidirectionalIterator> {
    public:
      using value_type      = iterator_traits<BidirectionalIterator>::value_type;
      using difference_type = iterator_traits<BidirectionalIterator>::difference_type;
      using iterator        = BidirectionalIterator;
      using string_type     = basic_string<value_type>;

      bool matched;

      constexpr sub_match();

      difference_type length() const;
      operator string_type() const;
      string_type str() const;

      int compare(const sub_match& s) const;
      int compare(const string_type& s) const;
      int compare(const value_type* s) const;

      void swap(sub_match& s) noexcept(@\seebelow@);
    };
}
\end{codeblock}


\rSec3[re.submatch.members]{Members}

\indexlibraryctor{sub_match}%
\begin{itemdecl}
constexpr sub_match();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Value-initializes the \tcode{pair} base class subobject and the member
\tcode{matched}.
\end{itemdescr}

\indexlibrarymember{sub_match}{length}%
\begin{itemdecl}
difference_type length() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{matched ?\ distance(first, second) :\ 0}.
\end{itemdescr}

\indexlibrarymember{operator basic_string}{sub_match}%
\begin{itemdecl}
operator string_type() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{matched ?\ string_type(first, second) :\ string_type()}.
\end{itemdescr}

\indexlibrarymember{sub_match}{str}%
\begin{itemdecl}
string_type str() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{matched ?\ string_type(first, second) :\ string_type()}.
\end{itemdescr}

\indexlibrarymember{sub_match}{compare}%
\begin{itemdecl}
int compare(const sub_match& s) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{str().compare(s.str())}.
\end{itemdescr}

\indexlibrarymember{sub_match}{compare}%
\begin{itemdecl}
int compare(const string_type& s) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{str().compare(s)}.
\end{itemdescr}

\indexlibrarymember{sub_match}{compare}%
\begin{itemdecl}
int compare(const value_type* s) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{str().compare(s)}.
\end{itemdescr}

\indexlibrarymember{sub_match}{swap}%
\begin{itemdecl}
void swap(sub_match& s) noexcept(@\seebelow@);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{BidirectionalIterator} meets
the \oldconcept{Swappable} requirements\iref{swappable.requirements}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
this->pair<BidirectionalIterator, BidirectionalIterator>::swap(s);
std::swap(matched, s.matched);
\end{codeblock}

\pnum
\remarks
The exception specification is equivalent to
\tcode{is_nothrow_swappable_v<BidirectionalIter\-ator>}.
\end{itemdescr}

\rSec3[re.submatch.op]{Non-member operators}

\pnum
Let \tcode{\placeholdernc{SM-CAT}(I)} be
\begin{codeblock}
compare_three_way_result_t<basic_string<typename iterator_traits<I>::value_type>>
\end{codeblock}

\indexlibrarymember{sub_match}{operator==}%
\begin{itemdecl}
template<class BiIter>
  bool operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.compare(rhs) == 0}.
\end{itemdescr}

\indexlibrarymember{sub_match}{operator<=>}%
\begin{itemdecl}
template<class BiIter>
  auto operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{static_cast<\placeholdernc{SM-CAT}(BiIter)>(lhs.compare(rhs) <=> 0)}.
\end{itemdescr}

\indexlibrarymember{operator==}{sub_match}%
\begin{itemdecl}
template<class BiIter, class ST, class SA>
  bool operator==(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
lhs.compare(typename sub_match<BiIter>::string_type(rhs.data(), rhs.size())) == 0
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator<=>}{sub_match}%
\begin{itemdecl}
template<class BiIter, class ST, class SA>
  auto operator<=>(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
static_cast<@\placeholdernc{SM-CAT}@(BiIter)>(lhs.compare(
    typename sub_match<BiIter>::string_type(rhs.data(), rhs.size()))
      <=> 0
    )
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{sub_match}{operator==}%
\begin{itemdecl}
template<class BiIter>
  bool operator==(const sub_match<BiIter>& lhs,
                  const typename iterator_traits<BiIter>::value_type* rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.compare(rhs) == 0}.
\end{itemdescr}

\indexlibrarymember{sub_match}{operator<=>}%
\begin{itemdecl}
template<class BiIter>
  auto operator<=>(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type* rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{static_cast<\placeholdernc{SM-CAT}(BiIter)>(lhs.compare(rhs) <=> 0)}.
\end{itemdescr}

\indexlibrarymember{sub_match}{operator==}%
\begin{itemdecl}
template<class BiIter>
  bool operator==(const sub_match<BiIter>& lhs,
                  const typename iterator_traits<BiIter>::value_type& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.compare(typename sub_match<BiIter>::string_type(1, rhs)) == 0}.
\end{itemdescr}

\indexlibrarymember{sub_match}{operator<=>}%
\begin{itemdecl}
template<class BiIter>
  auto operator<=>(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
static_cast<@\placeholdernc{SM-CAT}@(BiIter)>(lhs.compare(
    typename sub_match<BiIter>::string_type(1, rhs))
      <=> 0
    )
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{basic_ostream}%
\indexlibrarymember{sub_match}{operator<<}%
\begin{itemdecl}
template<class charT, class ST, class BiIter>
  basic_ostream<charT, ST>&
    operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{os << m.str()}.
\end{itemdescr}

\rSec2[re.results]{Class template \tcode{match_results}}

\rSec3[re.results.general]{General}
\pnum
\indexlibraryglobal{match_results}%
Class template \tcode{match_results} denotes a collection of character
sequences representing the result of a regular expression
match. Storage for the collection is allocated and freed as necessary
by the member functions of class template \tcode{match_results}.

\pnum
\indextext{requirements!container}%
\indextext{requirements!sequence}%
The class template \tcode{match_results} meets the requirements of an
allocator-aware container\iref{container.alloc.reqmts} and of
a sequence container\iref{container.requirements.general,sequence.reqmts}
except that only
copy assignment,
move assignment, and
operations defined for const-qualified sequence containers
are supported and
that the semantics of the comparison operator functions are different from those
required for a container.

\pnum
A default-constructed \tcode{match_results} object has no fully established result state. A
match result is \defn{ready} when, as a consequence of a completed regular expression match
modifying such an object, its result state becomes fully established. The effects of calling
most member functions from a \tcode{match_results} object that is not ready are undefined.

\pnum
\indexlibrarymember{match_results}{matched}%
The \tcode{sub_match} object stored at index 0 represents sub-expression 0,
i.e., the whole match. In this case the \tcode{sub_match} member
\tcode{matched} is always \tcode{true}. The \tcode{sub_match}
object stored at index \tcode{n} denotes what matched the marked
sub-expression \tcode{n} within the matched expression. If the
sub-expression \tcode{n} participated in a regular expression
match then the \tcode{sub_match} member \tcode{matched} evaluates to \tcode{true}, and
members \tcode{first} and \tcode{second} denote the range of characters
\range{first}{second} which formed that
match. Otherwise \tcode{matched} is \tcode{false}, and members \tcode{first}
and \tcode{second} point to the end of the sequence
that was searched.
\begin{note}
The \tcode{sub_match} objects representing
different sub-expressions that did not participate in a regular expression
match need not be distinct.
\end{note}

\begin{codeblock}
namespace std {
  template<class BidirectionalIterator,
           class Allocator = allocator<sub_match<BidirectionalIterator>>>
    class match_results {
    public:
      using value_type      = sub_match<BidirectionalIterator>;
      using const_reference = const value_type&;
      using reference       = value_type&;
      using const_iterator  = @\impdefx{type of \tcode{match_results::const_iterator}}@;
      using iterator        = const_iterator;
      using difference_type = iterator_traits<BidirectionalIterator>::difference_type;
      using size_type       = allocator_traits<Allocator>::size_type;
      using allocator_type  = Allocator;
      using char_type       = iterator_traits<BidirectionalIterator>::value_type;
      using string_type     = basic_string<char_type>;

      // \ref{re.results.const}, construct/copy/destroy
      match_results() : match_results(Allocator()) {}
      explicit match_results(const Allocator& a);
      match_results(const match_results& m);
      match_results(const match_results& m, const Allocator& a);
      match_results(match_results&& m) noexcept;
      match_results(match_results&& m, const Allocator& a);
      match_results& operator=(const match_results& m);
      match_results& operator=(match_results&& m);
      ~match_results();

      // \ref{re.results.state}, state
      bool ready() const;

      // \ref{re.results.size}, size
      size_type size() const;
      size_type max_size() const;
      bool empty() const;

      // \ref{re.results.acc}, element access
      difference_type length(size_type sub = 0) const;
      difference_type position(size_type sub = 0) const;
      string_type str(size_type sub = 0) const;
      const_reference operator[](size_type n) const;

      const_reference prefix() const;
      const_reference suffix() const;
      const_iterator begin() const;
      const_iterator end() const;
      const_iterator cbegin() const;
      const_iterator cend() const;

      // \ref{re.results.form}, format
      template<class OutputIter>
        OutputIter
          format(OutputIter out,
                 const char_type* fmt_first, const char_type* fmt_last,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      template<class OutputIter, class ST, class SA>
        OutputIter
          format(OutputIter out,
                 const basic_string<char_type, ST, SA>& fmt,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      template<class ST, class SA>
        basic_string<char_type, ST, SA>
          format(const basic_string<char_type, ST, SA>& fmt,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      string_type
        format(const char_type* fmt,
               regex_constants::match_flag_type flags = regex_constants::format_default) const;

      // \ref{re.results.all}, allocator
      allocator_type get_allocator() const;

      // \ref{re.results.swap}, swap
      void swap(match_results& that);
    };
}
\end{codeblock}

\rSec3[re.results.const]{Constructors}

\pnum
\tref{re.results.const} lists the postconditions of
\tcode{match_results} copy/move constructors and copy/move assignment operators.
For move operations,
the results of the expressions depending on the parameter \tcode{m} denote
the values they had before the respective function calls.

\indexlibraryctor{match_results}%
\begin{itemdecl}
explicit match_results(const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The stored \tcode{Allocator} value is constructed from \tcode{a}.

\pnum
\ensures
\tcode{ready()} returns \tcode{false}.
\tcode{size()} returns \tcode{0}.
\end{itemdescr}

\indexlibraryctor{match_results}%
\begin{itemdecl}
match_results(const match_results& m);
match_results(const match_results& m, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
For the first form,
the stored \tcode{Allocator} value is obtained
as specified in \ref{container.reqmts}.
For the second form,
the stored \tcode{Allocator} value is constructed from \tcode{a}.

\pnum
\ensures
As specified in \tref{re.results.const}.
\end{itemdescr}

\indexlibraryctor{match_results}%
\begin{itemdecl}
match_results(match_results&& m) noexcept;
match_results(match_results&& m, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
For the first form,
the stored \tcode{Allocator} value is move constructed from \tcode{m.get_allocator()}.
For the second form,
the stored \tcode{Allocator} value is constructed from \tcode{a}.

\pnum
\ensures
As specified in \tref{re.results.const}.

\pnum
\throws
The second form throws nothing if
\tcode{a == m.get_allocator()} is \tcode{true}.
\end{itemdescr}

\indexlibrarymember{match_results}{operator=}%
\begin{itemdecl}
match_results& operator=(const match_results& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
As specified in \tref{re.results.const}.
\end{itemdescr}

\indexlibrarymember{match_results}{operator=}%
\begin{itemdecl}
match_results& operator=(match_results&& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
As specified in \tref{re.results.const}.
\end{itemdescr}

\begin{libefftabvalue}
  {\tcode{match_results} copy/move operation postconditions}
  {re.results.const}
\tcode{ready()}         & \tcode{m.ready()}       \\ \rowsep
\tcode{size()}          & \tcode{m.size()}        \\ \rowsep
\tcode{str(n)}          & \tcode{m.str(n)} for all non-negative integers \tcode{n < m.size()} \\ \rowsep
\tcode{prefix()}        & \tcode{m.prefix()} \\ \rowsep
\tcode{suffix()}        & \tcode{m.suffix()} \\ \rowsep
\tcode{(*this)[n]}      & \tcode{m[n]} for all non-negative integers \tcode{n < m.size()} \\ \rowsep
\tcode{length(n)}       & \tcode{m.length(n)} for all non-negative integers \tcode{n < m.size()} \\ \rowsep
\tcode{position(n)}     & \tcode{m.position(n)} for all non-negative integers \tcode{n < m.size()} \\
\end{libefftabvalue}

\rSec3[re.results.state]{State}

\indexlibrarymember{match_results}{ready}%
\begin{itemdecl}
bool ready() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \tcode{*this} has a fully established result state, otherwise
\tcode{false}.
\end{itemdescr}

\rSec3[re.results.size]{Size}

\indexlibrarymember{match_results}{size}%
\begin{itemdecl}
size_type size() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
One plus the number of marked sub-expressions in the
regular expression that was matched if \tcode{*this} represents the
result of a successful match.  Otherwise returns \tcode{0}.
\begin{note}
The state of a \tcode{match_results} object can be modified
only by passing that object to \tcode{regex_match} or \tcode{regex_search}.
Subclauses~\ref{re.alg.match} and~\ref{re.alg.search} specify the
effects of those algorithms on their \tcode{match_results} arguments.
\end{note}
\end{itemdescr}

\indexlibrarymember{match_results}{max_size}%
\begin{itemdecl}
size_type max_size() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The maximum number of \tcode{sub_match} elements that can be
stored in \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{match_results}{empty}%
\begin{itemdecl}
bool empty() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{size() == 0}.
\end{itemdescr}

\rSec3[re.results.acc]{Element access}

\indexlibrarymember{length}{match_results}%
\begin{itemdecl}
difference_type length(size_type sub = 0) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
\tcode{(*this)[sub].length()}.
\end{itemdescr}

\indexlibrarymember{position}{match_results}%
\begin{itemdecl}
difference_type position(size_type sub = 0) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
The distance from the start of the target sequence
to \tcode{(*this)[sub].first}.
\end{itemdescr}

\indexlibrarymember{match_results}{str}%
\begin{itemdecl}
string_type str(size_type sub = 0) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
\tcode{string_type((*this)[sub])}.
\end{itemdescr}

\indexlibrarymember{match_results}{operator[]}%
\begin{itemdecl}
const_reference operator[](size_type n) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
A reference to the \tcode{sub_match} object representing the
character sequence that matched marked sub-expression \tcode{n}. If \tcode{n == 0}
then returns a reference to a \tcode{sub_match} object representing the
character sequence that matched the whole regular expression. If
\tcode{n >= size()} then returns a \tcode{sub_match} object representing an
unmatched sub-expression.
\end{itemdescr}

\indexlibrarymember{match_results}{prefix}%
\begin{itemdecl}
const_reference prefix() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
A reference to the \tcode{sub_match} object representing the
character sequence from the start of the string being
matched/searched to the start of the match found.
\end{itemdescr}

\indexlibrarymember{match_results}{suffix}%
\begin{itemdecl}
const_reference suffix() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\returns
A reference to the \tcode{sub_match} object representing the
character sequence from the end of the match found to the end of the
string being matched/searched.
\end{itemdescr}

\indexlibrarymember{match_results}{begin}%
\begin{itemdecl}
const_iterator begin() const;
const_iterator cbegin() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A starting iterator that enumerates over all the
sub-expressions stored in \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{match_results}{end}%
\begin{itemdecl}
const_iterator end() const;
const_iterator cend() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A terminating iterator that enumerates over all the
sub-expressions stored in \tcode{*this}.
\end{itemdescr}

\rSec3[re.results.form]{Formatting}

\indexlibrarymember{match_results}{format}%
\begin{itemdecl}
template<class OutputIter>
  OutputIter format(
    OutputIter out,
    const char_type* fmt_first, const char_type* fmt_last,
    regex_constants::match_flag_type flags = regex_constants::format_default) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true} and \tcode{OutputIter} meets the requirements for a
\oldconcept{OutputIterator}\iref{output.iterators}.

\pnum
\effects
Copies the character sequence \range{fmt_first}{fmt_last} to
OutputIter \tcode{out}.  Replaces each format specifier or escape
sequence in the copied range with either the character(s) it represents or
the sequence of characters within \tcode{*this} to which it refers.
The bitmasks specified in \tcode{flags} determine which format
specifiers and escape sequences are recognized.

\pnum
\returns
\tcode{out}.
\end{itemdescr}

\indexlibrarymember{match_results}{format}%
\begin{itemdecl}
template<class OutputIter, class ST, class SA>
  OutputIter format(
    OutputIter out,
    const basic_string<char_type, ST, SA>& fmt,
    regex_constants::match_flag_type flags = regex_constants::format_default) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return format(out, fmt.data(), fmt.data() + fmt.size(), flags);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{match_results}{format}%
\begin{itemdecl}
template<class ST, class SA>
  basic_string<char_type, ST, SA> format(
    const basic_string<char_type, ST, SA>& fmt,
    regex_constants::match_flag_type flags = regex_constants::format_default) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\effects
Constructs an empty string \tcode{result} of type \tcode{basic_string<char_type, ST, SA>} and
calls:
\begin{codeblock}
format(back_inserter(result), fmt, flags);
\end{codeblock}

\pnum
\returns
\tcode{result}.
\end{itemdescr}

\indexlibrarymember{match_results}{format}%
\begin{itemdecl}
string_type format(
  const char_type* fmt,
  regex_constants::match_flag_type flags = regex_constants::format_default) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ready() == true}.

\pnum
\effects
Constructs an empty string \tcode{result} of type \tcode{string_type} and
calls:
\begin{codeblock}
format(back_inserter(result), fmt, fmt + char_traits<char_type>::length(fmt), flags);
\end{codeblock}

\pnum
\returns
\tcode{result}.
\end{itemdescr}

\rSec3[re.results.all]{Allocator}%

\indexlibrarymember{get_allocator}{match_results}%
\begin{itemdecl}
allocator_type get_allocator() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A copy of the Allocator that was passed to the object's constructor or, if that
allocator has been replaced, a copy of the most recent replacement.
\end{itemdescr}

\rSec3[re.results.swap]{Swap}

\indexlibrarymember{match_results}{swap}%
\begin{itemdecl}
void swap(match_results& that);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the contents of the two sequences.

\pnum
\ensures
\tcode{*this} contains the sequence of matched
sub-expressions that were in \tcode{that}, \tcode{that} contains the
sequence of matched sub-expressions that were in \tcode{*this}.

\pnum
\complexity
Constant time.
\end{itemdescr}

\indexlibrarymember{match_results}{swap}%
\begin{itemdecl}
template<class BidirectionalIterator, class Allocator>
  void swap(match_results<BidirectionalIterator, Allocator>& m1,
            match_results<BidirectionalIterator, Allocator>& m2);
\end{itemdecl}

\pnum
\effects
As if by \tcode{m1.swap(m2)}.

\rSec3[re.results.nonmember]{Non-member functions}

\indexlibrarymember{operator==}{match_results}%
\begin{itemdecl}
template<class BidirectionalIterator, class Allocator>
  bool operator==(const match_results<BidirectionalIterator, Allocator>& m1,
                  const match_results<BidirectionalIterator, Allocator>& m2);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if neither match result is ready, \tcode{false} if one match result is ready and the
other is not. If both match results are ready, returns \tcode{true} only if
\begin{itemize}
\item
\tcode{m1.empty() \&\& m2.empty()}, or

\item
\tcode{!m1.empty() \&\& !m2.empty()}, and the following conditions are satisfied:
\begin{itemize}
\item
\tcode{m1.prefix() == m2.prefix()},

\item
\tcode{m1.size() == m2.size() \&\& equal(m1.begin(), m1.end(), m2.begin())}, and

\item
\tcode{m1.suffix() == m2.suffix()}.
\end{itemize}
\end{itemize}
\begin{note}
The algorithm \tcode{equal} is defined in \ref{algorithms}.
\end{note}
\end{itemdescr}

\rSec2[re.alg]{Regular expression algorithms}

\rSec3[re.except]{Exceptions}
\pnum
The algorithms described in subclause~\ref{re.alg} may throw an exception
of type \tcode{regex_error}. If such an exception \tcode{e} is thrown,
\tcode{e.code()} shall return either \tcode{regex_constants::error_complexity}
or \tcode{regex_constants::error_stack}.

\rSec3[re.alg.match]{\tcode{regex_match}}
\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class BidirectionalIterator, class Allocator, class charT, class traits>
  bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                   match_results<BidirectionalIterator, Allocator>& m,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{BidirectionalIterator} models
\libconcept{bidirectional_iterator}\iref{iterator.concept.bidir}.

\pnum
\effects
Determines whether there is a match between the
regular expression \tcode{e}, and all of the character
sequence \range{first}{last}. The parameter \tcode{flags} is
used to control how the expression is matched against the character
sequence. When determining if there is a match, only potential matches
that match the entire character sequence are considered.
Returns \tcode{true} if such a match exists, \tcode{false}
otherwise.
\begin{example}
\begin{codeblock}
std::regex re("Get|GetValue");
std::cmatch m;
regex_search("GetValue", m, re);        // returns \tcode{true}, and \tcode{m[0]} contains \tcode{"Get"}
regex_match ("GetValue", m, re);        // returns \tcode{true}, and \tcode{m[0]} contains \tcode{"GetValue"}
regex_search("GetValues", m, re);       // returns \tcode{true}, and \tcode{m[0]} contains \tcode{"Get"}
regex_match ("GetValues", m, re);       // returns \tcode{false}
\end{codeblock}
\end{example}

\pnum
\ensures
\tcode{m.ready() == true} in all cases.
If the function returns \tcode{false}, then the effect
on parameter \tcode{m} is unspecified except that \tcode{m.size()}
returns \tcode{0} and \tcode{m.empty()} returns \tcode{true}.
Otherwise the effects on parameter \tcode{m} are given in
\tref{re.alg.match}.
\end{itemdescr}

\begin{longlibefftabvalue}
  {Effects of \tcode{regex_match} algorithm}
  {re.alg.match}
\tcode{m.size()}
&
\tcode{1 + e.mark_count()}
\\ \rowsep
\tcode{m.empty()}
&
\tcode{false}
\\ \rowsep
\tcode{m.prefix().first}
&
\tcode{first}
\\ \rowsep
\tcode{m.prefix().second}
&
\tcode{first}
\\ \rowsep
\tcode{m.prefix().matched}
&
\tcode{false}
\\ \rowsep
\tcode{m.suffix().first}
&
\tcode{last}
\\ \rowsep
\tcode{m.suffix().second}
&
\tcode{last}
\\ \rowsep
\tcode{m.suffix().matched}
&
\tcode{false}
\\ \rowsep
\tcode{m[0].first}
&
\tcode{first}
\\ \rowsep
\tcode{m[0].second}
&
\tcode{last}
\\ \rowsep
\tcode{m[0].matched}
&
\tcode{true}
\\ \rowsep
\tcode{m[n].first}
&
For all integers \tcode{0 < n < m.size()}, the start of the sequence that matched
sub-expression \tcode{n}. Alternatively, if sub-expression \tcode{n} did not participate
in the match, then \tcode{last}.
\\ \rowsep
\tcode{m[n].second}
&
For all integers \tcode{0 < n < m.size()}, the end of the sequence that matched
sub-expression \tcode{n}. Alternatively, if sub-expression \tcode{n} did not participate
in the match, then \tcode{last}.
\\ \rowsep
\tcode{m[n].matched}
&
For all integers \tcode{0 < n < m.size()}, \tcode{true} if sub-expression \tcode{n} participated in
the match, \tcode{false} otherwise.
\\
\end{longlibefftabvalue}

\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class BidirectionalIterator, class charT, class traits>
  bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Behaves ``as if'' by constructing an instance of
\tcode{match_results<BidirectionalIterator> what}, and then
returning the result of
\tcode{regex_match(first, last, what, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class charT, class Allocator, class traits>
  bool regex_match(const charT* str,
                   match_results<const charT*, Allocator>& m,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_match(str, str + char_traits<charT>::length(str), m, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class ST, class SA, class Allocator, class charT, class traits>
  bool regex_match(const basic_string<charT, ST, SA>& s,
                   match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                 Allocator>& m,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_match(s.begin(), s.end(), m, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class charT, class traits>
  bool regex_match(const charT* str,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_match(str, str + char_traits<charT>::length(str), e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_match}%
\begin{itemdecl}
template<class ST, class SA, class charT, class traits>
  bool regex_match(const basic_string<charT, ST, SA>& s,
                   const basic_regex<charT, traits>& e,
                   regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_match(s.begin(), s.end(), e, flags)}.
\end{itemdescr}

\rSec3[re.alg.search]{\tcode{regex_search}}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class BidirectionalIterator, class Allocator, class charT, class traits>
  bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                    match_results<BidirectionalIterator, Allocator>& m,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{BidirectionalIterator} models
\libconcept{bidirectional_iterator}\iref{iterator.concept.bidir}.

\pnum
\effects
Determines whether there is some sub-sequence within \range{first}{last} that matches
the regular expression \tcode{e}. The parameter \tcode{flags} is used to control how the
expression is matched against the character sequence. Returns \tcode{true} if such a sequence
exists, \tcode{false} otherwise.

\pnum
\ensures
\tcode{m.ready() == true} in all cases.
If the function returns \tcode{false}, then the effect
on parameter \tcode{m} is unspecified except that \tcode{m.size()}
returns \tcode{0} and \tcode{m.empty()} returns \tcode{true}.  Otherwise
the effects on parameter \tcode{m} are given in \tref{re.alg.search}.
\end{itemdescr}

\begin{longlibefftabvalue}
  {Effects of \tcode{regex_search} algorithm}
  {re.alg.search}
\tcode{m.size()}
&
\tcode{1 + e.mark_count()}
\\ \rowsep
\tcode{m.empty()}
&
\tcode{false}
\\ \rowsep
\tcode{m.prefix().first}
&
\tcode{first}
\\ \rowsep
\tcode{m.prefix().second}
&
\tcode{m[0].first}
\\ \rowsep
\tcode{m.prefix().matched}
&
\tcode{m.prefix().first != m.prefix().second}
\\ \rowsep
\tcode{m.suffix().first}
&
\tcode{m[0].second}
\\ \rowsep
\tcode{m.suffix().second}
&
\tcode{last}
\\ \rowsep
\tcode{m.suffix().matched}
&
\tcode{m.suffix().first != m.suffix().second}
\\ \rowsep
\tcode{m[0].first}
&
The start of the sequence of characters that matched the regular expression
\\ \rowsep
\tcode{m[0].second}
&
The end of the sequence of characters that matched the regular expression
\\ \rowsep
\tcode{m[0].matched}
&
\tcode{true}
\\ \rowsep
\tcode{m[n].first}
&
For all integers \tcode{0 < n < m.size()}, the start of the sequence that
matched sub-expression \tcode{n}. Alternatively, if sub-expression \tcode{n}
did not participate in the match, then \tcode{last}.
\\ \rowsep
\tcode{m[n].second}
&
For all integers \tcode{0 < n < m.size()}, the end of the sequence that matched
sub-expression \tcode{n}. Alternatively, if sub-expression \tcode{n} did not
participate in the match, then \tcode{last}.
\\ \rowsep
\tcode{m[n].matched}
&
For all integers \tcode{0 < n < m.size()}, \tcode{true} if sub-expression \tcode{n}
participated in the match, \tcode{false} otherwise.
\\
\end{longlibefftabvalue}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class charT, class Allocator, class traits>
  bool regex_search(const charT* str, match_results<const charT*, Allocator>& m,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_search(str, str + char_traits<charT>::length(str), m, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class ST, class SA, class Allocator, class charT, class traits>
  bool regex_search(const basic_string<charT, ST, SA>& s,
                    match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                  Allocator>& m,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_search(s.begin(), s.end(), m, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class BidirectionalIterator, class charT, class traits>
  bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Behaves ``as if'' by constructing an object \tcode{what}
of type \tcode{match_results<Bidirectional\-Iterator>} and returning
\tcode{regex_search(first, last, what, e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class charT, class traits>
  bool regex_search(const charT* str,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_search(str, str + char_traits<charT>::length(str), e, flags)}.
\end{itemdescr}

\indexlibraryglobal{regex_search}%
\begin{itemdecl}
template<class ST, class SA, class charT, class traits>
  bool regex_search(const basic_string<charT, ST, SA>& s,
                    const basic_regex<charT, traits>& e,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{regex_search(s.begin(), s.end(), e, flags)}.
\end{itemdescr}

\rSec3[re.alg.replace]{\tcode{regex_replace}}

\indexlibraryglobal{regex_replace}%
\begin{itemdecl}
template<class OutputIterator, class BidirectionalIterator,
         class traits, class charT, class ST, class SA>
  OutputIterator
    regex_replace(OutputIterator out,
                  BidirectionalIterator first, BidirectionalIterator last,
                  const basic_regex<charT, traits>& e,
                  const basic_string<charT, ST, SA>& fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
template<class OutputIterator, class BidirectionalIterator, class traits, class charT>
  OutputIterator
    regex_replace(OutputIterator out,
                  BidirectionalIterator first, BidirectionalIterator last,
                  const basic_regex<charT, traits>& e,
                  const charT* fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\indexlibraryglobal{format_no_copy}%
\indexlibraryglobal{format_first_only}%
\effects
Constructs a \tcode{regex_iterator} object \tcode{i}
as if by
\begin{codeblock}
regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags)
\end{codeblock}
and uses \tcode{i} to enumerate through all
of the matches \tcode{m} of type \tcode{match_results<BidirectionalIterator>}
that occur within the sequence \range{first}{last}.
If no such
matches are found and
\tcode{!(flags \& regex_constants::format_no_copy)}, then calls
\begin{codeblock}
out = copy(first, last, out)
\end{codeblock}
If any matches are found then, for each such match:
\begin{itemize}
\item
If \tcode{!(flags \& regex_constants::format_no_copy)}, calls
\begin{codeblock}
out = copy(m.prefix().first, m.prefix().second, out)
\end{codeblock}
\item
Then calls
\begin{codeblock}
out = m.format(out, fmt, flags)
\end{codeblock}
for the first form of the function and
\begin{codeblock}
out = m.format(out, fmt, fmt + char_traits<charT>::length(fmt), flags)
\end{codeblock}
for the second.
\end{itemize}
Finally, if such a match
is found and \tcode{!(flags \& regex_constants::format_no_copy)},
calls
\begin{codeblock}
out = copy(last_m.suffix().first, last_m.suffix().second, out)
\end{codeblock}
where \tcode{last_m} is a copy of the last match
found. If \tcode{flags \& regex_constants::format_first_only}
is nonzero, then only the first match found is replaced.

\pnum
\returns
\tcode{out}.
\end{itemdescr}

\indexlibraryglobal{regex_replace}%
\begin{itemdecl}
template<class traits, class charT, class ST, class SA, class FST, class FSA>
  basic_string<charT, ST, SA>
    regex_replace(const basic_string<charT, ST, SA>& s,
                  const basic_regex<charT, traits>& e,
                  const basic_string<charT, FST, FSA>& fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
template<class traits, class charT, class ST, class SA>
  basic_string<charT, ST, SA>
    regex_replace(const basic_string<charT, ST, SA>& s,
                  const basic_regex<charT, traits>& e,
                  const charT* fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an empty string \tcode{result} of
type \tcode{basic_string<charT, ST, SA>} and calls:
\begin{codeblock}
regex_replace(back_inserter(result), s.begin(), s.end(), e, fmt, flags);
\end{codeblock}

\pnum
\returns
\tcode{result}.
\end{itemdescr}

\indexlibraryglobal{regex_replace}%
\begin{itemdecl}
template<class traits, class charT, class ST, class SA>
  basic_string<charT>
    regex_replace(const charT* s,
                  const basic_regex<charT, traits>& e,
                  const basic_string<charT, ST, SA>& fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
template<class traits, class charT>
  basic_string<charT>
    regex_replace(const charT* s,
                  const basic_regex<charT, traits>& e,
                  const charT* fmt,
                  regex_constants::match_flag_type flags = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an empty string \tcode{result} of
type \tcode{basic_string<charT>} and calls:
\begin{codeblock}
regex_replace(back_inserter(result), s, s + char_traits<charT>::length(s), e, fmt, flags);
\end{codeblock}

\pnum
\returns
\tcode{result}.
\end{itemdescr}

\rSec2[re.iter]{Regular expression iterators}

\rSec3[re.regiter]{Class template \tcode{regex_iterator}}

\rSec4[re.regiter.general]{General}
\pnum
\indexlibraryglobal{regex_iterator}%
\indexlibraryglobal{match_results}%
The class template \tcode{regex_iterator} is an iterator adaptor.
It represents a new view of an existing iterator sequence, by
enumerating all the occurrences of a regular expression within that
sequence. A \tcode{regex_iterator} uses  \tcode{regex_search} to find successive
regular expression matches within the sequence from which it was
constructed.  After the iterator is constructed, and every time \tcode{operator++} is
used, the iterator finds and stores a value of
\tcode{match_results<BidirectionalIterator>}. If the end of the sequence is
reached (\tcode{regex_search} returns \tcode{false}), the iterator becomes equal to
the end-of-sequence iterator value. The default constructor
constructs an end-of-sequence iterator object,
which is the only legitimate iterator to be used for the end
condition. The result of \tcode{operator*} on an end-of-sequence iterator is not
defined. For any other iterator value a
\tcode{const match_results<BidirectionalIterator>\&} is returned. The result of
\tcode{operator->} on an end-of-sequence iterator is not defined. For any other
iterator value a \tcode{const match_results<BidirectionalIterator>*} is
returned. It is impossible to store things into \tcode{regex_iterator}s. Two
end-of-sequence iterators are always equal. An end-of-sequence
iterator is not equal to a non-end-of-sequence iterator. Two
non-end-of-sequence iterators are equal when they are constructed from
the same arguments.

\begin{codeblock}
namespace std {
  template<class BidirectionalIterator,
           class charT = typename iterator_traits<BidirectionalIterator>::value_type,
           class traits = regex_traits<charT>>
    class regex_iterator {
    public:
      using regex_type        = basic_regex<charT, traits>;
      using iterator_category = forward_iterator_tag;
      using iterator_concept  = input_iterator_tag;
      using value_type        = match_results<BidirectionalIterator>;
      using difference_type   = ptrdiff_t;
      using pointer           = const value_type*;
      using reference         = const value_type&;

      regex_iterator();
      regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
                     const regex_type& re,
                     regex_constants::match_flag_type m = regex_constants::match_default);
      regex_iterator(BidirectionalIterator, BidirectionalIterator,
                     const regex_type&&,
                     regex_constants::match_flag_type = regex_constants::match_default) = delete;
      regex_iterator(const regex_iterator&);
      regex_iterator& operator=(const regex_iterator&);
      bool operator==(const regex_iterator&) const;
      bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
      const value_type& operator*() const;
      const value_type* operator->() const;
      regex_iterator& operator++();
      regex_iterator operator++(int);

    private:
      BidirectionalIterator                begin;               // \expos
      BidirectionalIterator                end;                 // \expos
      const regex_type*                    pregex;              // \expos
      regex_constants::match_flag_type     flags;               // \expos
      match_results<BidirectionalIterator> match;               // \expos
    };
}
\end{codeblock}

\pnum
An object of type \tcode{regex_iterator} that is not an end-of-sequence iterator
holds a \textit{zero-length match} if \tcode{match[0].matched == true} and
\tcode{match[0].first == match[0].second}.
\begin{note}
For
example, this can occur when the part of the regular expression that
matched consists only of an assertion (such as \verb|'^'|, \verb|'$'|,
\tcode{'$\backslash$b'}, \tcode{'$\backslash$B'}).
\end{note}

\rSec4[re.regiter.cnstr]{Constructors}

\indexlibraryctor{regex_iterator}%
\begin{itemdecl}
regex_iterator();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an end-of-sequence iterator.
\end{itemdescr}

\indexlibraryctor{regex_iterator}%
\begin{itemdecl}
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
               const regex_type& re,
               regex_constants::match_flag_type m = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{begin} and \tcode{end} to
\tcode{a} and \tcode{b}, respectively, sets
\tcode{pregex} to \tcode{addressof(re)}, sets \tcode{flags} to
\tcode{m}, then calls \tcode{regex_search(begin, end, match, *pregex, flags)}. If this
call returns \tcode{false} the constructor sets \tcode{*this} to the end-of-sequence
iterator.
\end{itemdescr}

\rSec4[re.regiter.comp]{Comparisons}

\indexlibrarymember{regex_iterator}{operator==}%
\begin{itemdecl}
bool operator==(const regex_iterator& right) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \tcode{*this} and \tcode{right} are both end-of-sequence
iterators or if the following conditions all hold:
\begin{itemize}
\item \tcode{begin == right.begin},
\item \tcode{end == right.end},
\item \tcode{pregex == right.pregex},
\item \tcode{flags == right.flags}, and
\item \tcode{match[0] == right.match[0]};
\end{itemize}
otherwise \tcode{false}.
\end{itemdescr}

\rSec4[re.regiter.deref]{Indirection}

\indexlibrarymember{regex_iterator}{operator*}%
\begin{itemdecl}
const value_type& operator*() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{match}.
\end{itemdescr}

\indexlibrarymember{operator->}{regex_iterator}%
\begin{itemdecl}
const value_type* operator->() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{addressof(match)}.
\end{itemdescr}

\rSec4[re.regiter.incr]{Increment}

\indexlibrarymember{regex_iterator}{operator++}%
\indexlibrary{\idxcode{regex_iterator}!increment}%
\begin{itemdecl}
regex_iterator& operator++();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a local variable \tcode{start} of type \tcode{BidirectionalIterator} and
initializes it with the value of \tcode{match[0].second}.

\pnum
If the iterator holds a zero-length match and \tcode{start == end} the operator
sets \tcode{*this} to the end-of-sequence iterator and returns \tcode{*this}.

\pnum
\indexlibraryglobal{match_not_null}%
\indexlibraryglobal{match_continuous}%
Otherwise, if the iterator holds a zero-length match, the operator calls:
\begin{codeblock}
regex_search(start, end, match, *pregex,
             flags | regex_constants::match_not_null | regex_constants::match_continuous)
\end{codeblock}
If the call returns \tcode{true} the operator
returns \tcode{*this}. Otherwise the operator increments \tcode{start} and continues as if
the most recent match was not a zero-length match.

\pnum
\indexlibraryglobal{match_prev_avail}%
If the most recent match was not a zero-length match, the operator sets
\tcode{flags} to \tcode{flags | regex_constants::match_prev_avail} and
calls \tcode{regex_search(start, end, match, *pregex, flags)}. If the call returns
\tcode{false} the iterator sets \tcode{*this} to the end-of-sequence iterator. The
iterator then returns \tcode{*this}.

\pnum
In all cases in which the call to \tcode{regex_search} returns \tcode{true},
\tcode{match.prefix().first} shall be equal to the previous value of
\tcode{match[0].second}, and for each index \tcode{i} in the half-open range
\range{0}{match.size()} for which \tcode{match[i].matched} is \tcode{true},
\tcode{match.position(i)}
shall return \tcode{distance(begin, match[i].\brk{}first)}.

\pnum
\begin{note}
This means that \tcode{match.position(i)} gives the
offset from the beginning of the target sequence, which is often not
the same as the offset from the sequence passed in the call
to \tcode{regex_search}.
\end{note}

\pnum
It is unspecified how the implementation makes these adjustments.

\pnum
\begin{note}
This means that an implementation can call an
implementation-specific search function, in which case a program-defined
specialization of \tcode{regex_search} will not be
called.
\end{note}
\end{itemdescr}

\indexlibrarymember{regex_iterator}{operator++}%
\begin{itemdecl}
regex_iterator operator++(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by:
\begin{codeblock}
regex_iterator tmp = *this;
++(*this);
return tmp;
\end{codeblock}
\end{itemdescr}

\rSec3[re.tokiter]{Class template \tcode{regex_token_iterator}}

\rSec4[re.tokiter.general]{General}

\pnum
\indexlibraryglobal{regex_token_iterator}%
The class template \tcode{regex_token_iterator} is an iterator adaptor; that
is to say it represents a new view of an existing iterator sequence,
by enumerating all the occurrences of a regular expression within that
sequence, and presenting one or more sub-expressions for each match
found. Each position enumerated by the iterator is a \tcode{sub_match} class
template instance that represents what matched a particular sub-expression
within the regular expression.

\pnum
When class \tcode{regex_token_iterator} is used to enumerate a
single sub-expression with index $-1$ the iterator performs field
splitting: that is to say it enumerates one sub-expression for each section of
the character container sequence that does not match the regular
expression specified.

\pnum
\indexlibraryglobal{match_results}%
After it is constructed, the iterator finds and stores a value
\tcode{regex_iterator<BidirectionalIterator> position}
and sets the internal count \tcode{N} to zero. It also maintains a sequence
\tcode{subs} which contains a list of the sub-expressions which will be
enumerated. Every time \tcode{operator++} is used
the count \tcode{N} is incremented; if \tcode{N} exceeds or equals \tcode{subs.size()},
then the iterator increments member \tcode{position}
and sets count \tcode{N} to zero.

\pnum
If the end of sequence is reached (\tcode{position} is equal to the end of
sequence iterator), the iterator becomes equal to the end-of-sequence
iterator value, unless the sub-expression being enumerated has index $-1$,
in which case the iterator enumerates one last sub-expression that contains
all the characters from the end of the last regular expression match to the
end of the input sequence being enumerated, provided that this would not be an
empty sub-expression.

\pnum
\indexlibrary{\idxcode{regex_token_iterator}!end-of-sequence}%
The default constructor constructs
an end-of-sequence iterator object, which is the only legitimate
iterator to be used for the end condition. The result of \tcode{operator*} on
an end-of-sequence iterator is not defined. For any other iterator value a
\tcode{const sub_match<BidirectionalIterator>\&} is returned.
The result of \tcode{operator->} on an end-of-sequence iterator
is not defined. For any other iterator value a \tcode{const
sub_match<BidirectionalIterator>*} is returned.

\pnum
\indexlibrarymember{regex_token_iterator}{operator==}%
It is impossible to store things
into \tcode{regex_token_iterator}s. Two end-of-sequence iterators are always
equal. An end-of-sequence iterator is not equal to a
non-end-of-sequence iterator. Two non-end-of-sequence iterators are
equal when they are constructed from the same arguments.

\begin{codeblock}
namespace std {
  template<class BidirectionalIterator,
           class charT = typename iterator_traits<BidirectionalIterator>::value_type,
           class traits = regex_traits<charT>>
    class regex_token_iterator {
    public:
      using regex_type        = basic_regex<charT, traits>;
      using iterator_category = forward_iterator_tag;
      using iterator_concept  = input_iterator_tag;
      using value_type        = sub_match<BidirectionalIterator>;
      using difference_type   = ptrdiff_t;
      using pointer           = const value_type*;
      using reference         = const value_type&;

      regex_token_iterator();
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           int submatch = 0,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           const vector<int>& submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           initializer_list<int> submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      template<size_t N>
        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                             const regex_type& re,
                             const int (&submatches)[N],
                             regex_constants::match_flag_type m =
                               regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           int submatch = 0,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           const vector<int>& submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           initializer_list<int> submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      template<size_t N>
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           const int (&submatches)[N],
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(const regex_token_iterator&);
      regex_token_iterator& operator=(const regex_token_iterator&);
      bool operator==(const regex_token_iterator&) const;
      bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); }
      const value_type& operator*() const;
      const value_type* operator->() const;
      regex_token_iterator& operator++();
      regex_token_iterator operator++(int);

    private:
      using position_iterator =
        regex_iterator<BidirectionalIterator, charT, traits>;   // \expos
      position_iterator position;                               // \expos
      const value_type* result;                                 // \expos
      value_type suffix;                                        // \expos
      size_t N;                                                 // \expos
      vector<int> subs;                                         // \expos
    };
}
\end{codeblock}

\pnum
A \textit{suffix iterator} is a \tcode{regex_token_iterator} object
that points to a final sequence of characters at
the end of the target sequence. In a suffix iterator the
member \tcode{result} holds a pointer to the data
member \tcode{suffix}, the value of the member \tcode{suffix.matched}
is \tcode{true}, \tcode{suffix.first} points to the beginning of the
final sequence, and \tcode{suffix.second} points to the end of the
final sequence.

\pnum
\begin{note}
For a suffix iterator, data
member \tcode{suffix.first} is the same as the end of the last match
found, and \tcode{suffix\brk.second} is the same as the end of the target
sequence.
\end{note}

\pnum
The \textit{current match} is \tcode{(*position).prefix()} if \tcode{subs[N] == -1}, or
\tcode{(*position)[subs[N]]} for any other value of \tcode{subs[N]}.

\rSec4[re.tokiter.cnstr]{Constructors}

\indexlibraryctor{regex_token_iterator}%
\begin{itemdecl}
regex_token_iterator();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs the end-of-sequence iterator.
\end{itemdescr}

\indexlibraryctor{regex_token_iterator}%
\begin{itemdecl}
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                     const regex_type& re,
                     int submatch = 0,
                     regex_constants::match_flag_type m = regex_constants::match_default);

regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                     const regex_type& re,
                     const vector<int>& submatches,
                     regex_constants::match_flag_type m = regex_constants::match_default);

regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                     const regex_type& re,
                     initializer_list<int> submatches,
                     regex_constants::match_flag_type m = regex_constants::match_default);

template<size_t N>
  regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                       const regex_type& re,
                       const int (&submatches)[N],
                       regex_constants::match_flag_type m = regex_constants::match_default);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
Each of the initialization values of \tcode{submatches} is \tcode{>= -1}.

\pnum
\effects
The first constructor initializes the member \tcode{subs} to hold the single
value \tcode{submatch}.
The second, third, and fourth constructors
initialize the member \tcode{subs} to hold a copy of the sequence of integer values
pointed to by the iterator range
\range{begin(submatches)}{end(submatches)}.

\pnum
Each constructor then sets \tcode{N} to 0, and \tcode{position} to
\tcode{position_iterator(a, b, re, m)}. If \tcode{position} is not an
end-of-sequence iterator the constructor sets \tcode{result} to the
address of the current match. Otherwise if any of the values stored
in \tcode{subs} is equal to $-1$ the constructor sets \tcode{*this} to a suffix
iterator that points to the range \range{a}{b}, otherwise the constructor
sets \tcode{*this} to an end-of-sequence iterator.
\end{itemdescr}

\rSec4[re.tokiter.comp]{Comparisons}

\indexlibrarymember{regex_token_iterator}{operator==}%
\begin{itemdecl}
bool operator==(const regex_token_iterator& right) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \tcode{*this} and \tcode{right} are both end-of-sequence iterators,
or if \tcode{*this} and \tcode{right} are both suffix iterators and \tcode{suffix == right.suffix};
otherwise returns \tcode{false} if \tcode{*this} or \tcode{right} is an end-of-sequence
iterator or a suffix iterator. Otherwise returns \tcode{true} if \tcode{position == right.position},
\tcode{N == right.N}, and \tcode{subs == right.subs}. Otherwise returns \tcode{false}.
\end{itemdescr}

\rSec4[re.tokiter.deref]{Indirection}

\indexlibrarymember{regex_token_iterator}{operator*}%
\begin{itemdecl}
const value_type& operator*() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{*result}.
\end{itemdescr}

\indexlibrarymember{operator->}{regex_token_iterator}%
\begin{itemdecl}
const value_type* operator->() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{result}.
\end{itemdescr}


\rSec4[re.tokiter.incr]{Increment}

\indexlibrarymember{regex_token_iterator}{operator++}%
\begin{itemdecl}
regex_token_iterator& operator++();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a local variable \tcode{prev} of
type \tcode{position_iterator}, initialized with the value
of \tcode{position}.

\pnum
If \tcode{*this} is a suffix iterator, sets \tcode{*this} to an
end-of-sequence iterator.

\pnum
Otherwise, if \tcode{N + 1 < subs.size()}, increments \tcode{N} and
sets \tcode{result} to the address of the current match.

\pnum
Otherwise, sets \tcode{N} to 0 and
increments \tcode{position}. If \tcode{position} is not an
end-of-sequence iterator the operator sets \tcode{result} to the
address of the current match.

\pnum
Otherwise, if any of the values stored in \tcode{subs} is equal to $-1$ and
\tcode{prev->suffix().length()} is not 0 the operator sets \tcode{*this} to a
suffix iterator that points to the range \range{prev->suffix().first}{prev->suffix().second}.

\pnum
Otherwise, sets \tcode{*this} to an end-of-sequence iterator.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{regex_token_iterator}{operator++}%
\begin{itemdecl}
regex_token_iterator& operator++(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a copy \tcode{tmp} of \tcode{*this}, then calls \tcode{++(*this)}.

\pnum
\returns
\tcode{tmp}.
\end{itemdescr}

\rSec2[re.grammar]{Modified ECMAScript regular expression grammar}
\indextext{regular expression!grammar}%
\indextext{grammar!regular expression}%

\pnum
\indexlibraryglobal{basic_regex}%
\indextext{ECMAScript}%
The regular expression grammar recognized by
\tcode{basic_regex} objects constructed with the ECMAScript
flag is that specified by ECMA-262, except as specified below.

\pnum
\indexlibraryglobal{locale}%
\indextext{regular expression traits}%
Objects of type specialization of \tcode{basic_regex} store within themselves a
default-constructed instance of their \tcode{traits} template parameter, henceforth
referred to as \tcode{traits_inst}. This \tcode{traits_inst} object is used to support localization
of the regular expression; \tcode{basic_regex} member functions shall not call
any locale dependent C or \Cpp{} API, including the formatted string input functions.
Instead they shall call the appropriate traits member function to achieve the required effect.

\pnum
The following productions within the ECMAScript grammar are modified as follows:

\begin{ncrebnf}
\renontermdef{ClassAtom}\br
  \terminal{-}\br
  ClassAtomNoDash\br
  ClassAtomExClass\br
  ClassAtomCollatingElement\br
  ClassAtomEquivalence
\end{ncrebnf}

\begin{ncrebnf}
\renontermdef{IdentityEscape}\br
  SourceCharacter \textnormal{\textbf{but not}} \terminal{c}
\end{ncrebnf}

\pnum
The following new productions are then added:

\begin{ncrebnf}
\renontermdef{ClassAtomExClass}\br
  \terminal{[:} ClassName \terminal{:]}
\end{ncrebnf}

\begin{ncrebnf}
\renontermdef{ClassAtomCollatingElement}\br
  \terminal{[.} ClassName \terminal{.]}
\end{ncrebnf}

\begin{ncrebnf}
\renontermdef{ClassAtomEquivalence}\br
  \terminal{[=} ClassName \terminal{=]}
\end{ncrebnf}

\begin{ncrebnf}
\renontermdef{ClassName}\br
  ClassNameCharacter\br
  ClassNameCharacter ClassName
\end{ncrebnf}

\begin{ncrebnf}
\renontermdef{ClassNameCharacter}\br
  SourceCharacter \textnormal{\textbf{but not one of}} \terminal{.} \textnormal{\textbf{or}} \terminal{=} \textnormal{\textbf{or}} \terminal{:}
\end{ncrebnf}

\pnum
The productions \regrammarterm{ClassAtomExClass}, \regrammarterm{ClassAtomCollatingElement}
and \regrammarterm{ClassAtomEquivalence} provide functionality
equivalent to that of the same features in regular expressions in POSIX.

\pnum
The regular expression grammar may be modified by
any \tcode{regex_constants::syntax_option_type} flags specified when
constructing an object of type specialization of \tcode{basic_regex}
according to the rules in \tref{re.synopt}.

\pnum
A \regrammarterm{ClassName} production, when used in \regrammarterm{ClassAtomExClass},
is not valid if \tcode{traits_inst.lookup_classname} returns zero for
that name.  The names recognized as valid \regrammarterm{ClassName}s are
determined by the type of the traits class, but at least the following
names shall be recognized:
\tcode{alnum}, \tcode{alpha}, \tcode{blank}, \tcode{cntrl}, \tcode{digit},
\tcode{graph}, \tcode{lower}, \tcode{print}, \tcode{punct}, \tcode{space},
\tcode{upper}, \tcode{xdigit}, \tcode{d}, \tcode{s}, \tcode{w}.
In addition the following expressions shall be equivalent:

\begin{codeblock}
\d @\textnormal{and}@ [[:digit:]]

\D @\textnormal{and}@ [^[:digit:]]

\s @\textnormal{and}@ [[:space:]]

\S @\textnormal{and}@ [^[:space:]]

\w @\textnormal{and}@ [_[:alnum:]]

\W @\textnormal{and}@ [^_[:alnum:]]
\end{codeblock}

\pnum
\indexlibrary{regular expression traits!\idxcode{lookup_collatename}}%
\indexlibrary{\idxcode{lookup_collatename}!regular expression traits}%
A \regrammarterm{ClassName} production when used in
a \regrammarterm{ClassAtomCollatingElement} production is not valid
if the value returned by \tcode{traits_inst.lookup_collatename} for
that name is an empty string.

\pnum
\indexlibrary{regular expression traits!\idxcode{isctype}}%
\indexlibrary{\idxcode{isctype}!regular expression traits}%
\indexlibrary{regular expression traits!\idxcode{lookup_classname}}%
\indexlibrary{\idxcode{lookup_classname}!regular expression traits}%
The results from multiple calls
to \tcode{traits_inst.lookup_classname} can be bitwise \logop{or}'ed
together and subsequently passed to \tcode{traits_inst.isctype}.

\pnum
A \regrammarterm{ClassName} production when used in
a \regrammarterm{ClassAtomEquivalence} production is not valid if the value
returned by \tcode{traits_inst.lookup_collatename} for that name is an
empty string or if the value returned by \tcode{traits_inst\brk.transform_primary}
for the result of the call to \tcode{traits_inst.lookup_collatename}
is an empty string.

\pnum
\indexlibraryglobal{regex_error}%
When the sequence of characters being transformed to a finite state
machine contains an invalid class name the translator shall throw an
exception object of type \tcode{regex_error}.

\pnum
\indexlibraryglobal{regex_error}%
If the \textit{CV} of a \textit{UnicodeEscapeSequence} is greater than the largest
value that can be held in an object of type \tcode{charT} the translator shall
throw an exception object of type \tcode{regex_error}.
\begin{note}
This means that values of the form \tcode{"\textbackslash{}uxxxx"} that do not fit in
a character are invalid.
\end{note}

\pnum
Where the regular expression grammar requires the conversion of a sequence of characters
to an integral value, this is accomplished by calling \tcode{traits_inst.value}.

\pnum
\indexlibraryglobal{match_flag_type}%
The behavior of the internal finite state machine representation when used to match a
sequence of characters is as described in ECMA-262.
The behavior is modified according
to any \tcode{match_flag_type} flags\iref{re.matchflag} specified when using the regular expression
object in one of the regular expression algorithms\iref{re.alg}. The behavior is also
localized by interaction with the traits class template parameter as follows:
\begin{itemize}
\item During matching of a regular expression finite state machine
against a sequence of characters, two characters \tcode{c}
and \tcode{d} are compared using the following rules:
\begin{itemize}
\item if \tcode{(flags() \& regex_constants::icase)} the two characters are equal
if \tcode{traits_inst.trans\-late_nocase(c) == traits_inst.translate_nocase(d)};
\item otherwise, if \tcode{flags() \& regex_constants::collate} the
two characters are equal if
\tcode{traits_inst\brk.translate(c) == traits_inst\brk.translate(d)};
\indexlibrarymember{syntax_option_type}{collate}%
\item otherwise, the two characters are equal if \tcode{c == d}.
\end{itemize}

\item During matching of a regular expression finite state machine
against a sequence of characters, comparison of a collating element
range \tcode{c1-c2} against a character \tcode{c} is
conducted as follows: if \tcode{flags() \& regex_constants::collate}
is \tcode{false} then the character \tcode{c} is matched if \tcode{c1
<= c \&\& c <= c2}, otherwise \tcode{c} is matched in
accordance with the following algorithm:

\begin{codeblock}
string_type str1 = string_type(1,
  flags() & icase ?
    traits_inst.translate_nocase(c1) : traits_inst.translate(c1));
string_type str2 = string_type(1,
  flags() & icase ?
    traits_inst.translate_nocase(c2) : traits_inst.translate(c2));
string_type str = string_type(1,
  flags() & icase ?
    traits_inst.translate_nocase(c) : traits_inst.translate(c));
return traits_inst.transform(str1.begin(), str1.end())
      <= traits_inst.transform(str.begin(), str.end())
  && traits_inst.transform(str.begin(), str.end())
      <= traits_inst.transform(str2.begin(), str2.end());
\end{codeblock}

\item During matching of a regular expression finite state machine against a sequence of
characters, testing whether a collating element is a member of a primary equivalence
class is conducted by first converting the collating element and the equivalence
class to sort keys using \tcode{traits::transform_primary}, and then comparing the sort
keys for equality.
\indextext{regular expression traits!\idxcode{transform_primary}}%
\indextext{transform_primary@\tcode{transform_primary}!regular expression traits}%

\item During matching of a regular expression finite state machine against a sequence
of characters, a character \tcode{c} is a member of a character class designated by an
iterator range \range{first}{last} if
\tcode{traits_inst.isctype(c, traits_inst.lookup_classname(first, last, flags() \& icase))} is \tcode{true}.
\end{itemize}
\xref{ECMA-262 15.10}
\indextext{regular expression|)}

\rSec1[text.c.strings]{Null-terminated sequence utilities}

\rSec2[cctype.syn]{Header \tcode{<cctype>} synopsis}

\indexlibraryglobal{isalnum}%
\indexlibraryglobal{isalpha}%
\indexlibraryglobal{isblank}%
\indexlibraryglobal{iscntrl}%
\indexlibraryglobal{isdigit}%
\indexlibraryglobal{isgraph}%
\indexlibraryglobal{islower}%
\indexlibraryglobal{isprint}%
\indexlibraryglobal{ispunct}%
\indexlibraryglobal{isspace}%
\indexlibraryglobal{isupper}%
\indexlibraryglobal{isxdigit}%
\indexlibraryglobal{tolower}%
\indexlibraryglobal{toupper}%
\begin{codeblock}
namespace std {
  int isalnum(int c);
  int isalpha(int c);
  int isblank(int c);
  int iscntrl(int c);
  int isdigit(int c);
  int isgraph(int c);
  int islower(int c);
  int isprint(int c);
  int ispunct(int c);
  int isspace(int c);
  int isupper(int c);
  int isxdigit(int c);
  int tolower(int c);
  int toupper(int c);
}
\end{codeblock}

\pnum
The contents and meaning of the header \libheaderdef{cctype}
are the same as the C standard library header \libheader{ctype.h}.

\xrefc{7.4}

\rSec2[cwctype.syn]{Header \tcode{<cwctype>} synopsis}

\indexlibraryglobal{wint_t}%
\indexlibraryglobal{wctrans_t}%
\indexlibraryglobal{wctype_t}%
\indexlibraryglobal{iswalnum}%
\indexlibraryglobal{iswalpha}%
\indexlibraryglobal{iswblank}%
\indexlibraryglobal{iswcntrl}%
\indexlibraryglobal{iswdigit}%
\indexlibraryglobal{iswgraph}%
\indexlibraryglobal{iswlower}%
\indexlibraryglobal{iswprint}%
\indexlibraryglobal{iswpunct}%
\indexlibraryglobal{iswspace}%
\indexlibraryglobal{iswupper}%
\indexlibraryglobal{iswxdigit}%
\indexlibraryglobal{iswctype}%
\indexlibraryglobal{wctype}%
\indexlibraryglobal{towlower}%
\indexlibraryglobal{towupper}%
\indexlibraryglobal{towctrans}%
\indexlibraryglobal{wctrans}%
\begin{codeblock}
namespace std {
  using wint_t = @\seebelow@;
  using wctrans_t = @\seebelow@;
  using wctype_t = @\seebelow@;

  int iswalnum(wint_t wc);
  int iswalpha(wint_t wc);
  int iswblank(wint_t wc);
  int iswcntrl(wint_t wc);
  int iswdigit(wint_t wc);
  int iswgraph(wint_t wc);
  int iswlower(wint_t wc);
  int iswprint(wint_t wc);
  int iswpunct(wint_t wc);
  int iswspace(wint_t wc);
  int iswupper(wint_t wc);
  int iswxdigit(wint_t wc);
  int iswctype(wint_t wc, wctype_t desc);
  wctype_t wctype(const char* property);
  wint_t towlower(wint_t wc);
  wint_t towupper(wint_t wc);
  wint_t towctrans(wint_t wc, wctrans_t desc);
  wctrans_t wctrans(const char* property);
}

#define @\libmacro{WEOF}@ @\seebelow@
\end{codeblock}

\pnum
The contents and meaning of the header \libheaderdef{cwctype}
are the same as the C standard library header \libheader{wctype.h}.

\xrefc{7.32}

\rSec2[cwchar.syn]{Header \tcode{<cwchar>} synopsis}

\indexheader{cwchar}%
\indexlibraryglobal{btowc}%
\indexlibraryglobal{fgetwc}%
\indexlibraryglobal{fgetws}%
\indexlibraryglobal{fputwc}%
\indexlibraryglobal{fputws}%
\indexlibraryglobal{fwide}%
\indexlibraryglobal{fwprintf}%
\indexlibraryglobal{fwscanf}%
\indexlibraryglobal{getwchar}%
\indexlibraryglobal{getwc}%
\indexlibraryglobal{mbrlen}%
\indexlibraryglobal{mbrtowc}%
\indexlibraryglobal{mbsinit}%
\indexlibraryglobal{mbsrtowcs}%
\indexlibraryglobal{mbstate_t}%
\indexlibraryglobal{putwchar}%
\indexlibraryglobal{putwc}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{swprintf}%
\indexlibraryglobal{swscanf}%
\indexlibraryglobal{tm}%
\indexlibraryglobal{ungetwc}%
\indexlibraryglobal{vfwprintf}%
\indexlibraryglobal{vfwscanf}%
\indexlibraryglobal{vswprintf}%
\indexlibraryglobal{vswscanf}%
\indexlibraryglobal{vwprintf}%
\indexlibraryglobal{vwscanf}%
\indexlibraryglobal{wcrtomb}%
\indexlibraryglobal{wcscat}%
\indexlibraryglobal{wcschr}%
\indexlibraryglobal{wcscmp}%
\indexlibraryglobal{wcscoll}%
\indexlibraryglobal{wcscpy}%
\indexlibraryglobal{wcscspn}%
\indexlibraryglobal{wcsftime}%
\indexlibraryglobal{wcslen}%
\indexlibraryglobal{wcsncat}%
\indexlibraryglobal{wcsncmp}%
\indexlibraryglobal{wcsncpy}%
\indexlibraryglobal{wcspbrk}%
\indexlibraryglobal{wcsrchr}%
\indexlibraryglobal{wcsrtombs}%
\indexlibraryglobal{wcsspn}%
\indexlibraryglobal{wcsstr}%
\indexlibraryglobal{wcstod}%
\indexlibraryglobal{wcstof}%
\indexlibraryglobal{wcstok}%
\indexlibraryglobal{wcstold}%
\indexlibraryglobal{wcstoll}%
\indexlibraryglobal{wcstol}%
\indexlibraryglobal{wcstoull}%
\indexlibraryglobal{wcstoul}%
\indexlibraryglobal{wcsxfrm}%
\indexlibraryglobal{wctob}%
\indexlibraryglobal{wint_t}%
\indexlibraryglobal{wmemchr}%
\indexlibraryglobal{wmemcmp}%
\indexlibraryglobal{wmemcpy}%
\indexlibraryglobal{wmemmove}%
\indexlibraryglobal{wmemset}%
\indexlibraryglobal{wprintf}%
\indexlibraryglobal{wscanf}%
\begin{codeblock}
#define __STDC_VERSION_WCHAR_H__ 202311L

namespace std {
  using size_t = @\textit{see \ref{support.types.layout}}@;                                             // freestanding
  using mbstate_t = @\seebelow@;                                          // freestanding
  using wint_t = @\seebelow@;                                             // freestanding

  struct tm;

  int fwprintf(FILE* stream, const wchar_t* format, ...);
  int fwscanf(FILE* stream, const wchar_t* format, ...);
  int swprintf(wchar_t* s, size_t n, const wchar_t* format, ...);
  int swscanf(const wchar_t* s, const wchar_t* format, ...);
  int vfwprintf(FILE* stream, const wchar_t* format, va_list arg);
  int vfwscanf(FILE* stream, const wchar_t* format, va_list arg);
  int vswprintf(wchar_t* s, size_t n, const wchar_t* format, va_list arg);
  int vswscanf(const wchar_t* s, const wchar_t* format, va_list arg);
  int vwprintf(const wchar_t* format, va_list arg);
  int vwscanf(const wchar_t* format, va_list arg);
  int wprintf(const wchar_t* format, ...);
  int wscanf(const wchar_t* format, ...);
  wint_t fgetwc(FILE* stream);
  wchar_t* fgetws(wchar_t* s, int n, FILE* stream);
  wint_t fputwc(wchar_t c, FILE* stream);
  int fputws(const wchar_t* s, FILE* stream);
  int fwide(FILE* stream, int mode);
  wint_t getwc(FILE* stream);
  wint_t getwchar();
  wint_t putwc(wchar_t c, FILE* stream);
  wint_t putwchar(wchar_t c);
  wint_t ungetwc(wint_t c, FILE* stream);
  double wcstod(const wchar_t* nptr, wchar_t** endptr);
  float wcstof(const wchar_t* nptr, wchar_t** endptr);
  long double wcstold(const wchar_t* nptr, wchar_t** endptr);
  long int wcstol(const wchar_t* nptr, wchar_t** endptr, int base);
  long long int wcstoll(const wchar_t* nptr, wchar_t** endptr, int base);
  unsigned long int wcstoul(const wchar_t* nptr, wchar_t** endptr, int base);
  unsigned long long int wcstoull(const wchar_t* nptr, wchar_t** endptr, int base);
  wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2);                      // freestanding
  wchar_t* wcsncpy(wchar_t* s1, const wchar_t* s2, size_t n);           // freestanding
  wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n);           // freestanding
  wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);          // freestanding
  wchar_t* wcscat(wchar_t* s1, const wchar_t* s2);                      // freestanding
  wchar_t* wcsncat(wchar_t* s1, const wchar_t* s2, size_t n);           // freestanding
  int wcscmp(const wchar_t* s1, const wchar_t* s2);                     // freestanding
  int wcscoll(const wchar_t* s1, const wchar_t* s2);
  int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);          // freestanding
  size_t wcsxfrm(wchar_t* s1, const wchar_t* s2, size_t n);
  int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n);          // freestanding
  const wchar_t* wcschr(const wchar_t* s, wchar_t c);                   // freestanding; see \ref{library.c}
  wchar_t* wcschr(wchar_t* s, wchar_t c);                               // freestanding; see \ref{library.c}
  size_t wcscspn(const wchar_t* s1, const wchar_t* s2);                 // freestanding
  const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);         // freestanding; see \ref{library.c}
  wchar_t* wcspbrk(wchar_t* s1, const wchar_t* s2);                     // freestanding; see \ref{library.c}
  const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);                  // freestanding; see \ref{library.c}
  wchar_t* wcsrchr(wchar_t* s, wchar_t c);                              // freestanding; see \ref{library.c}
  size_t wcsspn(const wchar_t* s1, const wchar_t* s2);                  // freestanding
  const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);          // freestanding; see \ref{library.c}
  wchar_t* wcsstr(wchar_t* s1, const wchar_t* s2);                      // freestanding; see \ref{library.c}
  wchar_t* wcstok(wchar_t* s1, const wchar_t* s2, wchar_t** ptr);       // freestanding
  const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);        // freestanding; see \ref{library.c}
  wchar_t* wmemchr(wchar_t* s, wchar_t c, size_t n);                    // freestanding; see \ref{library.c}
  size_t wcslen(const wchar_t* s);                                      // freestanding
  wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);                    // freestanding
  size_t wcsftime(wchar_t* s, size_t maxsize, const wchar_t* format, const tm* timeptr);
  wint_t btowc(int c);
  int wctob(wint_t c);

  // \ref{c.mb.wcs}, multibyte / wide string and character conversion functions
  int mbsinit(const mbstate_t* ps);
  size_t mbrlen(const char* s, size_t n, mbstate_t* ps);
  size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps);
  size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps);
  size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps);
  size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps);
}

#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@                                                  // freestanding
#define @\libmacro{WCHAR_MAX}@ @\seebelow@                                             // freestanding
#define @\libmacro{WCHAR_MIN}@ @\seebelow@                                             // freestanding
#define @\libmacro{WEOF}@ @\seebelow@                                                  // freestanding
#define @\libmacro{WCHAR_WIDTH}@ @\seebelow@                                           // freestanding
\end{codeblock}

\pnum
The contents and meaning of the header \libheader{cwchar}
are the same as the C standard library header
\libheader{wchar.h}, except that it does not declare a type \keyword{wchar_t}.

\pnum
\begin{note}
The functions
\tcode{wcschr}, \tcode{wcspbrk}, \tcode{wcsrchr}, \tcode{wcsstr}, and \tcode{wmemchr}
have different signatures in this document,
but they have the same behavior as in the C standard library\iref{library.c}.
\end{note}

\xrefc{7.31}

\rSec2[cuchar.syn]{Header \tcode{<cuchar>} synopsis}

\indexlibraryglobal{mbstate_t}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{mbrtoc8}%
\indexlibraryglobal{c8rtomb}%
\indexlibraryglobal{mbrtoc16}%
\indexlibraryglobal{c16rtomb}%
\indexlibraryglobal{mbrtoc32}%
\indexlibraryglobal{c32rtomb}%
\begin{codeblock}
#define __STDC_VERSION_UCHAR_H__ 202311L

namespace std {
  using mbstate_t = @\seebelow@;
  using size_t = @\textit{see \ref{support.types.layout}}@;

  size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps);
  size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps);
  size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
  size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
  size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
  size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
}
\end{codeblock}

\pnum
The contents and meaning of the header \libheaderdef{cuchar}
are the same as the C standard library header \libheader{uchar.h},
except that it does not declare types
\keyword{char8_t}, \keyword{char16_t}, or \keyword{char32_t}.

\xrefc{7.30}

\rSec2[c.mb.wcs]{Multibyte / wide string and character conversion functions}

\pnum
\begin{note}
The headers \libheaderref{cstdlib},
\libheaderref{cuchar},
and \libheaderref{cwchar}
declare the functions described in this subclause.
\end{note}

\indexlibraryglobal{mbsinit}%
\indexlibraryglobal{mblen}%
\indexlibraryglobal{mbstowcs}%
\indexlibraryglobal{wcstombs}%
\begin{itemdecl}
int mbsinit(const mbstate_t* ps);
int mblen(const char* s, size_t n);
size_t mbstowcs(wchar_t* pwcs, const char* s, size_t n);
size_t wcstombs(char* s, const wchar_t* pwcs, size_t n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
These functions have the semantics specified in the C standard library.
\end{itemdescr}

\xrefc{7.24.8.2, 7.24.9, 7.31.6.3.1}

\indexlibraryglobal{mbtowc}%
\indexlibraryglobal{wctomb}%
\begin{itemdecl}
int mbtowc(wchar_t* pwc, const char* s, size_t n);
int wctomb(char* s, wchar_t wchar);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
These functions have the semantics specified in the C standard library.

\pnum
\remarks
Calls to these functions
may introduce a data race\iref{res.on.data.races}
with other calls to the same function.
\end{itemdescr}

\xrefc{7.24.8}

\begin{itemdecl}
size_t @\libglobal{mbrlen}@(const char* s, size_t n, mbstate_t* ps);
size_t @\libglobal{mbrtowc}@(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps);
size_t @\libglobal{wcrtomb}@(char* s, wchar_t wc, mbstate_t* ps);
size_t @\libglobal{mbrtoc8}@(char8_t* pc8, const char* s, size_t n, mbstate_t* ps);
size_t @\libglobal{c8rtomb}@(char* s, char8_t c8, mbstate_t* ps);
size_t @\libglobal{mbrtoc16}@(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
size_t @\libglobal{c16rtomb}@(char* s, char16_t c16, mbstate_t* ps);
size_t @\libglobal{mbrtoc32}@(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
size_t @\libglobal{c32rtomb}@(char* s, char32_t c32, mbstate_t* ps);
size_t @\libglobal{mbsrtowcs}@(wchar_t* dst, const char** src, size_t len, mbstate_t* ps);
size_t @\libglobal{wcsrtombs}@(char* dst, const wchar_t** src, size_t len, mbstate_t* ps);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
These functions have the semantics specified in the C standard library.

\pnum
\remarks
Calling these functions
with an \tcode{mbstate_t*} argument that is a null pointer value
may introduce a data race\iref{res.on.data.races}
with other calls to the same function
with an \tcode{mbstate_t*} argument that is a null pointer value.
\end{itemdescr}

\xrefc{7.30.2, 7.31.6.4, 7.31.6.5}
