From e62f8e77e9961936fbf52fcde5dbd37f3aac3ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 5 Aug 2024 12:09:56 +0100 Subject: [PATCH 01/95] Update configuration for building working drafts after N4988. --- source/config.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/config.tex b/source/config.tex index 48233ea56a..990cc07b44 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4988} -\newcommand{\prevdocno}{N4986} +\newcommand{\docno}{Dxxxx} +\newcommand{\prevdocno}{N4988} \newcommand{\cppver}{202302L} %% Release date From 15a43d522467d389bd9340081d65dbf17d44d255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 5 Aug 2024 12:21:56 +0100 Subject: [PATCH 02/95] [temp.over.link] Reword to clarify that declarations correspond (#5999) --- source/templates.tex | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index c91178088f..23876c39b3 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -3908,15 +3908,19 @@ whether two constructs are equivalent, and they are functionally equivalent but not equivalent, the program is ill-formed, no diagnostic required. -% FIXME: What does it mean for two function templates to correspond? -Furthermore, if two function templates that do not correspond +Furthermore, if two declarations $A$ and $B$ of function templates \begin{itemize} -\item have the same name, -\item have corresponding signatures\iref{basic.scope.scope}, -\item would declare the same entity\iref{basic.link} considering them to correspond, and -% FIXME: What does it mean for a set of template argument lists to satisfy a function template? -\item accept and are satisfied by the same set of template argument lists, +\item +introduce the same name, +\item +have corresponding signatures\iref{basic.scope.scope}, +\item +would declare the same entity, +when considering $A$ and $B$ to correspond in that determination\iref{basic.link}, and +\item +accept and are satisfied by the same set of template argument lists, \end{itemize} +but do not correspond, the program is ill-formed, no diagnostic required. \pnum From 3c0f4cf0a03892157ebf3a472d3e9450a41f038e Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Sun, 4 Aug 2024 09:26:26 +0930 Subject: [PATCH 03/95] [snd.expos] Fix typo in definition of SCHED-ENV exposition-only helper Change `o1` -> `o2` to reference the expression declared as part of the definition of `SCHED-ENV`. --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 4ed6ea4271..f7ce3e0de9 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1312,7 +1312,7 @@ \tcode{sch.query(get_domain)}. \tcode{\exposid{SCHED-ENV}(sch)} is an expression \tcode{o2} whose type satisfies \exposconcept{queryable} -such that \tcode{o1.query(get_scheduler)} is a prvalue +such that \tcode{o2.query(get_scheduler)} is a prvalue with the same type and value as \tcode{sch}, and such that \tcode{o2.query(get_domain)} is expression-equivalent to \tcode{sch.query(get_domain)}. From ca38e0b9b6b557c951f4523fa987658728e3ae28 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Mon, 5 Aug 2024 12:35:32 +0800 Subject: [PATCH 04/95] [mdspan.layout.leftpad.cons] Add \exposid for static-padding-stride --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 1dd9f1f918..4f77cee83b 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -21949,9 +21949,9 @@ \mandates If \tcode{OtherExtents::rank()} is greater than \tcode{1}, then \begin{codeblock} -(static-padding-stride== dynamic_extent) || +(@\exposid{static-padding-stride}@ == dynamic_extent) || (OtherExtents::static_extent(0) == dynamic_extent) || -(static-padding-stride== OtherExtents::static_extent(0)) +(@\exposid{static-padding-stride}@ == OtherExtents::static_extent(0)) \end{codeblock} is \tcode{true}. From 5422d7475ad17532a89c42d061f5d2c94024ab72 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Mon, 5 Aug 2024 14:44:51 +0800 Subject: [PATCH 05/95] [exec.sync.wait] Added missing \exposid and \libcecpt for two alias templates --- source/exec.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index f7ce3e0de9..fe48927ffb 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -4487,11 +4487,11 @@ \begin{codeblock} namespace std::this_thread { template Sndr> - using sync-wait-result-type = + using @\exposid{sync-wait-result-type}@ = optional>; - template Sndr> + template Sndr> using @\exposid{sync-wait-with-variant-result-type}@ = optional>; } From 5056b86597f5ba9278601db46a415f2d76e1bc8f Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 2 Aug 2024 17:38:05 +0200 Subject: [PATCH 06/95] [temp.constr.order] Reflect fold expanded constraints in footnotes --- source/templates.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index 23876c39b3..34db14f83a 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2023,7 +2023,7 @@ in the disjunctive normal form \begin{footnote} A constraint is in disjunctive normal form when it is a disjunction of -clauses where each clause is a conjunction of atomic constraints. +clauses where each clause is a conjunction of fold expanded or atomic constraints. For atomic constraints $A$, $B$, and $C$, the disjunctive normal form of the constraint $A \land (B \lor C)$ @@ -2036,7 +2036,7 @@ in the conjunctive normal form \begin{footnote} A constraint is in conjunctive normal form when it is a conjunction -of clauses where each clause is a disjunction of atomic constraints. +of clauses where each clause is a disjunction of fold expanded or atomic constraints. For atomic constraints $A$, $B$, and $C$, the constraint $A \land (B \lor C)$ is in conjunctive normal form. % From c92bc384b118412322f9893832508bf17f46f644 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 1 Aug 2024 12:35:50 +0200 Subject: [PATCH 07/95] [dcl.fct] Fix obsolete phrasing when defining 'function type' --- source/declarations.tex | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 987905fa4c..b92783068d 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3588,16 +3588,14 @@ the optional \keyword{noexcept} is present if and only if the exception specification\iref{except.spec} is non-throwing. \end{itemize} -The optional \grammarterm{attribute-specifier-seq} -appertains to the function type. - -\pnum -\indextext{type!function}% -A type of either form is a \term{function type}.% +Such a type is a \defnadj{function}{type}. \begin{footnote} As indicated by syntax, cv-qualifiers are a significant component in function return types. \end{footnote} +The optional \grammarterm{attribute-specifier-seq} +appertains to the function type. +\pnum \indextext{declaration!function}% \begin{bnf} \nontermdef{parameter-declaration-clause}\br From fabbff2d812e0a99bd1162460812ec2f5399636e Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Thu, 8 Aug 2024 17:15:39 -0400 Subject: [PATCH 08/95] [sequences] Consistent comma in "If X, there are no effects" (#7139) --- source/containers.tex | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 4f77cee83b..b891a886c0 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6911,7 +6911,7 @@ If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of -\tcode{T} +\tcode{T}, there are no effects. If an exception is thrown while inserting a single element at either end, there are no effects. @@ -8270,7 +8270,7 @@ \pnum \remarks Does not affect the validity of iterators and references. -If an exception is thrown there are no effects. +If an exception is thrown, there are no effects. \end{itemdescr} \indexlibrarymember{erase}{list}% @@ -8570,7 +8570,7 @@ Stable\iref{algorithm.stable}. If \tcode{addressof(x) != this}, \tcode{x} is empty after the merge. No elements are copied by this operation. -If an exception is thrown other than by a comparison there are no effects. +If an exception is thrown other than by a comparison, there are no effects. \end{itemdescr} \indexlibrarymember{reverse}{list}% @@ -9018,7 +9018,7 @@ It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} by causing reallocation. If an exception is thrown other than by the move constructor -of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. +of a non-\oldconcept{CopyInsertable} \tcode{T}, there are no effects. \pnum \complexity @@ -9075,7 +9075,7 @@ \pnum \remarks If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} -\tcode{T} there are no effects. +\tcode{T}, there are no effects. \end{itemdescr} \indexlibrarymember{resize}{vector}% @@ -9097,7 +9097,7 @@ \pnum \remarks -If an exception is thrown there are no effects. +If an exception is thrown, there are no effects. \end{itemdescr} \rSec3[vector.data]{Data} @@ -9163,7 +9163,7 @@ If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of -\tcode{T} or by any \tcode{InputIterator} operation +\tcode{T} or by any \tcode{InputIterator} operation, there are no effects. If an exception is thrown while inserting a single element at the end and \tcode{T} is \oldconcept{CopyInsertable} or \tcode{is_nothrow_move_constructible_v} @@ -9932,7 +9932,7 @@ \pnum \remarks -If an exception is thrown there are no effects on \tcode{*this}. +If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} \indexlibrarymember{try_emplace_back}{inplace_vector}% @@ -9980,7 +9980,7 @@ \pnum \remarks -If an exception is thrown there are no effects on \tcode{*this}. +If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} \indexlibrarymember{try_append_range}{inplace_vector}% From f1379f5a4165a762b6b7ed5353700eaac5ea273c Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sat, 10 Aug 2024 02:45:03 +0800 Subject: [PATCH 09/95] [exec.when.all] Add italics for expression e (#7209) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index fe48927ffb..4ecfdfc88b 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -4104,7 +4104,7 @@ is initialized with a callable object equivalent to the following lambda expression: \begin{codeblock} -[](Sndr&& sndr, Rcvr& rcvr) noexcept(@$e$@) -> decltype(e) { +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@$e$@) -> decltype(@$e$@) { return @$e$@; } \end{codeblock} From 6ce5874c0a5ab8b84ad43feed783be5b15d1a3cb Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Mon, 12 Aug 2024 18:15:02 +0930 Subject: [PATCH 10/95] [exec.sync.wait] Mark use of state.error as exposition-only (#7215) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 4ecfdfc88b..b9d739c0b8 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -4604,7 +4604,7 @@ state.@\exposid{loop}@.run(); if (state.@\exposid{error}@) { - rethrow_exception(std::move(state.error)); + rethrow_exception(std::move(state.@\exposid{error}@)); } return std::move(state.@\exposid{result}@); \end{codeblock} From 1249e89200ad33c1473a865bea5543ad502fc9ee Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Wed, 14 Aug 2024 04:43:53 +0800 Subject: [PATCH 11/95] [exec.recv.concepts] Add \libconcept for receiver (#7218) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index b9d739c0b8..25fd60d368 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1112,7 +1112,7 @@ \end{codeblock} \pnum -Class types that are marked \tcode{final} do not model the receiver concept. +Class types that are marked \tcode{final} do not model the \libconcept{receiver} concept. \pnum Let \tcode{rcvr} be a receiver and From 2189fd8116a9b820488c0397d8fd716ca787fb2e Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Wed, 14 Aug 2024 04:44:22 +0800 Subject: [PATCH 12/95] [exec.snd.concepts] Use \libconcept for copy_constructible (#7217) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 25fd60d368..02a584aa95 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -2027,7 +2027,7 @@ that accepts an rvalue sender and \item only expose an overload of a member \tcode{connect} -that accepts an lvalue sender if they model \tcode{copy_constructible}. +that accepts an lvalue sender if they model \libconcept{copy_constructible}. \end{itemize} \rSec2[exec.awaitable]{Awaitable helpers} From b0b3a8ce396b019dab0203a35e62f014e163fb12 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Wed, 14 Aug 2024 19:05:24 +0800 Subject: [PATCH 13/95] [exec.fwd.env] Use \libconcept for derived_from (#7219) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 02a584aa95..1af35b7b8d 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -769,7 +769,7 @@ The expression above has type \tcode{bool} and is a core constant expression if \tcode{q} is a core constant expression. \item -Otherwise, true if \tcode{derived_from} is \tcode{true}. +Otherwise, true if \tcode{\libconcept{derived_from}} is \tcode{true}. \item Otherwise, \tcode{false}. \end{itemize} From 18da34a3c76caa99d405a4be79d4d12091f102d1 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Wed, 14 Aug 2024 19:06:46 +0800 Subject: [PATCH 14/95] [exec.getcomplsigs] Use \exposconcept for is-awaitable (#7220) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 1af35b7b8d..5d70eba0db 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -2361,7 +2361,7 @@ \item Otherwise, -if \tcode{\exposid{is-awaitable}>} is \tcode{true}, +if \tcode{\exposconcept{is-awaitable}>} is \tcode{true}, then: \begin{codeblock} completion_signatures< From 26f794b6536779ce7b22fd32b924f8014fd266be Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Wed, 14 Aug 2024 19:16:35 +0800 Subject: [PATCH 15/95] [exec.when.all] Add \libconcept for sender (#7221) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 5d70eba0db..4bc4c2af03 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -4047,7 +4047,7 @@ \item \tcode{sizeof...(sndrs)} is \tcode{0}, or \item -\tcode{(sender \&\& ...)} is \tcode{false}, or +\tcode{(\libconcept{sender} \&\& ...)} is \tcode{false}, or \item \tcode{CD} is ill-formed. \end{itemize} From a3af0b1e15b6a56d5e773f8e4151b290da4a384e Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Thu, 15 Aug 2024 20:50:21 +0800 Subject: [PATCH 16/95] [exec.split] Add \exposid for local-state (#7224) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 4bc4c2af03..bf70230b9c 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -3982,7 +3982,7 @@ that has a function call operator equivalent to the following: \begin{codeblock} template -void operator()(local-state& state, Rcvr& rcvr) const noexcept; +void operator()(@\exposid{local-state}@& state, Rcvr& rcvr) const noexcept; \end{codeblock} \effects From 72758c6fdb6c1e967edd0db15efea718a311e277 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Thu, 15 Aug 2024 20:52:07 +0800 Subject: [PATCH 17/95] [exec.general] Add \exposid for MATCHING-SIG (#7226) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index bf70230b9c..9fb21a6373 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -79,7 +79,7 @@ \pnum For function types \tcode{F1} and \tcode{F2} denoting \tcode{R1(Args1...)} and \tcode{R2(Args2...)}, respectively, -\tcode{MATCHING-SIG(F1, F2)} is \tcode{true} if and only if +\tcode{\exposid{MATCHING-SIG}(F1, F2)} is \tcode{true} if and only if \tcode{\libconcept{same_as}} is \tcode{true}. From c37b4be1c440dad2f5e45ac120d5926779798816 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Fri, 16 Aug 2024 01:11:46 +0800 Subject: [PATCH 18/95] [exec.snd.expos] Add \exposid for COMPL-DOMAIN (#7225) --- source/exec.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 9fb21a6373..eb233c368c 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1351,9 +1351,9 @@ \pnum \effects If all of the types -\tcode{COMPL-DOMAIN(set_value_t)}, -\tcode{COMPL-DOMAIN(set_error_t)}, and -\tcode{COMPL-DO\-MAIN(set_stopped_t)} are ill-formed, +\tcode{\exposid{COMPL-DOMAIN}(set_value_t)}, +\tcode{\exposid{COMPL-DOMAIN}(set_error_t)}, and\linebreak +\tcode{\exposid{COMPL-DOMAIN}(set_stopped_t)} are ill-formed, \tcode{completion-domain(sndr)} is a default-constructed prvalue of type \tcode{Default}. Otherwise, if they all share a common type\iref{meta.trans.other} From 34cf8c87788cb44e9f67e71c2e715ccd7416eb63 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Fri, 16 Aug 2024 17:00:42 +0800 Subject: [PATCH 19/95] [exec.fwd.env] Mark "true" with \tcode (#7227) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index eb233c368c..1c5dadc798 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -769,7 +769,7 @@ The expression above has type \tcode{bool} and is a core constant expression if \tcode{q} is a core constant expression. \item -Otherwise, true if \tcode{\libconcept{derived_from}} is \tcode{true}. +Otherwise, \tcode{true} if \tcode{\libconcept{derived_from}} is \tcode{true}. \item Otherwise, \tcode{false}. \end{itemize} From 1d0dbbae465080fa1b59db5ac215ce7eaef2d3d9 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Fri, 16 Aug 2024 17:35:25 +0800 Subject: [PATCH 20/95] [exec.adapt.obj] Add \tcode for sender_adaptor_closure (#7228) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 1c5dadc798..56aa864887 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -2722,7 +2722,7 @@ \tcode{T} does not satisfy \tcode{sender}. \pnum -The template parameter \tcode{D} for sender_adaptor_closure can be +The template parameter \tcode{D} for \tcode{sender_adaptor_closure} can be an incomplete type. Before any expression of type \cv{} \tcode{D} appears as an operand to the \tcode{|} operator, From 99784b9c0081292dfd6d787e63d9fde58ab0b935 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sat, 17 Aug 2024 19:38:50 +0800 Subject: [PATCH 21/95] [mdspan.layout.rightpad.expo] Add \exposid for LEAST-MULTIPLE-AT-LEAST (#7229) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index b891a886c0..3bcf0f0a01 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -22445,7 +22445,7 @@ \tcode{dynamic_extent}; \item otherwise, the \tcode{size_t} value which is -\tcode{LEAST-MULTIPLE-AT-LEAST(padding_value, \exposid{last-sta\-tic-extent})}. +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, \exposid{last-sta\-tic-extent})}. \end{itemize} \end{itemdescr} From e1cd0fef5a891808abb745aff23604cbf10742a9 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sat, 17 Aug 2024 20:14:28 +0800 Subject: [PATCH 22/95] [set.modifiers] Add \tcode for true (#7230) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 3bcf0f0a01..41e7f686a7 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -11752,7 +11752,7 @@ \pnum \returns For the first overload, -the \tcode{bool} component of the returned pair is true +the \tcode{bool} component of the returned pair is \tcode{true} if and only if the insertion took place. The returned iterator points to the set element that is equivalent to \tcode{x}. From 068b2f6ab0c4e1c5519fa4e6b66b5cf0f87942f4 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sun, 18 Aug 2024 00:39:14 +0800 Subject: [PATCH 23/95] [flat.set.modifiers,mdspan.layout.leftpad.cons] Add \tcode for true (#7231) --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 41e7f686a7..6ee4f872c8 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18023,7 +18023,7 @@ \pnum \expects The conversion from \tcode{x} into \tcode{value_type} constructs -an object \tcode{u}, for which \tcode{find(x) == find(u)} is true. +an object \tcode{u}, for which \tcode{find(x) == find(u)} is \tcode{true}. \pnum \effects @@ -22055,7 +22055,7 @@ LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value \end{codeblock} -is true. +is \tcode{true}. \pnum \begin{itemize} From fc0f1b5586d9a126e7d038a6d97a009fd059ecfd Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sun, 18 Aug 2024 00:39:49 +0800 Subject: [PATCH 24/95] [exec.snd.expos] Use \tcode for false (#7232) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 56aa864887..09a78b3ff6 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1837,7 +1837,7 @@ the set of completion operations that are potentially evaluated as a result of starting\iref{exec.async.ops} the operation state that results from connecting \tcode{sndr} and \tcode{rcvr}. -When \tcode{\libconcept{sender_in}} is \exposid{false}, +When \tcode{\libconcept{sender_in}} is \tcode{false}, the type denoted by \tcode{\exposid{completion-signatures-for}}, if any, is not a specialization of \tcode{completion_signatures}. From 23a2b8035228f1cf7bc2dd51e4c531fd99717be6 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Sun, 18 Aug 2024 00:40:24 +0800 Subject: [PATCH 25/95] [exec.async.ops] Add \tcode for true (#7233) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 09a78b3ff6..668aa569a4 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -358,7 +358,7 @@ the function type \tcode{decltype(auto(set))(decltype((args))...)}. A completion signature \tcode{Sig} is associated with \tcode{c} if and only if -\tcode{\exposid{MATCHING-SIG}(Sig, F)} is true\iref{exec.general}). +\tcode{\exposid{MATCHING-SIG}(Sig, F)} is \tcode{true}\iref{exec.general}). Together, a sender type and an environment type \tcode{Env} determine the set of completion signatures of an asynchronous operation that results from connecting the sender with a receiver From 04c5a0c509dbf8f9f81223d1de5bb917cd3074c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dus=C3=ADkov=C3=A1?= Date: Tue, 20 Aug 2024 12:21:43 +0200 Subject: [PATCH 26/95] [meta.const.eval] Fix function declaration in example (#7234) --- source/meta.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/meta.tex b/source/meta.tex index d791342bbc..8903d5be01 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -2522,7 +2522,7 @@ } } - constexpr auto operator*() -> bool& { + constexpr auto operator*() const -> const bool& { return b; } }; From ab4c0663dc72f09fb8ef6c366352c9d1a68e8fa9 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Fri, 23 Aug 2024 22:06:05 +0400 Subject: [PATCH 27/95] [expr.prim.lambda.capture] Incorporate ellipsis into "captured by copy" definition --- source/expressions.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index eeca4bfebc..69b5e92933 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2625,8 +2625,8 @@ \item it is explicitly captured with a capture that is not of the form \keyword{this}, -\tcode{\&} \grammarterm{identifier}, or -\tcode{\&} \grammarterm{identifier} \grammarterm{initializer}. +\tcode{\&} \grammarterm{identifier} \opt{\tcode{...}}, or +\tcode{\&} \opt{\tcode{...}} \grammarterm{identifier} \grammarterm{initializer}. \end{itemize} For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The declaration order of From 6ea6df4c96653d6696bb0133253ea0159b0f278f Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Sat, 24 Aug 2024 23:24:01 +0400 Subject: [PATCH 28/95] [dcl.type.elab] Remove redundant full stop (#7242) --- source/declarations.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index b92783068d..f42ef66892 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1604,7 +1604,7 @@ \begin{codeblock} friend class T; \end{codeblock} -is ill-formed. However, the similar declaration \tcode{friend T;} is well-formed.\iref{class.friend}. +is ill-formed. However, the similar declaration \tcode{friend T;} is well-formed\iref{class.friend}. \end{note} \pnum From 24ceda755967b022e8e089d4f0cdcf4bc99a4adb Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Mon, 26 Aug 2024 18:29:28 +0800 Subject: [PATCH 29/95] [exec.snd.apply,exec.schedule.from] Properly mark "see below" (#7210) --- source/exec.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 668aa569a4..280e892038 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -2306,7 +2306,7 @@ namespace std::execution { template constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) - noexcept(see below); + noexcept(@\seebelow@); } \end{itemdecl} @@ -2957,7 +2957,7 @@ The member \tcode{\exposid{impls-for}::\exposid{get-state}} is initialized with a callable object equivalent to the following lambda: \begin{codeblock} -[](Sndr&& sndr, Rcvr& rcvr) noexcept(see below) +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@\seebelow@) requires @\libconcept{sender_in}@<@\exposid{child-type}@, env_of_t> { auto& [_, sch, child] = sndr; From 447b6291061d50a582f72dd42d9d6265857ded5c Mon Sep 17 00:00:00 2001 From: Joachim Wuttke Date: Mon, 26 Aug 2024 22:30:39 +0200 Subject: [PATCH 30/95] [numerics] Correct typo Bessell -> Bessel (#7244) --- source/numerics.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index ef2f93f4f2..83b9f8dd57 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -10143,7 +10143,7 @@ \indexlibraryglobal{cyl_bessel_if}% \indexlibraryglobal{cyl_bessel_il}% \indextext{Bessel functions!$\mathsf{I}_\nu$}% -\indextext{I nu@$\mathsf{I}_\nu$ (Bessell functions)}% +\indextext{I nu@$\mathsf{I}_\nu$ (Bessel functions)}% \begin{itemdecl} @\placeholder{floating-point-type}@ cyl_bessel_i(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_if(float nu, float x); @@ -10186,7 +10186,7 @@ \indexlibraryglobal{cyl_bessel_jf}% \indexlibraryglobal{cyl_bessel_jl}% \indextext{Bessel functions!$\mathsf{J}_\nu$}% -\indextext{J nu@$\mathsf{J}_\nu$ (Bessell functions)}% +\indextext{J nu@$\mathsf{J}_\nu$ (Bessel functions)}% \begin{itemdecl} @\placeholder{floating-point-type}@ cyl_bessel_j(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_jf(float nu, float x); @@ -10226,7 +10226,7 @@ \indexlibraryglobal{cyl_bessel_kf}% \indexlibraryglobal{cyl_bessel_kl}% \indextext{Bessel functions!$\mathsf{K}_\nu$}% -\indextext{K nu@$\mathsf{K}_\nu$ (Bessell functions)}% +\indextext{K nu@$\mathsf{K}_\nu$ (Bessel functions)}% \begin{itemdecl} @\placeholder{floating-point-type}@ cyl_bessel_k(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_kf(float nu, float x); From db0ca108a9b44ef8f06338ecf68f1e4653be4267 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Thu, 29 Aug 2024 06:13:18 -0400 Subject: [PATCH 31/95] [inplace.vector] Fix some spelling/grammar issues (#7243) --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 6ee4f872c8..b9560296fd 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9882,7 +9882,7 @@ \begin{itemdescr} \pnum -Let $n$ be value of \tcode{size()} before this call for +Let $n$ be the value of \tcode{size()} before this call for the \tcode{append_range} overload, and \tcode{distance(begin, position)} otherwise. @@ -9924,7 +9924,7 @@ \pnum \throws \tcode{bad_alloc} or -any exception thrown by initialization of inserted element. +any exception thrown by the initialization of the inserted element. \pnum \complexity @@ -9972,7 +9972,7 @@ \pnum \throws -Nothing unless an exception is thrown by initialization of inserted element. +Nothing unless an exception is thrown by the initialization of the inserted element. \pnum \complexity @@ -10005,7 +10005,7 @@ \returns An iterator pointing to the first element of \tcode{rg} that was not inserted into \tcode{*this}, -or \tcode{ranged::end(rg)} if no such element exists. +or \tcode{ranges::end(rg)} if no such element exists. \pnum \complexity From 21e477fb6dbfa7813eb2263bfa31c748bdce589b Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 30 Aug 2024 05:07:36 -0700 Subject: [PATCH 32/95] [lib] Remove `inline` from variable templates (#7240) --- source/exec.tex | 6 +++--- source/time.tex | 4 ++-- source/utilities.tex | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 280e892038..2b9c50a4eb 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -464,7 +464,7 @@ enum class forward_progress_guarantee; inline constexpr get_forward_progress_guarantee_t get_forward_progress_guarantee{}; template - inline constexpr get_completion_scheduler_t get_completion_scheduler{}; + constexpr get_completion_scheduler_t get_completion_scheduler{}; struct empty_env {}; struct get_env_t { @\unspec@ }; @@ -550,7 +550,7 @@ template requires @\libconcept{sender_in}@ - inline constexpr bool sends_stopped = @\seebelow@; + constexpr bool sends_stopped = @\seebelow@; template using @\exposidnc{single-sender-value-type}@ = @\seebelownc@; // \expos @@ -4827,7 +4827,7 @@ template requires @\libconcept{sender_in}@ - inline constexpr bool sends_stopped = + constexpr bool sends_stopped = !@\libconcept{same_as}@<@\exposid{type-list}@<>, @\exposid{gather-signatures}@, @\exposid{type-list}@, @\exposid{type-list}@>>; diff --git a/source/time.tex b/source/time.tex index 13e83b76c0..dfa1601013 100644 --- a/source/time.tex +++ b/source/time.tex @@ -10834,7 +10834,7 @@ of \tcode{enable_nonlocking_formatter_optimization}: \begin{codeblock} template - inline constexpr bool enable_nonlocking_formatter_optimization< + constexpr bool enable_nonlocking_formatter_optimization< chrono::duration> = enable_nonlocking_formatter_optimization; \end{codeblock} @@ -10845,7 +10845,7 @@ \tcode{enable_nonlocking_formatter_optimization}: \begin{codeblock} template - inline constexpr bool enable_nonlocking_formatter_optimization< + constexpr bool enable_nonlocking_formatter_optimization< chrono::zoned_time> = true; \end{codeblock} diff --git a/source/utilities.tex b/source/utilities.tex index 389dc53694..bf80d4f26b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15896,7 +15896,7 @@ template requires (format_kind != range_format::disabled) - inline constexpr bool enable_nonlocking_formatter_optimization = false; + constexpr bool enable_nonlocking_formatter_optimization = false; // \ref{format.arguments}, arguments // \ref{format.arg}, class template \tcode{basic_format_arg} @@ -18799,7 +18799,7 @@ }; template - inline constexpr bool enable_nonlocking_formatter_optimization<@\placeholder{pair-or-tuple}@> = + constexpr bool enable_nonlocking_formatter_optimization<@\placeholder{pair-or-tuple}@> = (enable_nonlocking_formatter_optimization && ...); } \end{codeblock} From c001805bb769fe237034151d59ddd20835a17298 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 30 Aug 2024 20:52:00 +0800 Subject: [PATCH 33/95] [lib] Remove `friend class X` (#6427) Friendship between library classes is considered an implementation detail. --- source/containers.tex | 3 --- source/iostreams.tex | 8 +------- source/utilities.tex | 3 --- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index b9560296fd..0a7254b3ce 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9266,7 +9266,6 @@ // bit reference class @\libmember{reference}{vector}@ { - friend class vector; constexpr reference() noexcept; public: @@ -10380,7 +10379,6 @@ using insert_return_type = @\placeholdernc{insert-return-type}@; class value_compare { - friend class map; protected: Compare comp; value_compare(Compare c) : comp(c) {} @@ -11117,7 +11115,6 @@ using node_type = @\unspec@; class value_compare { - friend class multimap; protected: Compare comp; value_compare(Compare c) : comp(c) { } diff --git a/source/iostreams.tex b/source/iostreams.tex index f4e9bfff7a..0c982f1e5d 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -16096,7 +16096,6 @@ private: filesystem::path pathobject; // \expos - friend class directory_iterator; // \expos }; } \end{codeblock} @@ -16115,10 +16114,7 @@ \pnum \begin{note} -For purposes of exposition, -class \tcode{directory_iterator}\iref{fs.class.directory.iterator} -is shown above as a friend of class \tcode{directory_entry}. -Friendship allows the \tcode{directory_iterator} implementation to cache +\tcode{directory_iterator} can cache already available attribute values directly into a \tcode{directory_entry} object without the cost of an unneeded call to \tcode{refresh()}. @@ -16620,8 +16616,6 @@ any \tcode{directory_entry} \tcode{refresh} function. \begin{note} The exact mechanism for storing cached attribute values is not exposed to users. -For exposition, class \tcode{directory_iterator} is shown in \ref{fs.class.directory.entry} -as a friend of class \tcode{directory_entry}. \end{note} \pnum diff --git a/source/utilities.tex b/source/utilities.tex index bf80d4f26b..639034753b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -9799,7 +9799,6 @@ public: // bit reference class reference { - friend class bitset; constexpr reference() noexcept; public: @@ -18605,8 +18604,6 @@ template explicit handle(T& val) noexcept; // \expos - friend class basic_format_arg; // \expos - public: void format(basic_format_parse_context&, Context& ctx) const; }; From 1fafde9a04a3760debb932839791b1d2047ba432 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 30 Aug 2024 20:52:49 +0800 Subject: [PATCH 34/95] [fs.class.directory.entry.general] Remove superfluous "unneeded" (#7245) --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 0c982f1e5d..63414ca6d2 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -16117,7 +16117,7 @@ \tcode{directory_iterator} can cache already available attribute values directly into a \tcode{directory_entry} object -without the cost of an unneeded call to \tcode{refresh()}. +without the cost of a call to \tcode{refresh()}. \end{note} \pnum From e010cf6cde64a498c2bc4291e7e79e66e8ace79a Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Fri, 23 Aug 2024 21:03:51 +0400 Subject: [PATCH 35/95] [basic.scope.scope] Fix a note about declarations that do not bind names The note is saying that declarations of qualified names do not bind names, but this is not supported by normative wording in [dcl.meaning] --- source/basic.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 035a4c2eaa..9524265f81 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -889,8 +889,7 @@ inhabits the same scope as the \grammarterm{template-declaration}. \item Friend declarations and -declarations of qualified names and -template specializations do not bind names\iref{dcl.meaning}; +declarations of template specializations do not bind names\iref{dcl.meaning}; those with qualified names target a specified scope, and other friend declarations and certain \grammarterm{elaborated-type-specifier}s\iref{dcl.type.elab} From 36a1f39068e71d69e4ca534c5b72891055675e88 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Wed, 4 Sep 2024 10:23:14 -0400 Subject: [PATCH 36/95] [forward.list] Replace misplaced comma with period (#7246) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 0a7254b3ce..fd863c72e2 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -7011,7 +7011,7 @@ A \tcode{forward_list} meets all of the requirements of a container\iref{container.reqmts}, except that the \tcode{size()} member function is not provided and -\tcode{operator==} has linear complexity, +\tcode{operator==} has linear complexity. A \tcode{forward_list} also meets all of the requirements for an allocator-aware container\iref{container.alloc.reqmts}. In addition, a \tcode{forward_list} From f23059bf704a48b4805db28441ec73b61054ab9d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 5 Sep 2024 00:03:56 +0800 Subject: [PATCH 37/95] [optional.syn] Use `decay_t` directly instead of "see below" (#7247) --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 639034753b..e70d3bbdd5 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -3238,7 +3238,7 @@ constexpr void swap(optional&, optional&) noexcept(@\seebelow@); template - constexpr optional<@\seebelow@> make_optional(T&&); + constexpr optional> make_optional(T&&); template constexpr optional make_optional(Args&&... args); template From 9d9a3777f1a571dd2648023fe70848c32aebda09 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sun, 8 Sep 2024 12:13:53 -0700 Subject: [PATCH 38/95] [associative.reqmts.general,unord.req.general] Fix cross-references to [container.alloc.reqmts] and [container.reqmts] (#7249) Both paragraphs incorrectly point to [container.reqmts] instead of [container.alloc.reqmts] for "the requirements of an allocator-aware container". --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index fd863c72e2..fc85658ffd 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -2726,12 +2726,12 @@ \pnum A type \tcode{X} meets the \defnadj{associative}{container} requirements if \tcode{X} meets all the requirements of an allocator-aware -container\iref{container.reqmts} and +container\iref{container.alloc.reqmts} and the following types, statements, and expressions are well-formed and have the specified semantics, except that for \tcode{map} and \tcode{multimap}, the requirements placed on \tcode{value_type} -in \ref{container.alloc.reqmts} apply instead to \tcode{key_type} +in \ref{container.reqmts} apply instead to \tcode{key_type} and \tcode{mapped_type}. \begin{note} For example, in some cases \tcode{key_type} and \tcode{mapped_type} @@ -4225,11 +4225,11 @@ A type \tcode{X} meets the \defnadj{unordered associative}{container} requirements if \tcode{X} meets all the requirements of -an allocator-aware container\iref{container.reqmts} and +an allocator-aware container\iref{container.alloc.reqmts} and the following types, statements, and expressions are well-formed and have the specified semantics, except that for \tcode{unordered_map} and \tcode{unordered_multimap}, -the requirements placed on \tcode{value_type} in \ref{container.alloc.reqmts} +the requirements placed on \tcode{value_type} in \ref{container.reqmts} apply instead to \tcode{key_type} and \tcode{mapped_type}. \begin{note} For example, \tcode{key_type} and \tcode{mapped_type} From d930c5fa6728dd0b599f9c7918a2f0a0f747aaa2 Mon Sep 17 00:00:00 2001 From: Jan Schultke Date: Mon, 16 Sep 2024 20:35:33 +0200 Subject: [PATCH 39/95] [expr.delete] Remove stray "the" between words (#7253) --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 69b5e92933..389ac435b8 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -5948,7 +5948,7 @@ \end{note} \pnum -The deallocation the function to be called is selected as follows: +The deallocation function to be called is selected as follows: \begin{itemize} \item If any of the deallocation functions is a destroying operator delete, From 9243ba5befaea8fd3e878e6114942db8d556a6e0 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Tue, 17 Sep 2024 06:13:18 -0400 Subject: [PATCH 40/95] [optional.assign] Use itemized list for operator=(U&& v) constraints (#7255) --- source/utilities.tex | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index e70d3bbdd5..ced6ebc2e4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -3767,10 +3767,12 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_same_v, optional>} is \tcode{false}, -\tcode{conjunction_v, is_same>>} is \tcode{false}, -\tcode{is_constructible_v} is \tcode{true}, and -\tcode{is_assignable_v} is \tcode{true}. +\begin{itemize} +\item \tcode{is_same_v, optional>} is \tcode{false}, +\item \tcode{conjunction_v, is_same>>} is \tcode{false}, +\item \tcode{is_constructible_v} is \tcode{true}, and +\item \tcode{is_assignable_v} is \tcode{true}. +\end{itemize} \pnum \effects From 4930897a2a45fa57fd9d766a24229a9e3f14f23e Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 21 Aug 2021 13:58:22 +0200 Subject: [PATCH 41/95] [dcl.spec.general,dcl.fct.spec] Clarify duplication of decl-specifiers --- source/declarations.tex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index f42ef66892..446aebd3aa 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -418,9 +418,9 @@ same type. \pnum -Each \grammarterm{decl-specifier} -shall appear at most once in a complete \grammarterm{decl-specifier-seq}, -except that \tcode{long} may appear twice. +At most one of each of the \grammarterm{decl-specifier}s +\keyword{friend}, \keyword{typedef}, or \keyword{inline} +shall appear in a \grammarterm{decl-specifier-seq}. At most one of the \keyword{constexpr}, \keyword{consteval}, and \keyword{constinit} keywords shall appear in a \grammarterm{decl-specifier-seq}. @@ -651,6 +651,9 @@ A \grammarterm{function-specifier} can be used only in a function declaration. +At most one \grammarterm{explicit-specifier} and +at most one \keyword{virtual} keyword shall appear in +a \grammarterm{decl-specifier-seq}. \begin{bnf} \nontermdef{function-specifier}\br From 29c770f5b345e7187afe966e6823aa5adcb9c636 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 27 Sep 2024 00:41:11 +0800 Subject: [PATCH 42/95] [input.output] Use `\exposid` for exposition-only names (#7208) Also renaming - init_buf_ptrs to init-buf-ptrs - emit_on_sync to emit-on-sync - pathobject to path-object init_cnt is not changed because it should be removed. --- source/iostreams.tex | 448 +++++++++++++++++++++---------------------- 1 file changed, 224 insertions(+), 224 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 63414ca6d2..15569285d2 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -844,9 +844,9 @@ ios_base(); private: - static int index; // \expos - long* iarray; // \expos - void** parray; // \expos + static int @\exposid{index}@; // \expos + long* @\exposid{iarray}@; // \expos + void** @\exposid{parray}@; // \expos }; } \end{codeblock} @@ -882,19 +882,19 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{static int index}, +\tcode{static int \exposid{index}}, specifies the next available unique index for the integer or pointer arrays maintained for the private use of the program, initialized to an unspecified value; \item -\tcode{long* iarray}, +\tcode{long* \exposid{iarray}}, points to the first element of an arbitrary-length \tcode{long} array maintained for the private use of the program; \item -\tcode{void** parray}, +\tcode{void** \exposid{parray}}, points to the first element of an arbitrary-length pointer array maintained for the private use of the program. \end{itemize} @@ -1446,7 +1446,7 @@ \begin{itemdescr} \pnum \returns -\tcode{index} +\exposid{index} \tcode{++}. \pnum @@ -1467,20 +1467,20 @@ \pnum \effects -If \tcode{iarray} is a null pointer, allocates an array of +If \exposid{iarray} is a null pointer, allocates an array of \tcode{long} of unspecified size and stores a pointer to its first element in -\tcode{iarray}. +\exposid{iarray}. The function then extends the array pointed at by -\tcode{iarray} as necessary to include the element -\tcode{iarray[idx]}. +\exposid{iarray} as necessary to include the element +\tcode{\exposid{iarray}[idx]}. Each newly allocated element of the array is initialized to zero. The reference returned is invalid after any other operation on the object. \begin{footnote} An implementation is free to implement both the integer -array pointed at by \tcode{iarray} and the pointer array pointed at by -\tcode{parray} as sparse data structures, possibly with a one-element +array pointed at by \exposid{iarray} and the pointer array pointed at by +\exposid{parray} as sparse data structures, possibly with a one-element cache for each. \end{footnote} However, the value of the storage referred to is retained, so @@ -1505,7 +1505,7 @@ \pnum \returns On success -\tcode{iarray[idx]}. +\tcode{\exposid{iarray}[idx]}. On failure, a valid \tcode{long\&} initialized to 0. @@ -1523,13 +1523,13 @@ \pnum \effects -If \tcode{parray} is a null pointer, allocates an array of +If \exposid{parray} is a null pointer, allocates an array of pointers to \keyword{void} of unspecified size and stores a pointer to its -first element in \tcode{parray}. +first element in \exposid{parray}. The function then extends the array -pointed at by \tcode{parray} as necessary to include the element -\tcode{parray[idx]}. +pointed at by \exposid{parray} as necessary to include the element +\tcode{\exposid{parray}[idx]}. Each newly allocated element of the array is initialized to a null pointer. The reference returned is invalid after any other operation on the @@ -1657,7 +1657,7 @@ void state(stateT); private: - stateT st; // \expos + stateT @\exposid{st}@; // \expos }; } \end{codeblock} @@ -1672,7 +1672,7 @@ \begin{itemdescr} \pnum \effects -Assigns \tcode{s} to \tcode{st}. +Assigns \tcode{s} to \exposid{st}. \end{itemdescr} \indexlibrarymember{state}{fpos}% @@ -1683,7 +1683,7 @@ \begin{itemdescr} \pnum \returns -Current value of \tcode{st}. +Current value of \exposid{st}. \end{itemdescr} \rSec3[fpos.operations]{Requirements} @@ -4521,12 +4521,12 @@ namespace std { template class basic_istream::sentry { - bool ok_; // \expos + bool @\exposid{ok_}@; // \expos public: explicit sentry(basic_istream& is, bool noskipws = false); ~sentry(); - explicit operator bool() const { return ok_; } + explicit operator bool() const { return @\exposid{ok_}@; } sentry(const sentry&) = delete; sentry& operator=(const sentry&) = delete; }; @@ -4623,9 +4623,9 @@ \tcode{is.good()} is \tcode{true}, -\tcode{ok_ != false} +\tcode{\exposid{ok_} != false} otherwise, -\tcode{ok_ == false}. +\tcode{\exposid{ok_} == false}. During preparation, the constructor may call \tcode{setstate(failbit)} (which may throw @@ -4660,7 +4660,7 @@ \begin{itemdescr} \pnum \returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec3[istream.formatted]{Formatted input functions} @@ -6189,12 +6189,12 @@ namespace std { template class basic_ostream::sentry { - bool ok_; // \expos + bool @\exposid{ok_}@; // \expos public: explicit sentry(basic_ostream& os); ~sentry(); - explicit operator bool() const { return ok_; } + explicit operator bool() const { return @\exposid{ok_}@; } sentry(const sentry&) = delete; sentry& operator=(const sentry&) = delete; @@ -6235,9 +6235,9 @@ \tcode{os.good()} is \tcode{true}, -\tcode{ok_ == true} +\tcode{\exposid{ok_} == true} otherwise, -\tcode{ok_ == false}. +\tcode{\exposid{ok_} == false}. During preparation, the constructor may call \tcode{setstate(failbit)} (which may throw @@ -6278,7 +6278,7 @@ \pnum \effects Returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec4[ostream.seeks]{Seek members} @@ -7114,7 +7114,7 @@ To work around the issue that the \tcode{Allocator} template argument cannot be deduced, implementations can introduce an intermediate base class -to \tcode{basic_syncbuf} that manages its \tcode{emit_on_sync} flag. +to \tcode{basic_syncbuf} that manages its \exposid{emit-on-sync} flag. \end{note} \pnum @@ -8121,9 +8121,9 @@ = ios_base::in | ios_base::out) override; private: - ios_base::openmode mode; // \expos - basic_string buf; // \expos - void init_buf_ptrs(); // \expos + ios_base::openmode @\exposid{mode}@; // \expos + basic_string @\exposid{buf}@; // \expos + void @\exposid{init-buf-ptrs}@(); // \expos }; } \end{codeblock} @@ -8144,17 +8144,17 @@ the maintained data and internal pointer initialization is presented here as: \begin{itemize} \item - \tcode{ios_base::openmode mode}, has + \tcode{ios_base::openmode \exposid{mode}}, has \tcode{in} set if the input sequence can be read, and \tcode{out} set if the output sequence can be written. \item - \tcode{basic_string buf} + \tcode{basic_string \exposid{buf}} contains the underlying character sequence. \item - \tcode{init_buf_ptrs()} sets the base class' + \tcode{\exposid{init-buf-ptrs}()} sets the base class' get area\iref{streambuf.get.area} and put area\iref{streambuf.put.area} pointers - after initializing, moving from, or assigning to \tcode{buf} accordingly. + after initializing, moving from, or assigning to \exposid{buf} accordingly. \end{itemize} \rSec3[stringbuf.cons]{Constructors} @@ -8169,7 +8169,7 @@ \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, and -\tcode{mode} +\exposid{mode} with \tcode{which}. It is \impldef{whether sequence pointers are initialized to null pointers} @@ -8195,9 +8195,9 @@ \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, -\tcode{mode} with \tcode{which}, and -\tcode{buf} with \tcode{s}, -then calls \tcode{init_buf_ptrs()}. +\exposid{mode} with \tcode{which}, and +\exposid{buf} with \tcode{s}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% @@ -8210,9 +8210,9 @@ \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, -\tcode{mode} with \tcode{which}, and -\tcode{buf} with \tcode{a}, -then calls \tcode{init_buf_ptrs()}. +\exposid{mode} with \tcode{which}, and +\exposid{buf} with \tcode{a}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \pnum \ensures @@ -8230,9 +8230,9 @@ \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, -\tcode{mode} with \tcode{which}, and -\tcode{buf} with \tcode{std::move(s)}, -then calls \tcode{init_buf_ptrs()}. +\exposid{mode} with \tcode{which}, and +\exposid{buf} with \tcode{std::move(s)}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% @@ -8247,9 +8247,9 @@ \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, -\tcode{mode} with \tcode{which}, and -\tcode{buf} with \tcode{\{s,a\}}, -then calls \tcode{init_buf_ptrs()}. +\exposid{mode} with \tcode{which}, and +\exposid{buf} with \tcode{\{s,a\}}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% @@ -8268,9 +8268,9 @@ \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, -\tcode{mode} with \tcode{which}, and -\tcode{buf} with \tcode{s}, -then calls \tcode{init_buf_ptrs()}. +\exposid{mode} with \tcode{which}, and +\exposid{buf} with \tcode{s}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% @@ -8299,9 +8299,9 @@ Creates a variable \tcode{sv} as if by \tcode{basic_string_view sv = t}, then value-initializes the base class, -initializes \tcode{mode} with \tcode{which}, and -direct-non-list-initializes \tcode{buf} with \tcode{sv, a}, -then calls \tcode{init_buf_ptrs()}. +initializes \exposid{mode} with \tcode{which}, and +direct-non-list-initializes \exposid{buf} with \tcode{sv, a}, +then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% @@ -8314,10 +8314,10 @@ \pnum \effects Copy constructs the base class from \tcode{rhs} and -initializes \tcode{mode} with \tcode{rhs.mode}. +initializes \exposid{mode} with \tcode{rhs.mode}. In the first form \tcode{buf} is initialized from \tcode{std::move(rhs).str()}. -In the second form \tcode{buf} is initialized +In the second form \exposid{buf} is initialized from \tcode{\{std::move(rhs).str(), a\}}. It is \impldef{whether sequence pointers are copied by \tcode{basic_stringbuf} move @@ -8422,39 +8422,39 @@ (except for those characters re-initialized by the new \tcode{basic_string}). \begin{itemdecl} -void init_buf_ptrs(); // \expos +void @\exposid{init-buf-ptrs}@(); // \expos \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes the input and output sequences from \tcode{buf} -according to \tcode{mode}. +Initializes the input and output sequences from \exposid{buf} +according to \exposid{mode}. \pnum \ensures \begin{itemize} -\item If \tcode{ios_base::out} is set in \tcode{mode}, - \tcode{pbase()} points to \tcode{buf.front()} and - \tcode{epptr() >= pbase() + buf.size()} is \tcode{true}; +\item If \tcode{ios_base::out} is set in \exposid{mode}, + \tcode{pbase()} points to \tcode{\exposid{buf}.front()} and + \tcode{epptr() >= pbase() + \exposid{buf}.size()} is \tcode{true}; \begin{itemize} - \item in addition, if \tcode{ios_base::ate} is set in \tcode{mode}, - \tcode{pptr() == pbase() + buf.size()} is \tcode{true}, + \item in addition, if \tcode{ios_base::ate} is set in \exposid{mode}, + \tcode{pptr() == pbase() + \exposid{buf}.size()} is \tcode{true}, \item otherwise \tcode{pptr() == pbase()} is \tcode{true}. \end{itemize} -\item If \tcode{ios_base::in} is set in \tcode{mode}, - \tcode{eback()} points to \tcode{buf.front()}, and - \tcode{(gptr() == eback() \&\& egptr() == eback() + buf.size())} +\item If \tcode{ios_base::in} is set in \exposid{mode}, + \tcode{eback()} points to \tcode{\exposid{buf}.front()}, and + \tcode{(gptr() == eback() \&\& egptr() == eback() + \exposid{buf}.size())} is \tcode{true}. \end{itemize} \pnum \begin{note} For efficiency reasons, -stream buffer operations can violate invariants of \tcode{buf} +stream buffer operations can violate invariants of \exposid{buf} while it is held encapsulated in the \tcode{basic_stringbuf}, e.g., by writing to characters in the range -\range{\tcode{buf.data() + buf.size()}}{\tcode{buf.data() + buf.capacity()}}. +\range{\tcode{\exposid{buf}.data() + \exposid{buf}.size()}}{\tcode{\exposid{buf}.data() + \exposid{buf}.capacity()}}. All operations retrieving a \tcode{basic_string} from \tcode{buf} ensure that the \tcode{basic_string} invariants hold on the returned value. \end{note} @@ -8468,7 +8468,7 @@ \begin{itemdescr} \pnum \returns -\tcode{buf.get_allocator()}. +\tcode{\exposid{buf}.get_allocator()}. \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% @@ -8515,7 +8515,7 @@ The underlying character sequence \tcode{buf} is empty and \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}, \tcode{eback()}, \tcode{gptr()}, and \tcode{egptr()} -are initialized as if by calling \tcode{init_buf_ptrs()} +are initialized as if by calling \tcode{\exposid{init-buf-ptrs}()} with an empty \tcode{buf}. \pnum @@ -8541,9 +8541,9 @@ A \tcode{sv} object referring to the \tcode{basic_stringbuf}'s underlying character sequence in \tcode{buf}: \begin{itemize} -\item If \tcode{ios_base::out} is set in \tcode{mode}, +\item If \tcode{ios_base::out} is set in \exposid{mode}, then \tcode{sv(pbase(), high_mark-pbase())} is returned. -\item Otherwise, if \tcode{ios_base::in} is set in \tcode{mode}, +\item Otherwise, if \tcode{ios_base::in} is set in \exposid{mode}, then \tcode{sv(eback(), egptr()-eback())} is returned. \item Otherwise, \tcode{sv()} is returned. \end{itemize} @@ -8566,8 +8566,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8586,8 +8586,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8601,8 +8601,8 @@ \effects Equivalent to: \begin{codeblock} -buf = std::move(s); -init_buf_ptrs(); +@\exposid{buf}@ = std::move(s); +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8623,8 +8623,8 @@ Equivalent to: \begin{codeblock} basic_string_view sv = t; -buf = sv; -init_buf_ptrs(); +@\exposid{buf}@ = sv; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8683,7 +8683,7 @@ \tcode{false} and if the input sequence has a putback position available, and -if \tcode{mode} +if \exposid{mode} \tcode{\&} \tcode{ios_base::out} is nonzero, @@ -8769,14 +8769,14 @@ \pnum The function can make a write position available only if -\tcode{ios_base::out} is set in \tcode{mode}. +\tcode{ios_base::out} is set in \exposid{mode}. To make a write position available, the function reallocates (or initially allocates) an array object with a sufficient number of elements to hold the current array object (if any), plus at least one additional write position. -If \tcode{ios_base::in} is set in \tcode{mode}, +If \tcode{ios_base::in} is set in \exposid{mode}, the function alters the read end pointer \tcode{egptr()} to point just past the new write position. @@ -8964,7 +8964,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -8980,7 +8980,7 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{sb}, the \tcode{stringbuf} object. +\exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[istringstream.cons]{Constructors} @@ -8994,8 +8994,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9010,8 +9010,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9024,8 +9024,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::in, a)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9040,8 +9040,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which | ios_base::\brk{}in)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9057,8 +9057,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9078,8 +9078,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9106,8 +9106,8 @@ \pnum \effects -Initializes the base class with \tcode{addressof(sb)}, and -direct-non-list-initializes \tcode{sb} with \tcode{t, which | ios_base::in, a}. +Initializes the base class with \tcode{addressof(\exposid{sb})}, and +direct-non-list-initializes \exposid{sb} with \tcode{t, which | ios_base::in, a}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% @@ -9121,7 +9121,7 @@ Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Then calls \tcode{basic_istream::set_rdbuf(addressof(sb))} +Then calls \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} @@ -9138,7 +9138,7 @@ Equivalent to: \begin{codeblock} basic_istream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9166,7 +9166,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% @@ -9337,7 +9337,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9353,7 +9353,7 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{sb}, the \tcode{stringbuf} object. +\exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[ostringstream.cons]{Constructors} @@ -9367,8 +9367,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9383,8 +9383,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9397,8 +9397,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9413,8 +9413,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which | ios_base::\brk{}out)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9430,8 +9430,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9451,8 +9451,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} +and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} @@ -9479,8 +9479,8 @@ \pnum \effects -Initializes the base class with \tcode{addressof(sb)}, and -direct-non-list-initializes \tcode{sb} with \tcode{t, which | ios_base::out, a}. +Initializes the base class with \tcode{addressof(\exposid{sb})}, and +direct-non-list-initializes \exposid{sb} with \tcode{t, which | ios_base::out, a}. \end{itemdescr} \indexlibraryctor{basic_ostringstream}% @@ -9494,7 +9494,7 @@ Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Then calls \tcode{basic_ostream::set_rdbuf(addressof(sb))} +Then calls \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} @@ -9511,7 +9511,7 @@ Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9538,7 +9538,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% @@ -9710,7 +9710,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9727,7 +9727,7 @@ For the sake of exposition, the maintained data is presented here as \begin{itemize} \item -\tcode{sb}, the \tcode{stringbuf} object. +\exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[stringstream.cons]{Constructors} @@ -9741,9 +9741,9 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and -\tcode{sb} +\exposid{sb} with \tcode{basic_string\-buf(which)}. \end{itemdescr} @@ -9759,9 +9759,9 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and -\tcode{sb} +\exposid{sb} with \tcode{basic_string\-buf(s, which)}. \end{itemdescr} @@ -9775,8 +9775,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} -and \tcode{sb} with +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} +and \exposid{sb} with \tcode{basic_stringbuf(which, a)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9791,8 +9791,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} -and \tcode{sb} with +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} +and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9808,8 +9808,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} -and \tcode{sb} with +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} +and \exposid{sb} with \tcode{basic_stringbuf(s, which, a)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9829,8 +9829,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} -and \tcode{sb} with +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} +and \exposid{sb} with \tcode{basic_stringbuf(s, which)}\iref{stringbuf.cons}. \end{itemdescr} @@ -9857,8 +9857,8 @@ \pnum \effects -Initializes the base class with \tcode{addressof(sb)}, and -direct-non-list-initializes \tcode{sb} with \tcode{t, which, a}. +Initializes the base class with \tcode{addressof(\exposid{sb})}, and +direct-non-list-initializes \exposid{sb} with \tcode{t, which, a}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% @@ -9872,7 +9872,7 @@ Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Then calls \tcode{basic_istream::set_rdbuf(addressof(sb))} +Then calls \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} @@ -9889,7 +9889,7 @@ Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9916,7 +9916,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% @@ -10365,7 +10365,7 @@ if \tcode{ios_base::out} is set in \exposid{mode} and \tcode{ios_base::in} is not set in \exposid{mode}, \item -\tcode{buf.size()} otherwise. +\tcode{\exposid{buf}.size()} otherwise. \end{itemize} \end{itemize} @@ -10453,7 +10453,7 @@ template void span(ROS&& s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10476,8 +10476,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))} +and \exposid{sb} with \tcode{basic_spanbuf(s, which | ios_base::in)}\iref{spanbuf.cons}. \end{itemdescr} @@ -10490,9 +10490,9 @@ \pnum \effects Initializes the base class with \tcode{std::move(rhs)} -and \tcode{sb} with \tcode{std::move(rhs.sb)}. -Next, \tcode{basic_istream::set_rdbuf(addressof(sb))} is called -to install the contained \tcode{basic_spanbuf}. +and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. +Next, \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} is called +to install the contained \tcode{ba\-sic_\-span\-buf}. \end{itemdescr} \indexlibraryctor{basic_ispanstream}% @@ -10529,7 +10529,7 @@ Equivalent to: \begin{codeblock} basic_istream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10557,7 +10557,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10639,7 +10639,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10656,8 +10656,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))} +and \exposid{sb} with \tcode{basic_spanbuf(s, which | ios_base::out)}\iref{spanbuf.cons}. \end{itemdescr} @@ -10670,9 +10670,9 @@ \pnum \effects Initializes the base class with \tcode{std::move(rhs)} -and \tcode{sb} with \tcode{std::move(rhs.sb)}. -Next, \tcode{basic_ostream::set_rdbuf(addressof(sb))} -is called to install the contained \tcode{basic_spanbuf}. +and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. +Next, \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))} +is called to install the contained \tcode{ba\-sic_\-span\-buf}. \end{itemdescr} \rSec3[ospanstream.swap]{Swap} @@ -10688,7 +10688,7 @@ Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10716,7 +10716,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10778,7 +10778,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10795,8 +10795,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))} -and \tcode{sb} with +\tcode{basic_iostream(addressof(\exposid{sb}))} +and \exposid{sb} with \tcode{basic_spanbuf(s, which)}\iref{spanbuf.cons}. \end{itemdescr} @@ -10809,8 +10809,8 @@ \pnum \effects Initializes the base class with \tcode{std::move(rhs)} -and \tcode{sb} with \tcode{std::move(rhs.sb)}. -Next, \tcode{basic_iostream::set_rdbuf(addressof(sb))} +and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. +Next, \tcode{basic_iostream::set_rdbuf(addressof(\exposid{sb}))} is called to install the contained \tcode{basic_spanbuf}. \end{itemdescr} @@ -10827,7 +10827,7 @@ Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10855,7 +10855,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -11834,7 +11834,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -11850,7 +11850,7 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{sb}, the \tcode{filebuf} object. +\exposid{sb}, the \tcode{filebuf} object. \end{itemize} \rSec3[ifstream.cons]{Constructors} @@ -11864,8 +11864,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream.cons} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream.cons} +and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} @@ -11881,8 +11881,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_istream(addressof(sb))}\iref{istream.cons} -and \tcode{sb} with +\tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream.cons} +and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::in)}. @@ -11927,7 +11927,7 @@ \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. -Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(sb))} +Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} @@ -11944,7 +11944,7 @@ Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_istream::swap(rhs)} and -\tcode{sb.swap(rhs.sb)}. +\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_ifstream}% @@ -11969,7 +11969,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(@\exposid{sb}@))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ifstream}% @@ -12093,7 +12093,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12109,7 +12109,7 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{sb}, the \tcode{filebuf} object. +\exposid{sb}, the \tcode{filebuf} object. \end{itemize} \rSec3[ofstream.cons]{Constructors} @@ -12123,8 +12123,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream.cons} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream.cons} +and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} @@ -12140,8 +12140,8 @@ \pnum \effects Initializes the base class with -\tcode{basic_ostream(addressof(sb))}\iref{ostream.cons} -and \tcode{sb} with +\tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream.cons} +and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::out)}. @@ -12186,7 +12186,7 @@ \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. -Then calls \tcode{basic_ostream::set_rdbuf(\brk{}addressof(sb))} +Then calls \tcode{basic_ostream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} @@ -12203,7 +12203,7 @@ Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_ostream::swap(rhs)} and -\tcode{sb.swap(rhs.sb)}. +\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_ofstream}% @@ -12228,7 +12228,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ofstream}% @@ -12360,7 +12360,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12376,7 +12376,7 @@ For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item -\tcode{sb}, the \tcode{basic_filebuf} object. +\exposid{sb}, the \tcode{basic_filebuf} object. \end{itemize} \rSec3[fstream.cons]{Constructors} @@ -12390,9 +12390,9 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and -\tcode{sb} with \tcode{basic_filebuf()}. +\exposid{sb} with \tcode{basic_filebuf()}. \end{itemdescr} \indexlibraryctor{basic_fstream}% @@ -12409,9 +12409,9 @@ \pnum \effects Initializes the base class with -\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} +\tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and -\tcode{sb} with \tcode{basic_filebuf()}. +\exposid{sb} with \tcode{basic_filebuf()}. Then calls \tcode{rdbuf()->open(s, mode)}. If that function returns a null pointer, calls @@ -12456,7 +12456,7 @@ \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. -Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(sb))} +Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} @@ -12473,7 +12473,7 @@ Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_iostream::swap(rhs)} and -\tcode{sb.swap(rhs.sb)}. +\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_fstream}% @@ -12499,7 +12499,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_fstream}% @@ -12661,8 +12661,8 @@ int sync() override; private: - streambuf_type* wrapped; // \expos - bool emit_on_sync{}; // \expos + streambuf_type* @\exposid{wrapped}@; // \expos + bool @\exposid{emit-on-sync}@{}; // \expos }; } \end{codeblock} @@ -12672,7 +12672,7 @@ written to it, known as the associated output, into internal buffers allocated using the object's allocator. The associated output is transferred to the -wrapped stream buffer object \tcode{*wrapped} +wrapped stream buffer object \tcode{*\exposid{wrapped}} when \tcode{emit()} is called or when the \tcode{basic_syncbuf} object is destroyed. Such transfers are atomic with respect to transfers @@ -12689,7 +12689,7 @@ \begin{itemdescr} \pnum \effects -Sets \tcode{wrapped} to \tcode{obuf}. +Sets \exposid{wrapped} to \tcode{obuf}. \pnum \ensures @@ -12823,10 +12823,10 @@ \pnum \effects Atomically transfers the associated output of \tcode{*this} -to the stream buffer \tcode{*wrapped}, +to the stream buffer \tcode{*\exposid{wrapped}}, so that it appears in the output stream as a contiguous sequence of characters. -\tcode{wrapped->pubsync()} is called +\tcode{\exposid{wrapped}->pubsync()} is called if and only if a call was made to \tcode{sync()} since the most recent call to \tcode{emit()}, if any. @@ -12849,15 +12849,15 @@ \tcode{true} if all of the following conditions hold; otherwise \tcode{false}: \begin{itemize} -\item \tcode{wrapped == nullptr} is \tcode{false}. +\item \tcode{\exposid{wrapped} == nullptr} is \tcode{false}. \item All of the characters in the associated output were successfully transferred. -\item The call to \tcode{wrapped->pubsync()} (if any) succeeded. +\item The call to \tcode{\exposid{wrapped}->pubsync()} (if any) succeeded. \end{itemize} \pnum \remarks -May call member functions of \tcode{wrapped} -while holding a lock uniquely associated with \tcode{wrapped}. +May call member functions of \exposid{wrapped} +while holding a lock uniquely associated with \exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_wrapped}{basic_syncbuf}% @@ -12868,7 +12868,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wrapped}. +\exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_allocator}{basic_syncbuf}% @@ -12890,7 +12890,7 @@ \begin{itemdescr} \pnum \effects -\tcode{emit_on_sync = b}. +\tcode{\exposid{emit-on-sync} = b}. \end{itemdescr} \rSec3[syncstream.syncbuf.virtuals]{Overridden virtual functions} @@ -12904,9 +12904,9 @@ \pnum \effects Records that the wrapped stream buffer is to be flushed. -Then, if \tcode{emit_on_sync} is \tcode{true}, calls \tcode{emit()}. +Then, if \exposid{emit-on-sync} is \tcode{true}, calls \tcode{emit()}. \begin{note} -If \tcode{emit_on_sync} is \tcode{false}, +If \exposid{emit-on-sync} is \tcode{false}, the actual flush is delayed until a call to \tcode{emit()}. \end{note} @@ -12968,10 +12968,10 @@ // \ref{syncstream.osyncstream.members}, member functions void emit(); streambuf_type* get_wrapped() const noexcept; - syncbuf_type* rdbuf() const noexcept { return const_cast(addressof(sb)); } + syncbuf_type* rdbuf() const noexcept { return const_cast(addressof(@\exposid{sb}@)); } private: - syncbuf_type sb; // \expos + syncbuf_type @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -13013,8 +13013,8 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{sb} from \tcode{buf} and \tcode{allocator}. -Initializes the base class with \tcode{basic_ostream(addressof(sb))}. +Initializes \exposid{sb} from \tcode{buf} and \tcode{allocator}. +Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}. \pnum \begin{note} @@ -13037,8 +13037,8 @@ \pnum \effects Move constructs the base class -and \tcode{sb} from the corresponding subobjects of \tcode{other}, -and calls \tcode{basic_ostream::set_rdbuf(addressof(sb))}. +and \exposid{sb} from the corresponding subobjects of \tcode{other}, +and calls \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))}. \pnum \ensures @@ -13059,7 +13059,7 @@ \pnum \effects Behaves as an unformatted output function\iref{ostream.unformatted}. -After constructing a \tcode{sentry} object, calls \tcode{sb.emit()}. +After constructing a \tcode{sentry} object, calls \tcode{\exposid{sb}.emit()}. If that call returns \tcode{false}, calls \tcode{setstate(ios_base::badbit)}. @@ -13104,7 +13104,7 @@ \begin{itemdescr} \pnum \returns -\tcode{sb.get_wrapped()}. +\tcode{\exposid{sb}.get_wrapped()}. \pnum \begin{example} @@ -16095,7 +16095,7 @@ operator<<(basic_ostream& os, const directory_entry& d); private: - filesystem::path pathobject; // \expos + filesystem::path @\exposid{path-object}@; // \expos }; } \end{codeblock} @@ -16186,7 +16186,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to \tcode{pathobject = p}, +Equivalent to \tcode{\exposid{path-object} = p}, then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. If an error occurs, the values of any cached attributes are unspecified. @@ -16204,7 +16204,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to \tcode{pathobject.replace_filename(p)}, +Equivalent to \tcode{\exposid{path-object}.replace_filename(p)}, then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. If an error occurs, the values of any cached attributes are unspecified. @@ -16255,7 +16255,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject}. +\exposid{path-object}. \end{itemdescr} \indexlibrarymember{exists}{directory_entry}% @@ -16495,7 +16495,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject == rhs.pathobject}. +\tcode{\exposid{path-object} == rhs.\exposid{path-object}}. \end{itemdescr} \indexlibrarymember{operator<=>}{directory_entry}% @@ -16506,7 +16506,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject <=> rhs.pathobject}. +\tcode{\exposid{path-object} <=> rhs.\exposid{path-object}}. \end{itemdescr} \rSec3[fs.dir.entry.io]{Inserter} From d0c00bf629f4b91d19176c2397aa3ff7c1c0ce63 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 26 Sep 2024 18:49:15 +0200 Subject: [PATCH 43/95] [tab:lex.charset.literal] Shorten table heading Fixes ISO/CS comment (C++23 proof) --- source/lex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lex.tex b/source/lex.tex index 7cb0a8f3ef..adb82aa862 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -410,7 +410,7 @@ all characters of the basic character set, plus the control characters specified in \tref{lex.charset.literal}. -\begin{floattable}{Additional control characters in the basic literal character set}{lex.charset.literal}{ll} +\begin{floattable}{Additional control characters}{lex.charset.literal}{ll} \topline \ohdrx{2}{character} \\ \capsep \ucode{0000} & \uname{null} \\ From 945b1c071ed511d11a2152aa70e08290f91a7856 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 26 Sep 2024 19:11:58 +0200 Subject: [PATCH 44/95] [tab:re.matchflag] Shorten table heading Fixes ISO/CS comment (C++23 proof) --- source/regex.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/regex.tex b/source/regex.tex index d9a53ba893..a4422ef8ef 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -784,8 +784,7 @@ any bitmask elements set. \begin{longlibefftab} - {\tcode{regex_constants::match_flag_type} effects when obtaining a match against a - character container sequence \range{first}{last}.} + {\tcode{regex_constants::match_flag_type} effects} {re.matchflag} % \indexlibraryglobal{match_not_bol}% From 4e34492bc7279fedb0e066f4925860e686fa81dc Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 26 Sep 2024 19:43:50 +0200 Subject: [PATCH 45/95] [rand.req] Fix table headers for longtable continued on following page Fixes ISO/CS comment (C++23 proof) --- source/numerics.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 83b9f8dd57..7ae38cf805 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -1920,7 +1920,8 @@ & \rhdr{Complexity} \\ \capsep \endfirsthead -\hline +\continuedcaption\\ +\topline \lhdr{Expression} & \chdr{Return type} & \chdr{Pre/post-condition} @@ -2308,7 +2309,8 @@ & \rhdr{Complexity} \\ \capsep \endfirsthead -\hline +\continuedcaption\\ +\topline \lhdr{Expression} & \chdr{Return type} & \chdr{Pre/post-condition} From 2b1e6d2952987bf4ada8275212a7bb297bb0c1c7 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 26 Sep 2024 20:19:01 +0200 Subject: [PATCH 46/95] [macros] Fix duplicate vertical lines visible in tables in [optional.assign] Fixes ISO/CS comment (C++23 proof) --- source/tables.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/tables.tex b/source/tables.tex index 7bbd34d2d7..678ec5d98b 100644 --- a/source/tables.tex +++ b/source/tables.tex @@ -492,7 +492,7 @@ \newcommand{\bottomline}{\rowsep} \newcommand{\hdstyle}[1]{\textbf{##1}} \newcommand{\rowhdr}[1]{\hdstyle{##1}&} - \newcommand{\colhdr}[1]{\multicolumn{1}{|>{\centering}m{#6}|}{\hdstyle{##1}}} + \newcommand{\colhdr}[1]{\multicolumn{1}{>{\centering}m{#6}|}{\hdstyle{##1}}} \begin{floattablebasex} {#1}{#2} {>{\centering}m{#5}|@{}p{0.2\normalbaselineskip}@{}|m{#6}|m{#7} } From 0680a08ee677e0970b4460fd614f58b122845047 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 26 Sep 2024 21:59:34 +0100 Subject: [PATCH 47/95] [ios.init] Remove unused Init::init_cnt static member (#7263) The text that made use of this variable was removed by LWG1123 and has not been present in the WP since N3090. The effects of Init construction and destruction are specified entirely without the use of this variable, so it serves no purpose now. --- source/iostreams.tex | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 15569285d2..65b16c1494 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1132,9 +1132,6 @@ Init(const Init&) = default; ~Init(); Init& operator=(const Init&) = default; - - private: - static int init_cnt; // \expos }; } \end{codeblock} @@ -1148,17 +1145,6 @@ provided for by the functions declared in \libheaderref{cstdio}. -\pnum -For the sake of exposition, the maintained data is presented here as: -\begin{itemize} -\item -\tcode{static int init_cnt}, -counts the number of -constructor and destructor calls for class -\tcode{Init}, -initialized to zero. -\end{itemize} - \indexlibraryctor{ios_base::Init}% \begin{itemdecl} Init(); From da5fa3146bb601ee9caea6ebc8357d8816176e95 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 26 Sep 2024 23:27:09 +0200 Subject: [PATCH 48/95] [std] Format URLs in blue regular font See ISO/IEC Directives, Part 2, section 6.5 Supplementary content Fixes ISO/CS comment (C++23 proof) --- source/std.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/std.tex b/source/std.tex index e7a523d790..2761dbee82 100644 --- a/source/std.tex +++ b/source/std.tex @@ -43,6 +43,7 @@ colorlinks=true, linkcolor=blue, citecolor=blue, + urlcolor=blue, % ISO/IEC Directives, Part 2, section 6.5 plainpages=false} \usepackage{memhfixc} % fix interactions between hyperref and memoir \usepackage[active,header=false,handles=false,copydocumentclass=false,generate=std-gram.ext,extract-cmdline={gramSec},extract-env={bnf,simplebnf}]{extract} % Grammar extraction @@ -87,6 +88,10 @@ %% turn off all ligatures inside \texttt \DisableLigatures{encoding = T1, family = tt*} +%%-------------------------------------------------- +%% select regular text font for \url +\urlstyle{same} + \begin{document} \chapterstyle{cppstd} \pagestyle{cpppage} From afdd158f555892507bc44c6d372c3b45a7f09832 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 27 Sep 2024 00:09:11 +0200 Subject: [PATCH 49/95] [styles] Format title of \codeblocktu using 'caption' package This restores the C++20 status of the formatting. --- source/macros.tex | 16 ---------------- source/styles.tex | 6 +++--- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/source/macros.tex b/source/macros.tex index d54104139d..f257575dca 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -587,22 +587,6 @@ \lstnewenvironment{codeblock}{\CodeBlockSetup}{} -% Left-align listings titles -\makeatletter -\def\lst@maketitle{\@makeleftcaption\lst@title@dropdelim} -\long\def\@makeleftcaption#1#2{% - \vskip\abovecaptionskip - \sbox\@tempboxa{#1: #2}% - \ifdim \wd\@tempboxa >\hsize - #1: #2\par - \else - \global \@minipagefalse - \hb@xt@\hsize{%\hfil -- REMOVED - \box\@tempboxa\hfil}% - \fi - \vskip\belowcaptionskip}% -\makeatother - \lstnewenvironment{codeblocktu}[1]{% \lstset{title={%\parabullnum{Bullets1}{0pt} #1:}}\CodeBlockSetup}{} diff --git a/source/styles.tex b/source/styles.tex index e6372565cd..715825cb74 100644 --- a/source/styles.tex +++ b/source/styles.tex @@ -121,10 +121,10 @@ leftmargin=\bnfindentrest, listparindent=-\bnfindentinc, itemindent=\listparindent} %%-------------------------------------------------- -%% set caption style -\captionstyle{\centering} +%% set caption styles \DeclareCaptionLabelSeparator{emdash}{ --- } -\captionsetup{labelsep=emdash,font+=bf} +\captionsetup{justification=centering,labelsep=emdash,font+=bf} +\captionsetup[lstlisting]{justification=raggedright,singlelinecheck=false,font=normal} %%-------------------------------------------------- %% set global styles that get reset by \mainmatter From 9225f4ec2c18b1994aafccb089e7510b30559c4a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 27 Sep 2024 17:49:23 +0200 Subject: [PATCH 50/95] [macros] Avoid page break between section heading and grammar snippet --- source/macros.tex | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/macros.tex b/source/macros.tex index f257575dca..f6dd90ac33 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -660,7 +660,17 @@ \setlength{\BnfInc}{\BnfIndent} \newlength{\BnfRest} \setlength{\BnfRest}{2\BnfIndent} -\newcommand{\BnfNontermshape}{\small\color{grammar-gray}\sffamily\itshape} +\newcommand{\BnfNontermshape}{% + \small% + \color{grammar-gray}% + % The color setting inserts a \pdfcolorstack entry into the vertical list, + % breaking the connection of the \penalty entry from a preceding heading + % with the \glue entries that precede the grammar snippet. + % Add a penalty here that prevents making those \glue entries page-breaking + % opportunities. + \penalty10000% + \sffamily% + \itshape} \newcommand{\BnfReNontermshape}{\small\rmfamily\itshape} \newcommand{\BnfTermshape}{\small\ttfamily\upshape} From 2b3e09e2cc773b7205310917c5a6b2bdd87340af Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 1 Oct 2024 03:22:29 -0700 Subject: [PATCH 51/95] [inplace.vector.cons] "Constructs an object" is redundant (#7252) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index fc85658ffd..e1f5d9df96 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9768,7 +9768,7 @@ \begin{itemdescr} \pnum \effects -Constructs an \tcode{inplace_vector} object with +Constructs an \tcode{inplace_vector} with the elements of the range \tcode{rg}. \pnum From 007035211614c503c5f6242e220048dbfffbe0a2 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 30 Sep 2024 16:54:45 +0200 Subject: [PATCH 52/95] [styles] Do not add a page break opportunity before codeblocks --- source/macros.tex | 2 +- source/styles.tex | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/macros.tex b/source/macros.tex index f6dd90ac33..af31164433 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -578,7 +578,7 @@ % surrounded by @ signs. \newcommand{\CodeBlockSetup}{% \lstset{escapechar=@, aboveskip=\parskip, belowskip=0pt, - beginpenalty=200, midpenalty=500, endpenalty=-50, + midpenalty=500, endpenalty=-50, emptylinepenalty=-250, semicolonpenalty=0,upquote=true}% \renewcommand{\tcode}[1]{\textup{\CodeStylex{##1}}} \renewcommand{\term}[1]{\textit{##1}}% diff --git a/source/styles.tex b/source/styles.tex index 715825cb74..224c99d1e1 100644 --- a/source/styles.tex +++ b/source/styles.tex @@ -175,15 +175,17 @@ \else \lst@ifdisplaystyle \lst@EveryDisplay - % make penalty configurable - \par\lst@beginpenalty + \par\lst@beginpenalty % penalty is now configurable \vspace\lst@aboveskip \fi \fi \normalbaselines \abovecaptionskip\lst@abovecaption\relax \belowcaptionskip\lst@belowcaption\relax - \lst@MakeCaption t% + \let\savedallowbreak\allowbreak + \let\allowbreak\relax + \lst@MakeCaption t% % neuter \allowbreak before non-existing top caption + \let\allowbreak\savedallowbreak \lsthk@PreInit \lsthk@Init \lst@ifdisplaystyle \global\let\lst@ltxlabel\@empty From c6297adc009913fd67c3c14f3944b2333e3f547e Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 1 Oct 2024 16:44:23 +0200 Subject: [PATCH 53/95] [macros] Fine-tune page breaking around 'itemdecl' --- source/macros.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/macros.tex b/source/macros.tex index af31164433..9afe466f40 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -631,9 +631,9 @@ { \lstset{escapechar=@, xleftmargin=0em, - midpenalty=500, + midpenalty=3000, semicolonpenalty=-50, - endpenalty=3000, + endpenalty=2000, aboveskip=2ex, belowskip=0ex % leave this alone: it keeps these things out of the % footnote area From c3890ea32e2e3086fe778612612d9903bdc814f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Tue, 1 Oct 2024 23:14:02 +0100 Subject: [PATCH 54/95] [ostream.inserters.arithmetic] Put use_facet use on fewer lines This is more compact, keeps the whole template-id on a single line, and avoids some awkward page breaks. --- source/iostreams.tex | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 65b16c1494..c62378a9e0 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -6432,9 +6432,8 @@ \tcode{const void*}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), val).failed(); +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), val).failed(); \end{codeblock} When \tcode{val} is of type @@ -6442,9 +6441,8 @@ the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), baseflags == ios_base::oct || baseflags == ios_base::hex ? static_cast(static_cast(val)) : static_cast(val)).failed(); @@ -6455,9 +6453,8 @@ the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), baseflags == ios_base::oct || baseflags == ios_base::hex ? static_cast(static_cast(val)) : static_cast(val)).failed(); @@ -6469,20 +6466,16 @@ \tcode{unsigned int} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), - static_cast(val)).failed(); +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} When \tcode{val} is of type \tcode{float} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), - static_cast(val)).failed(); +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} \pnum @@ -6539,20 +6532,16 @@ is less than or equal to that of \tcode{double}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), - static_cast(val)).failed(); +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} Otherwise, if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is less than or equal to that of \tcode{long double}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} -bool failed = use_facet< - num_put> - >(getloc()).put(*this, *this, fill(), - static_cast(val)).failed(); +bool failed = use_facet>>( + getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} Otherwise, an invocation of the operator function is conditionally supported with \impldef{\tcode{operator<<} for large extended floating-point types} From ddd614210a5e9b72c563001ed3e0419fcedda5e5 Mon Sep 17 00:00:00 2001 From: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:43:53 +0200 Subject: [PATCH 55/95] [ostream.inserters.arithmetic] Fix indentation --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index c62378a9e0..80a58115aa 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -6433,7 +6433,7 @@ the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( - getloc()).put(*this, *this, fill(), val).failed(); + getloc()).put(*this, *this, fill(), val).failed(); \end{codeblock} When \tcode{val} is of type From 70954edf0b2c915d9b2ca4a1cff99b1c1cba2089 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Tue, 1 Oct 2024 23:09:04 -0400 Subject: [PATCH 56/95] [depr.lit] Fix grammar according to P2361R6 P2361R6 introduced the notion of unevaluated strings, and updated the grammar for literal operator function accodingly. Unfortunely, the corresponding grammar reference that was deprecated was not similarly updated. --- source/future.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/future.tex b/source/future.tex index fbf49b4ee2..a16d108869 100644 --- a/source/future.tex +++ b/source/future.tex @@ -171,7 +171,7 @@ \pnum A \grammarterm{literal-operator-id}\iref{over.literal} of the form \begin{codeblock} -operator @\grammarterm{string-literal}@ @\grammarterm{identifier}@ +operator @\grammarterm{unevaluated-string}@ @\grammarterm{identifier}@ \end{codeblock} is deprecated. From 2920badb0e092c24039d4c00d7a8e921737ed889 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Fri, 4 Oct 2024 13:03:22 +0400 Subject: [PATCH 57/95] [check] Improve the error message for comment misalignment (#7285) State explicitly that multiple of 4 is expected. --- tools/check-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check-source.sh b/tools/check-source.sh index 5ddbdf9dfc..e3cf49d72c 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -170,7 +170,7 @@ for f in $texfiles; do sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | awk '{ match($0,"^[-a-z0-9]*[.]tex:[0-9]*:"); n=match(substr($0,RLENGTH+1),"[ ;]//"); if (n % 4 != 0) print "comment starts in column " n ": " $0; }' done | - fail "comment not aligned" || failed=1 + fail "comment not aligned to multiple of 4" || failed=1 # Deleted special member function with a parameter name. grep -n "&[ 0-9a-z_]\+) = delete" $texfiles | From 08b167d5476c9fd02a7a0484ae031cb358a99ddf Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sat, 5 Oct 2024 22:24:02 +0100 Subject: [PATCH 58/95] [priqueue.cons.alloc] Add missing initialization for comp (#7291) This is consistent with p2 and p8 which also value-initialize it. --- source/containers.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index e1f5d9df96..1b77bf8b45 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15285,8 +15285,9 @@ \pnum \effects Initializes -\tcode{c} with \tcode{ranges::to(std::forward(rg), a)}; -calls \tcode{make_heap(c.\linebreak begin(), c.end(), comp)}. +\tcode{c} with \tcode{ranges::to(std::forward(rg), a)} +and value-initializes \tcode{comp}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. \end{itemdescr} \rSec3[priqueue.members]{Members} From 738b14f990e0575a3ca63b579d87edb5a6133ffb Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 5 Oct 2024 15:03:04 -0700 Subject: [PATCH 59/95] [array.creation] Clarify "Mandates" for `to_array` overloads (#7286) It's confusing that these `to_array` overloads require `T` to be constructible from various types, when they actually construct `remove_cv_t` objects. We experts know that initialization doesn't depend on the cv-qualification of the target type ([dcl.init.general]/16), but there's no need to make readers jump through hoops to understand the spec. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 1b77bf8b45..df5bee11ba 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6460,7 +6460,7 @@ \pnum \mandates \tcode{is_array_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}. +\tcode{is_constructible_v, T\&>} is \tcode{true}. \pnum \expects @@ -6481,7 +6481,7 @@ \pnum \mandates \tcode{is_array_v} is \tcode{false} and -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v, T>} is \tcode{true}. \pnum \expects From d5c9f2d248860e8e7de78f595b93a8b01c7e02c8 Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Tue, 8 Oct 2024 21:07:48 +1030 Subject: [PATCH 60/95] [exec.split,exec.when.all] Fix typo stop_callback_of_t -> stop_callback_for_t (#7295) --- source/exec.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 2b9c50a4eb..da4dec96b8 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -3690,7 +3690,7 @@ template struct @\exposid{local-state}@ : @\exposid{local-state-base}@ { // \expos using @\exposid{on-stop-callback}@ = // \expos - stop_callback_of_t>, @\exposid{on-stop-request}@>; + stop_callback_for_t>, @\exposid{on-stop-request}@>; @\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept; ~@\exposid{local-state}@(); @@ -4126,7 +4126,7 @@ auto operator()(auto, auto, Sndrs&&... sndrs) const { using values_tuple = @\seebelow@; using errors_variant = @\seebelow@; - using stop_callback = stop_callback_of_t>, @\exposid{on-stop-request}@>; + using stop_callback = stop_callback_for_t>, @\exposid{on-stop-request}@>; struct @\exposid{state-type}@ { void @\exposid{arrive}@(Rcvr& rcvr) noexcept { // \expos From 58c01ba5765e8c91ce4aab462d25247167a7e481 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 8 Oct 2024 11:38:42 +0100 Subject: [PATCH 61/95] [re.grammar] Add missing backslash to UnicodeEscapeSequence example (#7290) --- source/regex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/regex.tex b/source/regex.tex index a4422ef8ef..fd6292e34e 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -3929,7 +3929,7 @@ 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{"uxxxx"} that do not fit in +This means that values of the form \tcode{"\textbackslash{}uxxxx"} that do not fit in a character are invalid. \end{note} From aa62b377e85e3ea11ac99049123a3d50c4fc0cc7 Mon Sep 17 00:00:00 2001 From: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> Date: Tue, 8 Oct 2024 12:39:37 +0200 Subject: [PATCH 62/95] [optional.optional.general] Fix whitespace around pointer declarator (#7289) --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index ced6ebc2e4..caabf2ff35 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -3335,7 +3335,7 @@ constexpr void reset() noexcept; private: - T *val; // \expos + T* val; // \expos }; template From ebef68dd9f1c3bccfe06d14eb83c05a7a35dcec3 Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Tue, 8 Oct 2024 22:06:23 +1030 Subject: [PATCH 63/95] [exec.just] Add missing LaTeX escape for product-type construction (#7216) --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index da4dec96b8..28fa001a5d 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -2583,7 +2583,7 @@ \end{itemize} Otherwise, it is expression-equivalent to -\tcode{\exposid{make-sender}(\exposid{just-cpo}, \exposid{product-type}{ts...})}. +\tcode{\exposid{make-sender}(\exposid{just-cpo}, \exposid{product-type}\{ts...\})}. For \tcode{just}, \tcode{just_error}, and \tcode{just_stopped}, let \exposid{set-cpo} be From f72d8a11f480c3e06c4387527e597cf0e86a2e91 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Tue, 8 Oct 2024 16:28:47 -0400 Subject: [PATCH 64/95] [container.adaptors] Index missing members of the flat containers (#7288) --- source/containers.tex | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index df5bee11ba..6983fbbe7f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -122,6 +122,10 @@ \indexlibrarymemberx{unordered_set}{#1}% \indexlibrarymemberx{unordered_multiset}{#1}% \indexlibrarymemberx{unordered_multimap}{#1}% +\indexlibrarymemberx{flat_map}{#1}% +\indexlibrarymemberx{flat_set}{#1}% +\indexlibrarymemberx{flat_multiset}{#1}% +\indexlibrarymemberx{flat_multimap}{#1}% } \pnum @@ -733,6 +737,10 @@ \indexlibrarymemberx{unordered_set}{#1}% \indexlibrarymemberx{unordered_multiset}{#1}% \indexlibrarymemberx{unordered_multimap}{#1}% +\indexlibrarymemberx{flat_map}{#1}% +\indexlibrarymemberx{flat_set}{#1}% +\indexlibrarymemberx{flat_multiset}{#1}% +\indexlibrarymemberx{flat_multimap}{#1}% } \pnum @@ -2747,6 +2755,10 @@ \indexlibrary{\idxcode{map}!\idxcode{#1}}% \indexlibrary{\idxcode{multiset}!\idxcode{#1}}% \indexlibrary{\idxcode{multimap}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_set}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_map}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_multiset}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_multimap}!\idxcode{#1}}% } \indexordmem{key_type}% @@ -18039,7 +18051,7 @@ whose key is equivalent to \tcode{x}. \end{itemdescr} -\indexlibrarymember{insert}{flatset}% +\indexlibrarymember{insert}{flat_set}% \begin{itemdecl} template void insert(InputIterator first, InputIterator last); @@ -18132,7 +18144,7 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{extract}{flatset}% +\indexlibrarymember{extract}{flat_set}% \begin{itemdecl} container_type extract() &&; \end{itemdecl} From dec596a84e9fa1438c59aae9c60237e84af01509 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 10 Oct 2024 17:53:30 +0800 Subject: [PATCH 65/95] [mdspan.mdspan.overview] Fix misplacing for `\exposid` and `.` --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 6983fbbe7f..6f09c21908 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -23238,7 +23238,7 @@ constexpr bool is_exhaustive() const { return @\exposid{map_}@.is_exhaustive(); } constexpr bool is_strided() const - { return @\exposid{map_.}@is_strided(); } + { return @\exposid{map_}@.is_strided(); } constexpr index_type stride(rank_type r) const { return @\exposid{map_}@.stride(r); } From 7ea8f59e19842e720360f15b64c2199ea27641ac Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 10 Oct 2024 17:53:54 +0800 Subject: [PATCH 66/95] [mutex.syn] Add missing ',' for consistency --- source/threads.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/threads.tex b/source/threads.tex index 48711723b1..9686dea66a 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -6456,7 +6456,7 @@ class mutex; // \ref{thread.mutex.recursive}, class \tcode{recursive_mutex} class recursive_mutex; - // \ref{thread.timedmutex.class} class \tcode{timed_mutex} + // \ref{thread.timedmutex.class}, class \tcode{timed_mutex} class timed_mutex; // \ref{thread.timedmutex.recursive}, class \tcode{recursive_timed_mutex} class recursive_timed_mutex; From 7c6322a59e3359c5002357831328b25939cd5383 Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Sun, 13 Oct 2024 04:07:30 +1030 Subject: [PATCH 67/95] [stoptoken.concepts] Remove redundant 'swappable' clause from 'stoppable_token' concept (#7299) The `stoppable_token` concept requires both `copyable` and `swappable`. However, the `copyable` requirement already subsumes `movable`, which subsumes `swappable`. Therefore the requirement for `swappable` can be removed from the `stoppable_token` concept definition with no semantic change. --- source/threads.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index 9686dea66a..d116de9da3 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -692,8 +692,7 @@ { Token(tok) } noexcept; // see implicit expression variations\iref{concepts.equality} } && @\libconcept{copyable}@ && - @\libconcept{equality_comparable}@ && - @\libconcept{swappable}@; + @\libconcept{equality_comparable}@; template concept @\deflibconcept{unstoppable_token}@ = From 9bf42221ab5a52ef10cb980a22e8a9617dbbf18b Mon Sep 17 00:00:00 2001 From: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> Date: Sat, 12 Oct 2024 22:39:57 +0200 Subject: [PATCH 68/95] [rcu.syn] Add missing ',' in comment (#7301) --- source/threads.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/threads.tex b/source/threads.tex index d116de9da3..cb0f99e12a 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -12194,7 +12194,7 @@ // \ref{saferecl.rcu.domain}, class \tcode{rcu_domain} class rcu_domain; - // \ref{saferecl.rcu.domain.func} non-member functions + // \ref{saferecl.rcu.domain.func}, non-member functions rcu_domain& rcu_default_domain() noexcept; void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept; void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept; From a0411db859cf1eabc2be24a5d2add4eaf288dac5 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 14 Oct 2024 12:30:30 +0200 Subject: [PATCH 69/95] [expr.const] Add paragraph number for general example --- source/expressions.tex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/expressions.tex b/source/expressions.tex index 389ac435b8..dc4d781ef6 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7749,6 +7749,8 @@ would disqualify $E$ from being a core constant expression. \end{note} \end{itemize} + +\pnum \begin{example} \begin{codeblock} int x; // not constant From 3982d5d5758df949e3c2e0174c72758189be6f2e Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Mon, 14 Oct 2024 08:54:22 -0400 Subject: [PATCH 70/95] [except.ctor] Retitle subclause as 'stack unwinding' (#7282) The purpose of this subclause is to define stack unwinding, which in specified in terms of the lifetime of objects, not just class types. Hence, while much of the text is addressing interactions with contructors and destructors (the original subclause title) it does more than just that. --- source/exceptions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 67e052c476..183eec2abd 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -359,7 +359,7 @@ \end{note} -\rSec1[except.ctor]{Constructors and destructors}% +\rSec1[except.ctor]{Stack unwinding}% \indextext{exception handling!constructors and destructors}% \indextext{constructor!exception handling|see{exception handling, constructors and destructors}}% \indextext{destructor!exception handling|see{exception handling, constructors and destructors}} From 555f3c34d2d915ba033c5e5abcfcc7d4ba2f467f Mon Sep 17 00:00:00 2001 From: Lewis Baker Date: Wed, 16 Oct 2024 00:41:00 +1030 Subject: [PATCH 71/95] [exec.snd.expos] Add '\exposid' for exposition-only identifiers in basic-state constructor (#7304) --- source/exec.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 28fa001a5d..8608dd9624 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1618,8 +1618,8 @@ template struct @\exposid{basic-state}@ { // \expos @\exposid{basic-state}@(Sndr&& sndr, Rcvr&& rcvr) noexcept(@\seebelow@) - : rcvr(std::move(rcvr)) - , state(@\exposid{impls-for}@>::@\exposid{get-state}@(std::forward(sndr), rcvr)) { } + : @\exposid{rcvr}@(std::move(rcvr)) + , @\exposid{state}@(@\exposid{impls-for}@>::@\exposid{get-state}@(std::forward(sndr), @\exposid{rcvr}@)) { } Rcvr @\exposid{rcvr}@; // \expos @\exposid{state-type}@ @\exposid{state}@; // \expos From 4eb30d3d618ef44ae3925a1a62090bbbbfe8cabf Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Wed, 16 Oct 2024 07:39:15 -0400 Subject: [PATCH 72/95] [cpp.subst] change "proprocessing file" to "translation unit" (#7293) The term 'preprocessing translation unit' is defined in [lex.separate] while the term 'preprocessing file' is never defined, and is not used anywhere else in the standard. Prefer to use the specified term, as it reasonably covers this case. --- source/preprocessor.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 2b9e3e7e05..02803cd469 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1215,7 +1215,7 @@ macros contained therein have been expanded. The argument's preprocessing tokens are completely macro replaced before being substituted as if they formed the rest of the preprocessing - file with no other preprocessing tokens being available. + tranlation unit with no other preprocessing tokens being available. \end{itemize} \begin{example} \begin{codeblock} From 40228c690cb8d2ac27bd54bdddeabe425bd022b2 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Wed, 16 Oct 2024 07:40:20 -0400 Subject: [PATCH 73/95] [cpp.import] Change "directive" to "definition" in "active macro directive" (#7292) The term 'active macro directive' is defined in p6, but never used. Meanwhile, there are multiple uses of 'active macro definition' but that term is never defined, including in the very sentence following the definition of the unused term, and in other clauses that cross-reference to this clause for their definition. --- source/preprocessor.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 02803cd469..0d50198e26 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -912,8 +912,8 @@ \end{itemize} \pnum -\indextext{active macro directive|see{macro, active}}% -A macro directive is \defnx{active}{macro!active} at a source location +\indextext{active macro definition|see{macro, active}}% +A macro definition is \defnx{active}{macro!active} at a source location if it has a point of definition in that translation unit preceding the location, and does not have a point of undefinition in that translation unit preceding the location. From 47da0e8b88bf1aa20aa474edf04a6d29e70b7563 Mon Sep 17 00:00:00 2001 From: Anders Schau Knatten Date: Wed, 16 Oct 2024 13:41:26 +0200 Subject: [PATCH 74/95] [over.oper.general] Change "basic type" to "fundamental type" (#7287) The term "basic type" is used twice in this note but it's never defined anywhere, nor used. --- source/overloading.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index d7cac76f7c..fb40049638 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -3380,14 +3380,14 @@ \pnum \indextext{operator}% \begin{note} -The identities among certain predefined operators applied to basic types +The identities among certain predefined operators applied to fundamental types (for example, \tcode{++a} $\equiv$ \tcode{a+=1}) need not hold for operator functions. Some predefined operators, such as \tcode{+=}, -require an operand to be an lvalue when applied to basic types; +require an operand to be an lvalue when applied to fundamental types; this is not required by operator functions. \end{note} From 7fe7519a5af674cd914344c650529f743fd92fc2 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Tue, 1 Oct 2024 22:13:53 -0400 Subject: [PATCH 75/95] [except.handle] Remove confusing comparison to variadic functions The analogy that the ellipsis in an exception handler was similar to an ellipsis in a function declaration may have made sense at one time, but the comparison with a syntax using a macro based API calling 'va_arg' to access its contents --- something that is not possible for an exception handler --- seems more confusing than helpful today. --- source/exceptions.tex | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 183eec2abd..8b6b62d651 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -604,10 +604,7 @@ \tcode{...} in a handler's \grammarterm{exception-declaration} -functions similarly to -\tcode{...} -in a function parameter declaration; -it specifies a match for any exception. +specifies a match for any exception. If present, a \tcode{...} handler shall be the last handler for its try block. From d225f51f8cb799fb014cb73beb7dcccc044392cc Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 20 Aug 2024 11:58:24 +0100 Subject: [PATCH 76/95] [text.encoding.aliases] Add note about what isn't required Make it explicit that `copyable` is intended, rather than `semiregular`, and that the return types of `begin()` and `end()` can differ. Also remove a FIXME comment for something that doesn't need fixing. These requirements on a type are specified in our usual form, it would be wrong to use _Remarks_: or _Requires_: here. --- source/locales.tex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/locales.tex b/source/locales.tex index 756cb9327d..a791026f92 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -5063,6 +5063,11 @@ \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 @@ -5071,7 +5076,6 @@ denote \tcode{const char*}. \pnum -%FIXME: Is this supposed to be a remark or a requirement? Same above? \tcode{ranges::iterator_t} is a constexpr iterator\iref{iterator.requirements.general}. \end{itemdescr} From 6338d95ae620f5e4d37d27a39a40f9de9af37b77 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Wed, 16 Oct 2024 08:47:02 -0400 Subject: [PATCH 77/95] [lex.charset] Introduce parent subclause [lex.char] for character sets and UCNs (#7067) The grammar for universal-character-name is oddly sandwiched into the middle of the subclause talking about the different character sets used by the standard. To improve the flow, extract that grammar into its own subclause. In the extraction, I make three other clarifying changes. First, describe this new subclause as 'a way to name any element of the of the translation character set using just the basic character set' rather than simply 'a way to name other characters'. Then, merge the sentence on where universal characters are prohibited into the new intro sentence describing universal characters, to make clear that there is no contradiction between nominating a character, and how that character can be used. Finally, remove the 'one of' in the grammar where there is only one option to choose. --- source/lex.tex | 158 +++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 78 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index adb82aa862..45d30ff62a 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -249,7 +249,9 @@ \indextext{translation!phases|)} \end{enumerate} -\rSec1[lex.charset]{Character sets} +\rSec1[lex.char]{Characters}% + +\rSec2[lex.charset]{Character sets} \pnum \indextext{character set|(}% @@ -326,11 +328,69 @@ \end{floattable} \pnum -The \grammarterm{universal-character-name} construct provides a way to name -other characters. +The \defnadj{basic literal}{character set} consists of +all characters of the basic character set, +plus the control characters specified in \tref{lex.charset.literal}. + +\begin{floattable}{Additional control characters in the basic literal character set}{lex.charset.literal}{ll} +\topline +\ohdrx{2}{character} \\ \capsep +\ucode{0000} & \uname{null} \\ +\ucode{0007} & \uname{alert} \\ +\ucode{0008} & \uname{backspace} \\ +\ucode{000d} & \uname{carriage return} \\ +\end{floattable} + +\pnum +A \defn{code unit} is an integer value +of character type\iref{basic.fundamental}. +Characters in a \grammarterm{character-literal} +other than a multicharacter or non-encodable character literal or +in a \grammarterm{string-literal} are encoded as +a sequence of one or more code units, as determined +by the \grammarterm{encoding-prefix}\iref{lex.ccon,lex.string}; +this is termed the respective \defnadj{literal}{encoding}. +The \defnadj{ordinary literal}{encoding} is +the encoding applied to an ordinary character or string literal. +The \defnadj{wide literal}{encoding} is the encoding applied +to a wide character or string literal. + +\pnum +A literal encoding or a locale-specific encoding of one of +the execution character sets\iref{character.seq} +encodes each element of the basic literal character set as +a single code unit with non-negative value, +distinct from the code unit for any other such element. +\begin{note} +A character not in the basic literal character set +can be encoded with more than one code unit; +the value of such a code unit can be the same as +that of a code unit for an element of the basic literal character set. +\end{note} +\indextext{character!null}% +\indextext{wide-character!null}% +The \unicode{0000}{null} character is encoded as the value \tcode{0}. +No other element of the translation character set +is encoded with a code unit of value \tcode{0}. +The code unit value of each decimal digit character after the digit \tcode{0} (\ucode{0030}) +shall be one greater than the value of the previous. +The ordinary and wide literal encodings are otherwise +\impldef{ordinary and wide literal encodings}. +\indextext{UTF-8}% +\indextext{UTF-16}% +\indextext{UTF-32}% +For a UTF-8, UTF-16, or UTF-32 literal, +the implementation shall encode +the Unicode scalar value +corresponding to each character of the translation character set +as specified in the Unicode Standard +for the respective Unicode encoding form. +\indextext{character set|)} + +\rSec2[lex.universal.char]{Universal character names} \begin{bnf} -\nontermdef{n-char} \textnormal{one of}\br +\nontermdef{n-char}\br \textnormal{any member of the translation character set except the \unicode{007d}{right curly bracket} or new-line character} \end{bnf} @@ -364,6 +424,22 @@ named-universal-character \end{bnf} +\pnum +The \grammarterm{universal-character-name} construct provides a way to name any +element in the translation character set using just the basic character set. +If a \grammarterm{universal-character-name} outside +the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or +\grammarterm{r-char-sequence} of a \grammarterm{character-literal} or +\grammarterm{string-literal} +(in either case, including within a \grammarterm{user-defined-literal}) +corresponds to a control character or to a character in the basic character set, +the program is ill-formed. +\begin{note} +A sequence of characters resembling a \grammarterm{universal-character-name} in an +\grammarterm{r-char-sequence}\iref{lex.string} does not form a +\grammarterm{universal-character-name}. +\end{note} + \pnum A \grammarterm{universal-character-name} of the form \tcode{\textbackslash u} \grammarterm{hex-quad}, @@ -391,80 +467,6 @@ None of these names or aliases have leading or trailing spaces. \end{note} -\pnum -If a \grammarterm{universal-character-name} outside -the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or -\grammarterm{r-char-sequence} of -a \grammarterm{character-literal} or \grammarterm{string-literal} -(in either case, including within a \grammarterm{user-defined-literal}) -corresponds to a control character or -to a character in the basic character set, the program is ill-formed. -\begin{note} -A sequence of characters resembling a \grammarterm{universal-character-name} in an -\grammarterm{r-char-sequence}\iref{lex.string} does not form a -\grammarterm{universal-character-name}. -\end{note} - -\pnum -The \defnadj{basic literal}{character set} consists of -all characters of the basic character set, -plus the control characters specified in \tref{lex.charset.literal}. - -\begin{floattable}{Additional control characters}{lex.charset.literal}{ll} -\topline -\ohdrx{2}{character} \\ \capsep -\ucode{0000} & \uname{null} \\ -\ucode{0007} & \uname{alert} \\ -\ucode{0008} & \uname{backspace} \\ -\ucode{000d} & \uname{carriage return} \\ -\end{floattable} - -\pnum -A \defn{code unit} is an integer value -of character type\iref{basic.fundamental}. -Characters in a \grammarterm{character-literal} -other than a multicharacter or non-encodable character literal or -in a \grammarterm{string-literal} are encoded as -a sequence of one or more code units, as determined -by the \grammarterm{encoding-prefix}\iref{lex.ccon,lex.string}; -this is termed the respective \defnadj{literal}{encoding}. -The \defnadj{ordinary literal}{encoding} is -the encoding applied to an ordinary character or string literal. -The \defnadj{wide literal}{encoding} is the encoding applied -to a wide character or string literal. - -\pnum -A literal encoding or a locale-specific encoding of one of -the execution character sets\iref{character.seq} -encodes each element of the basic literal character set as -a single code unit with non-negative value, -distinct from the code unit for any other such element. -\begin{note} -A character not in the basic literal character set -can be encoded with more than one code unit; -the value of such a code unit can be the same as -that of a code unit for an element of the basic literal character set. -\end{note} -\indextext{character!null}% -\indextext{wide-character!null}% -The \unicode{0000}{null} character is encoded as the value \tcode{0}. -No other element of the translation character set -is encoded with a code unit of value \tcode{0}. -The code unit value of each decimal digit character after the digit \tcode{0} (\ucode{0030}) -shall be one greater than the value of the previous. -The ordinary and wide literal encodings are otherwise -\impldef{ordinary and wide literal encodings}. -\indextext{UTF-8}% -\indextext{UTF-16}% -\indextext{UTF-32}% -For a UTF-8, UTF-16, or UTF-32 literal, -the implementation shall encode -the Unicode scalar value -corresponding to each character of the translation character set -as specified in the Unicode Standard -for the respective Unicode encoding form. -\indextext{character set|)} - \rSec1[lex.pptoken]{Preprocessing tokens} \indextext{token!preprocessing|(}% From 9b6b757f34bf4a1eeb6a66481a444b83f1ee5770 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Thu, 12 Sep 2024 21:41:02 +0200 Subject: [PATCH 78/95] [sf.cmath.assoc.laguerre,sf.cmath.assoc.legendre] Add reference to eq The associated Laguerre/Legendre functions build on the Laguerre/Legendre functions, which are defined in different equations. Point to them from the associated functions. Also use the correct \ell as used in the formula. --- source/numerics.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index 7ae38cf805..e8afb21e09 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -9951,6 +9951,7 @@ \returns $\mathsf{L}_n^m(x)$, where $\mathsf{L}_n^m$ is given by \eqref{sf.cmath.assoc.laguerre}, +$\mathsf{L}_{n+m}$ is given by \eqref{sf.cmath.laguerre}, $n$ is \tcode{n}, $m$ is \tcode{m}, and $x$ is \tcode{x}. @@ -9992,7 +9993,8 @@ \returns $\mathsf{P}_\ell^m(x)$, where $\mathsf{P}_\ell^m$ is given by \eqref{sf.cmath.assoc.legendre}, -$l$ is \tcode{l}, +$\mathsf{P}_\ell$ is given by \eqref{sf.cmath.legendre}, +$\ell$ is \tcode{l}, $m$ is \tcode{m}, and $x$ is \tcode{x}. \begin{formula}{sf.cmath.assoc.legendre} From 0456a32e41772b0a68b4055fb4e6533cb64e0e3d Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Thu, 5 Sep 2024 23:59:58 +0800 Subject: [PATCH 79/95] [utility.syn, flat.map.defn] Remove all [[nodiscard]] from library wording --- source/containers.tex | 12 ++++++------ source/utilities.tex | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 6f09c21908..1c8f212ec3 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16012,7 +16012,7 @@ const_reverse_iterator crend() const noexcept; // \ref{flat.map.capacity}, capacity - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -17200,7 +17200,7 @@ const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -17756,7 +17756,7 @@ const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -18419,7 +18419,7 @@ const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -23217,7 +23217,7 @@ constexpr reference operator[](const array& indices) const; constexpr size_type size() const noexcept; - [[nodiscard]] constexpr bool empty() const noexcept; + constexpr bool empty() const noexcept; friend constexpr void swap(mdspan& x, mdspan& y) noexcept; @@ -23683,7 +23683,7 @@ \indexlibrarymember{empty}{mdspan}% \begin{itemdecl} -[[nodiscard]] constexpr bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} diff --git a/source/utilities.tex b/source/utilities.tex index caabf2ff35..a461128eae 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -58,7 +58,7 @@ template constexpr T&& forward(remove_reference_t&& t) noexcept; template - [[nodiscard]] constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; + constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; template constexpr remove_reference_t&& move(T&&) noexcept; template From 8b2c7fc3c58bd109c82a016ee2cc5b691bdcd853 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Mon, 10 Jun 2024 23:22:04 +0200 Subject: [PATCH 80/95] [expr.new] Extend example for new-expressions with zero size arrays --- source/expressions.tex | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/expressions.tex b/source/expressions.tex index dc4d781ef6..1cf4411103 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -5315,6 +5315,15 @@ \grammarterm{expression} of a \grammarterm{noptr-new-declarator}), but \tcode{new float[5][n]} is ill-formed (because \tcode{n} is not a constant expression). +Furthermore, +\tcode{new float[0]} is well-formed +(because \tcode{0} is the \grammarterm{expression} +of a \grammarterm{noptr-new-declarator}, +where a value of zero results in the allocation of an array with no elements), +but \tcode{new float[n][0]} is ill-formed +(because \tcode{0} is the \grammarterm{constant-expression} +of a \grammarterm{noptr-new-declarator}, +where only values greater than zero are allowed). \end{example} \pnum From fb34daf31b53389cc35b3f5f65a69785fc6dd1de Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Tue, 23 Jul 2024 22:32:52 -0400 Subject: [PATCH 81/95] [char.traits] Better cross-reference several headers --- source/strings.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/strings.tex b/source/strings.tex index 2dd8539b35..32d5f1a9fa 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -201,7 +201,7 @@ \begin{codeblock} template struct char_traits; \end{codeblock} -is provided in the header \libheader{string} +is provided in the header \libheaderref{string} as a basis for explicit specializations. \rSec2[char.traits.typedefs]{Traits typedefs} @@ -307,7 +307,7 @@ \end{codeblock} \pnum -The type \tcode{mbstate_t} is defined in \libheader{cwchar} +The type \tcode{mbstate_t} is defined in \libheaderref{cwchar} and can represent any of the conversion states that can occur in an \impldef{supported multibyte character encoding rules} set of supported multibyte character encoding rules. From 220cb742e8056ad033ad8dce5630d7d3acaa4c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 15:37:39 +0100 Subject: [PATCH 82/95] [debugging] Move [debugging] to the end of Clause [diagnostics] Part of the C++26 clause restructuring (#5315). --- source/diagnostics.tex | 96 ++++++++++++++++++++++++++++++++++++++++- source/utilities.tex | 98 +----------------------------------------- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 573b268371..ef695fddef 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -20,7 +20,8 @@ \ref{assertions} & Assertions & \tcode{} \\ \rowsep \ref{errno} & Error numbers & \tcode{} \\ \rowsep \ref{syserr} & System error support & \tcode{} \\ \rowsep -\ref{stacktrace} & Stacktrace & \tcode{} \\ +\ref{stacktrace} & Stacktrace & \tcode{} \\ \rowsep +\ref{debugging} & Debugging & \tcode{} \\ \end{libsumtab} \rSec1[std.exceptions]{Exception classes} @@ -2485,3 +2486,96 @@ \pnum The specializations are enabled\iref{unord.hash}. \end{itemdescr} + +\rSec1[debugging]{Debugging} + +\rSec2[debugging.general]{General} + +\pnum +Subclause \ref{debugging} describes functionality to introspect and +interact with the execution of the program. + +\begin{note} +The facilities provided by the debugging functionality interact with a program +that could be tracing the execution of a \Cpp{} program, such as a debugger. +\end{note} + +\rSec2[debugging.syn]{Header \tcode{} synopsis} + +\indexheader{debugging}% +\begin{codeblock} +// all freestanding +namespace std { + // \ref{debugging.utility}, utility + void breakpoint() noexcept; + void breakpoint_if_debugging() noexcept; + bool is_debugger_present() noexcept; +} +\end{codeblock} + +\rSec2[debugging.utility]{Utility} + +\indexlibraryglobal{breakpoint}% +\begin{itemdecl} +void breakpoint() noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +The semantics of this function are \impldef{semantics of \tcode{breakpoint}}. + +\begin{note} +When invoked, the execution of the program temporarily halts and execution is +handed to the debugger until such a time as: The program is terminated by the +debugger, or the debugger resumes execution of the program as if the function +was not invoked. +\end{note} + +\end{itemdescr} + +\indexlibraryglobal{breakpoint_if_debugging}% +\begin{itemdecl} +void breakpoint_if_debugging() noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (is_debugger_present()) breakpoint(); +\end{codeblock} + +\end{itemdescr} + +\indexlibraryglobal{is_debugger_present}% +\begin{itemdecl} +bool is_debugger_present() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\replaceable +A \Cpp{} program may define a function with this function signature, and +thereby displace the default version defined by the \Cpp{} standard library. + +\pnum +\required +This function has no preconditions. + +\pnum +\default +\impldef{default semantics of \tcode{is_debugger_present}}. + +\begin{note} +When tracing the execution of a program with a debugger, an implementation +returns \tcode{true}. An implementation performs an immediate query, as needed, +to determine if the program is traced by a debugger. On Windows or equivalent +systems, this can be achieved by calling the \tcode{::IsDebuggerPresent()} Win32 +function. On POSIX, this can be achieved by checking for a tracer parent process, +with best effort determination that such a tracer parent process is a debugger. +\end{note} + +\end{itemdescr} diff --git a/source/utilities.tex b/source/utilities.tex index a461128eae..d23b7d3e3d 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -11,7 +11,7 @@ \begin{libsumtab}{General utilities library summary}{utilities.summary} \ref{utility} & Utility components & \tcode{} \\ -\ref{pairs} & Pairs & \\ \rowsep +\ref{pairs} & Pairs & \\ \rowsep \ref{tuple} & Tuples & \tcode{} \\ \rowsep \ref{optional} & Optional objects & \tcode{} \\ \rowsep \ref{variant} & Variants & \tcode{} \\ \rowsep @@ -23,8 +23,7 @@ \ref{execpol} & Execution policies & \tcode{} \\ \rowsep \ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep \ref{format} & Formatting & \tcode{} \\ \rowsep -\ref{bit} & Bit manipulation & \tcode{} \\ \rowsep -\ref{debugging} & Debugging & \tcode{} \\ +\ref{bit} & Bit manipulation & \tcode{} \\ \end{libsumtab} \rSec1[utility]{Utility components} @@ -19433,96 +19432,3 @@ Otherwise, \tcode{endian::native} is not equal to either \tcode{endian::big} or \tcode{endian::little}. \end{itemdescr} - -\rSec1[debugging]{Debugging} - -\rSec2[debugging.general]{General} - -\pnum -Subclause \ref{debugging} describes functionality to introspect and -interact with the execution of the program. - -\begin{note} -The facilities provided by the debugging functionality interact with a program -that could be tracing the execution of a \Cpp{} program, such as a debugger. -\end{note} - -\rSec2[debugging.syn]{Header \tcode{} synopsis} - -\indexheader{debugging}% -\begin{codeblock} -// all freestanding -namespace std { - // \ref{debugging.utility}, utility - void breakpoint() noexcept; - void breakpoint_if_debugging() noexcept; - bool is_debugger_present() noexcept; -} -\end{codeblock} - -\rSec2[debugging.utility]{Utility} - -\indexlibraryglobal{breakpoint}% -\begin{itemdecl} -void breakpoint() noexcept; -\end{itemdecl} - -\begin{itemdescr} - -\pnum -The semantics of this function are \impldef{semantics of \tcode{breakpoint}}. - -\begin{note} -When invoked, the execution of the program temporarily halts and execution is -handed to the debugger until such a time as: The program is terminated by the -debugger, or the debugger resumes execution of the program as if the function -was not invoked. -\end{note} - -\end{itemdescr} - -\indexlibraryglobal{breakpoint_if_debugging}% -\begin{itemdecl} -void breakpoint_if_debugging() noexcept; -\end{itemdecl} - -\begin{itemdescr} - -\pnum -\effects -Equivalent to: -\begin{codeblock} -if (is_debugger_present()) breakpoint(); -\end{codeblock} - -\end{itemdescr} - -\indexlibraryglobal{is_debugger_present}% -\begin{itemdecl} -bool is_debugger_present() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\replaceable -A \Cpp{} program may define a function with this function signature, and -thereby displace the default version defined by the \Cpp{} standard library. - -\pnum -\required -This function has no preconditions. - -\pnum -\default -\impldef{default semantics of \tcode{is_debugger_present}}. - -\begin{note} -When tracing the execution of a program with a debugger, an implementation -returns \tcode{true}. An implementation performs an immediate query, as needed, -to determine if the program is traced by a debugger. On Windows or equivalent -systems, this can be achieved by calling the \tcode{::IsDebuggerPresent()} Win32 -function. On POSIX, this can be achieved by checking for a tracer parent process, -with best effort determination that such a tracer parent process is a debugger. -\end{note} - -\end{itemdescr} From 7a2dafa6b4cca842e264bfd544b69452fb448c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 15:43:39 +0100 Subject: [PATCH 83/95] [execpol] Move [execpol] to the end of subclause [algorithms.parallel] Part of the C++26 clause restructuring (#5315). --- source/algorithms.tex | 175 +++++++++++++++++++++++++++++++++++++++++- source/utilities.tex | 167 ---------------------------------------- 2 files changed, 171 insertions(+), 171 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 62f32fb35c..a8c3809b34 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -17,15 +17,15 @@ \begin{libsumtab}{Algorithms library summary}{algorithms.summary} \ref{algorithms.requirements} & Algorithms requirements & \\ -\ref{algorithms.parallel} & Parallel algorithms & \\ \rowsep -\ref{algorithms.results} & Algorithm result types & \tcode{} \\ +\ref{algorithms.parallel} & Parallel algorithms & \tcode{} \\ \rowsep +\ref{algorithms.results} & Algorithm result types & \tcode{} \\ \ref{alg.nonmodifying} & Non-modifying sequence operations & \\ \ref{alg.modifying.operations} & Mutating sequence operations & \\ \ref{alg.sorting} & Sorting and related operations & \\ \rowsep -\ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep +\ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep \ref{specialized.algorithms} & Specialized \tcode{} algorithms & \tcode{} \\ \rowsep \ref{alg.rand} & Specialized \tcode{} algorithms & \tcode{} \\ \rowsep -\ref{alg.c.library} & C library algorithms & \tcode{} \\ +\ref{alg.c.library} & C library algorithms & \tcode{} \\ \end{libsumtab} \rSec1[algorithms.requirements]{Algorithms requirements} @@ -620,6 +620,173 @@ Parallel algorithms shall not participate in overload resolution unless \tcode{is_execution_policy_v>} is \tcode{true}. +\rSec2[execpol]{Execution policies} + +\rSec3[execpol.general]{General} + +\pnum +Subclause~\ref{execpol} describes classes that are \defn{execution policy} types. An +object of an execution policy type indicates the kinds of parallelism allowed +in the execution of an algorithm and expresses the consequent requirements on +the element access functions. +Execution policy types are declared in header \libheaderref{execution}. +\begin{example} +\begin{codeblock} +using namespace std; +vector v = @\commentellip@; + +// standard sequential sort +sort(v.begin(), v.end()); + +// explicitly sequential sort +sort(execution::seq, v.begin(), v.end()); + +// permitting parallel execution +sort(execution::par, v.begin(), v.end()); + +// permitting vectorization as well +sort(execution::par_unseq, v.begin(), v.end()); +\end{codeblock} +\end{example} +\begin{note} +Implementations can provide additional execution policies +to those described in this document as extensions +to address parallel architectures that require idiosyncratic +parameters for efficient execution. +\end{note} + +\rSec3[execpol.type]{Execution policy type trait} + +\indexlibraryglobal{is_execution_policy}% +\begin{itemdecl} +template struct is_execution_policy { @\seebelow@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{is_execution_policy} can be used to detect execution policies for the +purpose of excluding function signatures from otherwise ambiguous overload +resolution participation. + +\pnum +\tcode{is_execution_policy} is a \oldconcept{UnaryTypeTrait} with a +base characteristic of \tcode{true_type} if \tcode{T} is the type of a standard +or \impldef{additional execution policies supported by parallel algorithms} +execution policy, otherwise \tcode{false_type}. + +\begin{note} +This provision reserves the privilege of creating non-standard execution +policies to the library implementation. +\end{note} + +\pnum +The behavior of a program that adds specializations for +\tcode{is_execution_policy} is undefined. +\end{itemdescr} + +\rSec3[execpol.seq]{Sequenced execution policy} + +\indexlibraryglobal{execution::sequenced_policy}% +\begin{itemdecl} +class execution::sequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::sequenced_policy} is an execution policy type used +as a unique type to disambiguate parallel algorithm overloading and require +that a parallel algorithm's execution may not be parallelized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::sequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.par]{Parallel execution policy} + +\indexlibraryglobal{execution::parallel_policy}% +\begin{itemdecl} +class execution::parallel_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::parallel_policy} is an execution policy type used as +a unique type to disambiguate parallel algorithm overloading and indicate that +a parallel algorithm's execution may be parallelized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::parallel_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.parunseq]{Parallel and unsequenced execution policy} + +\indexlibraryglobal{execution::parallel_unsequenced_policy}% +\begin{itemdecl} +class execution::parallel_unsequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::parallel_unsequenced_policy} is an execution policy type +used as a unique type to disambiguate parallel algorithm overloading and +indicate that a parallel algorithm's execution may be parallelized and +vectorized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::parallel_unsequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.unseq]{Unsequenced execution policy} + +\indexlibraryglobal{execution::unsequenced_policy}% +\begin{itemdecl} +class execution::unsequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{unsequenced_policy} is an execution policy type +used as a unique type to disambiguate parallel algorithm overloading and +indicate that a parallel algorithm's execution may be vectorized, +e.g., executed on a single thread using instructions +that operate on multiple data items. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::unsequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.objects]{Execution policy objects} + +\indexlibraryglobal{seq}% +\indexlibraryglobal{par}% +\indexlibraryglobal{par_unseq}% +\indexlibrarymember{execution}{seq}% +\indexlibrarymember{execution}{par}% +\indexlibrarymember{execution}{par_unseq}% +\begin{itemdecl} +inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; +inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; +inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; +inline constexpr execution::unsequenced_policy execution::unseq{ @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The header \libheaderref{execution} declares global objects associated with each type of execution policy. +\end{itemdescr} + \rSec1[algorithm.syn]{Header \tcode{} synopsis} \indexheader{algorithm}% diff --git a/source/utilities.tex b/source/utilities.tex index d23b7d3e3d..ec98bef1df 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -20,7 +20,6 @@ \ref{bitset} & Fixed-size sequences of bits & \tcode{} \\ \rowsep \ref{function.objects} & Function objects & \tcode{} \\ \rowsep \ref{type.index} & Type indexes & \tcode{} \\ \rowsep -\ref{execpol} & Execution policies & \tcode{} \\ \rowsep \ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep \ref{format} & Formatting & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ @@ -15216,172 +15215,6 @@ \tcode{hash()(index)} shall evaluate to the same result as \tcode{index.hash_code()}. \end{itemdescr} -\rSec1[execpol]{Execution policies} -\rSec2[execpol.general]{General} - -\pnum -Subclause~\ref{execpol} describes classes that are \defn{execution policy} types. An -object of an execution policy type indicates the kinds of parallelism allowed -in the execution of an algorithm and expresses the consequent requirements on -the element access functions. -Execution policy types are declared in header \libheaderref{execution}. -\begin{example} -\begin{codeblock} -using namespace std; -vector v = @\commentellip@; - -// standard sequential sort -sort(v.begin(), v.end()); - -// explicitly sequential sort -sort(execution::seq, v.begin(), v.end()); - -// permitting parallel execution -sort(execution::par, v.begin(), v.end()); - -// permitting vectorization as well -sort(execution::par_unseq, v.begin(), v.end()); -\end{codeblock} -\end{example} -\begin{note} -Implementations can provide additional execution policies -to those described in this document as extensions -to address parallel architectures that require idiosyncratic -parameters for efficient execution. -\end{note} - -\rSec2[execpol.type]{Execution policy type trait} - -\indexlibraryglobal{is_execution_policy}% -\begin{itemdecl} -template struct is_execution_policy { @\seebelow@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{is_execution_policy} can be used to detect execution policies for the -purpose of excluding function signatures from otherwise ambiguous overload -resolution participation. - -\pnum -\tcode{is_execution_policy} is a \oldconcept{UnaryTypeTrait} with a -base characteristic of \tcode{true_type} if \tcode{T} is the type of a standard -or \impldef{additional execution policies supported by parallel algorithms} -execution policy, otherwise \tcode{false_type}. - -\begin{note} -This provision reserves the privilege of creating non-standard execution -policies to the library implementation. -\end{note} - -\pnum -The behavior of a program that adds specializations for -\tcode{is_execution_policy} is undefined. -\end{itemdescr} - -\rSec2[execpol.seq]{Sequenced execution policy} - -\indexlibraryglobal{execution::sequenced_policy}% -\begin{itemdecl} -class execution::sequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::sequenced_policy} is an execution policy type used -as a unique type to disambiguate parallel algorithm overloading and require -that a parallel algorithm's execution may not be parallelized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::sequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.par]{Parallel execution policy} - -\indexlibraryglobal{execution::parallel_policy}% -\begin{itemdecl} -class execution::parallel_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::parallel_policy} is an execution policy type used as -a unique type to disambiguate parallel algorithm overloading and indicate that -a parallel algorithm's execution may be parallelized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::parallel_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.parunseq]{Parallel and unsequenced execution policy} - -\indexlibraryglobal{execution::parallel_unsequenced_policy}% -\begin{itemdecl} -class execution::parallel_unsequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::parallel_unsequenced_policy} is an execution policy type -used as a unique type to disambiguate parallel algorithm overloading and -indicate that a parallel algorithm's execution may be parallelized and -vectorized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::parallel_unsequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.unseq]{Unsequenced execution policy} - -\indexlibraryglobal{execution::unsequenced_policy}% -\begin{itemdecl} -class execution::unsequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{unsequenced_policy} is an execution policy type -used as a unique type to disambiguate parallel algorithm overloading and -indicate that a parallel algorithm's execution may be vectorized, -e.g., executed on a single thread using instructions -that operate on multiple data items. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::unsequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.objects]{Execution policy objects} - -\indexlibraryglobal{seq}% -\indexlibraryglobal{par}% -\indexlibraryglobal{par_unseq}% -\indexlibrarymember{execution}{seq}% -\indexlibrarymember{execution}{par}% -\indexlibrarymember{execution}{par_unseq}% -\begin{itemdecl} -inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; -inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; -inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; -inline constexpr execution::unsequenced_policy execution::unseq{ @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The header \libheaderref{execution} declares global objects associated with each type of execution policy. -\end{itemdescr} - \rSec1[charconv]{Primitive numeric conversions} \rSec2[charconv.syn]{Header \tcode{} synopsis} From c5c771e5ef093cfdb160b01692cd03bcd7c94eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 15:52:54 +0100 Subject: [PATCH 84/95] [type.index] Move [type.index] into subclause [support.rtti] The subclause is integrated into the structure of [support.rtti], meaning that the synopsis becomes a sibling of the rest, and the subdivisions of the remaining text are removed (in analogy with [type.info]). Part of the C++26 clause restructuring (#5315). --- source/support.tex | 170 +++++++++++++++++++++++++++++++++++++++++- source/utilities.tex | 171 +------------------------------------------ source/xrefdelta.tex | 5 ++ 3 files changed, 174 insertions(+), 172 deletions(-) diff --git a/source/support.tex b/source/support.tex index bebd8957aa..28c15ac913 100644 --- a/source/support.tex +++ b/source/support.tex @@ -29,10 +29,10 @@ \ref{support.arith.types} & Arithmetic types & \tcode{}, \tcode{} \\ \rowsep \ref{support.start.term} & Start and termination & \tcode{} \\ \rowsep \ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep -\ref{support.rtti} & Type identification & \tcode{} \\ \rowsep +\ref{support.rtti} & Type identification & \tcode{}, \tcode{} \\ \rowsep \ref{support.srcloc} & Source location & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep -\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep +\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{cmp} & Comparisons & \tcode{} \\ \rowsep \ref{support.coroutine} & Coroutines & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & @@ -3180,12 +3180,16 @@ \rSec2[support.rtti.general]{General} \pnum -The header \libheaderdef{typeinfo} defines a +The header \libheaderref{typeinfo} defines a type associated with type information generated by the implementation. It also defines two types for reporting dynamic type identification errors. +The header \libheaderrefx{typeindex}{type.index.synopsis} defines +a wrapper type for use as an index type in associative containers\iref{associative} +and in unordered associative containers\iref{unord}. \rSec2[typeinfo.syn]{Header \tcode{} synopsis} +\indexheader{typeinfo}% \indexlibraryglobal{type_info}% \indexlibraryglobal{bad_cast}% \indexlibraryglobal{bad_typeid}% @@ -3365,6 +3369,166 @@ An \impldef{return value of \tcode{bad_typeid::what}} \ntbs{}. \end{itemdescr} +\rSec2[type.index.synopsis]{Header \tcode{} synopsis} + +\indexheader{typeindex}% +\begin{codeblock} +#include // see \ref{compare.syn} + +namespace std { + class type_index; + template struct hash; + template<> struct hash; +} +\end{codeblock} + +\rSec2[type.index]{Class \tcode{type_index}} + +\indexlibraryglobal{type_index}% +\begin{codeblock} +namespace std { + class type_index { + public: + type_index(const type_info& rhs) noexcept; + bool operator==(const type_index& rhs) const noexcept; + bool operator< (const type_index& rhs) const noexcept; + bool operator> (const type_index& rhs) const noexcept; + bool operator<=(const type_index& rhs) const noexcept; + bool operator>=(const type_index& rhs) const noexcept; + strong_ordering operator<=>(const type_index& rhs) const noexcept; + size_t hash_code() const noexcept; + const char* name() const noexcept; + + private: + const type_info* target; // \expos + // Note that the use of a pointer here, rather than a reference, + // means that the default copy/move constructor and assignment + // operators will be provided and work as expected. + }; +} +\end{codeblock} + +\pnum +The class \tcode{type_index} provides a simple wrapper for +\tcode{type_info} which can be used as an index type in associative +containers\iref{associative} and in unordered associative +containers\iref{unord}. + +\indexlibraryctor{type_index}% +\begin{itemdecl} +type_index(const type_info& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{type_index} object, the equivalent of \tcode{target = \&rhs}. +\end{itemdescr} + +\indexlibrarymember{operator==}{type_index}% +\begin{itemdecl} +bool operator==(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{*target == *rhs.target}. +\end{itemdescr} + +\indexlibrarymember{operator<}{type_index}% +\begin{itemdecl} +bool operator<(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{target->before(*rhs.target)}. +\end{itemdescr} + +\indexlibrarymember{operator>}{type_index}% +\begin{itemdecl} +bool operator>(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{rhs.target->before(*target)}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{type_index}% +\begin{itemdecl} +bool operator<=(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!rhs.target->before(*target)}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{type_index}% +\begin{itemdecl} +bool operator>=(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!target->before(*rhs.target)}. +\end{itemdescr} + +\indexlibrarymember{operator<=>}{type_index}% +\begin{itemdecl} +strong_ordering operator<=>(const type_index& rhs) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (*target == *rhs.target) return strong_ordering::equal; +if (target->before(*rhs.target)) return strong_ordering::less; +return strong_ordering::greater; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{hash_code}{type_index}% +\begin{itemdecl} +size_t hash_code() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{target->hash_code()}. +\end{itemdescr} + +\indexlibrarymember{name}{type_index}% +\begin{itemdecl} +const char* name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{target->name()}. +\end{itemdescr} + +\indexlibrarymember{hash}{type_index}% +\begin{itemdecl} +template<> struct hash; +\end{itemdecl} + +\begin{itemdescr} +\pnum +For an object \tcode{index} of type \tcode{type_index}, +\tcode{hash()(index)} shall evaluate to the same result as \tcode{index.hash_code()}. +\end{itemdescr} + \rSec1[support.srcloc]{Source location} \rSec2[source.location.syn]{Header \tcode{} synopsis} diff --git a/source/utilities.tex b/source/utilities.tex index ec98bef1df..1e799f9bc7 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -19,7 +19,6 @@ \ref{expected} & Expected objects & \tcode{} \\ \rowsep \ref{bitset} & Fixed-size sequences of bits & \tcode{} \\ \rowsep \ref{function.objects} & Function objects & \tcode{} \\ \rowsep -\ref{type.index} & Type indexes & \tcode{} \\ \rowsep \ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep \ref{format} & Formatting & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ @@ -15049,172 +15048,6 @@ program-defined specialization. \end{itemize} -\rSec1[type.index]{Class \tcode{type_index}} - -\rSec2[type.index.synopsis]{Header \tcode{} synopsis} - -\indexheader{typeindex}% -\begin{codeblock} -#include // see \ref{compare.syn} - -namespace std { - class type_index; - template struct hash; - template<> struct hash; -} -\end{codeblock} - -\rSec2[type.index.overview]{\tcode{type_index} overview} - -\indexlibraryglobal{type_index}% -\begin{codeblock} -namespace std { - class type_index { - public: - type_index(const type_info& rhs) noexcept; - bool operator==(const type_index& rhs) const noexcept; - bool operator< (const type_index& rhs) const noexcept; - bool operator> (const type_index& rhs) const noexcept; - bool operator<=(const type_index& rhs) const noexcept; - bool operator>=(const type_index& rhs) const noexcept; - strong_ordering operator<=>(const type_index& rhs) const noexcept; - size_t hash_code() const noexcept; - const char* name() const noexcept; - - private: - const type_info* target; // \expos - // Note that the use of a pointer here, rather than a reference, - // means that the default copy/move constructor and assignment - // operators will be provided and work as expected. - }; -} -\end{codeblock} - -\pnum -The class \tcode{type_index} provides a simple wrapper for -\tcode{type_info} which can be used as an index type in associative -containers\iref{associative} and in unordered associative -containers\iref{unord}. - -\rSec2[type.index.members]{\tcode{type_index} members} - -\indexlibraryctor{type_index}% -\begin{itemdecl} -type_index(const type_info& rhs) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs a \tcode{type_index} object, the equivalent of \tcode{target = \&rhs}. -\end{itemdescr} - -\indexlibrarymember{operator==}{type_index}% -\begin{itemdecl} -bool operator==(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{*target == *rhs.target}. -\end{itemdescr} - -\indexlibrarymember{operator<}{type_index}% -\begin{itemdecl} -bool operator<(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{target->before(*rhs.target)}. -\end{itemdescr} - -\indexlibrarymember{operator>}{type_index}% -\begin{itemdecl} -bool operator>(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rhs.target->before(*target)}. -\end{itemdescr} - -\indexlibrarymember{operator<=}{type_index}% -\begin{itemdecl} -bool operator<=(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{!rhs.target->before(*target)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{type_index}% -\begin{itemdecl} -bool operator>=(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{!target->before(*rhs.target)}. -\end{itemdescr} - -\indexlibrarymember{operator<=>}{type_index}% -\begin{itemdecl} -strong_ordering operator<=>(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -if (*target == *rhs.target) return strong_ordering::equal; -if (target->before(*rhs.target)) return strong_ordering::less; -return strong_ordering::greater; -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{hash_code}{type_index}% -\begin{itemdecl} -size_t hash_code() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{target->hash_code()}. -\end{itemdescr} - -\indexlibrarymember{name}{type_index}% -\begin{itemdecl} -const char* name() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{target->name()}. -\end{itemdescr} - -\rSec2[type.index.hash]{Hash support} - -\indexlibrarymember{hash}{type_index}% -\begin{itemdecl} -template<> struct hash; -\end{itemdecl} - -\begin{itemdescr} -\pnum -For an object \tcode{index} of type \tcode{type_index}, -\tcode{hash()(index)} shall evaluate to the same result as \tcode{index.hash_code()}. -\end{itemdescr} - \rSec1[charconv]{Primitive numeric conversions} \rSec2[charconv.syn]{Header \tcode{} synopsis} @@ -15233,14 +15066,14 @@ \indexheader{charconv}% \begin{codeblock} +namespace std { @% \indexlibraryglobal{chars_format}% \indexlibrarymember{scientific}{chars_format}% \indexlibrarymember{fixed}{chars_format}% \indexlibrarymember{hex}{chars_format}% \indexlibrarymember{general}{chars_format}% -@namespace std { - // floating-point format for primitive numerical conversion +@ // floating-point format for primitive numerical conversion enum class chars_format { scientific = @\unspec@, fixed = @\unspec@, diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index fd1251057e..04302a06d0 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -68,6 +68,11 @@ \removedxref{depr.conversions.general} \removedxref{depr.conversions.string} +% Clause restructuring +\removedxref{type.index.overview} +\removedxref{type.index.members} +\removedxref{type.index.hash} + %%% Renamed sections. %%% Examples: % From ad21e19e7543eebf0707584411dfab5d8c900405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 17:25:51 +0100 Subject: [PATCH 85/95] [containers] Move synopses right in front of the classes they define Part of the C++26 clause restructuring (#5315). --- source/containers.tex | 876 +++++++++++++++++++++--------------------- 1 file changed, 438 insertions(+), 438 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 1c8f212ec3..f43cc92f3b 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6046,188 +6046,6 @@ } \end{codeblock} -\rSec2[deque.syn]{Header \tcode{} synopsis} - -\indexheader{deque}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{deque}, class template \tcode{deque} - template> class deque; - - template - bool operator==(const deque& x, const deque& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const deque& x, - @\itcorr@ const deque& y); - - template - void swap(deque& x, deque& y) - noexcept(noexcept(x.swap(y))); - - // \ref{deque.erasure}, erasure - template - typename deque::size_type - erase(deque& c, const U& value); - template - typename deque::size_type - erase_if(deque& c, Predicate pred); - - namespace pmr { - template - using deque = std::deque>; - } -} -\end{codeblock} - -\rSec2[forward.list.syn]{Header \tcode{} synopsis} - -\indexheader{forward_list}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{forward.list}, class template \tcode{forward_list} - template> class forward_list; - - template - bool operator==(const forward_list& x, const forward_list& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const forward_list& x, - @\itcorr@ const forward_list& y); - - template - void swap(forward_list& x, forward_list& y) - noexcept(noexcept(x.swap(y))); - - // \ref{forward.list.erasure}, erasure - template - typename forward_list::size_type - erase(forward_list& c, const U& value); - template - typename forward_list::size_type - erase_if(forward_list& c, Predicate pred); - - namespace pmr { - template - using forward_list = std::forward_list>; - } -} -\end{codeblock} - -\rSec2[list.syn]{Header \tcode{} synopsis} - -\indexheader{list}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{list}, class template \tcode{list} - template> class list; - - template - bool operator==(const list& x, const list& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const list& x, - @\itcorr@ const list& y); - - template - void swap(list& x, list& y) - noexcept(noexcept(x.swap(y))); - - // \ref{list.erasure}, erasure - template - typename list::size_type - erase(list& c, const U& value); - template - typename list::size_type - erase_if(list& c, Predicate pred); - - namespace pmr { - template - using list = std::list>; - } -} -\end{codeblock} - -\rSec2[vector.syn]{Header \tcode{} synopsis} - -\indexheader{vector}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{vector}, class template \tcode{vector} - template> class vector; - - template - constexpr bool operator==(const vector& x, const vector& y); - template - constexpr @\placeholder{synth-three-way-result}@ operator<=>(const vector& x, - @\itcorr@ const vector& y); - - template - constexpr void swap(vector& x, vector& y) - noexcept(noexcept(x.swap(y))); - - // \ref{vector.erasure}, erasure - template - constexpr typename vector::size_type - erase(vector& c, const U& value); - template - constexpr typename vector::size_type - erase_if(vector& c, Predicate pred); - - namespace pmr { - template - using vector = std::vector>; - } - - // \ref{vector.bool}, specialization of \tcode{vector} for \tcode{bool} - // \ref{vector.bool.pspc}, partial class template specialization \tcode{vector} - template - class vector; - - template - constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos - - // hash support - template struct hash; - template struct hash>; - - // \ref{vector.bool.fmt}, formatter specialization for \tcode{vector} - template requires @\exposid{is-vector-bool-reference}@ - struct formatter; -} -\end{codeblock} - -\rSec2[inplace.vector.syn]{Header \tcode{} synopsis} - -\indexheader{inplace_vector}% -\begin{codeblock} -// mostly freestanding -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{inplace.vector}, class template \tcode{inplace_vector} - template class inplace_vector; // partially freestanding - - // \ref{inplace.vector.erasure}, erasure - template - constexpr typename inplace_vector::size_type - erase(inplace_vector& c, const U& value); - template - constexpr typename inplace_vector::size_type - erase_if(inplace_vector& c, Predicate pred); -} -\end{codeblock} - \rSec2[array]{Class template \tcode{array}} \indexlibraryglobal{array}% @@ -6551,6 +6369,42 @@ where indexing is zero-based. \end{itemdescr} +\rSec2[deque.syn]{Header \tcode{} synopsis} + +\indexheader{deque}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{deque}, class template \tcode{deque} + template> class deque; + + template + bool operator==(const deque& x, const deque& y); + template + @\placeholder{synth-three-way-result}@ operator<=>(const deque& x, + @\itcorr@ const deque& y); + + template + void swap(deque& x, deque& y) + noexcept(noexcept(x.swap(y))); + + // \ref{deque.erasure}, erasure + template + typename deque::size_type + erase(deque& c, const U& value); + template + typename deque::size_type + erase_if(deque& c, Predicate pred); + + namespace pmr { + template + using deque = std::deque>; + } +} +\end{codeblock} + \rSec2[deque]{Class template \tcode{deque}} \rSec3[deque.overview]{Overview} @@ -7005,6 +6859,42 @@ \end{codeblock} \end{itemdescr} +\rSec2[forward.list.syn]{Header \tcode{} synopsis} + +\indexheader{forward_list}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{forward.list}, class template \tcode{forward_list} + template> class forward_list; + + template + bool operator==(const forward_list& x, const forward_list& y); + template + @\placeholder{synth-three-way-result}@ operator<=>(const forward_list& x, + @\itcorr@ const forward_list& y); + + template + void swap(forward_list& x, forward_list& y) + noexcept(noexcept(x.swap(y))); + + // \ref{forward.list.erasure}, erasure + template + typename forward_list::size_type + erase(forward_list& c, const U& value); + template + typename forward_list::size_type + erase_if(forward_list& c, Predicate pred); + + namespace pmr { + template + using forward_list = std::forward_list>; + } +} +\end{codeblock} + \rSec2[forward.list]{Class template \tcode{forward_list}} \rSec3[forward.list.overview]{Overview} @@ -7906,6 +7796,42 @@ Equivalent to: \tcode{return c.remove_if(pred);} \end{itemdescr} +\rSec2[list.syn]{Header \tcode{} synopsis} + +\indexheader{list}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{list}, class template \tcode{list} + template> class list; + + template + bool operator==(const list& x, const list& y); + template + @\placeholder{synth-three-way-result}@ operator<=>(const list& x, + @\itcorr@ const list& y); + + template + void swap(list& x, list& y) + noexcept(noexcept(x.swap(y))); + + // \ref{list.erasure}, erasure + template + typename list::size_type + erase(list& c, const U& value); + template + typename list::size_type + erase_if(list& c, Predicate pred); + + namespace pmr { + template + using list = std::list>; + } +} +\end{codeblock} + \rSec2[list]{Class template \tcode{list}} \rSec3[list.overview]{Overview} @@ -8655,6 +8581,58 @@ Equivalent to: \tcode{return c.remove_if(pred);} \end{itemdescr} +\rSec2[vector.syn]{Header \tcode{} synopsis} + +\indexheader{vector}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{vector}, class template \tcode{vector} + template> class vector; + + template + constexpr bool operator==(const vector& x, const vector& y); + template + constexpr @\placeholder{synth-three-way-result}@ operator<=>(const vector& x, + @\itcorr@ const vector& y); + + template + constexpr void swap(vector& x, vector& y) + noexcept(noexcept(x.swap(y))); + + // \ref{vector.erasure}, erasure + template + constexpr typename vector::size_type + erase(vector& c, const U& value); + template + constexpr typename vector::size_type + erase_if(vector& c, Predicate pred); + + namespace pmr { + template + using vector = std::vector>; + } + + // \ref{vector.bool}, specialization of \tcode{vector} for \tcode{bool} + // \ref{vector.bool.pspc}, partial class template specialization \tcode{vector} + template + class vector; + + template + constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos + + // hash support + template struct hash; + template struct hash>; + + // \ref{vector.bool.fmt}, formatter specialization for \tcode{vector} + template requires @\exposid{is-vector-bool-reference}@ + struct formatter; +} +\end{codeblock} + \rSec2[vector]{Class template \tcode{vector}} \rSec3[vector.overview]{Overview} @@ -9501,6 +9479,28 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(ref, ctx);} \end{itemdescr} +\rSec2[inplace.vector.syn]{Header \tcode{} synopsis} + +\indexheader{inplace_vector}% +\begin{codeblock} +// mostly freestanding +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{inplace.vector}, class template \tcode{inplace_vector} + template class inplace_vector; // partially freestanding + + // \ref{inplace.vector.erasure}, erasure + template + constexpr typename inplace_vector::size_type + erase(inplace_vector& c, const U& value); + template + constexpr typename inplace_vector::size_type + erase_if(inplace_vector& c, Predicate pred); +} +\end{codeblock} + \rSec2[inplace.vector]{Class template \tcode{inplace_vector}} \rSec3[inplace.vector.overview]{Overview} @@ -10259,66 +10259,6 @@ } \end{codeblock} -\rSec2[associative.set.syn]{Header \tcode{} synopsis}% - -\indexheader{set}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{set}, class template \tcode{set} - template, class Allocator = allocator> - class set; - - template - bool operator==(const set& x, - const set& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const set& x, - @\itcorr@ const set& y); - - template - void swap(set& x, - set& y) - noexcept(noexcept(x.swap(y))); - - // \ref{set.erasure}, erasure for \tcode{set} - template - typename set::size_type - erase_if(set& c, Predicate pred); - - // \ref{multiset}, class template \tcode{multiset} - template, class Allocator = allocator> - class multiset; - - template - bool operator==(const multiset& x, - const multiset& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const multiset& x, - @\itcorr@ const multiset& y); - - template - void swap(multiset& x, - multiset& y) - noexcept(noexcept(x.swap(y))); - - // \ref{multiset.erasure}, erasure for \tcode{multiset} - template - typename multiset::size_type - erase_if(multiset& c, Predicate pred); - - namespace pmr { - template> - using set = std::set>; - - template> - using multiset = std::multiset>; - } -} -\end{codeblock} - \rSec2[map]{Class template \tcode{map}} \rSec3[map.overview]{Overview} @@ -11410,6 +11350,66 @@ \end{codeblock} \end{itemdescr} +\rSec2[associative.set.syn]{Header \tcode{} synopsis}% + +\indexheader{set}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{set}, class template \tcode{set} + template, class Allocator = allocator> + class set; + + template + bool operator==(const set& x, + const set& y); + template + @\placeholder{synth-three-way-result}@ operator<=>(const set& x, + @\itcorr@ const set& y); + + template + void swap(set& x, + set& y) + noexcept(noexcept(x.swap(y))); + + // \ref{set.erasure}, erasure for \tcode{set} + template + typename set::size_type + erase_if(set& c, Predicate pred); + + // \ref{multiset}, class template \tcode{multiset} + template, class Allocator = allocator> + class multiset; + + template + bool operator==(const multiset& x, + const multiset& y); + template + @\placeholder{synth-three-way-result}@ operator<=>(const multiset& x, + @\itcorr@ const multiset& y); + + template + void swap(multiset& x, + multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{multiset.erasure}, erasure for \tcode{multiset} + template + typename multiset::size_type + erase_if(multiset& c, Predicate pred); + + namespace pmr { + template> + using set = std::set>; + + template> + using multiset = std::multiset>; + } +} +\end{codeblock} + \rSec2[set]{Class template \tcode{set}} \rSec3[set.overview]{Overview} @@ -12176,74 +12176,6 @@ } \end{codeblock} -\rSec2[unord.set.syn]{Header \tcode{} synopsis} - -\indexheader{unordered_set}% -\indexlibraryglobal{unordered_set}% -\indexlibraryglobal{unordered_multiset}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{unord.set}, class template \tcode{unordered_set} - template, - class Pred = equal_to, - class Alloc = allocator> - class unordered_set; - - // \ref{unord.multiset}, class template \tcode{unordered_multiset} - template, - class Pred = equal_to, - class Alloc = allocator> - class unordered_multiset; - - template - bool operator==(const unordered_set& a, - const unordered_set& b); - - template - bool operator==(const unordered_multiset& a, - const unordered_multiset& b); - - template - void swap(unordered_set& x, - unordered_set& y) - noexcept(noexcept(x.swap(y))); - - template - void swap(unordered_multiset& x, - unordered_multiset& y) - noexcept(noexcept(x.swap(y))); - - // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} - template - typename unordered_set::size_type - erase_if(unordered_set& c, Predicate pred); - - // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} - template - typename unordered_multiset::size_type - erase_if(unordered_multiset& c, Predicate pred); - - namespace pmr { - template, - class Pred = equal_to> - using unordered_set = std::unordered_set>; - - template, - class Pred = equal_to> - using unordered_multiset = std::unordered_multiset>; - } -} -\end{codeblock} - \rSec2[unord.map]{Class template \tcode{unordered_map}}% \indexlibraryglobal{unordered_map} @@ -13459,9 +13391,77 @@ ++i; } } -return original_size - c.size(); +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[unord.set.syn]{Header \tcode{} synopsis} + +\indexheader{unordered_set}% +\indexlibraryglobal{unordered_set}% +\indexlibraryglobal{unordered_multiset}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{unord.set}, class template \tcode{unordered_set} + template, + class Pred = equal_to, + class Alloc = allocator> + class unordered_set; + + // \ref{unord.multiset}, class template \tcode{unordered_multiset} + template, + class Pred = equal_to, + class Alloc = allocator> + class unordered_multiset; + + template + bool operator==(const unordered_set& a, + const unordered_set& b); + + template + bool operator==(const unordered_multiset& a, + const unordered_multiset& b); + + template + void swap(unordered_set& x, + unordered_set& y) + noexcept(noexcept(x.swap(y))); + + template + void swap(unordered_multiset& x, + unordered_multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} + template + typename unordered_set::size_type + erase_if(unordered_set& c, Predicate pred); + + // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} + template + typename unordered_multiset::size_type + erase_if(unordered_multiset& c, Predicate pred); + + namespace pmr { + template, + class Pred = equal_to> + using unordered_set = std::unordered_set>; + + template, + class Pred = equal_to> + using unordered_multiset = std::unordered_multiset>; + } +} \end{codeblock} -\end{itemdescr} \rSec2[unord.set]{Class template \tcode{unordered_set}}% \indexlibraryglobal{unordered_set} @@ -14412,132 +14412,6 @@ } \end{codeblock} -\rSec2[stack.syn]{Header \tcode{} synopsis} - -\indexheader{stack}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{stack}, class template \tcode{stack} - template> class stack; - - template - bool operator==(const stack& x, const stack& y); - template - bool operator!=(const stack& x, const stack& y); - template - bool operator< (const stack& x, const stack& y); - template - bool operator> (const stack& x, const stack& y); - template - bool operator<=(const stack& x, const stack& y); - template - bool operator>=(const stack& x, const stack& y); - template - compare_three_way_result_t - operator<=>(const stack& x, const stack& y); - - template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); - template - struct uses_allocator, Alloc>; - - // \ref{container.adaptors.format}, formatter specialization for \tcode{stack} - template Container> - struct formatter, charT>; -} -\end{codeblock} - -\rSec2[flat.map.syn]{Header \tcode{} synopsis} - -\indexheader{flat_map}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{flat.map}, class template \tcode{flat_map} - template, - class KeyContainer = vector, class MappedContainer = vector> - class flat_map; - - struct sorted_unique_t { explicit sorted_unique_t() = default; }; - inline constexpr sorted_unique_t sorted_unique{}; - - template - struct uses_allocator, - Allocator>; - - // \ref{flat.map.erasure}, erasure for \tcode{flat_map} - template - typename flat_map::size_type - erase_if(flat_map& c, Predicate pred); - - // \ref{flat.multimap}, class template \tcode{flat_multimap} - template, - class KeyContainer = vector, class MappedContainer = vector> - class flat_multimap; - - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; - - template - struct uses_allocator, - Allocator>; - - // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} - template - typename flat_multimap::size_type - erase_if(flat_multimap& c, Predicate pred); -} -\end{codeblock} - -\rSec2[flat.set.syn]{Header \tcode{} synopsis}% -\indexheader{flat_set}% - -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{flat.set}, class template \tcode{flat_set} - template, class KeyContainer = vector> - class flat_set; - - struct sorted_unique_t { explicit sorted_unique_t() = default; }; - inline constexpr sorted_unique_t sorted_unique{}; - - template - struct uses_allocator, Allocator>; - - // \ref{flat.set.erasure}, erasure for \tcode{flat_set} - template - typename flat_set::size_type - erase_if(flat_set& c, Predicate pred); - - // \ref{flat.multiset}, class template \tcode{flat_multiset} - template, class KeyContainer = vector> - class flat_multiset; - - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; - - template - struct uses_allocator, Allocator>; - - // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} - template - typename flat_multiset::size_type - erase_if(flat_multiset& c, Predicate pred); -} -\end{codeblock} - \rSec2[queue]{Class template \tcode{queue}} \rSec3[queue.defn]{Definition} @@ -15405,6 +15279,44 @@ As if by \tcode{x.swap(y)}. \end{itemdescr} +\rSec2[stack.syn]{Header \tcode{} synopsis} + +\indexheader{stack}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{stack}, class template \tcode{stack} + template> class stack; + + template + bool operator==(const stack& x, const stack& y); + template + bool operator!=(const stack& x, const stack& y); + template + bool operator< (const stack& x, const stack& y); + template + bool operator> (const stack& x, const stack& y); + template + bool operator<=(const stack& x, const stack& y); + template + bool operator>=(const stack& x, const stack& y); + template + compare_three_way_result_t + operator<=>(const stack& x, const stack& y); + + template + void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; + + // \ref{container.adaptors.format}, formatter specialization for \tcode{stack} + template Container> + struct formatter, charT>; +} +\end{codeblock} + \rSec2[stack]{Class template \tcode{stack}} \rSec3[stack.general]{General} @@ -15763,6 +15675,54 @@ As if by \tcode{x.swap(y)}. \end{itemdescr} +\rSec2[flat.map.syn]{Header \tcode{} synopsis} + +\indexheader{flat_map}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{flat.map}, class template \tcode{flat_map} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_map; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + struct uses_allocator, + Allocator>; + + // \ref{flat.map.erasure}, erasure for \tcode{flat_map} + template + typename flat_map::size_type + erase_if(flat_map& c, Predicate pred); + + // \ref{flat.multimap}, class template \tcode{flat_multimap} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_multimap; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + struct uses_allocator, + Allocator>; + + // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} + template + typename flat_multimap::size_type + erase_if(flat_multimap& c, Predicate pred); +} +\end{codeblock} + \rSec2[flat.map]{Class template \tcode{flat_map}} \rSec3[flat.map.overview]{Overview} @@ -17552,6 +17512,46 @@ \end{note} \end{itemdescr} +\rSec2[flat.set.syn]{Header \tcode{} synopsis}% +\indexheader{flat_set}% + +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{flat.set}, class template \tcode{flat_set} + template, class KeyContainer = vector> + class flat_set; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + struct uses_allocator, Allocator>; + + // \ref{flat.set.erasure}, erasure for \tcode{flat_set} + template + typename flat_set::size_type + erase_if(flat_set& c, Predicate pred); + + // \ref{flat.multiset}, class template \tcode{flat_multiset} + template, class KeyContainer = vector> + class flat_multiset; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + struct uses_allocator, Allocator>; + + // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} + template + typename flat_multiset::size_type + erase_if(flat_multiset& c, Predicate pred); +} +\end{codeblock} + \rSec2[flat.set]{Class template \tcode{flat_set}} \rSec3[flat.set.overview]{Overview} From 374238a964107b95efcc6ef4e31738459330ae2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 15:27:06 +0100 Subject: [PATCH 86/95] [std] Reorder clauses: [algorithm], [strings] Part of the C++26 clause restructuring (#5315). --- source/std.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/std.tex b/source/std.tex index 2761dbee82..35cf5d7826 100644 --- a/source/std.tex +++ b/source/std.tex @@ -129,11 +129,11 @@ \include{memory} \include{meta} \include{utilities} -\include{strings} \include{containers} \include{iterators} \include{ranges} \include{algorithms} +\include{strings} \include{numerics} \include{time} \include{locales} From c9a026bcc7aa93f4ed1582becac063e2742ec03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 15:36:47 +0100 Subject: [PATCH 87/95] [std] Create new top-level Clause [text], following [strings] Part of the C++26 clause restructuring (#5315). --- source/std.tex | 1 + source/text.tex | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 source/text.tex diff --git a/source/std.tex b/source/std.tex index 35cf5d7826..eb0d3ad174 100644 --- a/source/std.tex +++ b/source/std.tex @@ -134,6 +134,7 @@ \include{ranges} \include{algorithms} \include{strings} +\include{text} \include{numerics} \include{time} \include{locales} diff --git a/source/text.tex b/source/text.tex new file mode 100644 index 0000000000..769fba8693 --- /dev/null +++ b/source/text.tex @@ -0,0 +1,12 @@ +%!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{text} & (placeholder) & (placeholder) \\ +\end{libsumtab} From fc6f670832980fc7b8219cb6945592cbe45d9239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 19:01:21 +0100 Subject: [PATCH 88/95] [text, re] Move [re] into [text] Part of the C++26 clause restructuring (#5315). --- source/regex.tex | 4000 --------------------------------------------- source/std.tex | 1 - source/text.tex | 4001 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 4000 insertions(+), 4002 deletions(-) delete mode 100644 source/regex.tex diff --git a/source/regex.tex b/source/regex.tex deleted file mode 100644 index fd6292e34e..0000000000 --- a/source/regex.tex +++ /dev/null @@ -1,4000 +0,0 @@ -%!TEX root = std.tex -\rSec0[re]{Regular expressions library} -\indextext{regular expression|(} - -\rSec1[re.general]{General} - - -\pnum -This Clause 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. - -\rSec1[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} - -\rSec1[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} - -\rSec1[re.const]{Namespace \tcode{std::regex_constants}} - -\rSec2[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. - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec1[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} - -\rSec1[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>) == 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} - -\rSec1[re.regex]{Class template \tcode{basic_regex}} - -\rSec2[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 = typename traits::string_type; - using flag_type = regex_constants::syntax_option_type; - using locale_type = typename 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} - -\rSec2[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} - -\rSec2[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} - - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec1[re.submatch]{Class template \tcode{sub_match}} - -\rSec2[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 = - typename iterator_traits::value_type; - using difference_type = - typename 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} - - -\rSec2[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} - -\rSec2[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} - -\rSec1[re.results]{Class template \tcode{match_results}} - -\rSec2[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 = - typename iterator_traits::difference_type; - using size_type = typename allocator_traits::size_type; - using allocator_type = Allocator; - using char_type = - typename 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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec2[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)}. - -\rSec2[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} - -\rSec1[re.alg]{Regular expression algorithms} - -\rSec2[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}. - -\rSec2[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} - -\rSec2[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} - -\rSec2[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} - -\rSec1[re.iter]{Regular expression iterators} - -\rSec2[re.regiter]{Class template \tcode{regex_iterator}} - -\rSec3[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 const -\tcode{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} - -\rSec3[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} - -\rSec3[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} - -\rSec3[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} - -\rSec3[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 -\tcode{[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} - -\rSec2[re.tokiter]{Class template \tcode{regex_token_iterator}} - -\rSec3[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.match} -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]}. - -\rSec3[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} - -\rSec3[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} - -\rSec3[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} - - -\rSec3[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} - -\rSec1[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|)} diff --git a/source/std.tex b/source/std.tex index eb0d3ad174..bd68a7b14e 100644 --- a/source/std.tex +++ b/source/std.tex @@ -139,7 +139,6 @@ \include{time} \include{locales} \include{iostreams} -\include{regex} \include{threads} \include{exec} diff --git a/source/text.tex b/source/text.tex index 769fba8693..ac194bccb6 100644 --- a/source/text.tex +++ b/source/text.tex @@ -8,5 +8,4004 @@ These components are summarized in \tref{text.summary}. \begin{libsumtab}{Text library summary}{text.summary} -\ref{text} & (placeholder) & (placeholder) \\ +\ref{re} & Regular expressions library & \tcode{} \\ \end{libsumtab} + +\rSec1[re]{Regular expressions library} +\indextext{regular expression|(} + +\rSec2[re.general]{General} + +\pnum +This Clause 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>) == 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 = typename traits::string_type; + using flag_type = regex_constants::syntax_option_type; + using locale_type = typename 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 = + typename iterator_traits::value_type; + using difference_type = + typename 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 = + typename iterator_traits::difference_type; + using size_type = typename allocator_traits::size_type; + using allocator_type = Allocator; + using char_type = + typename 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 const +\tcode{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 +\tcode{[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.match} +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|)} From 5d106373aada591874ab5e38301502b3012e0502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 19:06:03 +0100 Subject: [PATCH 89/95] [text, localization] Move [localization] into [text] The subclause [text.encodings] is extracted and elevated to a sibling subclause of [localization]. Part of the C++26 clause restructuring (#5315). --- source/locales.tex | 5376 ------------------------------------------- source/std.tex | 1 - source/text.tex | 5379 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 5378 insertions(+), 5378 deletions(-) delete mode 100644 source/locales.tex diff --git a/source/locales.tex b/source/locales.tex deleted file mode 100644 index a791026f92..0000000000 --- a/source/locales.tex +++ /dev/null @@ -1,5376 +0,0 @@ -%!TEX root = std.tex -\rSec0[localization]{Localization library} - -\rSec1[localization.general]{General} - -\pnum -This Clause 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 -\ref{text.encoding} & Text encodings identification & \tcode{} \\ -\end{libsumtab} - -\rSec1[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} - -\rSec1[locales]{Locales} - -\rSec2[locale]{Class \tcode{locale}} - -\rSec3[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}. - -\rSec3[locale.types]{Types} - -\rSec4[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. - -\rSec4[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 \term{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. - -\rSec4[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} - -\rSec3[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} - -\rSec3[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} - -\rSec3[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{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} - -\rSec3[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} - -\rSec2[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} - -\rSec2[locale.convenience]{Convenience interfaces} - -\rSec3[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} - -\rSec3[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} - -\rSec1[locale.categories]{Standard \tcode{locale} categories} - -\rSec2[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 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. - -\rSec2[category.ctype]{The \tcode{ctype} category} - -\rSec3[category.ctype.general]{General} - -\indexlibraryglobal{ctype_base}% -\begin{codeblock} -namespace std { - class ctype_base { - public: - using mask = @\seebelow@; - - // numeric values are for exposition only. - static constexpr mask space = 1 << 0; - static constexpr mask print = 1 << 1; - static constexpr mask cntrl = 1 << 2; - static constexpr mask upper = 1 << 3; - static constexpr mask lower = 1 << 4; - static constexpr mask alpha = 1 << 5; - static constexpr mask digit = 1 << 6; - static constexpr mask punct = 1 << 7; - static constexpr mask xdigit = 1 << 8; - static constexpr mask blank = 1 << 9; - static constexpr mask alnum = alpha | digit; - static constexpr mask graph = alnum | punct; - }; -} -\end{codeblock} - -\pnum -The type \tcode{mask} is a bitmask type\iref{bitmask.types}. - -\rSec3[locale.ctype]{Class template \tcode{ctype}} - -\rSec4[locale.ctype.general]{General} - -\indexlibraryglobal{ctype}% -\begin{codeblock} -namespace std { - template - class ctype : public locale::facet, public ctype_base { - public: - using char_type = 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 id; - - 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. - -\rSec4[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} - -\rSec4[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} - -\rSec3[locale.ctype.byname]{Class template \tcode{ctype_byname}} - -\indexlibraryglobal{ctype_byname}% -\begin{codeblock} -namespace std { - template - class ctype_byname : public ctype { - public: - using mask = typename 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} - -\rSec3[facet.ctype.special]{\tcode{ctype} specialization} - -\rSec4[facet.ctype.special.general]{General} - -\indexlibraryglobal{ctype}% -\begin{codeblock} -namespace std { - template<> - class ctype : public locale::facet, public ctype_base { - public: - using char_type = 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 id; - static const size_t table_size = @\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. - -\rSec4[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} - -\rSec4[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} - -\rSec4[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} - -\rSec4[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}. - -\rSec3[locale.codecvt]{Class template \tcode{codecvt}} - -\rSec4[locale.codecvt.general]{General} - -\indexlibraryglobal{codecvt}% -\begin{codeblock} -namespace std { - class codecvt_base { - public: - enum result { ok, partial, error, noconv }; - }; - - template - class codecvt : public locale::facet, public codecvt_base { - public: - using intern_type = internT; - using extern_type = externT; - using state_type = 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 id; - - 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. - -\rSec4[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} - -\rSec4[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 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} - -\rSec3[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} - -\rSec2[category.numeric]{The numeric category} - -\rSec3[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}. - -\rSec3[locale.num.get]{Class template \tcode{num_get}} - -\rSec4[locale.num.get.general]{General} - -\indexlibraryglobal{num_get}% -\begin{codeblock} -namespace std { - template> - class num_get : public locale::facet { - public: - using char_type = charT; - using iter_type = 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 id; - - 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. - -\rSec4[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} - -\rSec4[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} - -\rSec3[locale.nm.put]{Class template \tcode{num_put}} - -\rSec4[locale.nm.put.general]{General} - -\indexlibraryglobal{num_put}% -\begin{codeblock} -namespace std { - template> - class num_put : public locale::facet { - public: - using char_type = charT; - using iter_type = 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 id; - - 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. - -\rSec4[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} - -\rSec4[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} & \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} - -\rSec2[facet.numpunct]{The numeric punctuation facet} - -\rSec3[locale.numpunct]{Class template \tcode{numpunct}} - -\rSec4[locale.numpunct.general]{General} - -\indexlibraryglobal{numpunct}% -\begin{codeblock} -namespace std { - template - class numpunct : public locale::facet { - public: - using char_type = charT; - using string_type = 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 id; - - 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. - -\rSec4[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} - -\rSec4[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} - -\rSec3[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 char_type = charT; - using string_type = 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} - -\rSec2[category.collate]{The collate category} - -\rSec3[locale.collate]{Class template \tcode{collate}} - -\rSec4[locale.collate.general]{General} - -\indexlibraryglobal{collate}% -\begin{codeblock} -namespace std { - template - class collate : public locale::facet { - public: - using char_type = charT; - using string_type = 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 id; - - 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}. - -\rSec4[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} - -\rSec4[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} - -\rSec3[locale.collate.byname]{Class template \tcode{collate_byname}} - -\indexlibraryglobal{collate_byname}% -\begin{codeblock} -namespace std { - template - class collate_byname : public collate { - public: - using string_type = 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} - -\rSec2[category.time]{The time category} - -\rSec3[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. - -\rSec3[locale.time.get]{Class template \tcode{time_get}} - -\rSec4[locale.time.get.general]{General} - -\indexlibraryglobal{time_get}% -\begin{codeblock} -namespace std { - class time_base { - public: - enum dateorder { no_order, dmy, mdy, ymd, ydm }; - }; - - template> - class time_get : public locale::facet, public time_base { - public: - using char_type = charT; - using iter_type = 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 id; - - 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}. - -\rSec4[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} - -\rSec4[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} - -\rSec3[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 dateorder = time_base::dateorder; - using iter_type = 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} - -\rSec3[locale.time.put]{Class template \tcode{time_put}} - -\rSec4[locale.time.put.general]{General} - -\indexlibraryglobal{time_put}% -\begin{codeblock} -namespace std { - template> - class time_put : public locale::facet { - public: - using char_type = charT; - using iter_type = 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 id; - - 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} - -\rSec4[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} -\begin{footnote} -Although the C programming language defines no modifiers, most vendors do. -\end{footnote} -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} - -\rSec4[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} - -\rSec3[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 char_type = charT; - using iter_type = 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} - -\rSec2[category.monetary]{The monetary category} - -\rSec3[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. - -\rSec3[locale.money.get]{Class template \tcode{money_get}} - -\rSec4[locale.money.get.general]{General} - -\indexlibraryglobal{money_get}% -\begin{codeblock} -namespace std { - template> - class money_get : public locale::facet { - public: - using char_type = charT; - using iter_type = InputIterator; - using string_type = 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 id; - - 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} - -\rSec4[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} - -\rSec4[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} - -\rSec3[locale.money.put]{Class template \tcode{money_put}} - -\rSec4[locale.money.put.general]{General} - -\indexlibraryglobal{money_put}% -\begin{codeblock} -namespace std { - template> - class money_put : public locale::facet { - public: - using char_type = charT; - using iter_type = OutputIterator; - using string_type = 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 id; - - 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} - -\rSec4[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, loc, quant)}. -\end{itemdescr} - -\rSec4[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} - -\rSec3[locale.moneypunct]{Class template \tcode{moneypunct}} - -\rSec4[locale.moneypunct.general]{General} - -\indexlibraryglobal{moneypunct}% -\begin{codeblock} -namespace std { - class money_base { - public: - enum part { none, space, symbol, sign, value }; - struct pattern { char field[4]; }; - }; - - template - class moneypunct : public locale::facet, public money_base { - public: - using char_type = charT; - using string_type = 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 id; - static const bool intl = 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()}. - -\rSec4[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}()}. - -\rSec4[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} - -\rSec3[locale.moneypunct.byname]{Class template \tcode{moneypunct_byname}} - -\indexlibraryglobal{moneypunct_byname}% -\begin{codeblock} -namespace std { - template - class moneypunct_byname : public moneypunct { - public: - using pattern = money_base::pattern; - using string_type = 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} - -\rSec2[category.messages]{The message retrieval category} - -\rSec3[category.messages.general]{General} - -\pnum -Class \tcode{messages} -implements retrieval of strings from message catalogs. - -\rSec3[locale.messages]{Class template \tcode{messages}} - -\rSec4[locale.messages.general]{General} - -\indexlibraryglobal{messages}% -\begin{codeblock} -namespace std { - class messages_base { - public: - using catalog = @\textit{unspecified signed integer type}@; - }; - - template - class messages : public locale::facet, public messages_base { - public: - using char_type = charT; - using string_type = 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 id; - - 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}. - -\rSec4[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} - -\rSec4[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} - -\rSec3[locale.messages.byname]{Class template \tcode{messages_byname}} - -\indexlibraryglobal{messages_byname}% -\begin{codeblock} -namespace std { - template - class messages_byname : public messages { - public: - using catalog = messages_base::catalog; - using string_type = 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} - -\rSec1[c.locales]{C library locales} - -\rSec2[clocale.syn]{Header \tcode{} synopsis} - -\indexlibraryglobal{lconv}% -\indexlibraryglobal{setlocale}% -\indexlibraryglobal{localeconv}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{LC_ALL}% -\indexlibraryglobal{LC_COLLATE}% -\indexlibraryglobal{LC_CTYPE}% -\indexlibraryglobal{LC_MONETARY}% -\indexlibraryglobal{LC_NUMERIC}% -\indexlibraryglobal{LC_TIME}% -\begin{codeblock} -namespace std { - struct lconv; - - char* setlocale(int category, const char* locale); - lconv* localeconv(); -} - -#define NULL @\textit{see \ref{support.types.nullptr}}@ -#define LC_ALL @\seebelow@ -#define LC_COLLATE @\seebelow@ -#define LC_CTYPE @\seebelow@ -#define LC_MONETARY @\seebelow@ -#define LC_NUMERIC @\seebelow@ -#define 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}. - -\rSec2[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 max_name_length = 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; - - 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() == nullptr} 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_} if \tcode{(\exposid{name_}[0] != '\textbackslash 0')} -is \tcode{true}, and -\keyword{nullptr} otherwise. - -\pnum -\remarks -If \tcode{name() == nullptr} is \tcode{false}, -\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 { - other = 1, - unknown = 2, - ASCII = 3, - ISOLatin1 = 4, - ISOLatin2 = 5, - ISOLatin3 = 6, - ISOLatin4 = 7, - ISOLatinCyrillic = 8, - ISOLatinArabic = 9, - ISOLatinGreek = 10, - ISOLatinHebrew = 11, - ISOLatin5 = 12, - ISOLatin6 = 13, - ISOTextComm = 14, - HalfWidthKatakana = 15, - JISEncoding = 16, - ShiftJIS = 17, - EUCPkdFmtJapanese = 18, - EUCFixWidJapanese = 19, - ISO4UnitedKingdom = 20, - ISO11SwedishForNames = 21, - ISO15Italian = 22, - ISO17Spanish = 23, - ISO21German = 24, - ISO60DanishNorwegian = 25, - ISO69French = 26, - ISO10646UTF1 = 27, - ISO646basic1983 = 28, - INVARIANT = 29, - ISO2IntlRefVersion = 30, - NATSSEFI = 31, - NATSSEFIADD = 32, - ISO10Swedish = 35, - KSC56011987 = 36, - ISO2022KR = 37, - EUCKR = 38, - ISO2022JP = 39, - ISO2022JP2 = 40, - ISO13JISC6220jp = 41, - ISO14JISC6220ro = 42, - ISO16Portuguese = 43, - ISO18Greek7Old = 44, - ISO19LatinGreek = 45, - ISO25French = 46, - ISO27LatinGreek1 = 47, - ISO5427Cyrillic = 48, - ISO42JISC62261978 = 49, - ISO47BSViewdata = 50, - ISO49INIS = 51, - ISO50INIS8 = 52, - ISO51INISCyrillic = 53, - ISO54271981 = 54, - ISO5428Greek = 55, - ISO57GB1988 = 56, - ISO58GB231280 = 57, - ISO61Norwegian2 = 58, - ISO70VideotexSupp1 = 59, - ISO84Portuguese2 = 60, - ISO85Spanish2 = 61, - ISO86Hungarian = 62, - ISO87JISX0208 = 63, - ISO88Greek7 = 64, - ISO89ASMO449 = 65, - ISO90 = 66, - ISO91JISC62291984a = 67, - ISO92JISC62991984b = 68, - ISO93JIS62291984badd = 69, - ISO94JIS62291984hand = 70, - ISO95JIS62291984handadd = 71, - ISO96JISC62291984kana = 72, - ISO2033 = 73, - ISO99NAPLPS = 74, - ISO102T617bit = 75, - ISO103T618bit = 76, - ISO111ECMACyrillic = 77, - ISO121Canadian1 = 78, - ISO122Canadian2 = 79, - ISO123CSAZ24341985gr = 80, - ISO88596E = 81, - ISO88596I = 82, - ISO128T101G2 = 83, - ISO88598E = 84, - ISO88598I = 85, - ISO139CSN369103 = 86, - ISO141JUSIB1002 = 87, - ISO143IECP271 = 88, - ISO146Serbian = 89, - ISO147Macedonian = 90, - ISO150 = 91, - ISO151Cuba = 92, - ISO6937Add = 93, - ISO153GOST1976874 = 94, - ISO8859Supp = 95, - ISO10367Box = 96, - ISO158Lap = 97, - ISO159JISX02121990 = 98, - ISO646Danish = 99, - USDK = 100, - DKUS = 101, - KSC5636 = 102, - Unicode11UTF7 = 103, - ISO2022CN = 104, - ISO2022CNEXT = 105, - UTF8 = 106, - ISO885913 = 109, - ISO885914 = 110, - ISO885915 = 111, - ISO885916 = 112, - GBK = 113, - GB18030 = 114, - OSDEBCDICDF0415 = 115, - OSDEBCDICDF03IRV = 116, - OSDEBCDICDF041 = 117, - ISO115481 = 118, - KZ1048 = 119, - UCS2 = 1000, - UCS4 = 1001, - UnicodeASCII = 1002, - UnicodeLatin1 = 1003, - UnicodeJapanese = 1004, - UnicodeIBM1261 = 1005, - UnicodeIBM1268 = 1006, - UnicodeIBM1276 = 1007, - UnicodeIBM1264 = 1008, - UnicodeIBM1265 = 1009, - Unicode11 = 1010, - SCSU = 1011, - UTF7 = 1012, - UTF16BE = 1013, - UTF16LE = 1014, - UTF16 = 1015, - CESU8 = 1016, - UTF32 = 1017, - UTF32BE = 1018, - UTF32LE = 1019, - BOCU1 = 1020, - UTF7IMAP = 1021, - Windows30Latin1 = 2000, - Windows31Latin1 = 2001, - Windows31Latin2 = 2002, - Windows31Latin5 = 2003, - HPRoman8 = 2004, - AdobeStandardEncoding = 2005, - VenturaUS = 2006, - VenturaInternational = 2007, - DECMCS = 2008, - PC850Multilingual = 2009, - PC8DanishNorwegian = 2012, - PC862LatinHebrew = 2013, - PC8Turkish = 2014, - IBMSymbols = 2015, - IBMThai = 2016, - HPLegal = 2017, - HPPiFont = 2018, - HPMath8 = 2019, - HPPSMath = 2020, - HPDesktop = 2021, - VenturaMath = 2022, - MicrosoftPublishing = 2023, - Windows31J = 2024, - GB2312 = 2025, - Big5 = 2026, - Macintosh = 2027, - IBM037 = 2028, - IBM038 = 2029, - IBM273 = 2030, - IBM274 = 2031, - IBM275 = 2032, - IBM277 = 2033, - IBM278 = 2034, - IBM280 = 2035, - IBM281 = 2036, - IBM284 = 2037, - IBM285 = 2038, - IBM290 = 2039, - IBM297 = 2040, - IBM420 = 2041, - IBM423 = 2042, - IBM424 = 2043, - PC8CodePage437 = 2011, - IBM500 = 2044, - IBM851 = 2045, - PCp852 = 2010, - IBM855 = 2046, - IBM857 = 2047, - IBM860 = 2048, - IBM861 = 2049, - IBM863 = 2050, - IBM864 = 2051, - IBM865 = 2052, - IBM868 = 2053, - IBM869 = 2054, - IBM870 = 2055, - IBM871 = 2056, - IBM880 = 2057, - IBM891 = 2058, - IBM903 = 2059, - IBM904 = 2060, - IBM905 = 2061, - IBM918 = 2062, - IBM1026 = 2063, - IBMEBCDICATDE = 2064, - EBCDICATDEA = 2065, - EBCDICCAFR = 2066, - EBCDICDKNO = 2067, - EBCDICDKNOA = 2068, - EBCDICFISE = 2069, - EBCDICFISEA = 2070, - EBCDICFR = 2071, - EBCDICIT = 2072, - EBCDICPT = 2073, - EBCDICES = 2074, - EBCDICESA = 2075, - EBCDICESS = 2076, - EBCDICUK = 2077, - EBCDICUS = 2078, - Unknown8BiT = 2079, - Mnemonic = 2080, - Mnem = 2081, - VISCII = 2082, - VIQR = 2083, - KOI8R = 2084, - HZGB2312 = 2085, - IBM866 = 2086, - PC775Baltic = 2087, - KOI8U = 2088, - IBM00858 = 2089, - IBM00924 = 2090, - IBM01140 = 2091, - IBM01141 = 2092, - IBM01142 = 2093, - IBM01143 = 2094, - IBM01144 = 2095, - IBM01145 = 2096, - IBM01146 = 2097, - IBM01147 = 2098, - IBM01148 = 2099, - IBM01149 = 2100, - Big5HKSCS = 2101, - IBM1047 = 2102, - PTCP154 = 2103, - Amiga1251 = 2104, - KOI7switched = 2105, - BRF = 2106, - TSCII = 2107, - CP51932 = 2108, - windows874 = 2109, - windows1250 = 2250, - windows1251 = 2251, - windows1252 = 2252, - windows1253 = 2253, - windows1254 = 2254, - windows1255 = 2255, - windows1256 = 2256, - windows1257 = 2257, - windows1258 = 2258, - TIS620 = 2259, - CP50220 = 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} diff --git a/source/std.tex b/source/std.tex index bd68a7b14e..fea8f0a37c 100644 --- a/source/std.tex +++ b/source/std.tex @@ -137,7 +137,6 @@ \include{text} \include{numerics} \include{time} -\include{locales} \include{iostreams} \include{threads} \include{exec} diff --git a/source/text.tex b/source/text.tex index ac194bccb6..3b5d8e2ffc 100644 --- a/source/text.tex +++ b/source/text.tex @@ -8,9 +8,5386 @@ These components are summarized in \tref{text.summary}. \begin{libsumtab}{Text library summary}{text.summary} -\ref{re} & Regular expressions library & \tcode{} \\ +\ref{localization} & Localization library & \tcode{}, \tcode{} \\ \rowsep +\ref{text.encoding} & Text encodings identification & \tcode{} \\ \rowsep +\ref{re} & Regular expressions library & \tcode{} \\ \end{libsumtab} +\rSec1[localization]{Localization library} + +\rSec2[localization.general]{General} + +\pnum +This Clause 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 \term{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{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 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 mask = @\seebelow@; + + // numeric values are for exposition only. + static constexpr mask space = 1 << 0; + static constexpr mask print = 1 << 1; + static constexpr mask cntrl = 1 << 2; + static constexpr mask upper = 1 << 3; + static constexpr mask lower = 1 << 4; + static constexpr mask alpha = 1 << 5; + static constexpr mask digit = 1 << 6; + static constexpr mask punct = 1 << 7; + static constexpr mask xdigit = 1 << 8; + static constexpr mask blank = 1 << 9; + static constexpr mask alnum = alpha | digit; + static constexpr mask graph = 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 char_type = 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 id; + + 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 mask = typename 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 char_type = 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 id; + static const size_t table_size = @\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}% +\begin{codeblock} +namespace std { + class codecvt_base { + public: + enum result { ok, partial, error, noconv }; + }; + + template + class codecvt : public locale::facet, public codecvt_base { + public: + using intern_type = internT; + using extern_type = externT; + using state_type = 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 id; + + 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 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 char_type = charT; + using iter_type = 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 id; + + 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 char_type = charT; + using iter_type = 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 id; + + 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} & \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 char_type = charT; + using string_type = 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 id; + + 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 char_type = charT; + using string_type = 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 char_type = charT; + using string_type = 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 id; + + 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 string_type = 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_get}% +\begin{codeblock} +namespace std { + class time_base { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template> + class time_get : public locale::facet, public time_base { + public: + using char_type = charT; + using iter_type = 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 id; + + 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 dateorder = time_base::dateorder; + using iter_type = 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 char_type = charT; + using iter_type = 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 id; + + 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} +\begin{footnote} +Although the C programming language defines no modifiers, most vendors do. +\end{footnote} +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 char_type = charT; + using iter_type = 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 char_type = charT; + using iter_type = InputIterator; + using string_type = 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 id; + + 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 char_type = charT; + using iter_type = OutputIterator; + using string_type = 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 id; + + 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, loc, 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{moneypunct}% +\begin{codeblock} +namespace std { + class money_base { + public: + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + }; + + template + class moneypunct : public locale::facet, public money_base { + public: + using char_type = charT; + using string_type = 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 id; + static const bool intl = 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 pattern = money_base::pattern; + using string_type = 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}% +\begin{codeblock} +namespace std { + class messages_base { + public: + using catalog = @\textit{unspecified signed integer type}@; + }; + + template + class messages : public locale::facet, public messages_base { + public: + using char_type = charT; + using string_type = 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 id; + + 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 catalog = messages_base::catalog; + using string_type = 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}% +\indexlibraryglobal{NULL}% +\indexlibraryglobal{LC_ALL}% +\indexlibraryglobal{LC_COLLATE}% +\indexlibraryglobal{LC_CTYPE}% +\indexlibraryglobal{LC_MONETARY}% +\indexlibraryglobal{LC_NUMERIC}% +\indexlibraryglobal{LC_TIME}% +\begin{codeblock} +namespace std { + struct lconv; + + char* setlocale(int category, const char* locale); + lconv* localeconv(); +} + +#define NULL @\textit{see \ref{support.types.nullptr}}@ +#define LC_ALL @\seebelow@ +#define LC_COLLATE @\seebelow@ +#define LC_CTYPE @\seebelow@ +#define LC_MONETARY @\seebelow@ +#define LC_NUMERIC @\seebelow@ +#define 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 max_name_length = 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; + + 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() == nullptr} 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_} if \tcode{(\exposid{name_}[0] != '\textbackslash 0')} +is \tcode{true}, and +\keyword{nullptr} otherwise. + +\pnum +\remarks +If \tcode{name() == nullptr} is \tcode{false}, +\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 { + other = 1, + unknown = 2, + ASCII = 3, + ISOLatin1 = 4, + ISOLatin2 = 5, + ISOLatin3 = 6, + ISOLatin4 = 7, + ISOLatinCyrillic = 8, + ISOLatinArabic = 9, + ISOLatinGreek = 10, + ISOLatinHebrew = 11, + ISOLatin5 = 12, + ISOLatin6 = 13, + ISOTextComm = 14, + HalfWidthKatakana = 15, + JISEncoding = 16, + ShiftJIS = 17, + EUCPkdFmtJapanese = 18, + EUCFixWidJapanese = 19, + ISO4UnitedKingdom = 20, + ISO11SwedishForNames = 21, + ISO15Italian = 22, + ISO17Spanish = 23, + ISO21German = 24, + ISO60DanishNorwegian = 25, + ISO69French = 26, + ISO10646UTF1 = 27, + ISO646basic1983 = 28, + INVARIANT = 29, + ISO2IntlRefVersion = 30, + NATSSEFI = 31, + NATSSEFIADD = 32, + ISO10Swedish = 35, + KSC56011987 = 36, + ISO2022KR = 37, + EUCKR = 38, + ISO2022JP = 39, + ISO2022JP2 = 40, + ISO13JISC6220jp = 41, + ISO14JISC6220ro = 42, + ISO16Portuguese = 43, + ISO18Greek7Old = 44, + ISO19LatinGreek = 45, + ISO25French = 46, + ISO27LatinGreek1 = 47, + ISO5427Cyrillic = 48, + ISO42JISC62261978 = 49, + ISO47BSViewdata = 50, + ISO49INIS = 51, + ISO50INIS8 = 52, + ISO51INISCyrillic = 53, + ISO54271981 = 54, + ISO5428Greek = 55, + ISO57GB1988 = 56, + ISO58GB231280 = 57, + ISO61Norwegian2 = 58, + ISO70VideotexSupp1 = 59, + ISO84Portuguese2 = 60, + ISO85Spanish2 = 61, + ISO86Hungarian = 62, + ISO87JISX0208 = 63, + ISO88Greek7 = 64, + ISO89ASMO449 = 65, + ISO90 = 66, + ISO91JISC62291984a = 67, + ISO92JISC62991984b = 68, + ISO93JIS62291984badd = 69, + ISO94JIS62291984hand = 70, + ISO95JIS62291984handadd = 71, + ISO96JISC62291984kana = 72, + ISO2033 = 73, + ISO99NAPLPS = 74, + ISO102T617bit = 75, + ISO103T618bit = 76, + ISO111ECMACyrillic = 77, + ISO121Canadian1 = 78, + ISO122Canadian2 = 79, + ISO123CSAZ24341985gr = 80, + ISO88596E = 81, + ISO88596I = 82, + ISO128T101G2 = 83, + ISO88598E = 84, + ISO88598I = 85, + ISO139CSN369103 = 86, + ISO141JUSIB1002 = 87, + ISO143IECP271 = 88, + ISO146Serbian = 89, + ISO147Macedonian = 90, + ISO150 = 91, + ISO151Cuba = 92, + ISO6937Add = 93, + ISO153GOST1976874 = 94, + ISO8859Supp = 95, + ISO10367Box = 96, + ISO158Lap = 97, + ISO159JISX02121990 = 98, + ISO646Danish = 99, + USDK = 100, + DKUS = 101, + KSC5636 = 102, + Unicode11UTF7 = 103, + ISO2022CN = 104, + ISO2022CNEXT = 105, + UTF8 = 106, + ISO885913 = 109, + ISO885914 = 110, + ISO885915 = 111, + ISO885916 = 112, + GBK = 113, + GB18030 = 114, + OSDEBCDICDF0415 = 115, + OSDEBCDICDF03IRV = 116, + OSDEBCDICDF041 = 117, + ISO115481 = 118, + KZ1048 = 119, + UCS2 = 1000, + UCS4 = 1001, + UnicodeASCII = 1002, + UnicodeLatin1 = 1003, + UnicodeJapanese = 1004, + UnicodeIBM1261 = 1005, + UnicodeIBM1268 = 1006, + UnicodeIBM1276 = 1007, + UnicodeIBM1264 = 1008, + UnicodeIBM1265 = 1009, + Unicode11 = 1010, + SCSU = 1011, + UTF7 = 1012, + UTF16BE = 1013, + UTF16LE = 1014, + UTF16 = 1015, + CESU8 = 1016, + UTF32 = 1017, + UTF32BE = 1018, + UTF32LE = 1019, + BOCU1 = 1020, + UTF7IMAP = 1021, + Windows30Latin1 = 2000, + Windows31Latin1 = 2001, + Windows31Latin2 = 2002, + Windows31Latin5 = 2003, + HPRoman8 = 2004, + AdobeStandardEncoding = 2005, + VenturaUS = 2006, + VenturaInternational = 2007, + DECMCS = 2008, + PC850Multilingual = 2009, + PC8DanishNorwegian = 2012, + PC862LatinHebrew = 2013, + PC8Turkish = 2014, + IBMSymbols = 2015, + IBMThai = 2016, + HPLegal = 2017, + HPPiFont = 2018, + HPMath8 = 2019, + HPPSMath = 2020, + HPDesktop = 2021, + VenturaMath = 2022, + MicrosoftPublishing = 2023, + Windows31J = 2024, + GB2312 = 2025, + Big5 = 2026, + Macintosh = 2027, + IBM037 = 2028, + IBM038 = 2029, + IBM273 = 2030, + IBM274 = 2031, + IBM275 = 2032, + IBM277 = 2033, + IBM278 = 2034, + IBM280 = 2035, + IBM281 = 2036, + IBM284 = 2037, + IBM285 = 2038, + IBM290 = 2039, + IBM297 = 2040, + IBM420 = 2041, + IBM423 = 2042, + IBM424 = 2043, + PC8CodePage437 = 2011, + IBM500 = 2044, + IBM851 = 2045, + PCp852 = 2010, + IBM855 = 2046, + IBM857 = 2047, + IBM860 = 2048, + IBM861 = 2049, + IBM863 = 2050, + IBM864 = 2051, + IBM865 = 2052, + IBM868 = 2053, + IBM869 = 2054, + IBM870 = 2055, + IBM871 = 2056, + IBM880 = 2057, + IBM891 = 2058, + IBM903 = 2059, + IBM904 = 2060, + IBM905 = 2061, + IBM918 = 2062, + IBM1026 = 2063, + IBMEBCDICATDE = 2064, + EBCDICATDEA = 2065, + EBCDICCAFR = 2066, + EBCDICDKNO = 2067, + EBCDICDKNOA = 2068, + EBCDICFISE = 2069, + EBCDICFISEA = 2070, + EBCDICFR = 2071, + EBCDICIT = 2072, + EBCDICPT = 2073, + EBCDICES = 2074, + EBCDICESA = 2075, + EBCDICESS = 2076, + EBCDICUK = 2077, + EBCDICUS = 2078, + Unknown8BiT = 2079, + Mnemonic = 2080, + Mnem = 2081, + VISCII = 2082, + VIQR = 2083, + KOI8R = 2084, + HZGB2312 = 2085, + IBM866 = 2086, + PC775Baltic = 2087, + KOI8U = 2088, + IBM00858 = 2089, + IBM00924 = 2090, + IBM01140 = 2091, + IBM01141 = 2092, + IBM01142 = 2093, + IBM01143 = 2094, + IBM01144 = 2095, + IBM01145 = 2096, + IBM01146 = 2097, + IBM01147 = 2098, + IBM01148 = 2099, + IBM01149 = 2100, + Big5HKSCS = 2101, + IBM1047 = 2102, + PTCP154 = 2103, + Amiga1251 = 2104, + KOI7switched = 2105, + BRF = 2106, + TSCII = 2107, + CP51932 = 2108, + windows874 = 2109, + windows1250 = 2250, + windows1251 = 2251, + windows1252 = 2252, + windows1253 = 2253, + windows1254 = 2254, + windows1255 = 2255, + windows1256 = 2256, + windows1257 = 2257, + windows1258 = 2258, + TIS620 = 2259, + CP50220 = 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[re]{Regular expressions library} \indextext{regular expression|(} From 804846a56f7e73dafe4ebd621fa81097d2e94603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 20:15:42 +0100 Subject: [PATCH 90/95] [charconv, format] Move [charconv], [format] to [text] Part of the C++26 clause restructuring (#5315). --- source/text.tex | 3624 ++++++++++++++++++++++++++++++++++++++++++ source/utilities.tex | 3624 ------------------------------------------ 2 files changed, 3624 insertions(+), 3624 deletions(-) diff --git a/source/text.tex b/source/text.tex index 3b5d8e2ffc..82d0b01e44 100644 --- a/source/text.tex +++ b/source/text.tex @@ -8,11 +8,360 @@ 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{format} & Formatting & \tcode{} \\ \rowsep \ref{text.encoding} & Text encodings identification & \tcode{} \\ \rowsep \ref{re} & Regular expressions library & \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 cv-unqualified 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 { +@% +\indexlibraryglobal{chars_format}% +\indexlibrarymember{scientific}{chars_format}% +\indexlibrarymember{fixed}{chars_format}% +\indexlibrarymember{hex}{chars_format}% +\indexlibrarymember{general}{chars_format}% +@ // floating-point format for primitive numerical conversion + enum class chars_format { + scientific = @\unspec@, + fixed = @\unspec@, + hex = @\unspec@, + general = fixed | scientific + }; +@% +\indexlibraryglobal{to_chars_result}% +\indexlibrarymember{ptr}{to_chars_result}% +\indexlibrarymember{ec}{to_chars_result} +@ + // \ref{charconv.to.chars}, primitive numerical output conversion + struct to_chars_result { // freestanding + char* ptr; + errc ec; + 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); +@% +\indexlibraryglobal{from_chars_result}% +\indexlibrarymember{ptr}{from_chars_result}% +\indexlibrarymember{ec}{from_chars_result} +@ + // \ref{charconv.from.chars}, primitive numerical input conversion + struct from_chars_result { // freestanding + const char* ptr; + errc ec; + 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.21.6.1} + +\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{"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.22.1.3, 7.22.1.4} + \rSec1[localization]{Localization library} \rSec2[localization.general]{General} @@ -5388,6 +5737,3281 @@ 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{runtime-format-string}@ { // \expos + private: + basic_string_view @\exposid{str}@; // \expos + public: + @\exposid{runtime-format-string}@(basic_string_view s) noexcept : @\exposid{str}@(s) {} + @\exposid{runtime-format-string}@(const @\exposid{runtime-format-string}@&) = delete; + @\exposid{runtime-format-string}@& operator=(const @\exposid{runtime-format-string}@&) = delete; + }; + @\exposid{runtime-format-string}@ runtime_format(string_view fmt) noexcept { return fmt; } + @\exposid{runtime-format-string}@ runtime_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 + string format(format_string fmt, Args&&... args); + template + 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); + + string vformat(string_view fmt, format_args args); + 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 + Out format_to(Out out, format_string fmt, Args&&... args); + template + 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 + Out vformat_to(Out out, string_view fmt, format_args args); + template + 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 + format_to_n_result format_to_n(Out out, iter_difference_t n, + format_string fmt, Args&&... args); + template + 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 + size_t formatted_size(format_string fmt, Args&&... args); + template + 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 + @\exposid{format-arg-store}@ + make_format_args(Args&... fmt_args); + template + @\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 \iref{format.string.std}. +\item +For chrono types +the \fmtgrammarterm{format-spec} +is interpreted as a \fmtgrammarterm{chrono-format-spec} +as described in \iref{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"} Derived Extracted 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. +\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. + +\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. + +\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::falsename}. +\end{itemize} + +\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 +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 defined, +\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); + basic_format_string(@\exposid{runtime-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} +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 +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 + 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 + 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} +string vformat(string_view fmt, format_args args); +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 + 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 + 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 + Out vformat_to(Out out, string_view fmt, format_args args); +template + 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 + format_to_n_result format_to_n(Out out, iter_difference_t n, + format_string fmt, Args&&... args); +template + 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 + size_t formatted_size(format_string fmt, Args&&... args); +template + 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} +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{?}. +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 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 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!arithmetic types}% +For each \tcode{charT}, +for each cv-unqualified arithmetic type \tcode{ArithmeticT} +other than +\tcode{char}, +\keyword{wchar_t}, +\keyword{char8_t}, +\keyword{char16_t}, or +\keyword{char32_t}, +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 pointer type specializations +\begin{codeblock} +template<> struct formatter; +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 = typename 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}. +\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} 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 +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; + + basic_format_arg arg(size_t id) const noexcept; + std::locale locale(); + + iterator out(); + 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 instantiation 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} +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} +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} +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} +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> + 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> + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 char_type = typename Context::char_type; // \expos + + variant, + const void*, handle> value; // \expos + + template explicit basic_format_arg(T& v) noexcept; // \expos + + public: + basic_format_arg() noexcept; + + explicit operator bool() const noexcept; + + template + decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); + template + 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} +basic_format_arg() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{!(*this)}. +\end{itemdescr} + +\begin{itemdecl} +template 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{char_type*} or \tcode{const char_type*}, +\tcode{static_cast(v)} points to a NTCTS\iref{defns.ntcts}. + +\pnum +\effects +Let \tcode{TD} be \tcode{remove_const_t}. +\begin{itemize} +\item +If \tcode{TD} is \tcode{bool} or \tcode{char_type}, +initializes \tcode{value} with \tcode{v}; +\item +otherwise, if \tcode{TD} is \tcode{char} and \tcode{char_type} is +\keyword{wchar_t}, initializes \tcode{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 \tcode{value} with \tcode{static_cast(v)}; +\item +otherwise, if \tcode{TD} is an unsigned integer type and +\tcode{sizeof(TD) <= sizeof(unsigned int)}, initializes +\tcode{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 +\tcode{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 +\tcode{value} with +\tcode{static_cast(v)}; +\item +otherwise, if \tcode{TD} is a standard floating-point type, +initializes \tcode{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 \tcode{char_type}, +initializes \tcode{value} with +\tcode{basic_string_view(v.data(), v.size())}; +\item +otherwise, if \tcode{decay_t} is +\tcode{char_type*} or \tcode{const char_type*}, +initializes \tcode{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 \tcode{value} with \tcode{static_cast(v)}; +\item +otherwise, initializes \tcode{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} +explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!holds_alternative(value)}. +\end{itemdescr} + +\indexlibrarymember{visit}{basic_format_arg}% +\begin{itemdecl} +template + decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return arg.value.visit(std::forward(vis));} +\end{itemdescr} + +\indexlibrarymember{visit}{basic_format_arg}% +\begin{itemdecl} +template + R visit(this basic_format_arg arg, Visitor&& vis); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return arg.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* ptr_; // \expos + void (*format_)(basic_format_parse_context&, + Context&, const void*); // \expos + + template explicit handle(T& val) noexcept; // \expos + + public: + void format(basic_format_parse_context&, Context& ctx) const; + }; +} +\end{codeblock} + +\indexlibraryctor{basic_format_arg::handle}% +\begin{itemdecl} +template 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 +\tcode{ptr_} with \tcode{addressof(val)} and +\tcode{format_} with +\begin{codeblock} +[](basic_format_parse_context& 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} +void format(basic_format_parse_context& parse_ctx, Context& format_ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{format_(parse_ctx, format_ctx, 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 + @\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 + @\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 size_; // \expos + const basic_format_arg* data_; // \expos + + public: + template + basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; + + 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. +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 + basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{size_} with \tcode{sizeof...(Args)} and +\tcode{data_} with \tcode{store.args.data()}. +\end{itemdescr} + +\indexlibrarymember{get}{basic_format_args}% +\begin{itemdecl} +basic_format_arg get(size_t i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{i < size_ ?\ 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 + 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 + 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: + explicit format_error(const string& what_arg); + 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} +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} +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|(} diff --git a/source/utilities.tex b/source/utilities.tex index 1e799f9bc7..2f66d7d65f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -19,8 +19,6 @@ \ref{expected} & Expected objects & \tcode{} \\ \rowsep \ref{bitset} & Fixed-size sequences of bits & \tcode{} \\ \rowsep \ref{function.objects} & Function objects & \tcode{} \\ \rowsep -\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep -\ref{format} & Formatting & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ \end{libsumtab} @@ -15048,3628 +15046,6 @@ program-defined specialization. \end{itemize} -\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 cv-unqualified 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 { -@% -\indexlibraryglobal{chars_format}% -\indexlibrarymember{scientific}{chars_format}% -\indexlibrarymember{fixed}{chars_format}% -\indexlibrarymember{hex}{chars_format}% -\indexlibrarymember{general}{chars_format}% -@ // floating-point format for primitive numerical conversion - enum class chars_format { - scientific = @\unspec@, - fixed = @\unspec@, - hex = @\unspec@, - general = fixed | scientific - }; -@% -\indexlibraryglobal{to_chars_result}% -\indexlibrarymember{ptr}{to_chars_result}% -\indexlibrarymember{ec}{to_chars_result} -@ - // \ref{charconv.to.chars}, primitive numerical output conversion - struct to_chars_result { // freestanding - char* ptr; - errc ec; - 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); -@% -\indexlibraryglobal{from_chars_result}% -\indexlibrarymember{ptr}{from_chars_result}% -\indexlibrarymember{ec}{from_chars_result} -@ - // \ref{charconv.from.chars}, primitive numerical input conversion - struct from_chars_result { // freestanding - const char* ptr; - errc ec; - 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.21.6.1} - -\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{"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.22.1.3, 7.22.1.4} - -\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{runtime-format-string}@ { // \expos - private: - basic_string_view @\exposid{str}@; // \expos - public: - @\exposid{runtime-format-string}@(basic_string_view s) noexcept : @\exposid{str}@(s) {} - @\exposid{runtime-format-string}@(const @\exposid{runtime-format-string}@&) = delete; - @\exposid{runtime-format-string}@& operator=(const @\exposid{runtime-format-string}@&) = delete; - }; - @\exposid{runtime-format-string}@ runtime_format(string_view fmt) noexcept { return fmt; } - @\exposid{runtime-format-string}@ runtime_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 - string format(format_string fmt, Args&&... args); - template - 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); - - string vformat(string_view fmt, format_args args); - 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 - Out format_to(Out out, format_string fmt, Args&&... args); - template - 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 - Out vformat_to(Out out, string_view fmt, format_args args); - template - 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 - format_to_n_result format_to_n(Out out, iter_difference_t n, - format_string fmt, Args&&... args); - template - 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 - size_t formatted_size(format_string fmt, Args&&... args); - template - 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 - @\exposid{format-arg-store}@ - make_format_args(Args&... fmt_args); - template - @\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 \iref{format.string.std}. -\item -For chrono types -the \fmtgrammarterm{format-spec} -is interpreted as a \fmtgrammarterm{chrono-format-spec} -as described in \iref{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"} Derived Extracted 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. -\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. - -\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. - -\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::falsename}. -\end{itemize} - -\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 -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 defined, -\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); - basic_format_string(@\exposid{runtime-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} -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 -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 - 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 - 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} -string vformat(string_view fmt, format_args args); -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 - 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 - 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 - Out vformat_to(Out out, string_view fmt, format_args args); -template - 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 - format_to_n_result format_to_n(Out out, iter_difference_t n, - format_string fmt, Args&&... args); -template - 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 - size_t formatted_size(format_string fmt, Args&&... args); -template - 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} -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{?}. -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 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 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!arithmetic types}% -For each \tcode{charT}, -for each cv-unqualified arithmetic type \tcode{ArithmeticT} -other than -\tcode{char}, -\keyword{wchar_t}, -\keyword{char8_t}, -\keyword{char16_t}, or -\keyword{char32_t}, -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 pointer type specializations -\begin{codeblock} -template<> struct formatter; -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 = typename 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}. -\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} 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 -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; - - basic_format_arg arg(size_t id) const noexcept; - std::locale locale(); - - iterator out(); - 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 instantiation 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} -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} -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} -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} -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> - 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> - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 char_type = typename Context::char_type; // \expos - - variant, - const void*, handle> value; // \expos - - template explicit basic_format_arg(T& v) noexcept; // \expos - - public: - basic_format_arg() noexcept; - - explicit operator bool() const noexcept; - - template - decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); - template - 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} -basic_format_arg() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\ensures -\tcode{!(*this)}. -\end{itemdescr} - -\begin{itemdecl} -template 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{char_type*} or \tcode{const char_type*}, -\tcode{static_cast(v)} points to a NTCTS\iref{defns.ntcts}. - -\pnum -\effects -Let \tcode{TD} be \tcode{remove_const_t}. -\begin{itemize} -\item -If \tcode{TD} is \tcode{bool} or \tcode{char_type}, -initializes \tcode{value} with \tcode{v}; -\item -otherwise, if \tcode{TD} is \tcode{char} and \tcode{char_type} is -\keyword{wchar_t}, initializes \tcode{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 \tcode{value} with \tcode{static_cast(v)}; -\item -otherwise, if \tcode{TD} is an unsigned integer type and -\tcode{sizeof(TD) <= sizeof(unsigned int)}, initializes -\tcode{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 -\tcode{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 -\tcode{value} with -\tcode{static_cast(v)}; -\item -otherwise, if \tcode{TD} is a standard floating-point type, -initializes \tcode{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 \tcode{char_type}, -initializes \tcode{value} with -\tcode{basic_string_view(v.data(), v.size())}; -\item -otherwise, if \tcode{decay_t} is -\tcode{char_type*} or \tcode{const char_type*}, -initializes \tcode{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 \tcode{value} with \tcode{static_cast(v)}; -\item -otherwise, initializes \tcode{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} -explicit operator bool() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{!holds_alternative(value)}. -\end{itemdescr} - -\indexlibrarymember{visit}{basic_format_arg}% -\begin{itemdecl} -template - decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return arg.value.visit(std::forward(vis));} -\end{itemdescr} - -\indexlibrarymember{visit}{basic_format_arg}% -\begin{itemdecl} -template - R visit(this basic_format_arg arg, Visitor&& vis); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return arg.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* ptr_; // \expos - void (*format_)(basic_format_parse_context&, - Context&, const void*); // \expos - - template explicit handle(T& val) noexcept; // \expos - - public: - void format(basic_format_parse_context&, Context& ctx) const; - }; -} -\end{codeblock} - -\indexlibraryctor{basic_format_arg::handle}% -\begin{itemdecl} -template 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 -\tcode{ptr_} with \tcode{addressof(val)} and -\tcode{format_} with -\begin{codeblock} -[](basic_format_parse_context& 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} -void format(basic_format_parse_context& parse_ctx, Context& format_ctx) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{format_(parse_ctx, format_ctx, 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 - @\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 - @\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 size_; // \expos - const basic_format_arg* data_; // \expos - - public: - template - basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; - - 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. -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 - basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes -\tcode{size_} with \tcode{sizeof...(Args)} and -\tcode{data_} with \tcode{store.args.data()}. -\end{itemdescr} - -\indexlibrarymember{get}{basic_format_args}% -\begin{itemdecl} -basic_format_arg get(size_t i) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{i < size_ ?\ 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 - 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 - 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: - explicit format_error(const string& what_arg); - 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} -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} -format_error(const char* what_arg); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\ensures -\tcode{strcmp(what(), what_arg) == 0}. -\end{itemdescr} - \rSec1[bit]{Bit manipulation} \rSec2[bit.general]{General} From 4b1a9a76c29c31cc3f679a8bdb1603842baf3501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 20:31:33 +0100 Subject: [PATCH 91/95] [text, c.strings] Move text-related parts of [c.strings] to [text] The text-related subclauses [cctype.syn], [cwctype.syn], [cwchar.syn], [cuchar.syn], and [c.mb.wcs] are moved to a new subclause [text.c.strings]. Part of the C++26 clause restructuring (#5226, #5315). --- source/strings.tex | 474 +------------------------------------------- source/text.tex | 484 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 480 insertions(+), 478 deletions(-) diff --git a/source/strings.tex b/source/strings.tex index 32d5f1a9fa..c0dc123c6f 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -21,9 +21,7 @@ \ref{char.traits} & Character traits & \tcode{} \\ \ref{string.view} & String view classes & \tcode{} \\ \rowsep \ref{string.classes} & String classes & \tcode{} \\ \rowsep -\ref{c.strings} & Null-terminated sequence utilities & - \tcode{}, \tcode{}, \tcode{}, - \tcode{}, \tcode{}, \tcode{} \\ +\ref{c.strings} & Null-terminated sequence utilities & \tcode{} \\ \end{libsumtab} \rSec1[char.traits]{Character traits} @@ -5443,106 +5441,6 @@ \rSec1[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}% -\indexlibraryglobal{WEOF}% -\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 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.30} - \rSec2[cstring.syn]{Header \tcode{} synopsis} \indexlibraryglobal{memchr}% @@ -5629,373 +5527,3 @@ \end{note} \xrefc{7.24} - -\rSec2[cwchar.syn]{Header \tcode{} synopsis} - -\indexheader{cwchar}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{WCHAR_MAX}% -\indexlibraryglobal{WCHAR_MIN}% -\indexlibraryglobal{WEOF}% -\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} -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 NULL @\textit{see \ref{support.types.nullptr}}@ // freestanding -#define WCHAR_MAX @\seebelow@ // freestanding -#define WCHAR_MIN @\seebelow@ // freestanding -#define WEOF @\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.29} - -\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} -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 -declares the additional \tcode{mbrtoc8} and \tcode{c8rtomb} functions -and does not declare types \keyword{char16_t} nor \keyword{char32_t}. - -\xrefc{7.28} - -\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.22.7.1, 7.22.8, 7.29.6.2.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.22.7} - -\indexlibraryglobal{mbrlen}% -\indexlibraryglobal{mbrstowcs}% -\indexlibraryglobal{wcrstombs}% -\indexlibraryglobal{mbrtowc}% -\indexlibraryglobal{wcrtomb}% -\begin{itemdecl} -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); -\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.29.6.3} - -\indexlibraryglobal{mbrtoc8}% -\begin{itemdecl} -size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{s} is a null pointer, -equivalent to \tcode{mbrtoc8(nullptr, "", 1, ps)}. -Otherwise, the function inspects at most \tcode{n} bytes -beginning with the byte pointed to by \tcode{s} -to determine the number of bytes needed to complete -the next multibyte character (including any shift sequences). -If the function determines -that the next multibyte character is complete and valid, -\indextext{UTF-8}% -it determines the values of the corresponding UTF-8 code units and then, -if \tcode{pc8} is not a null pointer, -stores the value of the first (or only) such code unit -in the object pointed to by \tcode{pc8}. -Subsequent calls will store successive UTF-8 code units -without consuming any additional input -until all the code units have been stored. -If the corresponding Unicode character is \unicode{0000}{null}, -the resulting state described is the initial conversion state. - -\pnum -\returns -The first of the following that applies (given the current conversion state): -\begin{itemize} -\item \tcode{0}, if the next \tcode{n} or fewer bytes complete -the multibyte character -that corresponds to the \unicode{0000}{null} Unicode character -(which is the value stored). -\item between \tcode{1} and \tcode{n} (inclusive), -if the next n or fewer bytes complete a valid multibyte character -(whose first (or only) code unit is stored); -the value returned is the number of bytes that complete the multibyte character. -\item \tcode{(size_t)(-3)}, if the next code unit -resulting from a previous call has been stored -(no bytes from the input have been consumed by this call). -\item \tcode{(size_t)(-2)}, if the next \tcode{n} bytes -contribute to an incomplete (but potentially valid) multibyte character, and -all \tcode{n} bytes have been processed (no value is stored). -\item \tcode{(size_t)(-1)}, if an encoding error occurs, -in which case the next \tcode{n} or fewer bytes do not contribute to -a complete and valid multibyte character (no value is stored); -the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, and -the conversion state is unspecified. -\end{itemize} -\end{itemdescr} - -\indexlibraryglobal{c8rtomb}% -\begin{itemdecl} -size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{s} is a null pointer, equivalent to -\tcode{c8rtomb(buf, u8'$\backslash$0', ps)} -where \tcode{buf} is an internal buffer. -\indextext{UTF-8}% -Otherwise, if \tcode{c8} completes a sequence of valid UTF-8 code units, -determines the number of bytes needed -to represent the multibyte character (including any shift sequences), -and stores the multibyte character representation in the array -whose first element is pointed to by \tcode{s}. -At most \tcode{MB_CUR_MAX} bytes are stored. -If the multibyte character is a null character, a null byte is stored, -preceded by any shift sequence needed to restore the initial shift state; -the resulting state described is the initial conversion state. - -\pnum -\returns -The number of bytes stored in the array object (including any shift sequences). -If \tcode{c8} does not contribute to a sequence of \keyword{char8_t} -corresponding to a valid multibyte character, -the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, -\tcode{(size_t) (-1)} is returned, and the conversion state is unspecified. - -\pnum -\remarks -Calls to \tcode{c8rtomb} with a null pointer argument for \tcode{s} -may introduce a data race\iref{res.on.data.races} -with other calls to \tcode{c8rtomb} -with a null pointer argument for \tcode{s}. -\end{itemdescr} diff --git a/source/text.tex b/source/text.tex index 82d0b01e44..99d63ad2c5 100644 --- a/source/text.tex +++ b/source/text.tex @@ -8,11 +8,13 @@ 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{format} & Formatting & \tcode{} \\ \rowsep -\ref{text.encoding} & Text encodings identification & \tcode{} \\ \rowsep -\ref{re} & Regular expressions library & \tcode{} \\ +\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep +\ref{localization} & Localization library & \tcode{}, \tcode{} \\ \rowsep +\ref{format} & Formatting & \tcode{} \\ \rowsep +\ref{text.encoding} & Text encodings identification & \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} @@ -13010,3 +13012,475 @@ \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}% +\indexlibraryglobal{WEOF}% +\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 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.30} + +\rSec2[cwchar.syn]{Header \tcode{} synopsis} + +\indexheader{cwchar}% +\indexlibraryglobal{NULL}% +\indexlibraryglobal{WCHAR_MAX}% +\indexlibraryglobal{WCHAR_MIN}% +\indexlibraryglobal{WEOF}% +\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} +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 NULL @\textit{see \ref{support.types.nullptr}}@ // freestanding +#define WCHAR_MAX @\seebelow@ // freestanding +#define WCHAR_MIN @\seebelow@ // freestanding +#define WEOF @\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.29} + +\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} +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 +declares the additional \tcode{mbrtoc8} and \tcode{c8rtomb} functions +and does not declare types \keyword{char16_t} nor \keyword{char32_t}. + +\xrefc{7.28} + +\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.22.7.1, 7.22.8, 7.29.6.2.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.22.7} + +\indexlibraryglobal{mbrlen}% +\indexlibraryglobal{mbrstowcs}% +\indexlibraryglobal{wcrstombs}% +\indexlibraryglobal{mbrtowc}% +\indexlibraryglobal{wcrtomb}% +\begin{itemdecl} +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); +\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.29.6.3} + +\indexlibraryglobal{mbrtoc8}% +\begin{itemdecl} +size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{s} is a null pointer, +equivalent to \tcode{mbrtoc8(nullptr, "", 1, ps)}. +Otherwise, the function inspects at most \tcode{n} bytes +beginning with the byte pointed to by \tcode{s} +to determine the number of bytes needed to complete +the next multibyte character (including any shift sequences). +If the function determines +that the next multibyte character is complete and valid, +\indextext{UTF-8}% +it determines the values of the corresponding UTF-8 code units and then, +if \tcode{pc8} is not a null pointer, +stores the value of the first (or only) such code unit +in the object pointed to by \tcode{pc8}. +Subsequent calls will store successive UTF-8 code units +without consuming any additional input +until all the code units have been stored. +If the corresponding Unicode character is \unicode{0000}{null}, +the resulting state described is the initial conversion state. + +\pnum +\returns +The first of the following that applies (given the current conversion state): +\begin{itemize} +\item \tcode{0}, if the next \tcode{n} or fewer bytes complete +the multibyte character +that corresponds to the \unicode{0000}{null} Unicode character +(which is the value stored). +\item between \tcode{1} and \tcode{n} (inclusive), +if the next n or fewer bytes complete a valid multibyte character +(whose first (or only) code unit is stored); +the value returned is the number of bytes that complete the multibyte character. +\item \tcode{(size_t)(-3)}, if the next code unit +resulting from a previous call has been stored +(no bytes from the input have been consumed by this call). +\item \tcode{(size_t)(-2)}, if the next \tcode{n} bytes +contribute to an incomplete (but potentially valid) multibyte character, and +all \tcode{n} bytes have been processed (no value is stored). +\item \tcode{(size_t)(-1)}, if an encoding error occurs, +in which case the next \tcode{n} or fewer bytes do not contribute to +a complete and valid multibyte character (no value is stored); +the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, and +the conversion state is unspecified. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{c8rtomb}% +\begin{itemdecl} +size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{s} is a null pointer, equivalent to +\tcode{c8rtomb(buf, u8'$\backslash$0', ps)} +where \tcode{buf} is an internal buffer. +\indextext{UTF-8}% +Otherwise, if \tcode{c8} completes a sequence of valid UTF-8 code units, +determines the number of bytes needed +to represent the multibyte character (including any shift sequences), +and stores the multibyte character representation in the array +whose first element is pointed to by \tcode{s}. +At most \tcode{MB_CUR_MAX} bytes are stored. +If the multibyte character is a null character, a null byte is stored, +preceded by any shift sequence needed to restore the initial shift state; +the resulting state described is the initial conversion state. + +\pnum +\returns +The number of bytes stored in the array object (including any shift sequences). +If \tcode{c8} does not contribute to a sequence of \keyword{char8_t} +corresponding to a valid multibyte character, +the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, +\tcode{(size_t) (-1)} is returned, and the conversion state is unspecified. + +\pnum +\remarks +Calls to \tcode{c8rtomb} with a null pointer argument for \tcode{s} +may introduce a data race\iref{res.on.data.races} +with other calls to \tcode{c8rtomb} +with a null pointer argument for \tcode{s}. +\end{itemdescr} From 939e18a4cc7c95134c292ee7b6f3e8a35dede339 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 16 Oct 2024 21:13:19 +0200 Subject: [PATCH 92/95] [check] Remove regex.tex --- tools/check-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check-source.sh b/tools/check-source.sh index e3cf49d72c..74ca99b93d 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -6,7 +6,7 @@ failed=0 # Ignore files where rules may be violated within macro definitions. texfiles=$(ls *.tex | grep -v macros.tex | grep -v layout.tex | grep -v tables.tex) -texlibdesc="support.tex concepts.tex diagnostics.tex memory.tex meta.tex utilities.tex strings.tex containers.tex iterators.tex ranges.tex algorithms.tex numerics.tex time.tex locales.tex iostreams.tex regex.tex threads.tex" +texlibdesc="support.tex concepts.tex diagnostics.tex memory.tex meta.tex utilities.tex strings.tex containers.tex iterators.tex ranges.tex algorithms.tex numerics.tex time.tex locales.tex iostreams.tex threads.tex" texlib="lib-intro.tex $texlibdesc" # Filter that reformats the error message as a "workflow command", From 8003b627a7e336c2e9f350a3bb1ad395ec7c1cc7 Mon Sep 17 00:00:00 2001 From: lprv <100177227+lprv@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:41:35 +0000 Subject: [PATCH 93/95] [expr, temp.arg.nontype] Use 'pointer to' instead of 'address of' (#6174) Specifically, in: * [expr.prim.lambda.closure]p8, p11 * [expr.const]p13.3 * [temp.arg.nontype]p3 --- source/expressions.tex | 16 ++++++++-------- source/templates.tex | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 1cf4411103..54e40c91a9 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2137,9 +2137,9 @@ has a non-throwing exception specification. If the function call operator is a static member function, then the value returned by this conversion function is -the address of the function call operator. +a pointer to the function call operator. Otherwise, the value returned by this conversion function -is the address of a function \tcode{F} that, when invoked, +is a pointer to a function \tcode{F} that, when invoked, has the same effect as invoking the closure type's function call operator on a default-constructed instance of the closure type. \tcode{F} is a constexpr function @@ -2214,10 +2214,10 @@ If the function call operator template is a static member function template, then the value returned by any given specialization of this conversion function template is -the address of the corresponding function call operator template specialization. +a pointer to the corresponding function call operator template specialization. Otherwise, the value returned by any given specialization of this conversion function -template is the address of a function \tcode{F} that, when invoked, has the same +template is a pointer to a function \tcode{F} that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator template specialization on a default-constructed instance of the closure type. \tcode{F} is a constexpr function @@ -7986,10 +7986,10 @@ it does not have an indeterminate or erroneous value\iref{basic.indet}, \item - if the value is of pointer type, it contains - the address of an object with static storage duration, - the address past the end of such an object\iref{expr.add}, - the address of a non-immediate function, + if the value is of pointer type, it is + a pointer to an object with static storage duration, + a pointer past the end of such an object\iref{expr.add}, + a pointer to a non-immediate function, or a null pointer value, \item diff --git a/source/templates.tex b/source/templates.tex index 34db14f83a..ba8462df53 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -1200,8 +1200,8 @@ For a non-type \grammarterm{template-parameter} of reference or pointer type, or for each non-static data member of reference or pointer type in a non-type \grammarterm{template-parameter} of class type or subobject thereof, -the reference or pointer value shall not refer to -or be the address of (respectively): +the reference or pointer value shall not refer +or point to (respectively): \begin{itemize} \item a temporary object\iref{class.temporary}, \item a string literal object\iref{lex.string}, From 198e991fed47efcd8b7fe1ad98ecde4d8722a201 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Wed, 2 Oct 2024 15:55:49 -0400 Subject: [PATCH 94/95] [except.handle] group all paragraphs on searching for handler This commit moves all of the paragraphs involved in the search for a handler for an exception into a single logical sequence. After this change, [except.spec] deals only with specifying the 'noexcept' function decorator and its interaction with the 'noexcept' operator, and contains no text regarding exceptions themselves. It might be appropriate to move that subclause into the [dcl] structure at a future date. --- source/exceptions.tex | 69 +++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 8b6b62d651..a462fe0bff 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -615,6 +615,40 @@ handler continues in a dynamically surrounding try block of the same thread. +\pnum +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If the search for a handler +encounters the outermost block of a function with a +non-throwing exception specification, +the function \tcode{std::terminate}\iref{except.terminate} is invoked. +\begin{note} +An implementation is not permitted to reject an expression merely because, when +executed, it throws or might +throw an exception from a function with a non-throwing exception specification. +\end{note} +\begin{example} +\begin{codeblock} +extern void f(); // potentially-throwing + +void g() noexcept { + f(); // valid, even if \tcode{f} throws + throw 42; // valid, effectively a call to \tcode{std::terminate} +} +\end{codeblock} +The call to +\tcode{f} +is well-formed despite the possibility for it to throw an exception. +\end{example} + +\pnum +If no matching handler is found, +the function \tcode{std::terminate} is invoked; +whether or not the stack is unwound before this invocation of +\tcode{std::terminate} +is \impldef{stack unwinding before invocation of +\tcode{std::terminate}}\iref{except.terminate}. + \pnum A handler is considered \defnx{active}{exception handling!handler!active} when initialization is complete for the parameter (if any) of the catch clause. @@ -632,14 +666,6 @@ still active is called the \defnx{currently handled exception}{exception handling!currently handled exception}. -\pnum -If no matching handler is found, -the function \tcode{std::terminate} is invoked; -whether or not the stack is unwound before this invocation of -\tcode{std::terminate} -is \impldef{stack unwinding before invocation of -\tcode{std::terminate}}\iref{except.terminate}. - \pnum Referring to any non-static member or base class of an object in the handler for a @@ -804,33 +830,6 @@ has a non-throwing exception specification. \end{example} -\pnum -\indextext{exception handling!terminate called@\tcode{terminate} called}% -\indextext{\idxcode{terminate}!called}% -Whenever an exception is thrown -and the search for a handler\iref{except.handle} -encounters the outermost block of a function with a -non-throwing exception specification, -the function \tcode{std::terminate} is invoked\iref{except.terminate}. -\begin{note} -An implementation is not permitted to reject an expression merely because, when -executed, it throws or might -throw an exception from a function with a non-throwing exception specification. -\end{note} -\begin{example} -\begin{codeblock} -extern void f(); // potentially-throwing - -void g() noexcept { - f(); // valid, even if \tcode{f} throws - throw 42; // valid, effectively a call to \tcode{std::terminate} -} -\end{codeblock} -The call to -\tcode{f} -is well-formed despite the possibility for it to throw an exception. -\end{example} - \pnum An expression $E$ is \defnx{potentially-throwing}{potentially-throwing!expression} if From 6e29602da83c9a684dc758ace1c7eef21081b75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Oct 2024 18:01:39 +0100 Subject: [PATCH 95/95] Update configuration for new working draft N4993 and add corresponding Editors' Report N4994 --- papers/n4994.html | 737 +++++++++++++++++++++++++++++++++++++++++++++ papers/n4994.md | 590 ++++++++++++++++++++++++++++++++++++ papers/wd-index.md | 1 + source/config.tex | 2 +- 4 files changed, 1329 insertions(+), 1 deletion(-) create mode 100644 papers/n4994.html create mode 100644 papers/n4994.md diff --git a/papers/n4994.html b/papers/n4994.html new file mode 100644 index 0000000000..1778a35243 --- /dev/null +++ b/papers/n4994.html @@ -0,0 +1,737 @@ + + + + + +N4994 Editors’ Report: Programming Languages — C++ + + +

N4994 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-10-16

+ +

Thomas Köppe (editor, Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor, Bright Side Computing, LLC)
+Richard Smith (co-editor, Google Inc)

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes.

+ +

New papers

+ +
    +
  • N4993 is the +current working draft for C++26. It replaces +N4988.
  • +
  • N4994 is this Editors' Report.
  • +
+ +

Draft approval

+ +

The previous drafts +N4986 +and +N4988 +were not approved at any WG21 meeting. For approval of this draft, N4993, +please consult the previous Editors' reports +N4987 +and +N4989 +as well as this one.

+ +

No motions

+ +

There have been no new, approved WG21 motions. +This revision contains only editorial changes.

+ +

A few of the editorial changes fix mistakes in our LaTeX sources that were +reported to us by the ISO secretariat during the ongoing publication of C++23.

+ +

Editorial changes

+ +

Major editorial changes

+ +

For this revision, we have reorganised several clauses and subclauses. +As a reminder: the editorial team aims to perform only one major reorganisation +that changes top-level clause numbers per C++ revision, and this is it for C++26.

+ +

The changes create a new clause "Text processing library [text]" that collects +formatting, conversions, locales, regular expressions, and text-related C library +facilities. Clauses are rearranged as:

+ +
    +
  • Algorithms library [algorithms]
  • +
  • Strings library [strings]
  • +
  • Text processing library [text]
  • +
  • Numerics library [numerics]
  • +
  • Time library [time]
  • +
  • Input/output library [input.output]
  • +
+ +

The new [text] clause obtains the following contents:

+ +
    +
  • Primitive numeric conversions [charconv], from [utilities]
  • +
  • Formatting [format], from [utilities]
  • +
  • Text encodings identification [text.encoding], extracted from [localization]
  • +
  • Localization library [localization]
  • +
  • Regular expressions library [re]
  • +
  • C library facilities [cctype.syn], [cwctype.syn], [cwchar.syn], [cuchar.syn], and [c.mb.wcs]
  • +
+ +

Additionally, the following subclauses are moved:

+ +
    +
  • Debugging [debugging] from [utilities] to the end of [diagnostics]
  • +
  • Execution policies [execpol] from [utilities] to the end of [algorithms.parallel]
  • +
  • Class type_index [type.index] from [utilities] to [support.rtti]
  • +
+ +

This removes a number of unrelated clauses from the large [utilities] clause.

+ +

Finally, we spread the synopses in [containers] out to appear right in front +of the classes they define.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4988 is below. This +list excludes changes that do not affect the body text or only affect whitespace +or typeface. For a complete list including such changes (or for the actual +deltas applied by these changes), consult the +draft sources on GitHub.

+ +
commit 15a43d522467d389bd9340081d65dbf17d44d255
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 5 12:21:56 2024 +0100
+
+    [temp.over.link] Reword to clarify that declarations correspond (#5999)
+
+commit 3c0f4cf0a03892157ebf3a472d3e9450a41f038e
+Author: Lewis Baker <lewissbaker@users.noreply.github.com>
+Date:   Sun Aug 4 09:26:26 2024 +0930
+
+    [snd.expos] Fix typo in definition of SCHED-ENV exposition-only helper
+
+    Change `o1` -> `o2` to reference the expression declared as part of the definition of `SCHED-ENV`.
+
+commit 5056b86597f5ba9278601db46a415f2d76e1bc8f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Aug 2 17:38:05 2024 +0200
+
+    [temp.constr.order] Reflect fold expanded constraints in footnotes
+
+commit c92bc384b118412322f9893832508bf17f46f644
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 1 12:35:50 2024 +0200
+
+    [dcl.fct] Fix obsolete phrasing when defining 'function type'
+
+commit fabbff2d812e0a99bd1162460812ec2f5399636e
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Aug 8 17:15:39 2024 -0400
+
+    [sequences] Consistent comma in "If X, there are no effects" (#7139)
+
+commit 04c5a0c509dbf8f9f81223d1de5bb917cd3074c5
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Tue Aug 20 12:21:43 2024 +0200
+
+    [meta.const.eval] Fix function declaration in example (#7234)
+
+commit ab4c0663dc72f09fb8ef6c366352c9d1a68e8fa9
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Fri Aug 23 22:06:05 2024 +0400
+
+    [expr.prim.lambda.capture] Incorporate ellipsis into "captured by copy" definition
+
+commit 6ea6df4c96653d6696bb0133253ea0159b0f278f
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Sat Aug 24 23:24:01 2024 +0400
+
+    [dcl.type.elab] Remove redundant full stop (#7242)
+
+commit 24ceda755967b022e8e089d4f0cdcf4bc99a4adb
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Aug 26 18:29:28 2024 +0800
+
+    [exec.snd.apply,exec.schedule.from] Properly mark "see below" (#7210)
+
+commit 447b6291061d50a582f72dd42d9d6265857ded5c
+Author: Joachim Wuttke <j.wuttke@fz-juelich.de>
+Date:   Mon Aug 26 22:30:39 2024 +0200
+
+    [numerics] Correct typo Bessell -> Bessel (#7244)
+
+commit db0ca108a9b44ef8f06338ecf68f1e4653be4267
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Aug 29 06:13:18 2024 -0400
+
+    [inplace.vector] Fix some spelling/grammar issues (#7243)
+
+commit 21e477fb6dbfa7813eb2263bfa31c748bdce589b
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Aug 30 05:07:36 2024 -0700
+
+    [lib] Remove `inline` from variable templates (#7240)
+
+commit c001805bb769fe237034151d59ddd20835a17298
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 30 20:52:00 2024 +0800
+
+    [lib] Remove `friend class X` (#6427)
+
+    Friendship between library classes is considered an implementation detail.
+
+commit 1fafde9a04a3760debb932839791b1d2047ba432
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 30 20:52:49 2024 +0800
+
+    [fs.class.directory.entry.general] Remove superfluous "unneeded" (#7245)
+
+commit e010cf6cde64a498c2bc4291e7e79e66e8ace79a
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Fri Aug 23 21:03:51 2024 +0400
+
+    [basic.scope.scope] Fix a note about declarations that do not bind names
+
+    The note is saying that declarations of qualified names do not bind names, but this is not supported by normative wording in [dcl.meaning]
+
+commit 36a1f39068e71d69e4ca534c5b72891055675e88
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed Sep 4 10:23:14 2024 -0400
+
+    [forward.list] Replace misplaced comma with period (#7246)
+
+commit f23059bf704a48b4805db28441ec73b61054ab9d
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Sep 5 00:03:56 2024 +0800
+
+    [optional.syn] Use `decay_t<T>` directly instead of "see below" (#7247)
+
+commit 9d9a3777f1a571dd2648023fe70848c32aebda09
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sun Sep 8 12:13:53 2024 -0700
+
+    [associative.reqmts.general,unord.req.general] Fix cross-references to [container.alloc.reqmts] and [container.reqmts] (#7249)
+
+    Both paragraphs incorrectly point to [container.reqmts] instead of [container.alloc.reqmts] for "the requirements of an allocator-aware container".
+
+commit d930c5fa6728dd0b599f9c7918a2f0a0f747aaa2
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Sep 16 20:35:33 2024 +0200
+
+    [expr.delete] Remove stray "the" between words (#7253)
+
+commit 9243ba5befaea8fd3e878e6114942db8d556a6e0
+Author: Steve Downey <sdowney@gmail.com>
+Date:   Tue Sep 17 06:13:18 2024 -0400
+
+    [optional.assign] Use itemized list for operator=(U&& v) constraints (#7255)
+
+commit 4930897a2a45fa57fd9d766a24229a9e3f14f23e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Aug 21 13:58:22 2021 +0200
+
+    [dcl.spec.general,dcl.fct.spec] Clarify duplication of decl-specifiers
+
+commit d0c00bf629f4b91d19176c2397aa3ff7c1c0ce63
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 26 18:49:15 2024 +0200
+
+    [tab:lex.charset.literal] Shorten table heading
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 945b1c071ed511d11a2152aa70e08290f91a7856
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 26 19:11:58 2024 +0200
+
+    [tab:re.matchflag] Shorten table heading
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 4e34492bc7279fedb0e066f4925860e686fa81dc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 26 19:43:50 2024 +0200
+
+    [rand.req] Fix table headers for longtable continued on following page
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 2b1e6d2952987bf4ada8275212a7bb297bb0c1c7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 26 20:19:01 2024 +0200
+
+    [macros] Fix duplicate vertical lines visible in tables in [optional.assign]
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 0680a08ee677e0970b4460fd614f58b122845047
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Sep 26 21:59:34 2024 +0100
+
+    [ios.init] Remove unused Init::init_cnt static member (#7263)
+
+    The text that made use of this variable was removed by LWG1123 and has
+    not been present in the WP since N3090. The effects of Init construction
+    and destruction are specified entirely without the use of this variable,
+    so it serves no purpose now.
+
+commit afdd158f555892507bc44c6d372c3b45a7f09832
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 27 00:09:11 2024 +0200
+
+    [styles] Format title of \codeblocktu using 'caption' package
+
+    This restores the C++20 status of the formatting.
+
+commit 2b3e09e2cc773b7205310917c5a6b2bdd87340af
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Oct 1 03:22:29 2024 -0700
+
+    [inplace.vector.cons] "Constructs an object" is redundant (#7252)
+
+commit 70954edf0b2c915d9b2ca4a1cff99b1c1cba2089
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 1 23:09:04 2024 -0400
+
+    [depr.lit] Fix grammar according to P2361R6
+
+    P2361R6 introduced the notion of unevaluated strings, and
+    updated the grammar for literal operator function accodingly.
+    Unfortunely, the corresponding grammar reference that was
+    deprecated was not similarly updated.
+
+commit 08b167d5476c9fd02a7a0484ae031cb358a99ddf
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Oct 5 22:24:02 2024 +0100
+
+    [priqueue.cons.alloc] Add missing initialization for comp (#7291)
+
+    This is consistent with p2 and p8 which also value-initialize it.
+
+commit 738b14f990e0575a3ca63b579d87edb5a6133ffb
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Oct 5 15:03:04 2024 -0700
+
+    [array.creation] Clarify "Mandates" for `to_array` overloads (#7286)
+
+    It's confusing that these `to_array` overloads require `T` to be constructible from various types, when they actually construct `remove_cv_t<T>` objects. We experts know that initialization doesn't depend on the cv-qualification of the target type ([dcl.init.general]/16), but there's no need to make readers jump through hoops to understand the spec.
+
+commit d5c9f2d248860e8e7de78f595b93a8b01c7e02c8
+Author: Lewis Baker <lewissbaker@users.noreply.github.com>
+Date:   Tue Oct 8 21:07:48 2024 +1030
+
+    [exec.split,exec.when.all] Fix typo stop_callback_of_t -> stop_callback_for_t (#7295)
+
+commit 58c01ba5765e8c91ce4aab462d25247167a7e481
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Oct 8 11:38:42 2024 +0100
+
+    [re.grammar] Add missing backslash to UnicodeEscapeSequence example (#7290)
+
+commit ebef68dd9f1c3bccfe06d14eb83c05a7a35dcec3
+Author: Lewis Baker <lewissbaker@users.noreply.github.com>
+Date:   Tue Oct 8 22:06:23 2024 +1030
+
+    [exec.just] Add missing LaTeX escape for product-type construction (#7216)
+
+commit 7ea8f59e19842e720360f15b64c2199ea27641ac
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Oct 10 17:53:54 2024 +0800
+
+    [mutex.syn] Add missing ',' for consistency
+
+commit 7c6322a59e3359c5002357831328b25939cd5383
+Author: Lewis Baker <lewissbaker@users.noreply.github.com>
+Date:   Sun Oct 13 04:07:30 2024 +1030
+
+    [stoptoken.concepts] Remove redundant 'swappable<Token>' clause from 'stoppable_token' concept (#7299)
+
+    The `stoppable_token<Token>` concept requires both `copyable<Token>` and `swappable<Token>`. However, the `copyable<Token>` requirement already subsumes `movable<Token>`, which subsumes `swappable<Token>`.
+
+    Therefore the requirement for `swappable<Token>` can be removed from the `stoppable_token` concept definition with no semantic change.
+
+commit 9bf42221ab5a52ef10cb980a22e8a9617dbbf18b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Oct 12 22:39:57 2024 +0200
+
+    [rcu.syn] Add missing ',' in comment (#7301)
+
+commit a0411db859cf1eabc2be24a5d2add4eaf288dac5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 14 12:30:30 2024 +0200
+
+    [expr.const] Add paragraph number for general example
+
+commit 3982d5d5758df949e3c2e0174c72758189be6f2e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 14 08:54:22 2024 -0400
+
+    [except.ctor] Retitle subclause as 'stack unwinding' (#7282)
+
+    The purpose of this subclause is to define stack unwinding,
+    which in specified in terms of the lifetime of objects, not
+    just class types.  Hence, while much of the text is addressing
+    interactions with contructors and destructors (the original
+    subclause title) it does more than just that.
+
+commit 4eb30d3d618ef44ae3925a1a62090bbbbfe8cabf
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 16 07:39:15 2024 -0400
+
+    [cpp.subst] change "proprocessing file" to "translation unit" (#7293)
+
+    The term 'preprocessing translation unit' is defined in [lex.separate]
+    while the term 'preprocessing file' is never defined, and is
+    not used anywhere else in the standard.  Prefer to use the
+    specified term, as it reasonably covers this case.
+
+commit 40228c690cb8d2ac27bd54bdddeabe425bd022b2
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 16 07:40:20 2024 -0400
+
+    [cpp.import] Change "directive" to "definition" in "active macro directive" (#7292)
+
+    The term 'active macro directive' is defined in p6, but never used.
+    Meanwhile, there are multiple uses of 'active macro definition' but
+    that term is never defined, including in the very sentence following
+    the definition of the unused term, and in other clauses that
+    cross-reference to this clause for their definition.
+
+commit 47da0e8b88bf1aa20aa474edf04a6d29e70b7563
+Author: Anders Schau Knatten <anders@knatten.org>
+Date:   Wed Oct 16 13:41:26 2024 +0200
+
+    [over.oper.general] Change "basic type" to "fundamental type" (#7287)
+
+    The term "basic type" is used twice in this note but it's never defined anywhere, nor used.
+
+commit 7fe7519a5af674cd914344c650529f743fd92fc2
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 1 22:13:53 2024 -0400
+
+    [except.handle] Remove confusing comparison to variadic functions
+
+    The analogy that the ellipsis in an exception handler was similar to an
+    ellipsis in a function declaration may have made sense at one time, but
+    the comparison with a syntax using a macro based API calling 'va_arg'
+    to access its contents --- something that is not possible for an
+    exception handler --- seems more confusing than helpful today.
+
+commit d225f51f8cb799fb014cb73beb7dcccc044392cc
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Aug 20 11:58:24 2024 +0100
+
+    [text.encoding.aliases] Add note about what isn't required
+
+    Make it explicit that `copyable` is intended, rather than `semiregular`,
+    and that the return types of `begin()` and `end()` can differ.
+
+    Also remove a FIXME comment for something that doesn't need fixing.
+    These requirements on a type are specified in our usual form, it would
+    be wrong to use _Remarks_: or _Requires_: here.
+
+commit 6338d95ae620f5e4d37d27a39a40f9de9af37b77
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 16 08:47:02 2024 -0400
+
+    [lex.charset] Introduce parent subclause [lex.char] for character sets and UCNs (#7067)
+
+    The grammar for universal-character-name is oddly sandwiched into the
+    middle of the subclause talking about the different character sets used
+    by the standard.  To improve the flow, extract that grammar into its own
+    subclause.
+
+    In the extraction, I make three other clarifying changes.  First, describe
+    this new subclause as 'a way to name any element of the of the translation
+    character set using just the basic character set' rather than simply
+    'a way to name other characters'. Then, merge the sentence on where universal
+    characters are prohibited into the new intro sentence describing universal
+    characters, to make clear that there is no contradiction between nominating
+    a character, and how that character can be used. Finally, remove the 'one of'
+    in the grammar where there is only one option to choose.
+
+commit 9b6b757f34bf4a1eeb6a66481a444b83f1ee5770
+Author: Matthias Kretz <m.kretz@gsi.de>
+Date:   Thu Sep 12 21:41:02 2024 +0200
+
+    [sf.cmath.assoc.laguerre,sf.cmath.assoc.legendre] Add reference to eq
+
+    The associated Laguerre/Legendre functions build on the
+    Laguerre/Legendre functions, which are defined in different equations.
+    Point to them from the associated functions.
+
+    Also use the correct \ell as used in the formula.
+
+commit 0456a32e41772b0a68b4055fb4e6533cb64e0e3d
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Thu Sep 5 23:59:58 2024 +0800
+
+    [utility.syn, flat.map.defn] Remove all [[nodiscard]] from library wording
+
+commit 8b2c7fc3c58bd109c82a016ee2cc5b691bdcd853
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Jun 10 23:22:04 2024 +0200
+
+    [expr.new] Extend example for new-expressions with zero size arrays
+
+commit fb34daf31b53389cc35b3f5f65a69785fc6dd1de
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 23 22:32:52 2024 -0400
+
+    [char.traits] Better cross-reference several headers
+
+commit 220cb742e8056ad033ad8dce5630d7d3acaa4c7d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 15:37:39 2024 +0100
+
+    [debugging] Move [debugging] to the end of Clause [diagnostics]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 7a2dafa6b4cca842e264bfd544b69452fb448c39
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 15:43:39 2024 +0100
+
+    [execpol] Move [execpol] to the end of subclause [algorithms.parallel]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 93e2e1c6bcf5e9c3e551d964978e8bf241c392a4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 15:52:54 2024 +0100
+
+    [type.index] Move [type.index] into subclause [support.rtti]
+
+    The subclause is integrated into the structure of [support.rtti],
+    meaning that the synopsis becomes a sibling of the rest, and the
+    subdivisions of the remaining text are removed (in analogy with
+    [type.info]).
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit cdb120a4aee270f4e6e40dd7b07885c70651224e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 17:25:51 2024 +0100
+
+    [containers] Move synopses right in front of the classes they define
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit b7e389c9feca4839f77ad60985f509e01f96a399
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 15:27:06 2024 +0100
+
+    [std] Reorder clauses: [algorithm], [strings]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 5512050c2db44d87566d25ce4f70b530624cb330
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 15:36:47 2024 +0100
+
+    [std] Create new top-level Clause [text], following [strings]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit fc6f670832980fc7b8219cb6945592cbe45d9239
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 19:01:21 2024 +0100
+
+    [text, re] Move [re] into [text]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 5d106373aada591874ab5e38301502b3012e0502
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 19:06:03 2024 +0100
+
+    [text, localization] Move [localization] into [text]
+
+    The subclause [text.encodings] is extracted and elevated to a sibling
+    subclause of [localization].
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 804846a56f7e73dafe4ebd621fa81097d2e94603
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 20:15:42 2024 +0100
+
+    [charconv, format] Move [charconv], [format] to [text]
+
+    Part of the C++26 clause restructuring (#5315).
+
+commit 4b1a9a76c29c31cc3f679a8bdb1603842baf3501
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 20:31:33 2024 +0100
+
+    [text, c.strings] Move text-related parts of [c.strings] to [text]
+
+    The text-related subclauses [cctype.syn], [cwctype.syn], [cwchar.syn],
+    [cuchar.syn], and [c.mb.wcs] are moved to a new subclause [text.c.strings].
+
+    Part of the C++26 clause restructuring (#5226, #5315).
+
+commit 8003b627a7e336c2e9f350a3bb1ad395ec7c1cc7
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Oct 16 19:41:35 2024 +0000
+
+    [expr, temp.arg.nontype] Use 'pointer to' instead of 'address of' (#6174)
+
+    Specifically, in:
+     * [expr.prim.lambda.closure]p8, p11
+     * [expr.const]p13.3
+     * [temp.arg.nontype]p3
+
+commit 198e991fed47efcd8b7fe1ad98ecde4d8722a201
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 2 15:55:49 2024 -0400
+
+    [except.handle] group all paragraphs on searching for handler
+
+    This commit moves all of the paragraphs involved in the search for a
+    handler for an exception into a single logical sequence.
+
+    After this change, [except.spec] deals only with specifying the
+    'noexcept' function decorator and its interaction with the
+    'noexcept' operator, and contains no text regarding exceptions
+    themselves.  It might be appropriate to move that subclause into
+    the [dcl] structure at a future date.
+
+ + diff --git a/papers/n4994.md b/papers/n4994.md new file mode 100644 index 0000000000..223aaa59bd --- /dev/null +++ b/papers/n4994.md @@ -0,0 +1,590 @@ +# N4994 Editors' Report -- Programming Languages -- C++ + +Date: 2024-10-16 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4993](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4993.pdf) is the + current working draft for C++26. It replaces + [N4988](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf). + * N4994 is this Editors' Report. + +## Draft approval + +The previous drafts +[N4986](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf) +and +[N4988](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf) +were not approved at any WG21 meeting. For approval of this draft, N4993, +please consult the previous Editors' reports +[N4987](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4987.html) +and +[N4989](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4989.html) +as well as this one. + +## No motions + +There have been no new, approved WG21 motions. +This revision contains only editorial changes. + +A few of the editorial changes fix mistakes in our LaTeX sources that were +reported to us by the ISO secretariat during the ongoing publication of C++23. + +## Editorial changes + +### Major editorial changes + +For this revision, we have reorganised several clauses and subclauses. +As a reminder: the editorial team aims to perform only one major reorganisation +that changes top-level clause numbers per C++ revision, and this is it for C++26. + +The changes create a new clause "Text processing library `[text]`" that collects +formatting, conversions, locales, regular expressions, and text-related C library +facilities. Clauses are rearranged as: + + * Algorithms library `[algorithms]` + * Strings library `[strings]` + * Text processing library `[text]` + * Numerics library `[numerics]` + * Time library `[time]` + * Input/output library `[input.output]` + +The new `[text]` clause obtains the following contents: + + * Primitive numeric conversions `[charconv]`, from `[utilities]` + * Formatting `[format]`, from `[utilities]` + * Text encodings identification `[text.encoding]`, extracted from `[localization]` + * Localization library `[localization]` + * Regular expressions library `[re]` + * C library facilities `[cctype.syn]`, `[cwctype.syn]`, `[cwchar.syn]`, `[cuchar.syn]`, and `[c.mb.wcs]` + +Additionally, the following subclauses are moved: + +* Debugging `[debugging]` from `[utilities]` to the end of `[diagnostics]` +* Execution policies `[execpol]` from `[utilities]` to the end of `[algorithms.parallel]` +* Class `type_index` `[type.index]` from `[utilities]` to `[support.rtti]` + +This removes a number of unrelated clauses from the large `[utilities]` clause. + +Finally, we spread the synopses in `[containers]` out to appear right in front +of the classes they define. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4988 is below. This +list excludes changes that do not affect the body text or only affect whitespace +or typeface. For a complete list including such changes (or for the actual +deltas applied by these changes), consult the +[draft sources on GitHub](https://github.com/cplusplus/draft/compare/n4988...n4993). + + commit 15a43d522467d389bd9340081d65dbf17d44d255 + Author: Thomas Köppe + Date: Mon Aug 5 12:21:56 2024 +0100 + + [temp.over.link] Reword to clarify that declarations correspond (#5999) + + commit 3c0f4cf0a03892157ebf3a472d3e9450a41f038e + Author: Lewis Baker + Date: Sun Aug 4 09:26:26 2024 +0930 + + [snd.expos] Fix typo in definition of SCHED-ENV exposition-only helper + + Change `o1` -> `o2` to reference the expression declared as part of the definition of `SCHED-ENV`. + + commit 5056b86597f5ba9278601db46a415f2d76e1bc8f + Author: Jens Maurer + Date: Fri Aug 2 17:38:05 2024 +0200 + + [temp.constr.order] Reflect fold expanded constraints in footnotes + + commit c92bc384b118412322f9893832508bf17f46f644 + Author: Jens Maurer + Date: Thu Aug 1 12:35:50 2024 +0200 + + [dcl.fct] Fix obsolete phrasing when defining 'function type' + + commit fabbff2d812e0a99bd1162460812ec2f5399636e + Author: Arthur O'Dwyer + Date: Thu Aug 8 17:15:39 2024 -0400 + + [sequences] Consistent comma in "If X, there are no effects" (#7139) + + commit 04c5a0c509dbf8f9f81223d1de5bb917cd3074c5 + Author: Hana Dusíková + Date: Tue Aug 20 12:21:43 2024 +0200 + + [meta.const.eval] Fix function declaration in example (#7234) + + commit ab4c0663dc72f09fb8ef6c366352c9d1a68e8fa9 + Author: Vlad Serebrennikov + Date: Fri Aug 23 22:06:05 2024 +0400 + + [expr.prim.lambda.capture] Incorporate ellipsis into "captured by copy" definition + + commit 6ea6df4c96653d6696bb0133253ea0159b0f278f + Author: Vlad Serebrennikov + Date: Sat Aug 24 23:24:01 2024 +0400 + + [dcl.type.elab] Remove redundant full stop (#7242) + + commit 24ceda755967b022e8e089d4f0cdcf4bc99a4adb + Author: Hewill Kang + Date: Mon Aug 26 18:29:28 2024 +0800 + + [exec.snd.apply,exec.schedule.from] Properly mark "see below" (#7210) + + commit 447b6291061d50a582f72dd42d9d6265857ded5c + Author: Joachim Wuttke + Date: Mon Aug 26 22:30:39 2024 +0200 + + [numerics] Correct typo Bessell -> Bessel (#7244) + + commit db0ca108a9b44ef8f06338ecf68f1e4653be4267 + Author: Arthur O'Dwyer + Date: Thu Aug 29 06:13:18 2024 -0400 + + [inplace.vector] Fix some spelling/grammar issues (#7243) + + commit 21e477fb6dbfa7813eb2263bfa31c748bdce589b + Author: Casey Carter + Date: Fri Aug 30 05:07:36 2024 -0700 + + [lib] Remove `inline` from variable templates (#7240) + + commit c001805bb769fe237034151d59ddd20835a17298 + Author: A. Jiang + Date: Fri Aug 30 20:52:00 2024 +0800 + + [lib] Remove `friend class X` (#6427) + + Friendship between library classes is considered an implementation detail. + + commit 1fafde9a04a3760debb932839791b1d2047ba432 + Author: A. Jiang + Date: Fri Aug 30 20:52:49 2024 +0800 + + [fs.class.directory.entry.general] Remove superfluous "unneeded" (#7245) + + commit e010cf6cde64a498c2bc4291e7e79e66e8ace79a + Author: Vlad Serebrennikov + Date: Fri Aug 23 21:03:51 2024 +0400 + + [basic.scope.scope] Fix a note about declarations that do not bind names + + The note is saying that declarations of qualified names do not bind names, but this is not supported by normative wording in [dcl.meaning] + + commit 36a1f39068e71d69e4ca534c5b72891055675e88 + Author: Arthur O'Dwyer + Date: Wed Sep 4 10:23:14 2024 -0400 + + [forward.list] Replace misplaced comma with period (#7246) + + commit f23059bf704a48b4805db28441ec73b61054ab9d + Author: A. Jiang + Date: Thu Sep 5 00:03:56 2024 +0800 + + [optional.syn] Use `decay_t` directly instead of "see below" (#7247) + + commit 9d9a3777f1a571dd2648023fe70848c32aebda09 + Author: Casey Carter + Date: Sun Sep 8 12:13:53 2024 -0700 + + [associative.reqmts.general,unord.req.general] Fix cross-references to [container.alloc.reqmts] and [container.reqmts] (#7249) + + Both paragraphs incorrectly point to [container.reqmts] instead of [container.alloc.reqmts] for "the requirements of an allocator-aware container". + + commit d930c5fa6728dd0b599f9c7918a2f0a0f747aaa2 + Author: Jan Schultke + Date: Mon Sep 16 20:35:33 2024 +0200 + + [expr.delete] Remove stray "the" between words (#7253) + + commit 9243ba5befaea8fd3e878e6114942db8d556a6e0 + Author: Steve Downey + Date: Tue Sep 17 06:13:18 2024 -0400 + + [optional.assign] Use itemized list for operator=(U&& v) constraints (#7255) + + commit 4930897a2a45fa57fd9d766a24229a9e3f14f23e + Author: Jens Maurer + Date: Sat Aug 21 13:58:22 2021 +0200 + + [dcl.spec.general,dcl.fct.spec] Clarify duplication of decl-specifiers + + commit d0c00bf629f4b91d19176c2397aa3ff7c1c0ce63 + Author: Jens Maurer + Date: Thu Sep 26 18:49:15 2024 +0200 + + [tab:lex.charset.literal] Shorten table heading + + Fixes ISO/CS comment (C++23 proof) + + commit 945b1c071ed511d11a2152aa70e08290f91a7856 + Author: Jens Maurer + Date: Thu Sep 26 19:11:58 2024 +0200 + + [tab:re.matchflag] Shorten table heading + + Fixes ISO/CS comment (C++23 proof) + + commit 4e34492bc7279fedb0e066f4925860e686fa81dc + Author: Jens Maurer + Date: Thu Sep 26 19:43:50 2024 +0200 + + [rand.req] Fix table headers for longtable continued on following page + + Fixes ISO/CS comment (C++23 proof) + + commit 2b1e6d2952987bf4ada8275212a7bb297bb0c1c7 + Author: Jens Maurer + Date: Thu Sep 26 20:19:01 2024 +0200 + + [macros] Fix duplicate vertical lines visible in tables in [optional.assign] + + Fixes ISO/CS comment (C++23 proof) + + commit 0680a08ee677e0970b4460fd614f58b122845047 + Author: Jonathan Wakely + Date: Thu Sep 26 21:59:34 2024 +0100 + + [ios.init] Remove unused Init::init_cnt static member (#7263) + + The text that made use of this variable was removed by LWG1123 and has + not been present in the WP since N3090. The effects of Init construction + and destruction are specified entirely without the use of this variable, + so it serves no purpose now. + + commit afdd158f555892507bc44c6d372c3b45a7f09832 + Author: Jens Maurer + Date: Fri Sep 27 00:09:11 2024 +0200 + + [styles] Format title of \codeblocktu using 'caption' package + + This restores the C++20 status of the formatting. + + commit 2b3e09e2cc773b7205310917c5a6b2bdd87340af + Author: Casey Carter + Date: Tue Oct 1 03:22:29 2024 -0700 + + [inplace.vector.cons] "Constructs an object" is redundant (#7252) + + commit 70954edf0b2c915d9b2ca4a1cff99b1c1cba2089 + Author: Alisdair Meredith + Date: Tue Oct 1 23:09:04 2024 -0400 + + [depr.lit] Fix grammar according to P2361R6 + + P2361R6 introduced the notion of unevaluated strings, and + updated the grammar for literal operator function accodingly. + Unfortunely, the corresponding grammar reference that was + deprecated was not similarly updated. + + commit 08b167d5476c9fd02a7a0484ae031cb358a99ddf + Author: Jonathan Wakely + Date: Sat Oct 5 22:24:02 2024 +0100 + + [priqueue.cons.alloc] Add missing initialization for comp (#7291) + + This is consistent with p2 and p8 which also value-initialize it. + + commit 738b14f990e0575a3ca63b579d87edb5a6133ffb + Author: Casey Carter + Date: Sat Oct 5 15:03:04 2024 -0700 + + [array.creation] Clarify "Mandates" for `to_array` overloads (#7286) + + It's confusing that these `to_array` overloads require `T` to be constructible from various types, when they actually construct `remove_cv_t` objects. We experts know that initialization doesn't depend on the cv-qualification of the target type ([dcl.init.general]/16), but there's no need to make readers jump through hoops to understand the spec. + + commit d5c9f2d248860e8e7de78f595b93a8b01c7e02c8 + Author: Lewis Baker + Date: Tue Oct 8 21:07:48 2024 +1030 + + [exec.split,exec.when.all] Fix typo stop_callback_of_t -> stop_callback_for_t (#7295) + + commit 58c01ba5765e8c91ce4aab462d25247167a7e481 + Author: Jonathan Wakely + Date: Tue Oct 8 11:38:42 2024 +0100 + + [re.grammar] Add missing backslash to UnicodeEscapeSequence example (#7290) + + commit ebef68dd9f1c3bccfe06d14eb83c05a7a35dcec3 + Author: Lewis Baker + Date: Tue Oct 8 22:06:23 2024 +1030 + + [exec.just] Add missing LaTeX escape for product-type construction (#7216) + + commit 7ea8f59e19842e720360f15b64c2199ea27641ac + Author: A. Jiang + Date: Thu Oct 10 17:53:54 2024 +0800 + + [mutex.syn] Add missing ',' for consistency + + commit 7c6322a59e3359c5002357831328b25939cd5383 + Author: Lewis Baker + Date: Sun Oct 13 04:07:30 2024 +1030 + + [stoptoken.concepts] Remove redundant 'swappable' clause from 'stoppable_token' concept (#7299) + + The `stoppable_token` concept requires both `copyable` and `swappable`. However, the `copyable` requirement already subsumes `movable`, which subsumes `swappable`. + + Therefore the requirement for `swappable` can be removed from the `stoppable_token` concept definition with no semantic change. + + commit 9bf42221ab5a52ef10cb980a22e8a9617dbbf18b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Oct 12 22:39:57 2024 +0200 + + [rcu.syn] Add missing ',' in comment (#7301) + + commit a0411db859cf1eabc2be24a5d2add4eaf288dac5 + Author: Jens Maurer + Date: Mon Oct 14 12:30:30 2024 +0200 + + [expr.const] Add paragraph number for general example + + commit 3982d5d5758df949e3c2e0174c72758189be6f2e + Author: Alisdair Meredith + Date: Mon Oct 14 08:54:22 2024 -0400 + + [except.ctor] Retitle subclause as 'stack unwinding' (#7282) + + The purpose of this subclause is to define stack unwinding, + which in specified in terms of the lifetime of objects, not + just class types. Hence, while much of the text is addressing + interactions with contructors and destructors (the original + subclause title) it does more than just that. + + commit 4eb30d3d618ef44ae3925a1a62090bbbbfe8cabf + Author: Alisdair Meredith + Date: Wed Oct 16 07:39:15 2024 -0400 + + [cpp.subst] change "proprocessing file" to "translation unit" (#7293) + + The term 'preprocessing translation unit' is defined in [lex.separate] + while the term 'preprocessing file' is never defined, and is + not used anywhere else in the standard. Prefer to use the + specified term, as it reasonably covers this case. + + commit 40228c690cb8d2ac27bd54bdddeabe425bd022b2 + Author: Alisdair Meredith + Date: Wed Oct 16 07:40:20 2024 -0400 + + [cpp.import] Change "directive" to "definition" in "active macro directive" (#7292) + + The term 'active macro directive' is defined in p6, but never used. + Meanwhile, there are multiple uses of 'active macro definition' but + that term is never defined, including in the very sentence following + the definition of the unused term, and in other clauses that + cross-reference to this clause for their definition. + + commit 47da0e8b88bf1aa20aa474edf04a6d29e70b7563 + Author: Anders Schau Knatten + Date: Wed Oct 16 13:41:26 2024 +0200 + + [over.oper.general] Change "basic type" to "fundamental type" (#7287) + + The term "basic type" is used twice in this note but it's never defined anywhere, nor used. + + commit 7fe7519a5af674cd914344c650529f743fd92fc2 + Author: Alisdair Meredith + Date: Tue Oct 1 22:13:53 2024 -0400 + + [except.handle] Remove confusing comparison to variadic functions + + The analogy that the ellipsis in an exception handler was similar to an + ellipsis in a function declaration may have made sense at one time, but + the comparison with a syntax using a macro based API calling 'va_arg' + to access its contents --- something that is not possible for an + exception handler --- seems more confusing than helpful today. + + commit d225f51f8cb799fb014cb73beb7dcccc044392cc + Author: Jonathan Wakely + Date: Tue Aug 20 11:58:24 2024 +0100 + + [text.encoding.aliases] Add note about what isn't required + + Make it explicit that `copyable` is intended, rather than `semiregular`, + and that the return types of `begin()` and `end()` can differ. + + Also remove a FIXME comment for something that doesn't need fixing. + These requirements on a type are specified in our usual form, it would + be wrong to use _Remarks_: or _Requires_: here. + + commit 6338d95ae620f5e4d37d27a39a40f9de9af37b77 + Author: Alisdair Meredith + Date: Wed Oct 16 08:47:02 2024 -0400 + + [lex.charset] Introduce parent subclause [lex.char] for character sets and UCNs (#7067) + + The grammar for universal-character-name is oddly sandwiched into the + middle of the subclause talking about the different character sets used + by the standard. To improve the flow, extract that grammar into its own + subclause. + + In the extraction, I make three other clarifying changes. First, describe + this new subclause as 'a way to name any element of the of the translation + character set using just the basic character set' rather than simply + 'a way to name other characters'. Then, merge the sentence on where universal + characters are prohibited into the new intro sentence describing universal + characters, to make clear that there is no contradiction between nominating + a character, and how that character can be used. Finally, remove the 'one of' + in the grammar where there is only one option to choose. + + commit 9b6b757f34bf4a1eeb6a66481a444b83f1ee5770 + Author: Matthias Kretz + Date: Thu Sep 12 21:41:02 2024 +0200 + + [sf.cmath.assoc.laguerre,sf.cmath.assoc.legendre] Add reference to eq + + The associated Laguerre/Legendre functions build on the + Laguerre/Legendre functions, which are defined in different equations. + Point to them from the associated functions. + + Also use the correct \ell as used in the formula. + + commit 0456a32e41772b0a68b4055fb4e6533cb64e0e3d + Author: Yihe Li + Date: Thu Sep 5 23:59:58 2024 +0800 + + [utility.syn, flat.map.defn] Remove all [[nodiscard]] from library wording + + commit 8b2c7fc3c58bd109c82a016ee2cc5b691bdcd853 + Author: Eisenwave + Date: Mon Jun 10 23:22:04 2024 +0200 + + [expr.new] Extend example for new-expressions with zero size arrays + + commit fb34daf31b53389cc35b3f5f65a69785fc6dd1de + Author: Alisdair Meredith + Date: Tue Jul 23 22:32:52 2024 -0400 + + [char.traits] Better cross-reference several headers + + commit 220cb742e8056ad033ad8dce5630d7d3acaa4c7d + Author: Thomas Köppe + Date: Wed Oct 16 15:37:39 2024 +0100 + + [debugging] Move [debugging] to the end of Clause [diagnostics] + + Part of the C++26 clause restructuring (#5315). + + commit 7a2dafa6b4cca842e264bfd544b69452fb448c39 + Author: Thomas Köppe + Date: Wed Oct 16 15:43:39 2024 +0100 + + [execpol] Move [execpol] to the end of subclause [algorithms.parallel] + + Part of the C++26 clause restructuring (#5315). + + commit 93e2e1c6bcf5e9c3e551d964978e8bf241c392a4 + Author: Thomas Köppe + Date: Wed Oct 16 15:52:54 2024 +0100 + + [type.index] Move [type.index] into subclause [support.rtti] + + The subclause is integrated into the structure of [support.rtti], + meaning that the synopsis becomes a sibling of the rest, and the + subdivisions of the remaining text are removed (in analogy with + [type.info]). + + Part of the C++26 clause restructuring (#5315). + + commit cdb120a4aee270f4e6e40dd7b07885c70651224e + Author: Thomas Köppe + Date: Wed Oct 16 17:25:51 2024 +0100 + + [containers] Move synopses right in front of the classes they define + + Part of the C++26 clause restructuring (#5315). + + commit b7e389c9feca4839f77ad60985f509e01f96a399 + Author: Thomas Köppe + Date: Wed Oct 16 15:27:06 2024 +0100 + + [std] Reorder clauses: [algorithm], [strings] + + Part of the C++26 clause restructuring (#5315). + + commit 5512050c2db44d87566d25ce4f70b530624cb330 + Author: Thomas Köppe + Date: Wed Oct 16 15:36:47 2024 +0100 + + [std] Create new top-level Clause [text], following [strings] + + Part of the C++26 clause restructuring (#5315). + + commit fc6f670832980fc7b8219cb6945592cbe45d9239 + Author: Thomas Köppe + Date: Wed Oct 16 19:01:21 2024 +0100 + + [text, re] Move [re] into [text] + + Part of the C++26 clause restructuring (#5315). + + commit 5d106373aada591874ab5e38301502b3012e0502 + Author: Thomas Köppe + Date: Wed Oct 16 19:06:03 2024 +0100 + + [text, localization] Move [localization] into [text] + + The subclause [text.encodings] is extracted and elevated to a sibling + subclause of [localization]. + + Part of the C++26 clause restructuring (#5315). + + commit 804846a56f7e73dafe4ebd621fa81097d2e94603 + Author: Thomas Köppe + Date: Wed Oct 16 20:15:42 2024 +0100 + + [charconv, format] Move [charconv], [format] to [text] + + Part of the C++26 clause restructuring (#5315). + + commit 4b1a9a76c29c31cc3f679a8bdb1603842baf3501 + Author: Thomas Köppe + Date: Wed Oct 16 20:31:33 2024 +0100 + + [text, c.strings] Move text-related parts of [c.strings] to [text] + + The text-related subclauses [cctype.syn], [cwctype.syn], [cwchar.syn], + [cuchar.syn], and [c.mb.wcs] are moved to a new subclause [text.c.strings]. + + Part of the C++26 clause restructuring (#5226, #5315). + + commit 8003b627a7e336c2e9f350a3bb1ad395ec7c1cc7 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Oct 16 19:41:35 2024 +0000 + + [expr, temp.arg.nontype] Use 'pointer to' instead of 'address of' (#6174) + + Specifically, in: + * [expr.prim.lambda.closure]p8, p11 + * [expr.const]p13.3 + * [temp.arg.nontype]p3 + + commit 198e991fed47efcd8b7fe1ad98ecde4d8722a201 + Author: Alisdair Meredith + Date: Wed Oct 2 15:55:49 2024 -0400 + + [except.handle] group all paragraphs on searching for handler + + This commit moves all of the paragraphs involved in the search for a + handler for an exception into a single logical sequence. + + After this change, [except.spec] deals only with specifying the + 'noexcept' function decorator and its interaction with the + 'noexcept' operator, and contains no text regarding exceptions + themselves. It might be appropriate to move that subclause into + the [dcl] structure at a future date. diff --git a/papers/wd-index.md b/papers/wd-index.md index 83e6984ee2..bf7c4b1679 100644 --- a/papers/wd-index.md +++ b/papers/wd-index.md @@ -51,3 +51,4 @@ * [N4981](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4981.pdf) 2024-03 C++ Working Draft * [N4986](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf) 2024-06 C++ Working Draft * [N4986](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf) 2024-08 C++ Working Draft + * [N4986](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4993.pdf) 2024-10 C++ Working Draft diff --git a/source/config.tex b/source/config.tex index 990cc07b44..8253638e61 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,7 +1,7 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{Dxxxx} +\newcommand{\docno}{N4993} \newcommand{\prevdocno}{N4988} \newcommand{\cppver}{202302L}