%!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{} \\ \rowsep \ref{localization} & Localization library & \tcode{}, \tcode{} \\ \rowsep \ref{text.encoding} & Text encodings identification & \tcode{} \\ \rowsep \ref{format} & Formatting & \tcode{} \\ \rowsep \ref{re} & Regular expressions library & \tcode{} \\ \rowsep \ref{text.c.strings} & Null-terminated sequence utilities & \tcode{}, \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \end{libsumtab} \rSec1[charconv]{Primitive numeric conversions} \rSec2[charconv.syn]{Header \tcode{} 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{} \\ \ref{locale.categories} & Standard \tcode{locale} categories & \\ \rowsep \ref{c.locales} & C library locales & \tcode{} \\ \rowsep \end{libsumtab} \rSec2[locale.syn]{Header \tcode{} synopsis} \indexheader{locale}% \begin{codeblock} namespace std { // \ref{locale}, locale class locale; template const Facet& use_facet(const locale&); template bool has_facet(const locale&) noexcept; // \ref{locale.convenience}, convenience interfaces template bool isspace (charT c, const locale& loc); template bool isprint (charT c, const locale& loc); template bool iscntrl (charT c, const locale& loc); template bool isupper (charT c, const locale& loc); template bool islower (charT c, const locale& loc); template bool isalpha (charT c, const locale& loc); template bool isdigit (charT c, const locale& loc); template bool ispunct (charT c, const locale& loc); template bool isxdigit(charT c, const locale& loc); template bool isalnum (charT c, const locale& loc); template bool isgraph (charT c, const locale& loc); template bool isblank (charT c, const locale& loc); template charT toupper(charT c, const locale& loc); template charT tolower(charT c, const locale& loc); // \ref{category.ctype}, ctype class ctype_base; template class ctype; template<> class ctype; // specialization template class ctype_byname; class codecvt_base; template class codecvt; template class codecvt_byname; // \ref{category.numeric}, numeric template> class num_get; template> class num_put; template class numpunct; template class numpunct_byname; // \ref{category.collate}, collation template class collate; template class collate_byname; // \ref{category.time}, date and time class time_base; template> class time_get; template> class time_get_byname; template> class time_put; template> class time_put_byname; // \ref{category.monetary}, money class money_base; template> class money_get; template> class money_put; template class moneypunct; template class moneypunct_byname; // \ref{category.messages}, message retrieval class messages_base; template class messages; template 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 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 locale combine(const locale& other) const; string name() const; text_encoding encoding() const; bool operator==(const locale& other) const; template bool operator()(const basic_string& s1, const basic_string& 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}. \end{footnote} \begin{codeblock} template basic_ostream& operator<< (basic_ostream& s, Date d) { typename basic_ostream::sentry cerberos(s); if (cerberos) { tm tmbuf; d.extract(tmbuf); bool failed = use_facet>>( 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(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()}. 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&, const basic_string&) \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}, \tcode{collate} \\ \rowsep ctype & \tcode{ctype}, \tcode{ctype} \\ & \tcode{codecvt} \\ & \tcode{codecvt} \\ \rowsep monetary & \tcode{moneypunct}, \tcode{moneypunct} \\ & \tcode{moneypunct}, \tcode{moneypunct} \\ & \tcode{money_get}, \tcode{money_get} \\ & \tcode{money_put}, \tcode{money_put} \\ \rowsep numeric & \tcode{numpunct}, \tcode{numpunct} \\ & \tcode{num_get}, \tcode{num_get} \\ & \tcode{num_put}, \tcode{num_put} \\ \rowsep time & \tcode{time_get}, \tcode{time_get} \\ & \tcode{time_put}, \tcode{time_put} \\ \rowsep messages & \tcode{messages}, \tcode{messages} \\ \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(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}, \tcode{collate_byname} \\ \rowsep ctype & \tcode{ctype_byname}, \tcode{ctype_byname} \\ & \tcode{codecvt_byname} \\ & \tcode{codecvt_byname} \\ \rowsep monetary & \tcode{moneypunct_byname} \\ & \tcode{moneypunct_byname} \\ & \tcode{money_get} \\ & \tcode{money_put} \\ \rowsep numeric & \tcode{numpunct_byname}, \tcode{numpunct_byname} \\ & \tcode{num_get}, \tcode{num_put} \\ \rowsep time & \tcode{time_get} \\ & \tcode{time_get_byname} \\ & \tcode{time_get} \\ & \tcode{time_get_byname} \\ & \tcode{time_put} \\ & \tcode{time_put_byname} \\ & \tcode{time_put} \\ & \tcode{time_put_byname} \\ \rowsep messages & \tcode{messages_byname}, \tcode{messages_byname} \\ \end{floattable} \pnum The provided implementation of members of facets \tcode{num_get} and \tcode{num_put} calls \tcode{use_fac\-et(l)} only for facet \tcode{F} of types \tcode{numpunct} and \tcode{ctype}, 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(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 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 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(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 bool operator()(const basic_string& s1, const basic_string& s2) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Compares two strings according to the \tcode{std::collate} facet. \pnum \returns \begin{codeblock} use_facet>(*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 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(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 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 bool isspace (charT c, const locale& loc); template bool isprint (charT c, const locale& loc); template bool iscntrl (charT c, const locale& loc); template bool isupper (charT c, const locale& loc); template bool islower (charT c, const locale& loc); template bool isalpha (charT c, const locale& loc); template bool isdigit (charT c, const locale& loc); template bool ispunct (charT c, const locale& loc); template bool isxdigit(charT c, const locale& loc); template bool isalnum (charT c, const locale& loc); template bool isgraph (charT c, const locale& loc); template 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>(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 charT toupper(charT c, const locale& loc); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{use_facet>(loc).toupper(c)}. \end{itemdescr} \indexlibraryglobal{tolower}% \begin{itemdecl} template charT tolower(charT c, const locale& loc); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{use_facet>(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 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} and \tcode{ctype}, 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} 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} 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 ctype_byname : public ctype { public: using @\libmember{mask}{ctype_byname}@ = ctype::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} specialization} \rSec5[facet.ctype.special.general]{General} \indexlibraryglobal{ctype}% \begin{codeblock} namespace std { template<> class ctype : public locale::facet, public ctype_base { public: using @\libmember{char_type}{ctype}@ = 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}@; static const size_t @\libmember{table_size}{ctype}@ = @\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} 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}. \end{footnote} The \impldef{value of \tcode{ctype::table_size}} value of member \tcode{table_size} is at least 256. \rSec5[facet.ctype.char.dtor]{Destructor} \indexlibrarydtor{ctype}% \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}{ctype}% 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}% \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}{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}{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}{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}{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}{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}{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}{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}{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}{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}{do_toupper}% \indexlibrarymember{ctype}{do_tolower}% \indexlibrarymember{ctype}{do_widen}% \indexlibrarymember{ctype}{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 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} 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} implements a degenerate conversion; it does not convert at all. \tcode{codecvt} 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} 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}, 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::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 codecvt_byname : public codecvt { 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}, \tcode{num_get}, \tcode{num_get}, \tcode{num_put}, \tcode{num_put}, and \tcode{num_put}. 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 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>(loc)}, and \tcode{use_facet>(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>(loc).decimal_point()) c = '.'; bool discard = ct == use_facet>(loc).thousands_sep() && use_facet>(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>(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>(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>(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 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>(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>(loc).widen(c) \end{codeblock} A local variable \tcode{punct} is initialized via \begin{codeblock} const numpunct& punct = use_facet>(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>(loc).truename() : use_facet>(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 numpunct : public locale::facet { public: using @\libmember{char_type}{numpunct}@ = charT; using @\libmember{string_type}{numpunct}@ = basic_string; 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}, 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} 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 numpunct_byname : public numpunct { // 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; 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 collate : public locale::facet { public: using @\libmember{char_type}{collate}@ = charT; using @\libmember{string_type}{collate}@ = basic_string; 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} 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} and \tcode{collate}, 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} and \tcode{collate}, 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} 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::max())}. \end{itemdescr} \rSec4[locale.collate.byname]{Class template \tcode{collate_byname}} \indexlibraryglobal{collate_byname}% \begin{codeblock} namespace std { template class collate_byname : public collate { public: using @\libmember{string_type}{collate_byname}@ = basic_string; 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} and \tcode{time_put} 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 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} 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 time_get_byname : public time_get { 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 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} 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 time_put_byname : public time_put { 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 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; 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} facet reference \tcode{mp} and the character mapping specified by a \tcode{ctype} 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 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; 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} facet reference \tcode{mp} and the character mapping specified by a \tcode{ctype} 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 moneypunct : public locale::facet, public money_base { public: using @\libmember{char_type}{moneypunct}@ = charT; using @\libmember{string_type}{moneypunct}@ = basic_string; 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(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\&} 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::\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}, \item \tcode{moneypunct}, \item \tcode{moneypunct}, and \item \tcode{moneypunct}, \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 moneypunct_byname : public moneypunct { public: using @\libmember{pattern}{moneypunct_byname}@ = money_base::pattern; using @\libmember{string_type}{moneypunct_byname}@ = basic_string; 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} 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 messages : public locale::facet, public messages_base { public: using @\libmember{char_type}{messages}@ = charT; using @\libmember{string_type}{messages}@ = basic_string; 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 messages_byname : public messages { public: using @\libmember{catalog}{messages_byname}@ = messages_base::catalog; using @\libmember{string_type}{messages_byname}@ = basic_string; 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{} 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{} synopsis} \indexheader{text_encoding}% \begin{codeblock} namespace std { struct text_encoding; // \ref{text.encoding.hash}, hash support template struct hash; template<> struct hash; } \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 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 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 { 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} and \tcode{ranges::range_reference_t} denote \tcode{const char*}. \pnum \tcode{ranges::iterator_t} 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; \end{itemdecl} \begin{itemdescr} \pnum The specialization is enabled\iref{unord.hash}. \end{itemdescr} \rSec1[format]{Formatting} \rSec2[format.syn]{Header \tcode{} 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 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 basic_format_args; using format_args = basic_format_args; using wformat_args = basic_format_args; // \ref{format.fmt.string}, class template \tcode{basic_format_string} template struct basic_format_string; template struct @\exposid{dynamic-format-string}@ { // \expos private: basic_string_view @\exposid{str}@; // \expos public: constexpr @\exposid{dynamic-format-string}@(basic_string_view 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}@ dynamic_format(string_view fmt) noexcept { return fmt; } constexpr @\exposid{dynamic-format-string}@ dynamic_format(wstring_view fmt) noexcept { return fmt; } template using @\libglobal{format_string}@ = basic_format_string...>; template using @\libglobal{wformat_string}@ = basic_format_string...>; // \ref{format.functions}, formatting functions template constexpr string format(format_string fmt, Args&&... args); template constexpr wstring format(wformat_string fmt, Args&&... args); template string format(const locale& loc, format_string fmt, Args&&... args); template wstring format(const locale& loc, wformat_string 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 constexpr Out format_to(Out out, format_string fmt, Args&&... args); template constexpr Out format_to(Out out, wformat_string fmt, Args&&... args); template Out format_to(Out out, const locale& loc, format_string fmt, Args&&... args); template Out format_to(Out out, const locale& loc, wformat_string fmt, Args&&... args); template constexpr Out vformat_to(Out out, string_view fmt, format_args args); template constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args); template Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args); template Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args); template struct format_to_n_result { Out out; iter_difference_t size; }; template constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, format_string fmt, Args&&... args); template constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, wformat_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, wformat_string fmt, Args&&... args); template constexpr size_t formatted_size(format_string fmt, Args&&... args); template constexpr size_t formatted_size(wformat_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, wformat_string fmt, Args&&... args); // \ref{format.formatter}, formatter template struct formatter; // \ref{format.formatter.locking}, formatter locking template constexpr bool enable_nonlocking_formatter_optimization = false; // \ref{format.formattable}, concept \libconcept{formattable} template concept formattable = @\seebelow@; template concept @\defexposconcept{const-formattable-range}@ = // \expos ranges::@\libconcept{input_range}@ && @\libconcept{formattable}@, charT>; template using @\exposid{fmt-maybe-const}@ = // \expos conditional_t<@\exposconcept{const-formattable-range}@, const R, R>; // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} template class basic_format_parse_context; using format_parse_context = basic_format_parse_context; using wformat_parse_context = basic_format_parse_context; // \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 constexpr @\unspec@ format_kind = @\unspec@; template requires @\libconcept{same_as}@> constexpr range_format format_kind = @\seebelow@; // \ref{format.range.formatter}, class template \tcode{range_formatter} template requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter; // \ref{format.range.fmtdef}, class template \exposid{range-default-formatter} template 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 requires (format_kind != range_format::disabled) && @\libconcept{formattable}@, charT> struct formatter : @\exposid{range-default-formatter}@, R, charT> { }; template requires (format_kind != range_format::disabled) constexpr bool enable_nonlocking_formatter_optimization = false; // \ref{format.arguments}, arguments // \ref{format.arg}, class template \tcode{basic_format_arg} template class basic_format_arg; // \ref{format.arg.store}, class template \exposid{format-arg-store} template class @\exposidnc{format-arg-store}@; // \expos template constexpr @\exposid{format-arg-store}@ make_format_args(Args&... fmt_args); template constexpr @\exposid{format-arg-store}@ 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::infinity(); double nan = numeric_limits::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::grouping} and \tcode{numpunct::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::grouping}, \tcode{numpunct::thousands_sep}, and \tcode{numpunct::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::truename} or \tcode{numpunct::\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(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(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(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 struct @\libglobal{basic_format_string}@ { private: basic_string_view @\exposidnc{str}@; // \expos public: template consteval basic_format_string(const T& s); constexpr basic_format_string(@\exposid{dynamic-format-string}@ s) noexcept : str(s.@\exposid{str}@) {} constexpr basic_string_view get() const noexcept { return @\exposid{str}@; } }; } \end{codeblock} \begin{itemdecl} template consteval basic_format_string(const T& s); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{const T\&} models \tcode{\libconcept{convertible_to}>}. \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 constexpr string format(format_string 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 constexpr wstring format(wformat_string 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 string format(const locale& loc, format_string 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 wstring format(const locale& loc, wformat_string 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 constexpr Out format_to(Out out, format_string 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 constexpr Out format_to(Out out, wformat_string 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 Out format_to(Out out, const locale& loc, format_string 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 Out format_to(Out out, const locale& loc, wformat_string 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 constexpr Out vformat_to(Out out, string_view fmt, format_args args); template constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args); template Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args); template 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}}. \pnum \expects \tcode{Out} models \tcode{\libconcept{output_iterator}}. \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 constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, format_string fmt, Args&&... args); template constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, wformat_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, wformat_string 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}}. \pnum \expects \tcode{Out} models \tcode{\libconcept{output_iterator}}, and \tcode{formatter<}$\tcode{remove_cvref_t, 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 constexpr size_t formatted_size(format_string fmt, Args&&... args); template constexpr size_t formatted_size(wformat_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, wformat_string 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, 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}, \item \tcode{FC} is \tcode{basic_format_context}, \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 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}} be an unspecified type that models \tcode{\libconcept{output_iterator}}\iref{iterator.concept.output}. \begin{codeblock} template>> concept @\defexposconcept{formattable-with}@ = // \expos @\libconcept{semiregular}@ && requires(Formatter& f, const Formatter& cf, T&& t, Context fc, basic_format_parse_context pc) { { f.parse(pc) } -> @\libconcept{same_as}@; { cf.format(t, fc) } -> @\libconcept{same_as}@; }; template concept @\deflibconcept{formattable}@ = @\exposconcept{formattable-with}@, basic_format_context<@\placeholder{fmt-iter-for}@, charT>>; \end{codeblock} \pnum A type \tcode{T} and a character type \tcode{charT} model \libconcept{formattable} if \tcode{formatter, charT>} meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements} and, if \tcode{remove_reference_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; template<> struct formatter; template<> struct formatter; \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; template<> struct formatter; template struct formatter; template struct formatter, charT>; template struct formatter, 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; \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; \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; \end{codeblock} \item For each \tcode{charT}, the pointer type specializations \begin{codeblock} template<> struct formatter; template<> struct formatter; \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 = true; \end{codeblock} \begin{note} Specializations such as \tcode{formatter} 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; template<> struct formatter; template struct formatter; template struct formatter, wchar_t>; template struct formatter, 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} is disabled. \pnum If the library provides an explicit or partial specialization of \tcode{formatter}, 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}, \item \tcode{is_copy_constructible_v}, \item \tcode{is_move_constructible_v}, \item \tcode{is_copy_assignable_v}, and \item \tcode{is_move_assignable_v}. \end{itemize} \pnum An enabled specialization \tcode{formatter} meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}. \begin{example} \begin{codeblock} #include #include enum color { red, green, blue }; const char* color_names[] = { "red", "green", "blue" }; template<> struct std::formatter : std::formatter { auto format(color c, format_context& ctx) const { return formatter::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 basic_format_parse_context { public: using char_type = charT; using const_iterator = basic_string_view::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 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 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 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 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}, 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}) 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(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>(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 basic_format_context { basic_format_args 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 using formatter_type = formatter; constexpr basic_format_arg 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}}. \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}. \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}, \tcode{vector}, or any other container with contiguous storage by wrapping those in temporary objects with a uniform interface (such as a \tcode{span}) and polymorphic reallocation. \indexlibrarymember{arg}{basic_format_context}% \begin{itemdecl} constexpr basic_format_arg 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 { 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) throw format_error("width is not integral"); else if (value < 0 || value > numeric_limits::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 requires @\libconcept{same_as}@> constexpr range_format format_kind = @\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} is defined as follows: \begin{itemize} \item If \tcode{\libconcept{same_as}>, R>} is \tcode{true}, \tcode{format_kind} 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>}. If either \tcode{U} is a specialization of \tcode{pair} or \tcode{U} is a specialization of \tcode{tuple} and \tcode{tuple_size_v == 2}, \tcode{format_kind} is \tcode{range_format::map}. \item Otherwise, \tcode{format_kind} is \tcode{range_format::set}. \end{itemize} \item Otherwise, \tcode{format_kind} 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 requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter { formatter @\exposid{underlying_}@; // \expos basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("["); // \expos basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("]"); // \expos public: constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, basic_string_view closing) noexcept; constexpr formatter& underlying() noexcept { return @\exposid{underlying_}@; } constexpr const formatter& underlying() const noexcept { return @\exposid{underlying_}@; } template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template requires @\libconcept{formattable}@, charT> && @\libconcept{same_as}@>, 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}, the \fmtgrammarterm{format-spec} in a \fmtgrammarterm{range-underlying-spec}, if any, is interpreted by \tcode{formatter}. \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} 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 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 opening, basic_string_view 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 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 requires @\libconcept{formattable}@, charT> && @\libconcept{same_as}@>, 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(from_range, r)}. \item Otherwise, if the \fmtgrammarterm{range-type} was \tcode{?s}, then as if by formatting \tcode{basic_string(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 struct @\exposidnc{range-default-formatter}@ { // \expos private: using @\exposidnc{maybe-const-r}@ = @\exposidnc{fmt-maybe-const}@; // \expos range_formatter>, charT> @\exposid{underlying_}@; // \expos public: constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, basic_string_view closing) noexcept; template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template 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 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 opening, basic_string_view 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 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 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 struct @\exposid{range-default-formatter}@ { private: using @\exposidnc{maybe-const-map}@ = @\exposidnc{fmt-maybe-const}@; // \expos using @\exposidnc{element-type}@ = // \expos remove_cvref_t>; range_formatter<@\exposidnc{element-type}@, charT> @\exposid{underlying_}@; // \expos public: constexpr @\exposid{range-default-formatter}@(); template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template 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}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); @\exposid{underlying_}@.underlying().set_brackets({}, {}); @\exposid{underlying_}@.underlying().set_separator(@\exposid{STATICALLY-WIDEN}@(": ")); \end{codeblock} \end{itemdescr} \indexlibrarymemberexpos{parse}{range-default-formatter}% \begin{itemdecl} template 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 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 struct @\exposid{range-default-formatter}@ { private: using @\exposidnc{maybe-const-set}@ = @\exposidnc{fmt-maybe-const}@; // \expos range_formatter>, charT> @\exposid{underlying_}@; // \expos public: constexpr @\exposid{range-default-formatter}@(); template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template 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}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); \end{codeblock} \end{itemdescr} \indexlibrarymemberexpos{parse}{range-default-formatter}% \begin{itemdecl} template 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 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 requires (K == range_format::string || K == range_format::debug_string) struct @\exposid{range-default-formatter}@ { private: formatter, charT> @\exposid{underlying_}@; // \expos public: template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template constexpr typename FormatContext::iterator format(@\seebelow@& str, FormatContext& ctx) const; }; } \end{codeblock} \pnum \mandates \tcode{\libconcept{same_as}>, charT>} is \tcode{true}. \indexlibrarymemberexpos{parse}{range-default-formatter}% \begin{itemdecl} template 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 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}} is \tcode{true} and \tcode{R\&} otherwise. \pnum \effects Let \tcode{\placeholder{s}} be a \tcode{basic_string} 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 basic_format_arg { public: class handle; private: using @\exposid{char-type}@ = Context::char_type; // \expos variant, const void*, handle> @\exposid{value_}@; // \expos template constexpr explicit basic_format_arg(T& v) noexcept; // \expos public: constexpr basic_format_arg() noexcept; constexpr explicit operator bool() const noexcept; template constexpr decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); template 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 constexpr explicit basic_format_arg(T& v) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{T} satisfies \tcode{\exposconcept{formattable-with}}. \pnum \expects If \tcode{decay_t} is \tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*}, \tcode{static_cast(v)} points to an NTCTS\iref{defns.ntcts}. \pnum \effects Let \tcode{TD} be \tcode{remove_const_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(static_cast(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(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(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(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(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} is \tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*}, initializes \exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{is_void_v>} is \tcode{true} or \tcode{is_null_pointer_v} is \tcode{true}, initializes \exposid{value_} with \tcode{static_cast(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(\exposid{value_})}. \end{itemdescr} \indexlibrarymember{visit}{basic_format_arg}% \begin{itemdecl} template 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(vis));} \end{itemdescr} \indexlibrarymember{visit}{basic_format_arg}% \begin{itemdecl} template constexpr R visit(this basic_format_arg arg, Visitor&& vis); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return arg.\exposid{value_}.visit(std::forward(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 basic_format_arg::handle { const void* @\exposid{ptr_}@; // \expos void (*@\exposid{format_}@)(basic_format_parse_context<@\exposid{char-type}@>&, Context&, const void*); // \expos template 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 constexpr explicit handle(T& val) noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \begin{itemize} \item \tcode{TD} be \tcode{remove_const_t}, \item \tcode{TQ} be \tcode{const TD} if \tcode{const TD} satisfies \tcode{\exposconcept{formattable-with}} and \tcode{TD} otherwise. \end{itemize} \pnum \mandates \tcode{TQ} satisfies \tcode{\exposconcept{formattable-with}}. \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 f; parse_ctx.advance_to(f.parse(parse_ctx)); format_ctx.advance_to(f.format(*const_cast(static_cast(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 @\exposidnc{format-arg-store}@ { // \expos array, 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 constexpr @\exposid{format-arg-store}@ make_format_args(Args&... fmt_args); \end{itemdecl} \begin{itemdescr} \pnum \expects The type \tcode{typename Context::template formatter_type>}\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}} whose \exposid{args} data member is initialized with \tcode{\{basic_format_arg(fmt_args)...\}}. \end{itemdescr} \indexlibraryglobal{make_wformat_args}% \begin{itemdecl} template constexpr @\exposid{format-arg-store}@ make_wformat_args(Args&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return make_format_args(args...);} \end{itemdescr} \rSec3[format.args]{Class template \tcode{basic_format_args}} \begin{codeblock} namespace std { template class basic_format_args { size_t @\exposid{size_}@; // \expos const basic_format_arg* @\exposid{data_}@; // \expos public: template constexpr basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; constexpr basic_format_arg get(size_t i) const noexcept; }; template basic_format_args(@\exposid{format-arg-store}@) -> basic_format_args; } \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 constexpr basic_format_args(const @\exposid{format-arg-store}@& 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 get(size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{i < \exposid{size_} ?\ \exposid{data_}[i] :\ basic_format_arg()}. \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... Ts> struct formatter<@\placeholder{pair-or-tuple}@, charT> { private: tuple, charT>...> @\exposid{underlying_}@; // \expos basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("("); // \expos basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@(")"); // \expos public: constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, basic_string_view closing) noexcept; template constexpr typename ParseContext::iterator parse(ParseContext& ctx); template constexpr typename FormatContext::iterator format(@\seebelow@& elems, FormatContext& ctx) const; }; template constexpr bool enable_nonlocking_formatter_optimization<@\placeholder{pair-or-tuple}@> = (enable_nonlocking_formatter_optimization> && ...); } \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}@(": ")); 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 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 opening, basic_string_view 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 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 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} \&\& ...)} is \tcode{true}, \tcode{const \placeholder{pair-or-tuple}\&}. \item Otherwise \tcode{\placeholder{pair-or-tuple}\&}. \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(elems)} via \tcode{get(\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{} \\ \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}. \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} \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{} synopsis} \indexheader{regex}% \indexlibraryglobal{basic_regex}% \indexlibraryglobal{regex}% \indexlibraryglobal{wregex}% \begin{codeblock} #include // see \ref{compare.syn} #include // 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 struct regex_traits; // \ref{re.regex}, class template \tcode{basic_regex} template> class basic_regex; using regex = basic_regex; using wregex = basic_regex; // \ref{re.regex.swap}, \tcode{basic_regex} swap template void swap(basic_regex& e1, basic_regex& e2); // \ref{re.submatch}, class template \tcode{sub_match} template class sub_match; using csub_match = sub_match; using wcsub_match = sub_match; using ssub_match = sub_match; using wssub_match = sub_match; // \ref{re.submatch.op}, \tcode{sub_match} non-member operators template bool operator==(const sub_match& lhs, const sub_match& rhs); template auto operator<=>(const sub_match& lhs, const sub_match& rhs); template bool operator==( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); template auto operator<=>( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type* rhs); template auto operator<=>(const sub_match& lhs, const typename iterator_traits::value_type* rhs); template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type& rhs); template auto operator<=>(const sub_match& lhs, const typename iterator_traits::value_type& rhs); template basic_ostream& operator<<(basic_ostream& os, const sub_match& m); // \ref{re.results}, class template \tcode{match_results} template>> class match_results; using cmatch = match_results; using wcmatch = match_results; using smatch = match_results; using wsmatch = match_results; // \tcode{match_results} comparisons template bool operator==(const match_results& m1, const match_results& m2); // \ref{re.results.swap}, \tcode{match_results} swap template void swap(match_results& m1, match_results& m2); // \ref{re.alg.match}, function template \tcode{regex_match} template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_match(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_match(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_match(const basic_string&&, match_results::const_iterator, Allocator>&, const basic_regex&, regex_constants::match_flag_type = regex_constants::match_default) = delete; template bool regex_match(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_match(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); // \ref{re.alg.search}, function template \tcode{regex_search} template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); template bool regex_search(const basic_string&&, match_results::const_iterator, Allocator>&, const basic_regex&, regex_constants::match_flag_type = regex_constants::match_default) = delete; // \ref{re.alg.replace}, function template \tcode{regex_replace} template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const basic_string& s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const basic_string& s, const basic_regex& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const charT* s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const charT* s, const basic_regex& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); // \ref{re.regiter}, class template \tcode{regex_iterator} template::value_type, class traits = regex_traits> class regex_iterator; using cregex_iterator = regex_iterator; using wcregex_iterator = regex_iterator; using sregex_iterator = regex_iterator; using wsregex_iterator = regex_iterator; // \ref{re.tokiter}, class template \tcode{regex_token_iterator} template::value_type, class traits = regex_traits> class regex_token_iterator; using cregex_token_iterator = regex_token_iterator; using wcregex_token_iterator = regex_token_iterator; using sregex_token_iterator = regex_token_iterator; using wsregex_token_iterator = regex_token_iterator; namespace pmr { template using match_results = std::match_results>>; using cmatch = match_results; using wcmatch = match_results; using smatch = match_results; using wsmatch = match_results; } } \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 struct regex_traits { using char_type = charT; using string_type = basic_string; 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 string_type transform(ForwardIterator first, ForwardIterator last) const; template string_type transform_primary( ForwardIterator first, ForwardIterator last) const; template string_type lookup_collatename( ForwardIterator first, ForwardIterator last) const; template 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} and \tcode{regex_traits} 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::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>(getloc()).tolower(c)}. \end{itemdescr} \indexlibrarymember{regex_traits}{transform}% \begin{itemdecl} template 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>( getloc()).transform(str.data(), str.data() + str.length()); \end{codeblock} \end{itemdescr} \indexlibrarymember{regex_traits}{transform_primary}% \begin{itemdecl} template string_type transform_primary(ForwardIterator first, ForwardIterator last) const; \end{itemdecl} \begin{itemdescr} \pnum \effects If \begin{codeblock} typeid(use_facet>(getloc())) == typeid(collate_byname) \end{codeblock} and the form of the sort key returned by \tcode{collate_byname::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 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 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}, at least the narrow character names in \tref{re.traits.classnames} shall be recognized. For \tcode{regex_traits}, 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 ctype_base::mask convert(typename regex_traits::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(f); const ctype& ct = use_facet>(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 t; string d("d"); string u("upper"); regex_traits::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(f); // \tcode{m == ctype_base::digit | ctype_base::upper} \end{codeblock} \end{example} \begin{example} \begin{codeblock} regex_traits t; string w("w"); regex_traits::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 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 explicit basic_regex(const basic_string& s, flag_type f = regex_constants::ECMAScript); template basic_regex(ForwardIterator first, ForwardIterator last, flag_type f = regex_constants::ECMAScript); basic_regex(initializer_list 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 il); template basic_regex& operator=(const basic_string& 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 basic_regex& assign(const basic_string& s, flag_type f = regex_constants::ECMAScript); template basic_regex& assign(InputIterator first, InputIterator last, flag_type f = regex_constants::ECMAScript); basic_regex& assign(initializer_list, 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 basic_regex(ForwardIterator, ForwardIterator, regex_constants::syntax_option_type = regex_constants::ECMAScript) -> basic_regex::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::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::\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::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 explicit basic_regex(const basic_string& 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 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 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 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 basic_regex& operator=(const basic_string& 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 basic_regex& assign(const basic_string& 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 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 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 void swap(basic_regex& lhs, basic_regex& 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 sub_match : public pair { public: using value_type = iterator_traits::value_type; using difference_type = iterator_traits::difference_type; using iterator = BidirectionalIterator; using string_type = basic_string; 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::swap(s); std::swap(matched, s.matched); \end{codeblock} \pnum \remarks The exception specification is equivalent to \tcode{is_nothrow_swappable_v}. \end{itemdescr} \rSec3[re.submatch.op]{Non-member operators} \pnum Let \tcode{\placeholdernc{SM-CAT}(I)} be \begin{codeblock} compare_three_way_result_t::value_type>> \end{codeblock} \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} template bool operator==(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(rhs) == 0}. \end{itemdescr} \indexlibrarymember{sub_match}{operator<=>}% \begin{itemdecl} template auto operator<=>(const sub_match& lhs, const sub_match& 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 bool operator==( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \begin{codeblock} lhs.compare(typename sub_match::string_type(rhs.data(), rhs.size())) == 0 \end{codeblock} \end{itemdescr} \indexlibrarymember{operator<=>}{sub_match}% \begin{itemdecl} template auto operator<=>( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \begin{codeblock} static_cast<@\placeholdernc{SM-CAT}@(BiIter)>(lhs.compare( typename sub_match::string_type(rhs.data(), rhs.size())) <=> 0 ) \end{codeblock} \end{itemdescr} \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(rhs) == 0}. \end{itemdescr} \indexlibrarymember{sub_match}{operator<=>}% \begin{itemdecl} template auto operator<=>(const sub_match& lhs, const typename iterator_traits::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 bool operator==(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(typename sub_match::string_type(1, rhs)) == 0}. \end{itemdescr} \indexlibrarymember{sub_match}{operator<=>}% \begin{itemdecl} template auto operator<=>(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} \begin{itemdescr} \pnum \returns \begin{codeblock} static_cast<@\placeholdernc{SM-CAT}@(BiIter)>(lhs.compare( typename sub_match::string_type(1, rhs)) <=> 0 ) \end{codeblock} \end{itemdescr} \indexlibraryglobal{basic_ostream}% \indexlibrarymember{sub_match}{operator<<}% \begin{itemdecl} template basic_ostream& operator<<(basic_ostream& os, const sub_match& 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 match_results { public: using value_type = sub_match; 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::difference_type; using size_type = allocator_traits::size_type; using allocator_type = Allocator; using char_type = iterator_traits::value_type; using string_type = basic_string; // \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 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 OutputIter format(OutputIter out, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const; template basic_string format(const basic_string& 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 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 OutputIter format( OutputIter out, const basic_string& 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 basic_string format( const basic_string& 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} 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::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 void swap(match_results& m1, match_results& 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 bool operator==(const match_results& m1, const match_results& 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 bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& 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 bool regex_match(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& 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 what}, and then returning the result of \tcode{regex_match(first, last, what, e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_match}% \begin{itemdecl} template bool regex_match(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{regex_match(str, str + char_traits::length(str), m, e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_match}% \begin{itemdecl} template bool regex_match(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& 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 bool regex_match(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{regex_match(str, str + char_traits::length(str), e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_match}% \begin{itemdecl} template bool regex_match(const basic_string& s, const basic_regex& 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 bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& 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 bool regex_search(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{regex_search(str, str + char_traits::length(str), m, e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_search}% \begin{itemdecl} template bool regex_search(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& 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 bool regex_search(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& 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} and returning \tcode{regex_search(first, last, what, e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_search}% \begin{itemdecl} template bool regex_search(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{regex_search(str, str + char_traits::length(str), e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_search}% \begin{itemdecl} template bool regex_search(const basic_string& s, const basic_regex& 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 OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& 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 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} 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::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 basic_string regex_replace(const basic_string& s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const basic_string& s, const basic_regex& 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} 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 basic_string regex_replace(const charT* s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template basic_string regex_replace(const charT* s, const basic_regex& 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} and calls: \begin{codeblock} regex_replace(back_inserter(result), s, s + char_traits::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}. 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\&} 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*} 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::value_type, class traits = regex_traits> class regex_iterator { public: using regex_type = basic_regex; using iterator_category = forward_iterator_tag; using iterator_concept = input_iterator_tag; using value_type = match_results; 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 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 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\&} 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*} 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::value_type, class traits = regex_traits> class regex_token_iterator { public: using regex_type = basic_regex; using iterator_category = forward_iterator_tag; using iterator_concept = input_iterator_tag; using value_type = sub_match; 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& submatches, regex_constants::match_flag_type m = regex_constants::match_default); regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, initializer_list submatches, regex_constants::match_flag_type m = regex_constants::match_default); template 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& 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 submatches, regex_constants::match_flag_type m = regex_constants::match_default) = delete; template 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; // \expos position_iterator position; // \expos const value_type* result; // \expos value_type suffix; // \expos size_t N; // \expos vector 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& submatches, regex_constants::match_flag_type m = regex_constants::match_default); regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, initializer_list submatches, regex_constants::match_flag_type m = regex_constants::match_default); template 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{} 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{} 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{} 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{} 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}