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

+ + + +

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:

+ + + +

The new [text] clause obtains the following contents:

+ + + +

Additionally, the following subclauses are moved:

+ + + +

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/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/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} diff --git a/source/config.tex b/source/config.tex index 48233ea56a..8253638e61 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}{N4993} +\newcommand{\prevdocno}{N4988} \newcommand{\cppver}{202302L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index 1dd9f1f918..f43cc92f3b 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 @@ -2726,12 +2734,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} @@ -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}% @@ -4225,11 +4237,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} @@ -6034,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}% @@ -6460,7 +6290,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 +6311,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 @@ -6539,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} @@ -6911,7 +6777,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. @@ -6993,31 +6859,67 @@ \end{codeblock} \end{itemdescr} -\rSec2[forward.list]{Class template \tcode{forward_list}} +\rSec2[forward.list.syn]{Header \tcode{} synopsis} -\rSec3[forward.list.overview]{Overview} +\indexheader{forward_list}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} -\pnum -A \tcode{forward_list} is a container that supports forward iterators and allows -constant time insert and erase operations anywhere within the sequence, with storage -management handled automatically. Fast random access to list elements is not supported. -\begin{note} -It is intended that \tcode{forward_list} have zero space or time overhead -relative to a hand-written C-style singly linked list. Features that would conflict with -that goal have been omitted. -\end{note} +namespace std { + // \ref{forward.list}, class template \tcode{forward_list} + template> class forward_list; -\pnum -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, -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} -provides the \tcode{assign} member functions and -several of the optional sequence container requirements\iref{sequence.reqmts}. -Descriptions are provided here only for operations on + 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} + +\pnum +A \tcode{forward_list} is a container that supports forward iterators and allows +constant time insert and erase operations anywhere within the sequence, with storage +management handled automatically. Fast random access to list elements is not supported. +\begin{note} +It is intended that \tcode{forward_list} have zero space or time overhead +relative to a hand-written C-style singly linked list. Features that would conflict with +that goal have been omitted. +\end{note} + +\pnum +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. +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} +provides the \tcode{assign} member functions and +several of the optional sequence container requirements\iref{sequence.reqmts}. +Descriptions are provided here only for operations on \tcode{forward_list} that are not described in that table or for operations where there is additional semantic information. @@ -7894,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} @@ -8270,7 +8208,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 +8508,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}% @@ -8643,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} @@ -9018,7 +9008,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 +9065,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 +9087,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 +9153,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} @@ -9266,7 +9256,6 @@ // bit reference class @\libmember{reference}{vector}@ { - friend class vector; constexpr reference() noexcept; public: @@ -9490,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} @@ -9769,7 +9780,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 @@ -9882,7 +9893,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 +9935,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 @@ -9932,7 +9943,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}% @@ -9972,7 +9983,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 @@ -9980,7 +9991,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}% @@ -10005,7 +10016,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 @@ -10248,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} @@ -10380,7 +10331,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 +11067,6 @@ using node_type = @\unspec@; class value_compare { - friend class multimap; protected: Compare comp; value_compare(Compare c) : comp(c) { } @@ -11401,34 +11350,94 @@ \end{codeblock} \end{itemdescr} -\rSec2[set]{Class template \tcode{set}} +\rSec2[associative.set.syn]{Header \tcode{} synopsis}% -\rSec3[set.overview]{Overview} +\indexheader{set}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} -\pnum -\indexlibraryglobal{set}% -A -\tcode{set} -is an associative container that supports unique keys (i.e., contains at most one of each key value) and -provides for fast retrieval of the keys themselves. -The -\tcode{set} class -supports bidirectional iterators. +namespace std { + // \ref{set}, class template \tcode{set} + template, class Allocator = allocator> + class set; -\pnum -A \tcode{set} meets all of the requirements -of a container\iref{container.reqmts}, -of a reversible container\iref{container.rev.reqmts}, -of an allocator-aware container\iref{container.alloc.reqmts}. and -of an associative container\iref{associative.reqmts}. -A -\tcode{set} -also provides most operations described in~\ref{associative.reqmts} -for unique keys. -This means that a -\tcode{set} -supports the -\tcode{a_uniq} + 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} + +\pnum +\indexlibraryglobal{set}% +A +\tcode{set} +is an associative container that supports unique keys (i.e., contains at most one of each key value) and +provides for fast retrieval of the keys themselves. +The +\tcode{set} class +supports bidirectional iterators. + +\pnum +A \tcode{set} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}. and +of an associative container\iref{associative.reqmts}. +A +\tcode{set} +also provides most operations described in~\ref{associative.reqmts} +for unique keys. +This means that a +\tcode{set} +supports the +\tcode{a_uniq} operations in~\ref{associative.reqmts} but not the \tcode{a_eq} @@ -11752,7 +11761,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}. @@ -12167,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} @@ -13454,6 +13395,74 @@ \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} + \rSec2[unord.set]{Class template \tcode{unordered_set}}% \indexlibraryglobal{unordered_set} @@ -14301,231 +14310,105 @@ a type that does not qualify as an input iterator is deduced for that parameter. \pnum -For container adaptors that have them, -the \tcode{insert}, \tcode{emplace}, and \tcode{erase} members -affect the validity of iterators, references, and pointers -to the adaptor's container(s) in the same way that -the containers' respective -\tcode{insert}, \tcode{emplace}, and \tcode{erase} members do. -\begin{example} -A call to \tcode{flat_map::insert} -can invalidate all iterators to the \tcode{flat_map}. -\end{example} - -\pnum -A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: -\begin{itemize} -\item It has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. -\item It has a \tcode{Compare} template parameter and a type that qualifies as an allocator is deduced for that parameter. -\item It has a \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter and a type that qualifies as an allocator is deduced for that parameter. -\item It has no \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter, and it has an \tcode{Allocator} template parameter, and a type that does not qualify as an allocator is deduced for that parameter. -\item It has both \tcode{Container} and \tcode{Allocator} template parameters, and \tcode{uses_allocator_v} is \tcode{false}. -\item It has both \tcode{KeyContainer} and \tcode{Allocator} template parameters, and -\tcode{uses_allocator_v} is \tcode{false}. -\item It has both \tcode{KeyContainer} and \tcode{Compare} template parameters, and -\begin{codeblock} -is_invocable_v -\end{codeblock} -is not a valid expression or is \tcode{false}. -\item It has both \tcode{MappedContainer} and \tcode{Allocator} template parameters, and -\tcode{uses_allocator_v} is \tcode{false}. -\end{itemize} - -\pnum -The exposition-only alias template \exposid{iter-value-type} -defined in \ref{sequences.general} and -the exposition-only alias templates \exposid{iter-key-type}, \exposid{iter-mapped-type}, -\exposid{range-key-type}, and \exposid{range-mapped-type} -defined in \ref{associative.general} -may appear in deduction guides for container adaptors. - -\pnum -The following exposition-only alias template -may appear in deduction guides for container adaptors: -\begin{codeblock} -template - using @\exposid{alloc-rebind}@ = // \expos - typename allocator_traits::template rebind_alloc; -\end{codeblock} - -\rSec2[queue.syn]{Header \tcode{} synopsis} - -\indexheader{queue} -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{queue}, class template \tcode{queue} - template> class queue; - - template - bool operator==(const queue& x, const queue& y); - template - bool operator!=(const queue& x, const queue& y); - template - bool operator< (const queue& x, const queue& y); - template - bool operator> (const queue& x, const queue& y); - template - bool operator<=(const queue& x, const queue& y); - template - bool operator>=(const queue& x, const queue& y); - template - compare_three_way_result_t - operator<=>(const queue& x, const queue& y); - - template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); - template - struct uses_allocator, Alloc>; - - // \ref{container.adaptors.format}, formatter specialization for \tcode{queue} - template Container> - struct formatter, charT>; - - // \ref{priority.queue}, class template \tcode{priority_queue} - template, - class Compare = less> - class priority_queue; - - template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); - template - struct uses_allocator, Alloc>; - - // \ref{container.adaptors.format}, formatter specialization for \tcode{priority_queue} - template Container, class Compare> - struct formatter, charT>; -} -\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; +For container adaptors that have them, +the \tcode{insert}, \tcode{emplace}, and \tcode{erase} members +affect the validity of iterators, references, and pointers +to the adaptor's container(s) in the same way that +the containers' respective +\tcode{insert}, \tcode{emplace}, and \tcode{erase} members do. +\begin{example} +A call to \tcode{flat_map::insert} +can invalidate all iterators to the \tcode{flat_map}. +\end{example} - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; +\pnum +A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. +\item It has a \tcode{Compare} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has a \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has no \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter, and it has an \tcode{Allocator} template parameter, and a type that does not qualify as an allocator is deduced for that parameter. +\item It has both \tcode{Container} and \tcode{Allocator} template parameters, and \tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{KeyContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{KeyContainer} and \tcode{Compare} template parameters, and +\begin{codeblock} +is_invocable_v +\end{codeblock} +is not a valid expression or is \tcode{false}. +\item It has both \tcode{MappedContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. +\end{itemize} - template - struct uses_allocator, - Allocator>; +\pnum +The exposition-only alias template \exposid{iter-value-type} +defined in \ref{sequences.general} and +the exposition-only alias templates \exposid{iter-key-type}, \exposid{iter-mapped-type}, +\exposid{range-key-type}, and \exposid{range-mapped-type} +defined in \ref{associative.general} +may appear in deduction guides for container adaptors. - // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} - template - typename flat_multimap::size_type - erase_if(flat_multimap& c, Predicate pred); -} +\pnum +The following exposition-only alias template +may appear in deduction guides for container adaptors: +\begin{codeblock} +template + using @\exposid{alloc-rebind}@ = // \expos + typename allocator_traits::template rebind_alloc; \end{codeblock} -\rSec2[flat.set.syn]{Header \tcode{} synopsis}% -\indexheader{flat_set}% +\rSec2[queue.syn]{Header \tcode{} synopsis} +\indexheader{queue} \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{}; + // \ref{queue}, class template \tcode{queue} + template> class queue; - template - struct uses_allocator, Allocator>; + template + bool operator==(const queue& x, const queue& y); + template + bool operator!=(const queue& x, const queue& y); + template + bool operator< (const queue& x, const queue& y); + template + bool operator> (const queue& x, const queue& y); + template + bool operator<=(const queue& x, const queue& y); + template + bool operator>=(const queue& x, const queue& y); + template + compare_three_way_result_t + operator<=>(const queue& x, const queue& y); - // \ref{flat.set.erasure}, erasure for \tcode{flat_set} - template - typename flat_set::size_type - erase_if(flat_set& c, Predicate pred); + template + void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; - // \ref{flat.multiset}, class template \tcode{flat_multiset} - template, class KeyContainer = vector> - class flat_multiset; + // \ref{container.adaptors.format}, formatter specialization for \tcode{queue} + template Container> + struct formatter, charT>; - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; + // \ref{priority.queue}, class template \tcode{priority_queue} + template, + class Compare = less> + class priority_queue; - template - struct uses_allocator, Allocator>; + template + void swap(priority_queue& x, + priority_queue& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; - // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} - template - typename flat_multiset::size_type - erase_if(flat_multiset& c, Predicate pred); + // \ref{container.adaptors.format}, formatter specialization for \tcode{priority_queue} + template Container, class Compare> + struct formatter, charT>; } \end{codeblock} @@ -15288,8 +15171,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} @@ -15395,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} @@ -15753,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} @@ -16002,7 +15972,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; @@ -17190,7 +17160,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; @@ -17542,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} @@ -17746,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; @@ -18023,7 +18033,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 @@ -18041,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); @@ -18134,7 +18144,7 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{extract}{flatset}% +\indexlibrarymember{extract}{flat_set}% \begin{itemdecl} container_type extract() &&; \end{itemdecl} @@ -18409,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; @@ -21949,9 +21959,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}. @@ -22055,7 +22065,7 @@ LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value \end{codeblock} -is true. +is \tcode{true}. \pnum \begin{itemize} @@ -22445,7 +22455,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} @@ -23207,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; @@ -23228,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); } @@ -23673,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/declarations.tex b/source/declarations.tex index 987905fa4c..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 @@ -1604,7 +1607,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 @@ -3588,16 +3591,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 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/exceptions.tex b/source/exceptions.tex index 67e052c476..a462fe0bff 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}} @@ -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. @@ -618,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. @@ -635,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 @@ -807,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 diff --git a/source/exec.tex b/source/exec.tex index 4ed6ea4271..8608dd9624 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}. @@ -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 @@ -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 @@ -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, \tcode{true} if \tcode{\libconcept{derived_from}} is \tcode{true}. \item Otherwise, \tcode{false}. \end{itemize} @@ -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 @@ -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)}. @@ -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} @@ -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 @@ -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}. @@ -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} @@ -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} @@ -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< @@ -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 @@ -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, @@ -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; @@ -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}@(); @@ -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 @@ -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} @@ -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} @@ -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 @@ -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>; } @@ -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} @@ -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/expressions.tex b/source/expressions.tex index eeca4bfebc..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 @@ -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 @@ -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 @@ -5948,7 +5957,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, @@ -7749,6 +7758,8 @@ would disqualify $E$ from being a core constant expression. \end{note} \end{itemize} + +\pnum \begin{example} \begin{codeblock} int x; // not constant @@ -7975,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/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. diff --git a/source/iostreams.tex b/source/iostreams.tex index f4e9bfff7a..80a58115aa 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} @@ -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(); @@ -1446,7 +1432,7 @@ \begin{itemdescr} \pnum \returns -\tcode{index} +\exposid{index} \tcode{++}. \pnum @@ -1467,20 +1453,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 +1491,7 @@ \pnum \returns On success -\tcode{iarray[idx]}. +\tcode{\exposid{iarray}[idx]}. On failure, a valid \tcode{long\&} initialized to 0. @@ -1523,13 +1509,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 +1643,7 @@ void state(stateT); private: - stateT st; // \expos + stateT @\exposid{st}@; // \expos }; } \end{codeblock} @@ -1672,7 +1658,7 @@ \begin{itemdescr} \pnum \effects -Assigns \tcode{s} to \tcode{st}. +Assigns \tcode{s} to \exposid{st}. \end{itemdescr} \indexlibrarymember{state}{fpos}% @@ -1683,7 +1669,7 @@ \begin{itemdescr} \pnum \returns -Current value of \tcode{st}. +Current value of \exposid{st}. \end{itemdescr} \rSec3[fpos.operations]{Requirements} @@ -4521,12 +4507,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 +4609,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 +4646,7 @@ \begin{itemdescr} \pnum \returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec3[istream.formatted]{Formatted input functions} @@ -6189,12 +6175,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 +6221,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 +6264,7 @@ \pnum \effects Returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec4[ostream.seeks]{Seek members} @@ -6446,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 @@ -6456,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(); @@ -6469,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(); @@ -6483,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 @@ -6553,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} @@ -7114,7 +7089,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 +8096,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 +8119,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 +8144,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 +8170,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 +8185,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 +8205,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 +8222,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 +8243,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 +8274,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 +8289,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 +8397,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 +8443,7 @@ \begin{itemdescr} \pnum \returns -\tcode{buf.get_allocator()}. +\tcode{\exposid{buf}.get_allocator()}. \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% @@ -8515,7 +8490,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 +8516,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 +8541,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8586,8 +8561,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8601,8 +8576,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 +8598,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 +8658,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 +8744,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 +8939,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -8980,7 +8955,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 +8969,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 +8985,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 +8999,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 +9015,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 +9032,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 +9053,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 +9081,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 +9096,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 +9113,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 +9141,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% @@ -9337,7 +9312,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9353,7 +9328,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 +9342,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 +9358,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 +9372,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 +9388,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 +9405,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 +9426,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 +9454,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 +9469,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 +9486,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 +9513,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% @@ -9710,7 +9685,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9727,7 +9702,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 +9716,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 +9734,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 +9750,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 +9766,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 +9783,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 +9804,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 +9832,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 +9847,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 +9864,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 +9891,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% @@ -10365,7 +10340,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 +10428,7 @@ template void span(ROS&& s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10476,8 +10451,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 +10465,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 +10504,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 +10532,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10639,7 +10614,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10656,8 +10631,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 +10645,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 +10663,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 +10691,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10778,7 +10753,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10795,8 +10770,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 +10784,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 +10802,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 +10830,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -11834,7 +11809,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -11850,7 +11825,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 +11839,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 +11856,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 +11902,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 +11919,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 +11944,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 +12068,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12109,7 +12084,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 +12098,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 +12115,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 +12161,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 +12178,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 +12203,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 +12335,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12376,7 +12351,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 +12365,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 +12384,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 +12431,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 +12448,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 +12474,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 +12636,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 +12647,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 +12664,7 @@ \begin{itemdescr} \pnum \effects -Sets \tcode{wrapped} to \tcode{obuf}. +Sets \exposid{wrapped} to \tcode{obuf}. \pnum \ensures @@ -12823,10 +12798,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 +12824,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 +12843,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wrapped}. +\exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_allocator}{basic_syncbuf}% @@ -12890,7 +12865,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 +12879,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 +12943,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 +12988,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 +13012,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 +13034,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 +13079,7 @@ \begin{itemdescr} \pnum \returns -\tcode{sb.get_wrapped()}. +\tcode{\exposid{sb}.get_wrapped()}. \pnum \begin{example} @@ -16095,8 +16070,7 @@ operator<<(basic_ostream& os, const directory_entry& d); private: - filesystem::path pathobject; // \expos - friend class directory_iterator; // \expos + filesystem::path @\exposid{path-object}@; // \expos }; } \end{codeblock} @@ -16115,13 +16089,10 @@ \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()}. +without the cost of a call to \tcode{refresh()}. \end{note} \pnum @@ -16190,7 +16161,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. @@ -16208,7 +16179,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. @@ -16259,7 +16230,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject}. +\exposid{path-object}. \end{itemdescr} \indexlibrarymember{exists}{directory_entry}% @@ -16499,7 +16470,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject == rhs.pathobject}. +\tcode{\exposid{path-object} == rhs.\exposid{path-object}}. \end{itemdescr} \indexlibrarymember{operator<=>}{directory_entry}% @@ -16510,7 +16481,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} @@ -16620,8 +16591,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/lex.tex b/source/lex.tex index 7cb0a8f3ef..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 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|)} - \rSec1[lex.pptoken]{Preprocessing tokens} \indextext{token!preprocessing|(}% diff --git a/source/locales.tex b/source/locales.tex deleted file mode 100644 index 756cb9327d..0000000000 --- a/source/locales.tex +++ /dev/null @@ -1,5372 +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}}. - -\pnum -Both -\tcode{ranges::range_value_t} and -\tcode{ranges::range_reference_t} -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} - -\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/macros.tex b/source/macros.tex index d54104139d..9afe466f40 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}}% @@ -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}{} @@ -647,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 @@ -676,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} 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; } }; diff --git a/source/numerics.tex b/source/numerics.tex index ef2f93f4f2..e8afb21e09 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} @@ -9949,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}. @@ -9990,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} @@ -10143,7 +10147,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 +10190,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 +10230,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); 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} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 2b9e3e7e05..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. @@ -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} diff --git a/source/regex.tex b/source/regex.tex deleted file mode 100644 index d9a53ba893..0000000000 --- a/source/regex.tex +++ /dev/null @@ -1,4001 +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 when obtaining a match against a - character container sequence \range{first}{last}.} - {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{"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 e7a523d790..fea8f0a37c 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} @@ -124,16 +129,15 @@ \include{memory} \include{meta} \include{utilities} -\include{strings} \include{containers} \include{iterators} \include{ranges} \include{algorithms} +\include{strings} +\include{text} \include{numerics} \include{time} -\include{locales} \include{iostreams} -\include{regex} \include{threads} \include{exec} diff --git a/source/strings.tex b/source/strings.tex index 2dd8539b35..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} @@ -201,7 +199,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 +305,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. @@ -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/styles.tex b/source/styles.tex index e6372565cd..224c99d1e1 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 @@ -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 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/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} } diff --git a/source/templates.tex b/source/templates.tex index c91178088f..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}, @@ -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. % @@ -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 diff --git a/source/text.tex b/source/text.tex new file mode 100644 index 0000000000..99d63ad2c5 --- /dev/null +++ b/source/text.tex @@ -0,0 +1,13486 @@ +%!TEX root = std.tex + +\rSec0[text]{Text processing library} + +\rSec1[text.general]{General} + +This Clause describes components for dealing with text. +These components are summarized in \tref{text.summary}. + +\begin{libsumtab}{Text library summary}{text.summary} +\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep +\ref{localization} & Localization library & \tcode{}, \tcode{} \\ \rowsep +\ref{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} + +\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} + +\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[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|(} + +\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|)} + +\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} diff --git a/source/threads.tex b/source/threads.tex index 48711723b1..cb0f99e12a 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}@ = @@ -6456,7 +6455,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; @@ -12195,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; 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..2f66d7d65f 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 @@ -19,12 +19,7 @@ \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{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} @@ -58,7 +53,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 @@ -3238,7 +3233,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 @@ -3335,7 +3330,7 @@ constexpr void reset() noexcept; private: - T *val; // \expos + T* val; // \expos }; template @@ -3767,10 +3762,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 @@ -9799,7 +9796,6 @@ public: // bit reference class reference { - friend class bitset; constexpr reference() noexcept; public: @@ -15050,4242 +15046,286 @@ program-defined specialization. \end{itemize} -\rSec1[type.index]{Class \tcode{type_index}} - -\rSec2[type.index.synopsis]{Header \tcode{} synopsis} +\rSec1[bit]{Bit manipulation} -\indexheader{typeindex}% -\begin{codeblock} -#include // see \ref{compare.syn} +\rSec2[bit.general]{General} -namespace std { - class type_index; - template struct hash; - template<> struct hash; -} -\end{codeblock} +\pnum +The header \libheaderdef{bit} provides components to access, +manipulate and process both individual bits and bit sequences. -\rSec2[type.index.overview]{\tcode{type_index} overview} +\rSec2[bit.syn]{Header \tcode{} synopsis} -\indexlibraryglobal{type_index}% \begin{codeblock} +// all freestanding 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; + // \ref{bit.cast}, \tcode{bit_cast} + template + constexpr To bit_cast(const From& from) 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. + // \ref{bit.byteswap}, \tcode{byteswap} + template + constexpr T byteswap(T value) noexcept; + + // \ref{bit.pow.two}, integral powers of 2 + template + constexpr bool has_single_bit(T x) noexcept; + template + constexpr T bit_ceil(T x); + template + constexpr T bit_floor(T x) noexcept; + template + constexpr int bit_width(T x) noexcept; + + // \ref{bit.rotate}, rotating + template + constexpr T rotl(T x, int s) noexcept; + template + constexpr T rotr(T x, int s) noexcept; + + // \ref{bit.count}, counting + template + constexpr int countl_zero(T x) noexcept; + template + constexpr int countl_one(T x) noexcept; + template + constexpr int countr_zero(T x) noexcept; + template + constexpr int countr_one(T x) noexcept; + template + constexpr int popcount(T x) noexcept; + + // \ref{bit.endian}, endian + enum class endian { + little = @\seebelow@, + big = @\seebelow@, + native = @\seebelow@ }; } \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} +\rSec2[bit.cast]{Function template \tcode{bit_cast}} -\indexlibraryctor{type_index}% +\indexlibraryglobal{bit_cast}% \begin{itemdecl} -type_index(const type_info& rhs) noexcept; +template + constexpr To bit_cast(const From& from) 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} +\constraints +\begin{itemize} +\item \tcode{sizeof(To) == sizeof(From)} is \tcode{true}; +\item \tcode{is_trivially_copyable_v} is \tcode{true}; and +\item \tcode{is_trivially_copyable_v} is \tcode{true}. +\end{itemize} -\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} +An object of type \tcode{To}. +Implicitly creates objects nested within the result\iref{intro.object}. +Each bit of the value representation of the result +is equal to the corresponding bit in the object representation +of \tcode{from}. Padding bits of the result are unspecified. +For the result and each object created within it, +if there is no value of the object's type corresponding to the +value representation produced, the behavior is undefined. +If there are multiple such values, which value is produced is unspecified. +A bit in the value representation of the result is indeterminate if +it does not correspond to a bit in the value representation of \tcode{from} or +corresponds to a bit +for which the smallest enclosing object is not within its lifetime or +has an indeterminate value\iref{basic.indet}. +A bit in the value representation of the result is erroneous +if it corresponds to a bit +for which the smallest enclosing object has an erroneous value. +For each bit $b$ in the value representation of the result +that is indeterminate or erroneous, +let $u$ be the smallest object containing that bit enclosing $b$: +\begin{itemize} +\item +If $u$ is of unsigned ordinary character type or \tcode{std::byte} type, +$u$ has an indeterminate value +if any of the bits in its value representation are indeterminate, or +otherwise has an erroneous value. +\item +Otherwise, if $b$ is indeterminate, the behavior is undefined. +\item +Otherwise, the behaviour is erroneous, and the result is as specified above. +\end{itemize} +The result does not otherwise contain any indeterminate or erroneous values. -\begin{itemdescr} \pnum -\returns -\tcode{target->before(*rhs.target)}. +\remarks +This function is \keyword{constexpr} if and only if +\tcode{To}, \tcode{From}, and the types of all subobjects +of \tcode{To} and \tcode{From} are types \tcode{T} such that: +\begin{itemize} +\item \tcode{is_union_v} is \tcode{false}; +\item \tcode{is_pointer_v} is \tcode{false}; +\item \tcode{is_member_pointer_v} is \tcode{false}; +\item \tcode{is_volatile_v} is \tcode{false}; and +\item \tcode{T} has no non-static data members of reference type. +\end{itemize} \end{itemdescr} -\indexlibrarymember{operator>}{type_index}% +\rSec2[bit.byteswap]{\tcode{byteswap}} + +\indexlibraryglobal{byteswap}% \begin{itemdecl} -bool operator>(const type_index& rhs) const noexcept; +template + constexpr T byteswap(T value) 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} +\constraints +\tcode{T} models \libconcept{integral}. -\begin{itemdescr} \pnum -\returns -\tcode{!rhs.target->before(*target)}. -\end{itemdescr} +\mandates +\tcode{T} does not have padding bits\iref{basic.types.general}. -\indexlibrarymember{operator>=}{type_index}% -\begin{itemdecl} -bool operator>=(const type_index& rhs) const noexcept; -\end{itemdecl} +\pnum +Let the sequence $R$ comprise +the bytes of the object representation of \tcode{value} in reverse order. -\begin{itemdescr} \pnum \returns -\tcode{!target->before(*rhs.target)}. +An object \tcode{v} of type \tcode{T} +such that each byte in the object representation of \tcode{v} is equal to +the byte in the corresponding position in $R$. \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} +\rSec2[bit.pow.two]{Integral powers of 2} -\indexlibrarymember{hash_code}{type_index}% +\indexlibraryglobal{has_single_bit}% \begin{itemdecl} -size_t hash_code() const noexcept; +template + constexpr bool has_single_bit(T x) 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} +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. -\begin{itemdescr} \pnum \returns -\tcode{target->name()}. -\end{itemdescr} +\tcode{true} if \tcode{x} is an integral power of two; +\tcode{false} otherwise. -\rSec2[type.index.hash]{Hash support} +\end{itemdescr} -\indexlibrarymember{hash}{type_index}% +\indexlibraryglobal{bit_ceil}% \begin{itemdecl} -template<> struct hash; +template + constexpr T bit_ceil(T x); \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[execpol]{Execution policies} -\rSec2[execpol.general]{General} +Let $N$ be the smallest power of 2 greater than or equal to \tcode{x}. \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()); +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. -// explicitly sequential sort -sort(execution::seq, v.begin(), v.end()); +\pnum +\expects +$N$ is representable as a value of type \tcode{T}. -// permitting parallel execution -sort(execution::par, v.begin(), v.end()); +\pnum +\returns +$N$. -// 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} +\pnum +\throws +Nothing. -\rSec2[execpol.type]{Execution policy type trait} +\pnum +\remarks +A function call expression +that violates the precondition in the \expects element +is not a core constant expression\iref{expr.const}. +\end{itemdescr} -\indexlibraryglobal{is_execution_policy}% +\indexlibraryglobal{bit_floor}% \begin{itemdecl} -template struct is_execution_policy { @\seebelow@ }; +template + constexpr T bit_floor(T x) noexcept; \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. +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. \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} +\returns +If \tcode{x == 0}, \tcode{0}; +otherwise the maximal value \tcode{y} +such that \tcode{has_single_bit(y)} is \tcode{true} and \tcode{y <= x}. -\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}% +\indexlibraryglobal{bit_width}% \begin{itemdecl} -class execution::sequenced_policy { @\unspec@ }; +template + constexpr int bit_width(T x) noexcept; \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. +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. \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}. +\returns +If \tcode{x == 0}, \tcode{0}; +otherwise one plus the base-2 logarithm of \tcode{x}, +with any fractional part discarded. + \end{itemdescr} -\rSec2[execpol.par]{Parallel execution policy} +\rSec2[bit.rotate]{Rotating} + +\pnum +In the following descriptions, +let \tcode{N} denote \tcode{numeric_limits::digits}. -\indexlibraryglobal{execution::parallel_policy}% \begin{itemdecl} -class execution::parallel_policy { @\unspec@ }; +template + constexpr T rotl(T x, int s) noexcept; \end{itemdecl} +\indexlibraryglobal{rotl}% \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. +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. \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} +Let \tcode{r} be \tcode{s \% N}. -\rSec2[execpol.parunseq]{Parallel and unsequenced execution policy} +\pnum +\returns +If \tcode{r} is \tcode{0}, \tcode{x}; +if \tcode{r} is positive, \tcode{(x << r) | (x >> (N - r))}; +if \tcode{r} is negative, \tcode{rotr(x, -r)}. +\end{itemdescr} -\indexlibraryglobal{execution::parallel_unsequenced_policy}% \begin{itemdecl} -class execution::parallel_unsequenced_policy { @\unspec@ }; +template + constexpr T rotr(T x, int s) noexcept; \end{itemdecl} +\indexlibraryglobal{rotr}% \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} - -\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} -@% -\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 - 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) - inline 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 - - friend class basic_format_arg; // \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 - inline 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} - -\pnum -The header \libheaderdef{bit} provides components to access, -manipulate and process both individual bits and bit sequences. - -\rSec2[bit.syn]{Header \tcode{} synopsis} - -\begin{codeblock} -// all freestanding -namespace std { - // \ref{bit.cast}, \tcode{bit_cast} - template - constexpr To bit_cast(const From& from) noexcept; - - // \ref{bit.byteswap}, \tcode{byteswap} - template - constexpr T byteswap(T value) noexcept; - - // \ref{bit.pow.two}, integral powers of 2 - template - constexpr bool has_single_bit(T x) noexcept; - template - constexpr T bit_ceil(T x); - template - constexpr T bit_floor(T x) noexcept; - template - constexpr int bit_width(T x) noexcept; - - // \ref{bit.rotate}, rotating - template - constexpr T rotl(T x, int s) noexcept; - template - constexpr T rotr(T x, int s) noexcept; - - // \ref{bit.count}, counting - template - constexpr int countl_zero(T x) noexcept; - template - constexpr int countl_one(T x) noexcept; - template - constexpr int countr_zero(T x) noexcept; - template - constexpr int countr_one(T x) noexcept; - template - constexpr int popcount(T x) noexcept; - - // \ref{bit.endian}, endian - enum class endian { - little = @\seebelow@, - big = @\seebelow@, - native = @\seebelow@ - }; -} -\end{codeblock} - -\rSec2[bit.cast]{Function template \tcode{bit_cast}} - -\indexlibraryglobal{bit_cast}% -\begin{itemdecl} -template - constexpr To bit_cast(const From& from) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\begin{itemize} -\item \tcode{sizeof(To) == sizeof(From)} is \tcode{true}; -\item \tcode{is_trivially_copyable_v} is \tcode{true}; and -\item \tcode{is_trivially_copyable_v} is \tcode{true}. -\end{itemize} - -\pnum -\returns -An object of type \tcode{To}. -Implicitly creates objects nested within the result\iref{intro.object}. -Each bit of the value representation of the result -is equal to the corresponding bit in the object representation -of \tcode{from}. Padding bits of the result are unspecified. -For the result and each object created within it, -if there is no value of the object's type corresponding to the -value representation produced, the behavior is undefined. -If there are multiple such values, which value is produced is unspecified. -A bit in the value representation of the result is indeterminate if -it does not correspond to a bit in the value representation of \tcode{from} or -corresponds to a bit -for which the smallest enclosing object is not within its lifetime or -has an indeterminate value\iref{basic.indet}. -A bit in the value representation of the result is erroneous -if it corresponds to a bit -for which the smallest enclosing object has an erroneous value. -For each bit $b$ in the value representation of the result -that is indeterminate or erroneous, -let $u$ be the smallest object containing that bit enclosing $b$: -\begin{itemize} -\item -If $u$ is of unsigned ordinary character type or \tcode{std::byte} type, -$u$ has an indeterminate value -if any of the bits in its value representation are indeterminate, or -otherwise has an erroneous value. -\item -Otherwise, if $b$ is indeterminate, the behavior is undefined. -\item -Otherwise, the behaviour is erroneous, and the result is as specified above. -\end{itemize} -The result does not otherwise contain any indeterminate or erroneous values. - -\pnum -\remarks -This function is \keyword{constexpr} if and only if -\tcode{To}, \tcode{From}, and the types of all subobjects -of \tcode{To} and \tcode{From} are types \tcode{T} such that: -\begin{itemize} -\item \tcode{is_union_v} is \tcode{false}; -\item \tcode{is_pointer_v} is \tcode{false}; -\item \tcode{is_member_pointer_v} is \tcode{false}; -\item \tcode{is_volatile_v} is \tcode{false}; and -\item \tcode{T} has no non-static data members of reference type. -\end{itemize} -\end{itemdescr} - -\rSec2[bit.byteswap]{\tcode{byteswap}} - -\indexlibraryglobal{byteswap}% -\begin{itemdecl} -template - constexpr T byteswap(T value) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{T} models \libconcept{integral}. - -\pnum -\mandates -\tcode{T} does not have padding bits\iref{basic.types.general}. - -\pnum -Let the sequence $R$ comprise -the bytes of the object representation of \tcode{value} in reverse order. - -\pnum -\returns -An object \tcode{v} of type \tcode{T} -such that each byte in the object representation of \tcode{v} is equal to -the byte in the corresponding position in $R$. -\end{itemdescr} - -\rSec2[bit.pow.two]{Integral powers of 2} - -\indexlibraryglobal{has_single_bit}% -\begin{itemdecl} -template - constexpr bool has_single_bit(T x) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. - -\pnum -\returns -\tcode{true} if \tcode{x} is an integral power of two; -\tcode{false} otherwise. - -\end{itemdescr} - -\indexlibraryglobal{bit_ceil}% -\begin{itemdecl} -template - constexpr T bit_ceil(T x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -Let $N$ be the smallest power of 2 greater than or equal to \tcode{x}. - -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. - -\pnum -\expects -$N$ is representable as a value of type \tcode{T}. - -\pnum -\returns -$N$. - -\pnum -\throws -Nothing. - -\pnum -\remarks -A function call expression -that violates the precondition in the \expects element -is not a core constant expression\iref{expr.const}. -\end{itemdescr} - -\indexlibraryglobal{bit_floor}% -\begin{itemdecl} -template - constexpr T bit_floor(T x) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. - -\pnum -\returns -If \tcode{x == 0}, \tcode{0}; -otherwise the maximal value \tcode{y} -such that \tcode{has_single_bit(y)} is \tcode{true} and \tcode{y <= x}. - -\end{itemdescr} - -\indexlibraryglobal{bit_width}% -\begin{itemdecl} -template - constexpr int bit_width(T x) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. - -\pnum -\returns -If \tcode{x == 0}, \tcode{0}; -otherwise one plus the base-2 logarithm of \tcode{x}, -with any fractional part discarded. - -\end{itemdescr} - -\rSec2[bit.rotate]{Rotating} - -\pnum -In the following descriptions, -let \tcode{N} denote \tcode{numeric_limits::digits}. - -\begin{itemdecl} -template - constexpr T rotl(T x, int s) noexcept; -\end{itemdecl} - -\indexlibraryglobal{rotl}% -\begin{itemdescr} -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. - -\pnum -Let \tcode{r} be \tcode{s \% N}. - -\pnum -\returns -If \tcode{r} is \tcode{0}, \tcode{x}; -if \tcode{r} is positive, \tcode{(x << r) | (x >> (N - r))}; -if \tcode{r} is negative, \tcode{rotr(x, -r)}. -\end{itemdescr} - -\begin{itemdecl} -template - constexpr T rotr(T x, int s) noexcept; -\end{itemdecl} - -\indexlibraryglobal{rotr}% -\begin{itemdescr} -\pnum -\constraints -\tcode{T} is an unsigned integer type\iref{basic.fundamental}. +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. \pnum Let \tcode{r} be \tcode{s \% N}. @@ -19434,96 +15474,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} 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: % diff --git a/tools/check-source.sh b/tools/check-source.sh index 5ddbdf9dfc..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", @@ -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 |